Game Sales / Импорт каталога
  На главную

Game Sales

Импорт каталога

Создание и обновление каталога товаров с помощью импорта из JSON

Вы можете создать, обновить или отключить товары с помощью импорта из JSON-файла.

Примечание
Вы можете создать, обновить или отключить товары, используя методы API или вручную в Личном кабинете. При этом для каждого товара потребуется выполнять отдельный запрос или действие. С помощью импорта вы можете выполнить указанные действия для множества товаров одновременно, указав их в одном JSON-файле.

С помощью этого инструмента вы можете:

Чтобы создать новые товары в каталоге, при импортировании выберите действие Добавить новые товары.

Возможности:

  • Поддержка следующих типов товаров:
    • виртуальных предметов;
    • виртуальной валюты;
    • пакетов виртуальной валюты;
    • бандлов.
  • Валидация загружаемых данных. Если структура файла или формат данных не соответствуют требованиям, вы увидите список ошибок при импорте.

Ограничения:

Примечание
Для предварительно созданных товаров вы можете импортировать региональные цены из CSV-файла.

Импорт каталога товаров

Чтобы импортировать каталог товаров из файла:

  1. Откройте проект в Личном кабинете.
  2. В боковом меню нажмите Store и перейдите в раздел Виртуальная валюта, Виртуальные предметы или Бандлы.
  3. Нажмите Импортировать товары.

  1. Выберите нужное действие:
    • Добавить новые товары — будут добавлены только товары с новыми артикулами.
    • Добавить новые товары и обновить существующие — будут добавлены товары с новыми артикулами и обновлены данные существующих товаров.
    • Добавить новые, обновить существующие и отключить недостающие товары — товары с артикулами из файла будут добавлены/обновлены. Если товар есть в каталоге, но товара с таким артикулом нет в файле, статус товара в Личном кабинете будет изменен на Частично доступен. Такой товар нельзя приобрести отдельно, но он доступен в составе бандла или в качестве бонуса.

  1. Заполните файл для импорта:
    • Скачайте шаблон файла в окне загрузки и заполните его по примеру ниже.
    • Сделайте экспорт товаров и используйте экспортированный файл как шаблон.
    • Создайте свой JSON-файл и заполните его по примеру ниже.

Пример заполненного JSON-файла:

Copy
Full screen
Small screen

{
    "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
                }
            ]
        }
    ]
}

  1. Загрузите заполненный файл в соответствующее поле в окне импорта.
  2. Если при импорте возникнут ошибки, в окне импорта отобразится список этих ошибок и рекомендаций по исправлению. Внесите необходимые изменения в файл и загрузите его снова.

После успешной загрузки товары с указанными артикулами будут созданы, обновлены или отключены.

Примечание
Вы можете импортировать товары с помощью метода API Импорт товаров из JSON-файла.
Чтобы избежать ошибок при импорте, следуйте приведенным выше рекомендациям по заполнению файла.

Экспорт каталога товаров

Чтобы экспортировать товар или каталог товаров в JSON-файл:

  1. Откройте проект в Личном кабинете.
  2. В боковом меню нажмите Store и перейдите в раздел Виртуальная валюта, Виртуальные предметы или Бандлы.
  3. Нажмите Экспортировать товары.

  1. Выберите нужное действие:
    • Экспортировать все товары — будет выгружен весь каталог всех типов товаров данного проекта. Например, если вы перешли в раздел Виртуальная валюта и экспортируете все товары, в JSON-файл будут выгружены виртуальные валюты, пакеты виртуальной валюты, виртуальные предметы, пакеты игровых ключей вашего проекта.
    • Экспортировать только выбранные товары — в открывшемся окне выберите товары, которые должны быть экспортированы.

  1. Нажмите Экспортировать.

Загрузка JSON-файла начнется автоматически.

Импорт каталога из внешних платформ

Вы можете импортировать товары и подписки из внешних платформ и синхронизировать инвентарь пользователя.

Внимание
После импорта вы можете синхронизировать изменения каталога товаров и подписок в источнике импорта и Xsolla следующими способами:Если импорт каталога невозможен, настройте каталог товаров и подписок в Личном кабинете или с помощью методов 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 выключен, включите его. Применение настроек занимает время, поэтому сразу после включения настроек импорт может не удаться. Подождите несколько минут и повторите попытку.

  1. Откройте проект в Личном кабинете.
  2. Нажмите Store в боковом меню.
  3. В панели Управление каталогом нажмите Настроить.
  4. В панели Интеграция с внешними платформами нажмите Настроить.
  5. В панели Google Play нажмите Настроить.
  6. Укажите ID приложения — ID вашего приложения в Google Play.
