Import catalog
Create and update item catalog using JSON import
You can create, update, or deactivate items using import from a JSON file.
With this tool, you can:
Features:
- Support for the following types of items:
- virtual items
- virtual currency
- virtual currency packages
- bundles
- Data validation. If the file structure or data format does not meet the requirements, you will see a list of errors when importing.
Limitations:
- Import is not available for game keys, promotions, and reward systems.
- The size of the uploaded JSON file should not exceed 7 MB.
- The parameter format in the JSON file must match the format specified in the corresponding product creation method:
Import of the item catalog
To import an item catalog from a file:
- Open the project in Publisher Account.
- In the side menu, click Store and go to the Virtual currency, Virtual items, or Bundles section.
- Click Import items.
- Choose the action:
- Add new items — only items with new SKUs will be added.
- Add new items and update existing ones — items with new SKUs will be added and data of existing items will be updated.
- Add new, update existing, disable missing items — items with SKUs from the file will be added/updated. If there is an item in the catalog, but there is no such SKU in the file, the status of the item in the Publisher Account will be changed to Partially available — item cannot be purchased separately but is available as part of a bundle or bonus.
- Fill in the file for import:
- Download the file template in the download window and fill it in according to the example below.
- Export the items and use the exported file as a template.
- Create your own JSON file and fill it out as per the example below.
An example of a full JSON file:
- json
{
"virtual_currency": [
{
"sku": "Gem_test_import",
"name": {
"en": "Gem_test_import"
},
"type": "virtual_currency",
"description": {
"en": "my test imported currency"
},
"image_url": "https://cdn3.xsolla.com/img/misc/merchant/default-dc-image.png",
"description": {
"en": "my test imported currency",
"de": "meine importierte Testwährung"
},
"attributes": [],
"is_free": false,
"order": 1,
"groups": [],
"regional_prices": [],
"prices": [
{
"amount": 2,
"currency": "USD",
"is_default": true,
"is_enabled": true
}
],
"media_list": [],
"vc_prices": [],
"is_enabled": true,
"is_show_in_store": true,
"regions": [],
"limits": {
"per_user": null,
"per_item": null,
"recurrent_schedule": null
},
"periods": [],
"inventory_options": {
"consumable": true,
"expiration_period": null
},
"is_hard": false
}
],
"virtual_items": [
{
"sku": "event_access_test_import",
"name": {
"en": "Special Event Access_test_import"
},
"type": "virtual_good",
"description": {
"en": "Get special event access as a bonus only on your first purchase. Find the right doggy at the Robo-Dog Exhibition!"
},
"image_url": "https://cdn3.xsolla.com/img/misc/images/1e3ef1a96cc9dd8d98bc124d5d6fad79.png",
"long_description": null,
"attributes": [],
"is_free": false,
"order": 1,
"groups": [
"my_test_group"
],
"regional_prices": [],
"prices": [
{
"amount": 35,
"currency": "USD",
"is_default": true,
"is_enabled": true
}
],
"media_list": [],
"vc_prices": [],
"is_enabled": true,
"is_show_in_store": true,
"regions": [],
"limits": {
"per_user": null,
"per_item": null,
"recurrent_schedule": null
},
"periods": [],
"inventory_options": {
"consumable": true,
"expiration_period": null
}
}
],
"virtual_currency_packages": [
{
"item_id": 441982,
"sku": "small_gold_pack_test_import",
"type": "bundle",
"name": {
"en": "Small gold pack"
},
"bundle_type": "virtual_currency_package",
"description": {
"en": "Gold x100"
},
"image_url": "https://cdn3.xsolla.com/img/misc/images/ba43c46ea75fd5713c210f5736993a92.png",
"vc_prices": [],
"regional_prices": [],
"prices": [
{
"amount": 5,
"currency": "USD",
"is_default": true,
"is_enabled": true
}
],
"is_enabled": true,
"is_show_in_store": true,
"regions": [],
"limits": {
"per_user": null,
"per_item": null,
"recurrent_schedule": null
},
"periods": [],
"attributes": [],
"long_description": null,
"media_list": [],
"order": 100000000,
"is_free": false,
"groups": [],
"content": [
{
"sku": "Gem_test_import",
"quantity": 100
}
]
}
],
"bundles": [
{
"item_id": 684024,
"sku": "start_pack_test_import_test_import",
"type": "bundle",
"name": {
"en": "Legendary Start Pack"
},
"bundle_type": "standard",
"description": {
"en": "Crystal x 1\nGem x 1"
},
"image_url": "https://cdn3.xsolla.com/img/misc/merchant/default-dc-image.png",
"regional_prices": [],
"prices": [
{
"amount": 20,
"currency": "USD",
"is_default": true,
"is_enabled": true
}
],
"virtual_prices": [],
"is_enabled": true,
"is_show_in_store": true,
"regions": [],
"limits": {
"per_user": null,
"per_item": null,
"recurrent_schedule": null
},
"periods": [],
"attributes": [],
"long_description": null,
"media_list": [],
"order": 5,
"is_free": false,
"groups": [
"my_test_group"
],
"content": [
{
"sku": "Gem_test_import",
"quantity": 1
},
{
"sku": "event_access_test_import",
"quantity": 1
}
]
}
]
}
- Upload the full file to the corresponding field in the import window.
- If there are errors during import, a list of these errors and recommendations for correction will be displayed in the import window. Make the necessary changes to the file and upload it again.
After successful upload, the items with the specified SKUs will be created, updated, or disabled.
To avoid errors during import, follow the recommendations above for filling in the file.
Export of the item catalog
To export an item or item catalog to a JSON file:
- Open the project in the Publisher Account.
- In the side menu, click Store and go to the Virtual currency, Virtual items, or Bundles section.
- Click Export items.
- Choose the action:
- Export all items — the entire catalog of all types of items of this project will be exported. For example, if you navigate to the Virtual Currency section and export all items, the JSON file will unload virtual currencies, virtual currency packages, virtual items, game key packages of your project.
- Export only selected items — in the opened window select the items that should be exported.
- Click Export.
The JSON file download will start automatically.
Import catalog from external platforms
You can import items and subscriptions from external platforms and synchronize user inventory.
- reimport the catalog (except subscriptions)
- make changes to the catalog in your Publisher Account manually
- make changes to the catalog using API method groups for managing bundles, virtual items and currencies, subscription plans, and subscription products.
Import catalog from Google Play
Before you start importing, check that Google Play Android Developer API is enabled in your Google Play project. Visit https://console.developers.google.com/apis/api/androidpublisher.googleapis.com/overview?project={project_id}
, where project_id
— your project ID in Google Play. If this API disabled, enable it. The settings will take time to apply, so the import may fail if you try immediately after enabling the settings. Wait a few minutes and retry.
- Open your project in Publisher Account.
- Click Store in the side menu.
- In the Catalog Management pane, click Configure.
- In the Integration with external platforms pane, click Configure.
- In the Google Play pane, click Configure.
- Specify Application ID — your app’s ID from Google Play.
- Upload JSON with a private key.
- Go to the Google Play Console, in the side menu click Users and permissions and add service account as a new user with the role of Android Management User. This requires you to have the Project IAM admin role.
- Click Save.
- Click Start import. Catalog import will begin immediately.
- To sell virtual items in the web store created by Site Builder, configure item groups in Publisher Account and assign one or more of them to each item.
- To display item images, upload them to your Publisher Account.
Import catalog from App Store
- Application ID from the App Information section in App Store Connect.
- API Key and Issuer ID from the Users and Access section in App Store Connect.
Get Application ID
To get your Application ID in App Store Connect:- Log in to App Store Connect.
- Go to the Apps section.
- Open your application’s page.
- Navigate to General Information > App Information.
- In the General Information copy Application ID in Apple ID field.
Get API Key and Issuer ID
Issuer ID in App Store Connect is used for interaction with Apple API, including the App Store Connect API. It is required for setting up API keys to automate tasks such as app management, analytics data retrieval, and other operations in App Store Connect.
API Key is a unique identifier used to authenticate API requests in App Store Connect API and ensure secure access to Apple Developer Account data and functionality.
To get the Issuer ID and API Key in App Store Connect:
- Log in to App Store Connect and go to the Users and Access section.
- Open the Integrations tab.
- In the side menu Keys click App Store Connect API.
- Go to the Team Keys tab. Click the + icon to create a new API key.
- In the Generate API Key window, assign a name to the key and set the access level for this key.
- Click Generate.
- The newly created key will appear in the list of active API keys. Download it as a P8 file and copy the Key ID.
- In the Team Keys tab, copy the Issuer ID.
Import a catalog from the App Store
- Open your Publisher Account and go to Store > Catalog management > Integration with external platforms > App Store.
- Provide the data got in App Store Connect:
- Application ID
- Private key file (P8)
- Issuer ID
- Key ID.
- Click Start import. The catalog import will begin automatically.
To sell virtual items in the web store created using Site Builder, create item groups in your Publisher Account and assign one or more groups to each virtual item.
To display item images, you need to upload them by editing the imported item in Store > Virtual Items.
Import catalog from PlayFab
PlayFab offers game developers ready-to-use server solutions to manage catalogs and monetization. After integration with PlayFab, you can import a catalog from PlayFab to Store for using Xsolla solutions.
- Open your project in Publisher Account.
- Click Store in the side menu.
- In the Catalog Management pane, click Configure.
- In the Integration with external platforms pane, click Configure.
- In the PlayFab pane, click Configure.
- In the Item import tab specify:
- Title ID — project ID in PlayFab.
- Secret key — the key of the project in PlayFab.
- Click Save.
- Synchronize user inventory with PlayFab (optionally):
- Go to the Inventory synchronization and specify:
- Title ID — project ID in PlayFab.
- Secret key — the key of the project in PlayFab.
- Set the Synchronize user inventory with PlayFab toggle to On.
- Click Save.
- Go to the Inventory synchronization and specify:
- Go to the Item import tab and click Start import. Catalog import will start automatically.
- To sell virtual items in the web store created by Site Builder, configure item groups in Publisher Account and assign one or more of them to each item.
- To display item images, upload them to your Publisher Account.
To check if the import completed successfully, go to the Store section in the side menu and make sure that items, currency, and bundles are enabled on the Virtual currency, Virtual items, and Bundles tabs.
Reimport catalog
When reimporting the catalog, you need to consider that:
- Items that are already in the Store will be updated.
- Items that are not available in the Store will be added.
- Items that have already been removed from the source of import will remain in the Store. You can delete them in your Publisher Account or via API.
Automatic creation of items via API
If you need to create numerous items based on data from your system, you can automate this process using the API.
You need to:
- Export the item data from your system.
- Transform the exported data into a format that matches the data format in the API method of the required item type.
- Create a script that calls the required API method for each item in the export:
If you want to use item groups, create them in advance via the Publisher Account interface.
If you want to use multiple types of items, they should be created in the following order:
- Item groups in the Publisher Account.
- Virtual currencies.
- Virtual items.
- Virtual currency packages.
- Bundles.
Next is an example of a script that repeatedly calls the Create virtual item method to create virtual items.
The script is developed using JavaScript and the JavaScript runtime — Node.js.
- Import the
fetch
function of the“node-fetch”
module to send HTTP requests to the Xsolla server.
- javascript
import fetch from "node-fetch";
- Set the constants needed for request authorization. Instead of
<your project_id from PA>
and<your api key from PA>
, insert your values for the project ID and API key, which will be encoded using Base64 for subsequent use in API requests.
- javascript
const projectId = <your project_id from PA>;
const apiKey = <your api key from PA>;
const buff = new Buffer(`${projectId}:${apiKey}`);
const basicAuth = buff.toString('base64')
- Implement the helper function
sleep
, which is used to create a delay when sending requests. This is necessary in order not to exceed API request rate limits.
- javascript
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
- Implement the
getItems
function, which is specific to your system, to retrieve item data from your system.
- javascript
async function getItems() {
// receive items from the original system or read from a pre-prepared file
return items;
}
- Implement the
prepareData
function, which is specific to your system, to format item data in accordance with the data format in the Create virtual item API call.
- javascript
function prepareData(items) {
// format items in accordance with API requirements
return formattedItems;
}
- Add the
createItem
function, which sends aPOST
request to the Xsolla API to create a virtual item.
- javascript
async function createItem(item) {
const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items`;
return await fetch(url, {
method: "POST",
headers: {
Authorization: "Basic " + basicAuth,
"Content-Type": "application/json"
},
body: JSON.stringify(item),
});
}
- Add the
checkItemExist
function, which checks whether a virtual item with a specified SKU exists. The function sends aGET
request to the Xsolla API:- If a response with a
404
HTTP code is received, the item with the specified SKU is not found, and it needs to be created. - If a response with a
200
HTTP code is received, the item with the specified SKU is found and does not need to be created.
- If a response with a
- javascript
async function checkItemExist(sku) {
const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items/sku/${sku}`;
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: "Basic " + basicAuth
}
});
return response.status !== 404;
}
- Add the
createItems
function, which goes through the list of items and checks whether there is an item with a SKU from your system on the Xsolla side. If there is no item with such a SKU, the function creates it. The progress information is displayed in the console.
- javascript
async function createItems(items) {
let success = 0;
let alreadyCreated = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item['sku'] === undefined) {
console.log(`${i} Field "sku" not specified`);
continue;
}
const sku = item['sku'];
if (await checkItemExist(sku)) {
console.log(`${i} Item with sku "${sku}" already created`);
alreadyCreated++;
continue;
}
const response = await createItem(item);
if (response.status === 201) {
console.log(`${i} Item with sku "${sku}" successfully created`)
success++;
} else {
const jsonData = await response.json();
console.log(`${i} An error occurred while creating the items with sku "${sku}"`);
console.log(jsonData);
}
// add a delay so as not to run into rate limits
await sleep(500);
}
console.log(`${success} items out of ${items.length} created. ${alreadyCreated} items already existed`);
}
- Add the
run
function that calls all the above functions in the correct order.
- javascript
async function run() {
const items = await getItems();
const formattedItems = prepareData(items);
await createItems(formattedItems);
}
The full code:
- javascript
import fetch from "node-fetch";
const projectId = <your project_id from PA>;
const apiKey = <your api key from PA>;
const buff = new Buffer(`${projectId}:${apiKey}`);
const basicAuth = buff.toString('base64')
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getItems() {
// receive items from the original system or read from a pre-prepared file
return items;
}
function prepareData(items) {
// format items in accordance with API requirements
return formatedItems;
}
async function createItem(item) {
const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items`;
return await fetch(url, {
method: "POST",
headers: {
Authorization: "Basic " + basicAuth,
"Content-Type": "application/json"
},
body: JSON.stringify(item),
});
}
async function isItemExisted(sku) {
const url = `https://store.xsolla.com/api/v2/project/${projectId}/admin/items/virtual_items/sku/${sku}`;
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: "Basic " + basicAuth
}
});
return response.status !== 404;
}
async function createItems(items) {
let success = 0;
let alreadyCreated = 0;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item['sku'] === undefined) {
console.log(`${i} Field "sku" not specified`);
continue;
}
const sku = item['sku'];
if (await isItemExisted(sku)) {
console.log(`${i} Item with sku "${sku}" already created`);
alreadyCreated++;
continue;
}
const response = await createItem(item);
if (response.status === 201) {
console.log(`${i} Item with sku "${sku}" successfully created`)
success++;
} else {
const jsonData = await response.json();
console.log(`${i} An error occurred while creating the items with sku "${sku}"`);
console.log(jsonData);
}
// add a delay so as not to run into rate limits
await sleep(500);
}
console.log(`${success} items out of ${items.length} created. ${alreadyCreated} items already existed`);
}
async function run() {
const items = await getItems();
const formattedItems = prepareData(items);
await createItems(formattedItems);
}
run();
Found a typo or other text error? Select the text and press Ctrl+Enter.