Прямое пополнение по API: доставка по UID / Player ID
Для большой части каталога покупателю нечего выдавать — ни ключа, ни кода, ни входа в аккаунт. Вы передаёте нам игровой ID игрока, мы отправляем заказ поставщику, и валюта приходит на этот аккаунт, обычно меньше чем за минуту. В GameCore API это тип доставки id_only — по нему идут UC в PUBG Mobile, алмазы в Mobile Legends и Free Fire, кристаллы в Genshin Impact.
Здесь весь путь целиком: как найти такие товары, что класть в deliveryData, что мы проверяем и — что важнее — чего мы не проверяем.
Что на самом деле значит id_only
У каждого товара в каталоге есть deliveryType. Значений пять:
deliveryType | Что получает покупатель |
|---|---|
id_only | Ничего. Пополнение приходит на указанный аккаунт. |
gift_card | Ключ или код, который мы вернём вам при завершении. |
login_required | Мы пополняем через переданные вами данные аккаунта. |
service | Ручная услуга, её выполняет оператор. |
other | Тип ещё не определён — читайте схему самого товара. |
Поле nullable: у ещё не классифицированного товара приходит deliveryType: null, а не other. Отсюда два следствия. Ваш собственный тип поля обязан допускать null; и фильтр ?deliveryType= сравнивает значения на точное равенство, поэтому неклассифицированный товар не попадает ни в одну выборку по типу — увидеть его можно только запросом без фильтра. Что именно нужно такому SKU, показывает его deliveryDataSchema.
id_only — единственный тип, где успешный заказ возвращает ни ключа, ни кода. Это не пропавшее поле, это и есть товар. Заложить такое поведение в свою модель заказа с самого начала — большая часть интеграции.
Как найти товары id_only
Тип доставки — это и свойство каталога, и фильтр каталога. Запросите товары одной игры и сузьте выдачу:
GET /b2b/catalog/games/pubg-mobile/products?deliveryType=id_only X-Api-Key: gc_live_…
Две вещи про каталог, которые лучше знать до начала интеграции:
- Товары, форма которых требует скриншот или загрузку изображения, полностью исключены из B2B-каталога. Канала для файлов в этом API нет, поэтому такие SKU не просто скрыты — заказ по ним отклоняется с 400. Если товар, который вы видите в чужом магазине, отсутствует в вашем фиде, чаще всего причина именно эта.
- Храните ID товаров, а не названия и не цены. Названия переводятся заново, цены двигаются вместе с курсом, ID стабильны.
Поля доставки задаёт товар, а не эта страница
У каждого товара есть deliveryDataSchema — список полей, которые ему нужны. Ключи в deliveryData должны совпадать с id каждого поля схемы:
{"id": "gameUserId","type": "text","label": "Player ID","required": true}
Это поле превращается в:
"deliveryData": { "gameUserId": "5123456789" }
Три правила, на которых интеграторы теряют больше всего времени:
- Ключ — это
id, а неlabel. Label — это подпись для интерфейса, она переводится;id— имя на проводе. - Любое значение — строка JSON. Схема запроса — строка к строке.
"playerId": 1234567890без кавычек отбивается валидацией тела ещё до нашей собственной обработки ошибок, поэтому и форма ответа будет не такой, как у всех остальных ошибок на этой странице. - Читайте схему на уровне товара, а не игры. Формы заводят поставщики, и у одной игры имена полей могут отличаться между регионами и номиналами.
Типы полей, которые вам встретятся: text, number, select (значение должно быть одним из заявленных вариантов), а также password и image — оба вне сценария id_only.
Что спрашивает каждая игра
Ниже — форма запроса для четырёх самых востребованных тайтлов вместе с форматными правилами, которые наш валидатор применяет до списания. Id полей — те, что встречаются у поставщиков сегодня; читайте deliveryDataSchema, а не зашивайте их в код.
PUBG Mobile
Одно числовое поле, от 6 до 15 цифр. В зависимости от формы поставщика приходит как gameUserId, playerId, player_id, userId или target.
{"items": [{"productId": 34521,"quantity": 1,"deliveryData": { "gameUserId": "5123456789" }}]}
То же правило действует для PUBG Mobile Lite и PUBG: NEW STATE.
Free Fire
Одно числовое поле, от 6 до 15 цифр, обычно playerID или playerId. Free Fire MAX ведёт себя так же.
{"items": [{"productId": 41180,"quantity": 1,"deliveryData": { "playerID": "812345678" }}]}
Genshin Impact
Один числовой UID, от 8 до 10 цифр, чаще всего под id account. У Honkai: Star Rail тот же диапазон, у Zenless Zone Zero — от 9 до 11 цифр.
{"items": [{"productId": 52903,"quantity": 1,"deliveryData": { "account": "700123456" }}]}
Первая цифра UID в Genshin определяет сервер, поэтому UID, скопированный из другого региона, — это корректное число, указывающее на чужой аккаунт. Смотрите предупреждение ниже.
Mobile Legends
MLBB нужны два значения — ID игрока и ID сервера (зоны), — и их id самые нестандартизированные во всём каталоге. Фиксированной пары мы здесь не публикуем, потому что её не существует: поставщики называют эти поля по-разному, и страница, которая бы угадала, оказалась бы неправа для части ваших SKU. Читайте deliveryDataSchema того товара, который продаёте, и отправляйте все поля, помеченные required:
{"items": [{"productId": 38004,"quantity": 1,"deliveryData": { "playerId": "123456789", "zone": "2143" }}]}
Если обязательное поле не передано, заказ отклоняется с 400 и указанием поля — списания не происходит.
Создание заказа
POST /b2b/orders X-Api-Key: gc_live_… X-Idempotency-Key: 7f3c1a9e-2b44-4d1a-9d4e-1c0f9a2b3c4d Content-Type: application/json
{"items": [{"productId": 34521,"quantity": 1,"deliveryData": { "gameUserId": "5123456789" }}],"externalOrderId": "MP-98765","callbackUrl": "https://api.yourshop.com/webhooks/gamecore"}
X-Idempotency-Key обязателен — запрос без него получает 400. externalOrderId — ваш собственный идентификатор, мы возвращаем его везде. callbackUrl — адрес, куда придёт результат; подробности на странице вебхуков.
До 200 позиций в запросе. Позиции группируются по игре и поставщику, поэтому один запрос может создать несколько заказов:
{"success": true,"data": {"paymentCode": "P-AB12CD","totalAmount": 1064.5,"orders": [{"code": "ash-XY7K3M","gameId": "pubg-mobile","gameName": "PUBG Mobile","total": 1064.5,"itemCount": 1}]}}
Код заказа — это префикс магазина плюс шесть символов из алфавита без O, 0, 1, I и L: такой код безопасно диктовать покупателю голосом. Сохраняйте code — это ручка для всех дальнейших обращений.
Поля status в этом ответе нет, потому что сообщать пока нечего: из этого вызова каждый заказ выходит в статусе processing.
Мы не проверяем Player ID
Это самое дорогое знание, если получить его поздно. Корректно набранный ID, принадлежащий другому человеку, для нас неотличим от правильного. Пополнение уйдёт владельцу этого аккаунта, и вернуть его нельзя — ни нам, ни поставщику.
Что мы проверяем до любого списания:
- Обязательные поля переданы и не пусты.
- Формат — там, где для семейства игр заведено правило: количество цифр, «только цифры», варианты
select, диапазоны чисел. PUBG ID12будет отклонён,512345678999— принят. - Регион и доступность товара для вашего аккаунта.
Чего мы не проверяем: существует ли такой аккаунт, тот ли он регион, что у SKU, и тот ли это аккаунт, который имел в виду ваш покупатель. Живой проверки существования игрока на этом пути API нет.
Практический вывод: ввод ID — зона ответственности вашей воронки, а не нашей:
- Показывайте подпись поля из
deliveryDataSchemaдословно, на языке покупателя. - Просите подтвердить или повторно ввести ID до оплаты, а не после.
- Прямо на экране ввода говорите, что ошибка в ID не возвращается. Это конвертирует лучше, чем последующее обращение в поддержку.
completed без ключей — это успех
Опросите заказ или дождитесь вебхука:
GET /b2b/orders/ash-XY7K3M X-Api-Key: gc_live_…
{"success": true,"data": {"code": "ash-XY7K3M","status": "completed","items": [{"productName": "PUBG Mobile 660 UC","amount": 1,"price": 1064.5,"status": "completed","cdKeys": [],"completedAt": "2026-08-18T18:31:15.432Z"}]}}
cdKeys: [] у позиции в статусе completed — правильный и окончательный ответ для id_only: ключ не придёт позже. В теле вебхука у той же позиции поля cdKeys не будет вовсе, поэтому приёмник должен одинаково обрабатывать «пусто» и «поля нет».
Статусы заказа: pending, processing, completed, failed, cancelled, refunded. Первые два — не финальные, остальные — финальные.
Статусы позиций отдельные, и два из них обычно застают врасплох: кроме pending, completed и failed встречаются awaiting_code и awaiting_screenshot. Код, который ждёт только completed или failed, зависнет на них навсегда — считайте любой незнакомый статус позиции как «ещё в работе».
Заказ, где часть позиций выполнилась, а часть нет, на уровне заказа становится failed. Стоимость невыполненных позиций возвращается на ваш баланс автоматически.
Когда заказ отклонён
Ошибки заказа приходят как { "success": false, "error": "…" }. Специфичные для этого сценария:
| HTTP | Что произошло |
|---|---|
| 400 | Нет X-Idempotency-Key, пустой items, больше 200 позиций, неизвестный или недоступный товар, обязательное поле доставки отсутствует или не проходит формат, товару нужна загрузка изображения, регион запрещён. |
| 402 | Не хватает баланса или заказ превышает кредитный лимит. |
| 409 | Тот же X-Idempotency-Key уже использован с другими items, либо идентичный запрос ещё выполняется. |
| 429 | Сработал лимит запросов. В теле есть code: "RATE_LIMITED" и retryAfter, вместе с заголовком Retry-After. |
| 503 | Правило проверки поля не удалось применить. Повторите запрос; не выбрасывайте поле. |
Здесь важна точность: «другое» — это уже, чем весь запрос. Отпечаток, по которому срабатывает 409, считается только по items — productId, quantity и deliveryData в нормализованном виде: ключи схемы отсортированы, значения обрезаны по краям, а username приведён к нижнему регистру со снятой ведущей @, так что @Player1 и player1 — это один заказ, а не два. callbackUrl и externalOrderId в отпечаток намеренно не входят. Поэтому переиспользование ключа с теми же позициями, но другим адресом обратного вызова, который проходит валидацию, — это не 409, а повтор: вы получите исходный заказ, а новый адрес на него уже не повлияет. Адрес, не прошедший валидацию, так далеко не доходит: callbackUrl проверяется до поиска вашего ключа, поэтому плохой адрес получает 400 Invalid callbackUrl: …, а не повтор и не конфликт. Исправляйте callback до создания заказа, а не после.
409 по переиспользованному ключу нельзя повторять с тем же ключом — он будет отдавать 409 всегда. Для действительно нового заказа выпускайте новый ключ, а старый используйте только для повтора тех же позиций.
Обратите внимание: 401 и 403 отвечают в другом конверте — { "error": …, "message": … }, — поэтому клиент, который ветвится по success, увидит undefined ровно на тех двух ошибках, с которыми столкнётся раньше всего.
Перед выходом в прод
- Поля доставки читаются из
deliveryDataSchemaв момент запроса и ключуются поid. - Все значения в
deliveryData— строки. - Заказ
completedсcdKeys: []обрабатывается как выполненный, а не как ошибка. - Незнакомые статусы позиций считаются «в работе».
X-Idempotency-Keyсохраняется вместе с вашим заказом, чтобы повтор был повтором, а не вторым списанием.- Покупатель подтверждает ID до оплаты и знает, что ошибка необратима.
Обновлено 18 августа 2026 г.
Смотрите также: Поставка по API · Цены и тарифы
Нужен ключ API?
Напишите, какие игры и регионы вы продаёте, — выдадим ключ и пройдём интеграцию вместе с вами. На вопросы по интеграции отвечают те же люди, которые ведут API.