Примечание
Вы можете найти ID приложения в консоли администратора Google. В боковом меню нажмите All apps. Найдите в таблице нужное приложение. Его ID будет указан в столбце App рядом с логотипом и названием.
  1. Загрузите JSON-файл с приватным ключом.
Примечание
Приватный ключ создается в процессе создания сервисного аккаунта.

  1. Перейдите в Google Play Console, в боковом меню нажмите Users and permissions и добавьте сервисный аккаунт как нового пользователя с ролью Android Management User. Для этого у вас должна быть роль Project IAM admin.

  1. Нажмите Сохранить.
  2. Нажмите Начать импорт. Импорт каталога начнется автоматически.
Примечание
Артикул товара соответствует Product ID в источнике импорта.
  1. Если вы хотите продавать виртуальные предметы через веб-магазин, созданный с помощью Site Builder, в Личном кабинете создайте группы и укажите для каждого виртуального предмета одну или несколько групп.
  2. Если вы хотите, чтобы у товаров были изображения, необходимо добавить изображения в Личном кабинете.
Примечание
Для пользователей из Бангладеш цены в каталоге будут отображаться не в валюте BDT, а в базовой валюте USD.

Импорт каталога из App Store

Примечание
Импортируются только товары со статусом Approved в App Store Connect. В Личном кабинете в разделе Store импортированные товары отображаются в статусе Частично доступен. Чтобы товары отобразились, необходимо поменять статус на Доступен.
Перед импортом каталога из App Store необходимо получить следующие данные:

Получение ID приложения

Для получения ID вашего приложения в App Store Connect:
  1. Войдите в App Store Connect.
  2. Перейдите в раздел Apps.

  3. Откройте страницу вашего приложения.
  4. Перейдите в раздел General Information > App Information.
  5. В блоке General Information скопируйте ID приложения под заголовком Apple ID.

Получение ключа API и Issuer ID

Issuer ID в App Store Connect — это ID, который используется для взаимодействия с Apple API, включая App Store Connect API. Этот ID необходим для настройки ключей API для автоматизации задач, таких как управление приложениями, загрузка данных аналитики и других операций в App Store Connect.

Ключ API — это  уникальный ключ, который используется для аутентификации API-запросов в App Store Connect API и обеспечения безопасного доступа к данным и функциям Apple Developer Account.

Для получения Issuer ID и ключа API в App Store Connect:

  1. Перейдите на сайт App Store Connect в раздел Users and Access.
  2. Перейдите на вкладку Integrations.
  3. В боковом меню Keys нажмите App Store Connect API.
  4. Перейдите на вкладку Team Keys. Для создания ключа API нажмите значок +.

  5. В окне Generate API Key задайте имя ключа и уровень доступа к этому ключу.
  6. Нажмите Generate.

  7. В таблице активных ключей API появится ваш ключ. Скачайте его в виде файла с расширением P8 и скопируйте Key ID.

  8. На вкладке Team Keys скопируйте Issuer ID.

Импорт каталога из App Store

  1. В вашем проекте в Личном кабинете перейдите в раздел Store > Управление каталогом > Интеграция с внешними платформами > App Store.
  2. Укажите данные, которые вы получили в App Store Connect:
    • ID приложения;
    • Файл с Private key; 
    • Issuer ID;
    • Key ID.
  3. Нажмите Начать импорт. Импорт каталога начнется автоматически.

Если вы хотите продавать виртуальные предметы через Xsolla Site Builder, в Личном кабинете создайте группы и укажите для каждого виртуального предмета одну или несколько групп.

Если вы хотите, чтобы у товаров были изображения, отредактируйте импортированный товар в разделе Store > Виртуальные предметы.

Примечание
Артикул товара соответствует Product ID в App Store Connect.

Импорт каталога из PlayFab

Внимание
Поддерживаемая версия PlayFab API: Economy v1.
Руководство по импорту каталога из PlayFab приведено в документации.

Повторный импорт каталога

