Импорт каталога
Создание и обновление каталога товаров с помощью импорта из JSON
Вы можете создать, обновить или отключить товары с помощью импорта из JSON-файла.
С помощью этого инструмента вы можете:
Возможности:
- Поддержка следующих типов товаров:
- виртуальных предметов;
- виртуальной валюты;
- пакетов виртуальной валюты;
- бандлов.
- Валидация загружаемых данных. Если структура файла или формат данных не соответствуют требованиям, вы увидите список ошибок при импорте.
Ограничения:
- Импорт недоступен для игровых ключей, акций и системы вознаграждений.
- Размер загружаемого JSON-файла не должен превышать 7 МБ.
- Формат параметров в JSON-файле должен соответствовать формату, указанному в соответствующем методе создания товара:
Импорт каталога товаров
Чтобы импортировать каталог товаров из файла:
- Откройте проект в Личном кабинете.
- В боковом меню нажмите Store и перейдите в раздел Виртуальная валюта, Виртуальные предметы или Бандлы.
- Нажмите Импортировать товары.
- Выберите нужное действие:
- Добавить новые товары — будут добавлены только товары с новыми артикулами.
- Добавить новые товары и обновить существующие — будут добавлены товары с новыми артикулами и обновлены данные существующих товаров.
- Добавить новые, обновить существующие и отключить недостающие товары — товары с артикулами из файла будут добавлены/обновлены. Если товар есть в каталоге, но товара с таким артикулом нет в файле, статус товара в Личном кабинете будет изменен на Частично доступен. Такой товар нельзя приобрести отдельно, но он доступен в составе бандла или в качестве бонуса.
- Заполните файл для импорта:
- Скачайте шаблон файла в окне загрузки и заполните его по примеру ниже.
- Сделайте экспорт товаров и используйте экспортированный файл как шаблон.
- Создайте свой JSON-файл и заполните его по примеру ниже.
Пример заполненного JSON-файла:
- 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
}
]
}
]
}
- Загрузите заполненный файл в соответствующее поле в окне импорта.
- Если при импорте возникнут ошибки, в окне импорта отобразится список этих ошибок и рекомендаций по исправлению. Внесите необходимые изменения в файл и загрузите его снова.
После успешной загрузки товары с указанными артикулами будут созданы, обновлены или отключены.
Экспорт каталога товаров
Чтобы экспортировать товар или каталог товаров в JSON-файл:
- Откройте проект в Личном кабинете.
- В боковом меню нажмите Store и перейдите в раздел Виртуальная валюта, Виртуальные предметы или Бандлы.
- Нажмите Экспортировать товары.
- Выберите нужное действие:
- Экспортировать все товары — будет выгружен весь каталог всех типов товаров данного проекта. Например, если вы перешли в раздел Виртуальная валюта и экспортируете все товары, в JSON-файл будут выгружены виртуальные валюты, пакеты виртуальной валюты, виртуальные предметы, пакеты игровых ключей вашего проекта.
- Экспортировать только выбранные товары — в открывшемся окне выберите товары, которые должны быть экспортированы.
- Нажмите Экспортировать.
Загрузка JSON-файла начнется автоматически.
Импорт каталога из внешних платформ
Вы можете импортировать товары и подписки из внешних платформ и синхронизировать инвентарь пользователя.
- импортировать каталог повторно (за исключением подписок);
- внести изменения в каталог в Личном кабинете вручную;
- внести изменения в каталог с помощью групп методов API для управления бандлами, виртуальными предметами и валютой, планами подписок и продуктами подписок.
Импорт каталога из Google Play
Перед началом импорта проверьте, включен ли Google Play Android Developer API в вашем проекте в Google Play. Для этого перейдите по ссылке: https://console.developers.google.com/apis/api/androidpublisher.googleapis.com/overview?project={project_id}
, где project_id
— ID вашего проекта в Google Play. Если этот API выключен, включите его. Применение настроек занимает время, поэтому сразу после включения настроек импорт может не удаться. Подождите несколько минут и повторите попытку.
- Откройте проект в Личном кабинете.
- Нажмите Store в боковом меню.
- В панели Управление каталогом нажмите Настроить.
- В панели Интеграция с внешними платформами нажмите Настроить.
- В панели Google Play нажмите Настроить.
- Укажите ID приложения — ID вашего приложения в Google Play.
- Загрузите JSON-файл с приватным ключом.
- Перейдите в Google Play Console, в боковом меню нажмите Users and permissions и добавьте сервисный аккаунт как нового пользователя.
- Нажмите Сохранить.
- Нажмите Начать импорт. Импорт каталога начнется автоматически.
- Если вы хотите продавать виртуальные предметы через веб-магазин, созданный с помощью Site Builder, в Личном кабинете создайте группы и укажите для каждого виртуального предмета одну или несколько групп.
- Если вы хотите, чтобы у товаров были изображения, необходимо добавить изображения в Личном кабинете.
Импорт каталога из PlayFab
PlayFab предоставляет разработчикам игр готовые серверные решения для управления каталогом и для монетизации. После интеграции сервиса PlayFab вы можете импортировать каталог из PlayFab в магазин, чтобы пользоваться решениями Xsolla.
- Откройте проект в Личном кабинете.
- Нажмите Store в боковом меню.
- В панели Управление каталогом нажмите Настроить.
- В панели Интеграция с внешними платформами нажмите Настроить.
- В панели PlayFab нажмите Настроить.
- На вкладке Импорт товаров укажите:
- Title ID — ID проекта в PlayFab.
- Секретный ключ — ключ проекта в PlayFab.
- Нажмите Сохранить.
- Синхронизируйте инвентарь пользователя с PlayFab (опционально):
- Перейдите на вкладку Синхронизация инвентаря и укажите:
- Title ID — ID проекта в PlayFab.
- Секретный ключ — ключ проекта в PlayFab.
- Установите переключатель Синхронизировать инвентарь пользователя с PlayFab в положение Вкл.
- Нажмите Сохранить.
- Перейдите на вкладку Синхронизация инвентаря и укажите:
- Перейдите на вкладку Импорт товаров и нажмите Начать импорт. Импорт каталога начнется автоматически.
- Если вы хотите продавать виртуальные предметы через веб-магазин, созданный с помощью Site Builder, в Личном кабинете создайте группы и укажите для каждого виртуального предмета одну или несколько групп.
- Если вы хотите, чтобы у товаров были изображения, необходимо добавить изображения в Личном кабинете.
Чтобы проверить, успешно ли прошел импорт каталога, перейдите в раздел Store в боковом меню и убедитесь, что предметы, валюта и бандлы доступны на вкладках Виртуальная валюта, Виртуальные предметы и Бандлы.
Повторный импорт каталога
При повторном импорте каталога вам необходимо учитывать следующее:
- Товары, которые уже есть в магазине, будут обновлены.
- Товары, которые отсутствуют в магазине, будут добавлены.
- Товары, которые уже были удалены из источника импорта, останутся в магазине. Вы можете удалить их в Личном кабинете или с помощью API.
Автоматическое создание товаров через API
Если вам нужно создать большое количество товаров на основе данных из вашей системы, вы можете автоматизировать этот процесс с помощью API.
Вам потребуется:
- Выгрузить данные о товарах из вашей системы.
- Преобразовать выгруженные данные в формат, который соответствует формату данных в методе API нужного типа товара.
- Создать скрипт, который для каждого товара в выгрузке вызовет нужный метод API:
- Создание виртуального предмета — для виртуальных предметов.
- Создание виртуальной валюты — для виртуальной валюты.
- Создание пакета виртуальной валюты — для пакетов виртуальной валюты.
- Создание бандла — для бандлов.
Если вы хотите использовать группы товаров, предварительно создайте их через интерфейс Личного кабинета.
Если вы хотите использовать несколько типов товаров, они должны быть созданы в следующем порядке:
- Группы товаров в Личном кабинете.
- Виртуальные валюты.
- Виртуальные предметы.
- Пакеты виртуальной валюты.
- Бандлы.
Далее рассмотрен пример скрипта, который многократно вызывает метод API Создание виртуального предмета для создания виртуальных предметов.
Скрипт разработан с применением JavaScript и среды выполнения JavaScript — Node.js.
- Импортируйте функцию
fetch
модуля“node-fetch”
для отправки HTTP-запросов к серверу Xsolla.
- javascript
import fetch from "node-fetch";
- Задайте константы, необходимые для авторизации запросов. Вместо
<your project_id from PA>
и<your api key from PA>
подставьте ваши значения ID проекта и ключа API, которые будут закодированы по стандарту Base64 для последующего использования в API запросах.
- 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')
- Реализуйте вспомогательную функцию
sleep
, которая используется для создания задержки при отправке запросов. Это необходимо для того, чтобы не превышать ограничения частоты запросов к API.
- javascript
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
- Реализуйте функцию
getItems
, специфичную для вашей системы, которая позволит получать данные о товарах из вашей системы.
- javascript
async function getItems() {
// receive items from the original system or read from a pre-prepared file
return items;
}
- Реализуйте функцию
prepareData
, специфичную для вашей системы, которая форматирует данные о товарах в соответствии с форматом данных в методе API Создание виртуального предмета.
- javascript
function prepareData(items) {
// format items in accordance with API requirements
return formattedItems;
}
- Добавьте функцию
createItem
, которая отправляетPOST
-запрос к Xsolla API для создания виртуального предмета.
- 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),
});
}
- Добавьте функцию
checkItemExist
, которая проверяет, существует ли виртуальный товар с заданным артикулом (SKU). Для этого функция отправляетGET
-запрос к Xsolla API:- Если получен ответ с
404
HTTP-кодом, товар с заданным артикулом не найден, его требуется создать. - Если получен ответ с
200
HTTP-кодом, товар с заданным артикулом найден и его не требуется создавать.
- Если получен ответ с
- 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;
}
- Добавьте функцию
createItems
, которая проходит по списку товаров, и проверяет, есть ли товар с артикулом из вашей системы на стороне Xsolla. Если товара с таким артикулом нет, функция создает его. Информация о прогрессе выводится в консоль.
- 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`);
}
- Добавьте функцию
run
, которая вызывает все вышеперечисленные функции в правильном порядке.
- javascript
async function run() {
const items = await getItems();
const formattedItems = prepareData(items);
await createItems(formattedItems);
}
Полный код:
- 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();
Нашли опечатку или ошибку в тексте? Выделите ее и нажмите Ctrl+Enter.