При повторном импорте каталога вам необходимо учитывать следующее:

  • Товары, которые уже есть в Store, будут обновлены.
  • Товары, которые отсутствуют в Store, будут добавлены.Т
  • овары, которые уже были удалены из источника импорта, останутся в Store. Вы можете удалить их в Личном кабинете или с помощью API.

Автоматическое создание товаров через API

Если вам нужно создать большое количество товаров на основе данных из вашей системы, вы можете автоматизировать этот процесс с помощью API.

Вам потребуется:

Если вы хотите использовать группы товаров, предварительно создайте их через интерфейс Личного кабинета.

Если вы хотите использовать несколько типов товаров, они должны быть созданы в следующем порядке:

  1. Группы товаров в Личном кабинете.
  2. Виртуальные валюты.
  3. Виртуальные предметы.
  4. Пакеты виртуальной валюты.
  5. Бандлы.

Далее рассмотрен пример скрипта, который многократно вызывает метод API Создание виртуального предмета для создания виртуальных предметов.

Скрипт разработан с применением JavaScript и среды выполнения JavaScript — Node.js.

  1. Импортируйте функцию fetch модуля “node-fetch” для отправки HTTP-запросов к серверу Xsolla.
Copy
Full screen
Small screen
import fetch from "node-fetch";
  1. Задайте константы, необходимые для авторизации запросов. Вместо <your project_id from PA> и <your api key from PA> подставьте ваши значения ID проекта и ключа API, которые будут закодированы по стандарту Base64 для последующего использования в API запросах.
Copy
Full screen
Small screen
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')
  1. Реализуйте вспомогательную функцию sleep, которая используется для создания задержки при отправке запросов. Это необходимо для того, чтобы не превышать ограничения частоты запросов к API.
Copy
Full screen
Small screen
function sleep(ms) {

   return new Promise(resolve => setTimeout(resolve, ms));

}
  1. Реализуйте функцию getItems, специфичную для вашей системы, которая позволит получать данные о товарах из вашей системы.
Copy
Full screen
Small screen
async function getItems() {

   // receive items from the original system or read from a pre-prepared file

   return items;

}
  1. Реализуйте функцию prepareData, специфичную для вашей системы, которая форматирует данные о товарах в соответствии с форматом данных в методе API Создание виртуального предмета.
Copy
Full screen
Small screen
function prepareData(items) {

   // format items in accordance with API requirements

   return formattedItems;

}
  1. Добавьте функцию createItem, которая отправляет POST-запрос к Xsolla API для создания виртуального предмета.
Copy
Full screen
Small screen
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),

   });

}
  1. Добавьте функцию checkItemExist, которая проверяет, существует ли виртуальный товар с заданным артикулом (SKU). Для этого функция отправляет GET-запрос к Xsolla API:
    • Если получен ответ с 404 HTTP-кодом, товар с заданным артикулом не найден, его требуется создать.
    • Если получен ответ с 200 HTTP-кодом, товар с заданным артикулом найден и его не требуется создавать.
Copy
Full screen
Small screen
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;

}
  1. Добавьте функцию createItems, которая проходит по списку товаров, и проверяет, есть ли товар с артикулом из вашей системы на стороне Xsolla. Если товара с таким артикулом нет, функция создает его. Информация о прогрессе выводится в консоль.
Copy
Full screen
Small screen
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`);

}
  1. Добавьте функцию run, которая вызывает все вышеперечисленные функции в правильном порядке.
Copy
Full screen
Small screen
async function run() {

 const items = await getItems();

 const formattedItems = prepareData(items);

 await createItems(formattedItems);

}

Полный код:

Copy
Full screen
Small screen
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(); 
Была ли статья полезна?
Спасибо!
Что может сделать страницу еще лучше? Сообщение
Жаль, что так произошло
Расскажите, почему статья не была полезна. Сообщение
Спасибо за обратную связь!
Ваши мысли и идеи помогут нам улучшить ваш пользовательский опыт.
Последнее обновление: 8 ноября 2024

Нашли опечатку или ошибку в тексте? Выделите ее и нажмите Ctrl+Enter.

Сообщите о проблеме
Мы постоянно улучшаем качество нашей документации. Ваш отзыв поможет нам в этом.
Укажите email-адрес, чтобы мы могли связаться с вами
Спасибо за обратную связь!