GamesDrop.io API - Руководство для мерчантов
[!WARNING] Все offer groups в этой документации являются PRODUCTION-офферами! Для тестирования используйте только Test Offer ID 999. API Base URL:
https://partner.gamesdrop.io
Добро пожаловать в документацию Partner API GamesDrop.io! Это руководство содержит все необходимое для интеграции вашей реселлерской платформы с сетью GamesDrop.io. Интегрируясь с нами, вы получаете доступ к нашему каталогу из более чем 10 000 цифровых продуктов: от пополнения мобильных операторов до внутриигровой валюты популярных мобильных игр. Начните здесь, чтобы оптимизировать свои предложения продуктов и подключить своих клиентов к миру цифровых товаров.
Оглавление
- Авторизация
- Основные концепции
- Пошаговая интеграция
- API Endpoints
- Тестирование API
- Рекомендации по интеграции
- FAQ и Устранение неполадок
- Поддержка
Авторизация
Получение токена
Процесс получения
- Войдите в личный кабинет мерчанта
- Создайте новый магазин
- После создания магазина вы получите уникальный токен
- Формат токена:
abcdef1234567890abcdef1234567890
Способы авторизации
Система поддерживает два способа авторизации в зависимости от типа запроса:
-
API Токен магазина (Shop Token):
- Используется для всех операций с товарами и заказами (создание заказа, проверка статуса, проверка баланса магазина).
- Передается в заголовке:
Authorization: <ваш_токен> - Пример:
Authorization: abcdef1234567890abcdef1234567890
-
JWT Токен (для управления):
- Используется для личного кабинета и операций пополнения (Bank Transfer, PayPal и т.д.).
- Передается как Bearer токен:
Authorization: Bearer <jwt_token> - Примечание: JWT токен имеет ограниченный срок жизни.
Безопасность токена
- 🔒 Токен является конфиденциальной информацией
- ⚠️ Не передавайте токен третьим лицам
- 📝 Токен нельзя восстановить после создания
- 🔄 При необходимости можно сгенерировать новый токен (старый станет недействительным)
Основные концепции
Статусы заказов
| Статус | Описание | Действия |
|---|---|---|
SUBMITTED | Заказ создан и ожидает обработки | Ожидать перехода в PROCESSING |
PROCESSING | Заказ в процессе обработки | Ожидать завершения. Для прямых пополнений этот этап может занимать от 1 до 60 минут. |
COMPLETED | Заказ успешно выполнен | Получить ключ/товар |
CANCELED | Заказ отменен без успешной доставки | Проверить данные заказа и создать новый заказ при необходимости |
FAILED | Ошибка провайдера или системы | Прекратить опрос; создать новый заказ при необходимости |
REFUND | Заказ отменен, средства возвращены на баланс партнера | Средства возвращены на баланс партнера |
Поле message является необязательным и может отсутствовать в ответе. Для legacy-совместимости часть внутренних состояний FAILED в order-status может отображаться как CANCELED; при этом create-order может напрямую вернуть FAILED или REFUND.
Возможные ошибки
| Код ошибки | Описание | Решение |
|---|---|---|
INVALID_TOKEN | Неверный токен авторизации | Проверить токен или получить новый |
OFFER_NOT_FOUND | Товар не найден или нет доступа | Проверить ID товара и права доступа |
TRANSACTION_DUPLICATE | Дубликат транзакции | Использовать новый transaction_id |
WRONG_PRICE | Неверная цена товара | Обновить информацию о цене |
ORDER_NOT_FOUND | Заказ не найден | Проверить ID заказа |
ORDER_NOT_PROCESSING | Заказ еще не в обработке | Дождаться перехода в статус PROCESSING |
ORDER_NOT_COMPLETED | Заказ еще не завершен | Дождаться завершения заказа |
ORDER_ALREADY_CANCELED | Заказ уже отменен | Создать новый заказ |
ORDER_ALREADY_REFUNDED | Заказ уже возвращен | Создать новый заказ |
SERVICE_UNAVAILABLE | Сервис временно недоступен | Повторить попытку позже |
INVALID_REQUEST_BODY | Неверный формат запроса | Проверить структуру запроса |
INSUFFICIENT_BALANCE | Недостаточно средств на балансе | Пополнить баланс или уменьшить сумму покупки |
BALANCE_UNAVAILABLE | Баланс временно недоступен | Повторить запрос позже |
Совместимость расчетов с поставщиками
GamesDrop работает с несколькими поставщиками. Некоторые поставщики работают через фиатные расчетные каналы, некоторые через USDT, а некоторые поддерживают оба варианта. Чтобы избежать валютных рисков, каждому партнерскому аккаунту назначается balance profile, а каждому офферу поставщика назначается settlement method.
Профили баланса:
| Профиль | Значение |
|---|---|
FIAT | Партнер настроен на фиатные расчеты. |
USDT | Партнер настроен на расчеты в USDT. |
MIXED | Партнер может использовать офферы поставщиков FIAT и USDT. |
Методы расчетов офферов:
| Метод | Значение |
|---|---|
FIAT | Оффер поставщика рассчитывается через фиатные каналы. |
USDT | Оффер поставщика рассчитывается через USDT. |
MIXED | Оффер доступен как FIAT-, так и USDT-партнерам. |
Правила совместимости:
| Balance profile партнера | Видимые / доступные к покупке методы офферов |
|---|---|
FIAT | FIAT, MIXED |
USDT | USDT, MIXED |
MIXED | FIAT, USDT, MIXED |
Catalog и product endpoints возвращают только совместимые офферы. Если оффер несовместим с профилем вашего аккаунта, он скрывается из sync и find-one, а создание заказа напрямую будет отклонено.
Этот слой совместимости не связан с наценкой на товар и конвертацией валют. GamesDrop возвращает финальную цену покупки, доступную вашему аккаунту; при создании заказа всегда используйте последнюю price, полученную из sync или find-one.
Пошаговая интеграция
Используйте вызовы в таком порядке для заведения каталога товаров и создания заказов:
-
Загрузить каталог
POST /api/v1/offers/sync- Передайте необязательный ISO 3166-1 alpha-2
countryCode(например,USилиDE), чтобы рассчитать совместимость со страной активации. Это не фильтрует глобальный каталог. - Используйте этот ответ, чтобы создать или обновить товары в вашей системе.
- Сохраните
rows[].offerGroupIdкак числовой GamesDropofferIdдля всех следующих запросов. - Сохраните названия товаров, названия офферов, цену, валюту, наличие, платформу/регион и обязательные customer-поля.
-
Построить страницу товара или checkout-форму
- Покажите
productName,offerGroupName,priceиcurrency. - Если
isRequiredGameUserId=true, запросите у клиента game/user/player ID. - Если
isRequiredGameServerId=true, получите список серверов и попросите клиента выбрать сервер.
- Покажите
-
Обновить выбранный оффер перед оплатой/созданием заказа
POST /api/v1/offers/find-one- Передайте числовой GamesDrop offer group ID и тот же необязательный
countryCode. - Используйте возвращённую
priceкак подтверждённую цену GamesDrop дляcreate-order.
-
Получить серверы, если нужны
- Если
isRequiredGameServerId=true, вызовитеPOST /api/v1/partner/product-offer/servers. - Покажите ключи ответа пользователю как названия, а выбранное значение отправляйте как
gameServerId.
- Если
-
Проверить данные игрока, если нужны
- Если
isRequiredGameUserId=true, вызовитеPOST /api/v1/offers/check-game-data. - Для игр, которым нужен сервер, передайте
gameServerId.
- Если
-
Создать заказ
POST /api/v1/offers/create-order- Передайте
offerId, последнюю GamesDropprice, уникальныйtransactionId, тот же необязательныйcountryCodeи обязательные customer-поля. - Для предоплатных заказов с баланса передавайте
useBalance: true. Если вы не интегрируете баланс, используйте согласованный с GamesDrop settlement flow.
-
Проверять статус заказа
POST /api/v1/offers/order-status- Используйте
order_id, который вернулcreate-order, какorderId. - Опрос выполняется до финального статуса:
COMPLETED,CANCELED,FAILEDилиREFUND.
Что сохранять из sync
| Поле | Как использовать |
|---|---|
offerGroupId | Сохраните как GamesDrop offerId. Передавайте это значение в find-one, servers, check-game-data и create-order. |
productName | Название товара в вашем каталоге. |
offerGroupName | Продаваемый номинал/вариант, который видит клиент. |
price + currency | Цена покупки GamesDrop для вашего аккаунта. Перед созданием заказа обновляйте через find-one. |
inStock | Показывайте/продавайте только если true. |
isRequiredGameUserId | Если true, checkout должен собрать customer.gameUserId. |
isRequiredGameServerId | Если true, вызовите servers и соберите customer.gameServerId. |
platformCode, platformName, regionCode, regionName | Необязательные данные для отображения/фильтров. Используйте эти поля, а не парсинг региона/платформы из названия. |
regionalLimitations, excludedCountryCodes, countryCompatibility | Данные для предупреждения об активации. Исключенная страна получает статус blocked, но API не отклоняет заказ. ROW не гарантирует активацию во всех странах. |
selectedKeyFormat, availableKeyFormats, selectedKeyStock | Формат выдачи (text или image), доступные форматы и физический остаток выбранного seller offer. Image-key доступен только магазинам с отдельным opt-in. |
Правила параметров create-order
| Параметр | Когда обязателен | Примечание |
|---|---|---|
offerId | Всегда | Числовой GamesDrop offer group ID из sync. |
price | Всегда | Последняя цена GamesDrop из find-one или sync; не передавайте вашу розничную цену для клиента. |
transactionId | Всегда | Уникальный ID из вашей системы. Повторное использование вернёт существующий заказ или ошибку дубля. |
countryCode | Рекомендуется для игровых ключей | ISO 3166-1 alpha-2 код страны активации. Если у магазина настроена страна по умолчанию, она используется при отсутствии поля. |
keyFormat | Только для image-key | Передайте image, только если find-one вернул selectedKeyFormat: "image". Старые запросы без поля остаются text-only. |
useBalance | Balance/prepaid flow | Используйте true для предоплатных заказов с баланса. Не передавайте для тестового offer 999 и settlement flows, согласованных отдельно. |
customer.email | Необязательно | Используется для отслеживания/поддержки. |
customer.gameUserId | Если isRequiredGameUserId=true | Player ID, game account ID, Telegram user ID или другой идентификатор доставки. |
customer.gameServerId | Если isRequiredGameServerId=true | Используйте значение, которое вернул servers, например os_euro. |
Для key/gift-card товаров, где isReturnDataForCustomer=true и player-поля не нужны, обычно достаточно отправить offerId, price, transactionId и необязательный customer.email.
API Endpoints
Управление балансом
Проверка баланса
Вы можете проверить текущий баланс вашего аккаунта, используя API токен магазина.
HTTPGET /api/v1/partner/balance Authorization: {{token}}
[!NOTE] Эндпоинт
/api/v1/balanceтребует JWT-авторизацию и используется в основном для веб-интерфейса. Для интеграции по Shop Token используйте/api/v1/partner/balance.
Response:
JSON{
"balance": 500.25,
"draft_balance": 0.00,
"is_postpaid": false,
"balance_profile": "USDT",
"currency": {
"id": 3,
"code": "USD"
},
"partner_id": 123,
"shop_id": 70,
"shop_name": "EasyPay",
"owner_id": 392
}
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
balance | number | Текущий доступный баланс |
draft_balance | number | Зарезервированные средства (в обработке) |
is_postpaid | boolean | true: аккаунт с постоплатой. false: предоплатный аккаунт. |
balance_profile | FIAT | USDT | MIXED | Определяет, какие settlement methods офферов поставщиков видны и доступны к покупке. |
partner_id | number | Уникальный ID партнерского аккаунта |
shop_id | number | ID магазина, определённый по токену |
shop_name | string | Название магазина, определённое по токену |
owner_id | number | ID пользователя-владельца магазина |
currency | object | Информация о валюте баланса |
История транзакций баланса
HTTPGET /api/v1/balance/transactions?page=1&limit=20 Authorization: {{passwordHash}}
[!NOTE] Это endpoint личного кабинета/JWT, а не базового Shop Token order flow. Используйте его только при интеграции dashboard-level управления аккаунтом.
Response:
JSON{
"transactions": [
{
"id": 12,
"amount": -75.00,
"type": "PURCHASE",
"description": "API Purchase - Virtual credits",
"balanceAfter": 425.00,
"createdAt": "2025-07-28T05:21:46.121Z"
},
{
"id": 11,
"amount": -50.00,
"type": "PURCHASE",
"description": "Test Purchase - Mobile game credits",
"balanceAfter": 500.00,
"createdAt": "2025-07-28T05:16:23.718Z"
}
],
"total": 25
}
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
page | number | Номер страницы (по умолчанию: 1) |
limit | number | Количество записей на странице (по умолчанию: 20) |
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
transactions | array | Список транзакций |
transactions[].id | number | Уникальный ID транзакции |
transactions[].amount | number | Сумма операции (отрицательная для списаний) |
transactions[].type | string | Тип операции (DEPOSIT, PURCHASE, REFUND) |
transactions[].description | string | Описание операции |
transactions[].balanceAfter | number | Баланс после операции |
transactions[].createdAt | string | Дата и время операции (UTC) |
total | number | Общее количество транзакций |
Получение информации о товаре
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 1001, "offerGroupId": 1001, "productOfferId": 77881, "providerProductId": "620b94639e44a1f3767893cc", "providerOfferId": "66e170989a659600013da9f3", "countryCode": "DE" }
offerId в этом запросе должен быть числовым GamesDrop offer group ID, который возвращается как rows[].offerGroupId в sync. Не передавайте внешние ID провайдера или строковые коды продуктов.
Response:
JSON{
"offerId": 1001,
"productName": "Total War: WARHAMMER III PC Steam CD Key",
"offerName": "Total War: WARHAMMER III PC Steam CD Key",
"platformCode": "steam",
"platformName": "Steam",
"regionCode": "ROW",
"regionName": "RoW",
"regionalLimitations": "Rest of the world (RoW) - custom",
"excludedCountryCodes": ["KP", "JP", "CN", "HK", "KR", "TW"],
"countryCompatibility": "allowed",
"count": 1,
"available": 4,
"sellerOfferCount": 4,
"selectedTextStock": 39,
"price": 10.57,
"currency": "USD",
"priceBreakdown": {
"providerPrice": 8.99,
"providerCurrency": "EUR",
"addedPercent": 3,
"fxRate": 1.1418132,
"price": 10.57,
"currency": "USD"
},
"quoteCheckedAt": "2026-07-16T12:00:00Z",
"quoteExpiresAt": "2026-07-16T12:00:45Z",
"isPriceFresh": true,
"settlementMethod": "MIXED",
"balanceProfile": "MIXED",
"isSettlementCompatible": true,
"isReturnDataForCustomer": true,
"isRequiredGameUserId": false,
"isRequiredGameServerId": false
}
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
offerId | number | Числовой GamesDrop offer group ID из sync; должно быть числом, не строкой |
countryCode | string | Необязательный ISO 3166-1 alpha-2 код страны активации. |
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
offerId, offerGroupId | number | Стабильный GamesDrop offer group ID. Оба поля всегда равны. |
productOfferId | number | Внутренний ID seller offer для диагностики. Не передавайте его как offerId. |
providerProductId, providerOfferId | string | Точные ID провайдера для диагностики. Не передавайте их как offerId. |
productName | string | - |
offerName | string | - |
platformCode | string | Нормализованный код платформы, если доступен. |
platformName | string | Название платформы для отображения, если доступно. |
regionCode | string | Нормализованный код региона, например GLB, EU, ROW, CIS, US, NA, EMEA, OTH. |
regionName | string | Название региона для отображения, если доступно, например Global, Europe, RoW, CIS. |
regionalLimitations | string | Общая региональная метка поставщика. |
excludedCountryCodes | string[] | ISO-коды стран, где активация запрещена. Исключения имеют приоритет над общей меткой региона. |
countryCompatibility | allowed | blocked | unverified | not_checked | Результат проверки запрошенной страны или страны магазина по умолчанию. |
count | number | Количество единиц в запросе заказа, сейчас 1. |
available, sellerOfferCount | number | Число доступных seller offers, а не количество ключей. |
selectedTextStock | number | Количество текстовых ключей выбранного exact seller offer. |
selectedKeyFormat | text | image | Фактический формат выбранного seller offer. |
availableKeyFormats | string[] | Форматы, разрешенные и доступные для вашего магазина. |
selectedKeyStock | number | Физический остаток выбранного exact seller offer. Для image-key selectedTextStock равен 0. |
price | number | - |
currency | KZT, USD, RUB, etc. | Код валюты цены |
priceBreakdown | object | Цена и валюта провайдера, партнерская наценка, FX и итоговая цена. MIXED не добавляет скрытую комиссию. |
quoteCheckedAt, quoteExpiresAt, isPriceFresh | string, string, boolean | Свежесть provider quote. Вызывайте find-one непосредственно перед заказом. |
settlementMethod | FIAT | USDT | MIXED | Метод расчетов выбранного оффера поставщика. |
balanceProfile | FIAT | USDT | MIXED | Ваш профиль баланса партнера. |
isSettlementCompatible | boolean | Всегда true для возвращаемых офферов. Несовместимые офферы скрываются. |
isReturnDataForCustomer | boolean | true: Ключ/Карта (вернет key). false: Прямое пополнение (на баланс). |
isRequiredGameUserId | boolean | true, если для создания заказа нужен customer.gameUserId. |
isRequiredGameServerId | boolean | true, если для создания заказа нужен customer.gameServerId. |
При создании заказа используйте offerGroupId из sync или тот же offerId из find-one. offerId и offerGroupId всегда равны стабильному ID группы GamesDrop. Не заменяйте их на productOfferId или provider ID.
Синхронизация каталога (B2B Sync)
Endpoint Sync предназначен для партнеров, которым нужно регулярно обновлять локальные базы товаров. Он возвращает плоский оптимизированный список доступных офферов, актуальные цены с учетом вашей наценки и наличие на складе в одном запросе.
Ответ включает только офферы, совместимые с вашим balanceProfile. Например, партнер с профилем USDT не получит в этой выдаче fiat-only офферы поставщиков.
Для отображения платформы и региона используйте поля platformCode/platformName и regionCode/regionName из ответа. Не считайте товар Global только по названию. ROW означает широкую зону Rest of World, но активация может быть недоступна для стран из excludedCountryCodes. Передавайте countryCode, чтобы получить статус предупреждения; товар при этом остается в глобальном каталоге.
HTTPPOST /api/v1/offers/sync Authorization: {{token}} { "limit": 1000, "page": 1, "category": "Top Up", "search": "genshin", "countryCode": "DE" }
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
limit | number | Количество элементов на странице (максимум 5000). По умолчанию: 1000. |
page | number | Номер страницы. По умолчанию: 1. |
search | string | Необязательный текстовый поиск по названию товара. |
category | string | Необязательный фильтр по категории, например Top Up, Gift Cards. Также поддерживаются legacy aliases TOP_UP и GIFT_CARD. |
countryCode | string | Необязательный ISO 3166-1 alpha-2 код страны активации. Рассчитывает countryCompatibility, но не исключает строки из глобального каталога. |
Response:
JSON{
"count": 1250,
"rows": [
{
"productId": 5,
"productName": "PUBG Mobile",
"offerGroupId": 101,
"offerGroupName": "60 UC",
"platformCode": "mobile",
"platformName": "Mobile",
"regionCode": "GLB",
"regionName": "Global",
"regionalLimitations": "REGION FREE",
"excludedCountryCodes": [],
"countryCompatibility": "allowed",
"productOfferId": 77881,
"providerProductId": "620b94639e44a1f3767893cc",
"providerOfferId": "66e170989a659600013da9f3",
"sellerOfferCount": 4,
"selectedTextStock": 39,
"price": 0.99,
"currency": "USD",
"isPriceFresh": true,
"inStock": true,
"isRequiredGameUserId": true,
"isRequiredGameServerId": false
}
]
}
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
count | number | Общее количество элементов, подходящих под фильтры. |
rows[].offerGroupId | number | ID, который нужно передавать как offerId при создании заказа. |
rows[].productOfferId, rows[].providerProductId, rows[].providerOfferId | number, string, string | Диагностические ID seller/provider. Не используйте их как offerId. |
rows[].productName | string | Название продукта. |
rows[].offerGroupName | string | Название продаваемого варианта. |
rows[].platformCode | string | Нормализованный код платформы, если доступен. |
rows[].platformName | string | Название платформы для отображения, если доступно. |
rows[].regionCode | string | Нормализованный код региона, если доступен, например GLB, EU, ROW, CIS, US, NA. Не считайте товар Global только потому, что в названии написано PC Steam CD Key. |
rows[].regionName | string | Название региона для отображения, если доступно, например Global, Europe, RoW, CIS, North America. |
rows[].regionalLimitations | string | Общая региональная метка поставщика. |
rows[].excludedCountryCodes | string[] | ISO-коды стран, где активация запрещена. |
rows[].countryCompatibility | allowed | blocked | unverified | not_checked | Статус предупреждения для запрошенной страны или страны магазина по умолчанию. Покупку не блокирует. |
rows[].price | number | Финальная стоимость покупки товара в вашей валюте. |
rows[].priceBreakdown | object | Цена провайдера, партнерская наценка, FX и итоговая цена. |
rows[].sellerOfferCount | number | Число eligible seller offers, не количество ключей. |
rows[].selectedTextStock | number | Подтвержденный text stock выбранного offer. |
rows[].quoteCheckedAt, rows[].quoteExpiresAt, rows[].isPriceFresh | разные | Свежесть snapshot. sync может устареть; перед заказом окончательным источником является find-one. |
rows[].inStock | boolean | true, если хотя бы один поставщик сейчас активен. |
rows[].isRequiredGameUserId | boolean | true, если товар требует идентификатор игрока. |
rows[].isRequiredGameServerId | boolean | true, если товар требует идентификатор сервера. |
Создание заказа
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 1001, "price": 560.10, "transactionId": "test112321124214", "countryCode": "DE", "keyFormat": "text", "useBalance": true, "customer": { "email": "user@gmail.com", "gameUserId": "52357322414" } }
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
offerId | number | Числовой GamesDrop offer group ID из sync; должно быть числом, не строкой |
price | number | Последняя цена покупки GamesDrop, полученная из find-one или sync. Не передавайте вашу розничную цену для клиента. |
transactionId | string | Уникальный идентификатор транзакции в вашей системе |
countryCode | string | Необязательный ISO 3166-1 alpha-2 код страны активации. Используйте то же значение, что в sync и find-one. |
keyFormat | text | image | Необязательно. Без поля API использует text-only. image разрешен только для магазинов с opt-in. |
useBalance | boolean | Используйте true для предоплатных заказов с баланса. Для тестового offer 999 можно не передавать. |
customer | object | Данные клиента и доставки |
customer.email | string | Необязательное поле для отслеживания |
customer.gameUserId | string | Обязательно, если isRequiredGameUserId=true |
customer.gameServerId | string | Обязательно, если isRequiredGameServerId=true |
Подтверждение цены и выбор поставщика
Поле price в create-order является подтверждением цены. Оно должно совпадать с ценой GamesDrop, которую ваша система получила из find-one или sync перед созданием заказа.
Не передавайте цену, которую видит ваш конечный клиент. Наценка вашего магазина управляется на вашей стороне и не является частью запроса заказа в GamesDrop.
Для товаров с несколькими поставщиками GamesDrop может выбрать лучшего доступного поставщика в момент создания заказа. Заказ будет принят только если подтвержденная price все еще покрывает требуемую цену покупки GamesDrop. Если цены поставщиков изменились или самый дешевый поставщик стал недоступен, API вернет WRONG_PRICE, OFFER_NOT_FOUND, OUT_OF_STOCK или SERVICE_UNAVAILABLE в зависимости от ситуации. В этом случае обновите цену оффера и попросите клиента повторить покупку.
Response:
JSON{
"order_id": 10222502,
"count": 1,
"price": 560.10,
"currency": "RUB",
"offer_id": 1001,
"product_name": "PUBG MOBILE GIFT",
"offer_name": "60 UC",
"status": "COMPLETED",
"is_return_data_for_customer": true,
"selected_key_format": "text",
"key": "001434249936"
}
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
order_id | number | - |
count | number | Количество единиц товара |
price | number | - |
currency | KZT | USD | EUR | RUB | - |
offer_id | number | GamesDrop offer group ID, использованный для заказа |
product_name | string | - |
offer_name | string | - |
status | string | SUBMITTED, PROCESSING, COMPLETED, CANCELED, FAILED, REFUND |
is_return_data_for_customer | boolean | true: Товар-ключ. false: Прямое пополнение. |
key | string (optional) | Код активации/PIN. Присутствует ТОЛЬКО если is_return_data_for_customer: true И статус COMPLETED. |
selected_key_format | text | image | Формат фактической выдачи. |
fulfillment_items | object[] (optional) | Для image-key содержит format, mimeType, fileName, contentBase64 и provider IDs. Возвращается авторизованному магазину только после COMPLETED; base64 не дублируется в key. |
Для selected_key_format: "image" декодируйте fulfillment_items[].contentBase64 согласно mimeType и передайте клиенту оригинальное изображение без изменения. Не применяйте OCR как источник истины и не записывайте base64/serial в логи.
[!NOTE]
create-orderсейчас возвращает поля в snake_case.order-statusвозвращает поля в camelCase для legacy-совместимости.
Проверка статуса заказа
HTTPPOST /api/v1/offers/order-status Authorization: {{token}} { "orderId": 10222502 }
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
orderId | number | GamesDrop order ID, который create-order вернул как order_id |
[!NOTE] Короткий endpoint
/api/v1/offers/order-statusсейчас проверяет заказ поorderId. Если нужен поиск поtransactionId, используйте legacy endpointPOST /api/v1/partner/product-offer/status.
Response:
JSON{
"orderId": 10222502,
"count": 1,
"price": 560.10,
"currency": "RUB",
"offerId": 1001,
"productName": "PUBG MOBILE GIFT",
"offerName": "60 UC",
"status": "COMPLETED",
"isReturnDataForCustomer": true,
"key": "001434249936",
"createdAt": "2024-05-28 10:08:04.296+00"
}
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
orderId | number | - |
count | number | Количество единиц товара |
price | number | - |
currency | KZT | USD | EUR | RUB | - |
offerId | number | GamesDrop offer group ID |
productName | string | - |
offerName | string | - |
status | string | Текущий статус: SUBMITTED, PROCESSING, COMPLETED, CANCELED, FAILED, REFUND |
message | string (optional) | Дополнительные детали статуса, если доступны; поле не гарантировано. |
isReturnDataForCustomer | boolean | true: Товар-ключ. false: Прямое пополнение. |
key | string (optional) | Код активации/PIN. Присутствует ТОЛЬКО если isReturnDataForCustomer: true И статус COMPLETED. |
createdAt | string | UTC +0 |
[!NOTE] Для legacy-совместимости часть внутренних состояний
FAILEDможет возвращаться изorder-statusкакCANCELED. Оба статуса нужно считать финальными неуспешными статусами.
Получение списка серверов
Для товаров, которым требуется идентификатор сервера (isRequiredGameServerId: true), вы можете получить список доступных серверов и показать его в вашем UI.
HTTPPOST /api/v1/partner/product-offer/servers Authorization: {{token}} { "offerId": 1001 }
Response:
JSON{
"Europe": "os_euro",
"America": "os_usa",
"Asia": "os_asia"
}
Примечание: используйте ключ, например "Europe", как label для отображения, а значение, например "os_euro", как gameServerId при создании заказа.
Проверка игрока
HTTPPOST /api/v1/offers/check-game-data Authorization: {{token}} { "offerId": 1001, "gameUserId": "52357322414", "gameServerId": "1234" }
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
offerId | number | Важно: должно быть числом, не строкой |
gameUserId | string | Идентификатор игрока |
gameServerId | undefined | string | Идентификатор сервера (если требуется) |
Успешный ответ:
JSON{
"status": "VALID",
"gameUserLogin": "JJJ"
}
Описание полей успешного ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
status | "VALID" | Игрок валиден |
gameUserLogin | string | Логин игрока |
Ответ при ошибке:
JSON{
"status": "INVALID"
}
Описание полей ответа с ошибкой:
| Ключ | Значение | Дополнение |
|---|---|---|
status | "INVALID" | Игрок не валиден |
Тестирование API
Тестовый товар
Для тестирования интеграции с API доступен специальный тестовый товар:
- ID товара: 999
- Название: Steam US
- Наименование: TEST OFFER GROUP
- Цена: используйте значение, которое вернул
find-one - Возвращает ключ: Да
Пример запроса информации о тестовом товаре:
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 999 }
Пример создания тестового заказа:
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 999, "price": 21.79, "transactionId": "test_123456", "customer": { "email": "test@example.com", "gameUserId": "123456789" } }
Перед созданием тестового заказа вызовите find-one для offerId: 999 и скопируйте возвращённую price в create-order. Не хардкодьте цену из примера: она может отличаться в зависимости от валюты магазина и настроек цены.
Особенности тестового товара:
- Возвращает выполненный тестовый заказ, если тестовый оффер включён для вашего магазина
- Генерирует тестовый ключ активации
- Создаёт заказ со статусом COMPLETED
- Проверка игрока всегда возвращает VALID для тестового товара
- Работает в тестовом режиме без заказа у провайдера
Примеры работы с балансом
Проверка баланса перед покупкой:
JAVASCRIPT// 1. Проверяем текущий баланс
const balanceResponse = await fetch('/api/v1/partner/balance', {
headers: { 'Authorization': 'your-token-here' }
});
const { balance } = await balanceResponse.json();
// 2. Получаем информацию о товаре
const offerResponse = await fetch('/api/v1/offers/find-one', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ offerId: 1001 })
});
const { price } = await offerResponse.json();
// 3. Проверяем достаточность средств
if (balance >= price) {
// Создаем заказ
console.log('Sufficient balance, creating order...');
} else {
console.log('Insufficient balance, need to top up');
}
Получение истории транзакций:
JAVASCRIPTconst transactionsResponse = await fetch('/api/v1/balance/transactions', {
headers: { 'Authorization': 'Bearer your-dashboard-jwt-token' }
});
const { transactions, total } = await transactionsResponse.json();
console.log(`Total transactions: ${total}`);
transactions.forEach(tx => {
console.log(`${tx.createdAt}: ${tx.type} ${tx.amount} (Balance: ${tx.balanceAfter})`);
});
Рекомендации по использованию
💰 Работа с балансом
- Регулярно проверяйте баланс перед крупными покупками
- Ведите учет транзакций для сверки с вашей системой
- При недостатке средств уведомляйте пользователей о необходимости пополнения
- Используйте пагинацию при запросе истории транзакций
🔍 Перед созданием заказа
- Получите актуальную информацию о товаре
- Проверьте достаточность баланса для покупки
- Проверьте валидность игрока (в случае прямого пополнения)
📝 При создании заказа
- Используйте уникальный transactionId
- Указывайте последнюю цену GamesDrop, полученную из
find-oneилиsync - Не передавайте вашу розничную цену для клиента в поле
price - Указывайте offerId как число, не как строку
- Заполняйте все необходимые поля для данного типа товара
✅ После создания заказа
- Сохраните orderId
- Проверяйте статус заказа
- При статусе COMPLETED получите ключ/товар
⚠️ При возникновении ошибок
- Проверьте токен
- Убедитесь в корректности данных и формате запроса
- Создайте новый заказ при необходимости
FAQ и Устранение неполадок
Типы товаров (Пополнение vs Ключи)
Наша система поддерживает два основных типа доставки. Вы можете различить их, используя поле isReturnDataForCustomer в ответе информации о товаре.
1. Подарочные карты / Ключи (isReturnDataForCustomer: true)
- Что это: Клиент получает цифровой код, PIN или ссылку для ручной активации.
- Поток:
create-orderвозвращаетstatus: "COMPLETED"и полеkey.- Вы показываете этот
keyсвоему клиенту.
- Пример: Код пополнения Steam (Wallet Code), код на UC в PUBG.
2. Прямое пополнение (isReturnDataForCustomer: false)
- Что это: Средства зачисляются напрямую на игровой аккаунт игрока. Код не возвращается.
- Поток:
- Вы ОБЯЗАНЫ передать
gameUserId(и иногдаgameServerId) в запросеcreate-order. - Мы рекомендуем сначала проверить валидность ID через
/check-game-data. create-orderвозвращает текущий статус. Опроситеorder-status, пока заказ не станетCOMPLETEDилиCANCELED.
- Вы ОБЯЗАНЫ передать
- Пример: Пополнение Mobile Legends Diamonds по User ID.
Конвертация валют
- Ваш баланс партнера: Всегда ведется в USD.
- Цены товаров: Могут быть в разных валютах (RUB, KZT, EUR и т.д.) в зависимости от региона.
- Как это работает:
- Вам не нужно конвертировать средства вручную.
- Когда вы покупаете товар с ценой в
RUB(например, 500 RUB), система рассчитывает эквивалент вUSD(например, $5.50) и списывает его с вашего USD баланса. - Убедитесь, что у вас достаточно баланса в USD для покрытия конвертированной суммы.
- Совместимость расчетов с поставщиками: ваш каталог фильтруется по
balanceProfileдо возврата цен. Это предотвращает продажу fiat-only офферов USDT-only партнерам и наоборот. - Без ручной FX-наценки: GamesDrop не требует добавлять дополнительный процент на потери конвертации в API-запрос. Используйте последнюю цену, возвращенную
find-oneилиsync. Любая настроенная B2B-наценка уже включена в возвращаемую цену покупки GamesDrop.
Частые вопросы
"Я вижу упоминание параметра 'it', что это?"
В нашем API нет параметра с именем it. Вероятно, это опечатка вместо id или недопонимание.
- Идентификатор товара:
offerId. - Идентификатор транзакции:
transactionId. - Идентификатор пользователя:
gameUserId.
"Как проверить валидность ID игрока?"
Используйте эндпоинт POST /api/v1/offers/check-game-data. Он вернет VALID и никнейм игрока, если ID верен. Это настоятельно рекомендуется для товаров с прямым пополнением, чтобы избежать ошибок.
Поддержка
При возникновении вопросов обращайтесь в техническую поддержку:
- 📧 Email: info@gamesdrop.io
- 💬 Telegram: @igoryan34
Рекомендации по обработке ошибок
🔍 Проверка перед запросом
- Валидация токена
- Проверка ID товара
- Актуальность цены
- Уникальность transaction_id
- Корректность формата данных (особенно offerId как число)
🛠 Обработка ответов
- Обработка всех кодов ошибок
- Логирование ошибок
- Механизм повторных попыток
📊 Работа с заказами
- Сохранение ID заказов
- Мониторинг статусов
- Актуализация данных
Telegram Stars
🌟 GamesDrop интегрировал поддержку Telegram Stars! Теперь вы можете отправлять Telegram Stars пользователям через те же стандартные API эндпоинты.
Доступные продукты Telegram Stars
Для Partner API offerId должен быть числовым GamesDrop offer group ID, который возвращается sync или find-one. Строковые ID ниже являются внутренними идентификаторами продуктов провайдера и приведены только для справки.
| Internal Provider Product ID | Количество Stars | Динамическая цена |
|---|---|---|
telegram_stars_50 | 50 | Основана на курсе TON |
telegram_stars_100 | 100 | Основана на курсе TON |
telegram_stars_500 | 500 | Основана на курсе TON |
telegram_stars_1000 | 1000 | Основана на курсе TON |
Как работает ценообразование:
- A6-Gateway получает актуальный TON/USD курс от kernel currency API
- Цена рассчитывается на основе Fragment.com коэффициентов (100 Stars ≈ 0.3 TON)
- Цены обновляются в реальном времени при каждом запросе
Использование тех же эндпоинтов
1. Получение информации о Telegram Stars:
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 1001 }
Response:
JSON{
"offerId": 1001,
"productName": "Telegram Stars",
"offerName": "100 Stars",
"count": 1,
"price": 0.77,
"currency": "USD",
"isReturnDataForCustomer": true
}
2. Создание заказа на Telegram Stars:
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 1001, "price": 0.77, "transactionId": "tg_stars_12345", "customer": { "email": "user@example.com", "gameUserId": "143594291" } }
Ответ create-order:
JSON{
"order_id": 10228901,
"count": 1,
"price": 0.78,
"currency": "USD",
"offer_id": 1001,
"product_name": "Telegram Stars",
"offer_name": "100 Stars",
"status": "SUBMITTED",
"is_return_data_for_customer": false
}
Для проверки финальной доставки используйте order-status:
JSON{
"orderId": 10228902,
"transactionId": "tg_stars_12345",
"count": 1,
"price": 0.78,
"currency": "USD",
"offerId": 1001,
"productName": "Telegram Stars",
"offerName": "100 Stars",
"status": "CANCELED",
"isReturnDataForCustomer": false,
"createdAt": "2025-08-26T12:30:15.234Z"
}
🔑 Важные особенности Telegram Stars
gameUserId требования:
- gameUserId должен быть числовой Telegram User ID для создания заказа
- Получить User ID можно двумя способами:
- 📞 Через @userinfobot в Telegram
- 🆕 Через наш API валидации (см. раздел ниже)
- Пример:
"gameUserId": "143594291" - ❌ НЕ username (@username) для создания заказа
Статусы доставки:
COMPLETED- Stars успешно доставлены пользователюCANCELED- Не удалось доставить (неверный user ID, заблокирован бот, etc.)
Типичные ошибки доставки:
"user not found"- неверный Telegram User ID"STARGIFT_INVALID"- пользователь не может получить Stars (restrictions)"bot was blocked by user"- пользователь заблокировал бота
🆔 Валидация Telegram пользователей
🎯 Новый endpoint для валидации username и получения User ID!
Если ваши пользователи знают только свой @username, используйте этот endpoint для получения User ID перед созданием заказа.
Endpoint валидации:
HTTPPOST https://gamesdrop.io/api/aggregator/a6/telegram/user-info Authorization: {{token}} Content-Type: application/json { "username": "@igoryan34" }
Response при успешной валидации:
JSON{
"valid": true,
"username": "igoryan34",
"userInfo": {
"id": 143594291,
"first_name": "Igor",
"username": "igoryan34",
"photo_url": "AQADAgADRKgxGzMTjwgABCAI..."
},
"message": "User account verified successfully"
}
Response при невозможности получить User ID:
JSON{
"valid": true,
"username": "igoryan34",
"userInfo": {
"username": "igoryan34",
"first_name": "igoryan34"
},
"message": "Username format is valid, but user details are not publicly available. Full verification requires user interaction with the bot."
}
Описание полей запроса:
| Ключ | Значение | Дополнение |
|---|---|---|
username | string | Telegram username с @ или без |
Описание полей ответа:
| Ключ | Значение | Дополнение |
|---|---|---|
valid | boolean | Всегда true для корректных username |
username | string | Очищенный username без @ |
userInfo.id | number | 🎯 User ID для заказов (если доступен) |
userInfo.first_name | string | Имя пользователя |
userInfo.username | string | Username пользователя |
userInfo.photo_url | string | URL аватара (если доступен) |
message | string | Описание результата валидации |
⚠️ Важные особенности:
- Endpoint возвращает User ID только если пользователь взаимодействовал с ботом
- Если
userInfo.idотсутствует, попросите пользователя написать боту @gamesdrop_api_bot - Можно передавать как
"@username", так и"username" - Можно также передавать User ID для получения дополнительной информации
📱 Интеграция для разработчиков
Пример полного flow на JavaScript с валидацией username:
JAVASCRIPT// 1. Валидировать username и получить User ID
const validateTelegramUser = async (username) => {
const response = await fetch('https://gamesdrop.io/api/aggregator/a6/telegram/user-info', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ username })
});
const result = await response.json();
if (result.valid && result.userInfo && result.userInfo.id) {
return {
userId: result.userInfo.id,
firstName: result.userInfo.first_name,
username: result.userInfo.username
};
} else {
throw new Error('Unable to get User ID. Please ask user to message @gamesdrop_api_bot first.');
}
};
// 2. Найти числовой offer group ID в синхронизированном каталоге
const getTelegramStarsOfferGroupId = async (starsAmount) => {
const response = await fetch('/api/v1/offers/sync', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ limit: 5000, page: 1, search: 'Telegram Stars' })
});
const catalog = await response.json();
const row = catalog.rows.find((item) =>
item.productName?.includes('Telegram Stars') &&
item.offerGroupName?.includes(String(starsAmount))
);
if (!row) {
throw new Error(`Telegram Stars offer group not found for ${starsAmount} Stars`);
}
return row.offerGroupId;
};
// 3. Получить актуальную цену
const getStarsPrice = async (starsAmount) => {
const offerGroupId = await getTelegramStarsOfferGroupId(starsAmount); // Получаем из синхронизированного каталога
const response = await fetch('/api/v1/offers/find-one', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offerId: offerGroupId
})
});
return response.json();
};
// 4. Отправить Stars пользователю
const sendStarsByUsername = async (usernameOrId, starsAmount) => {
// Сначала получаем User ID если передали username
let userId;
if (isNaN(usernameOrId)) {
// Это username, нужно получить User ID
const userInfo = await validateTelegramUser(usernameOrId);
userId = userInfo.userId;
console.log(`✅ Validated user: ${userInfo.firstName} (@${userInfo.username}) - ID: ${userId}`);
} else {
// Это уже User ID
userId = parseInt(usernameOrId);
}
// Получаем цену
const { offerId, price } = await getStarsPrice(starsAmount);
// Создаем заказ
const response = await fetch('/api/v1/offers/create-order', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offerId: offerId,
price: price,
transactionId: `stars_${Date.now()}`,
customer: {
email: "optional@example.com",
gameUserId: userId.toString()
}
})
});
const result = await response.json();
if (result.status === 'COMPLETED') {
console.log(`✅ Successfully sent ${starsAmount} Stars to User ID ${userId}`);
return result;
} else {
console.error(`❌ Failed to send Stars: ${result.message}`);
throw new Error(result.message);
}
};
// Использование:
// С username:
sendStarsByUsername('@igoryan34', 100)
.then(order => console.log('Order created:', order.orderId))
.catch(error => console.error('Delivery failed:', error));
// С User ID:
sendStarsByUsername('143594291', 100)
.then(order => console.log('Order created:', order.orderId))
.catch(error => console.error('Delivery failed:', error));
💼 B2B кейсы использования
1. Награды в играх:
JAVASCRIPT// Наградить игрока за достижение
await sendStars(userTelegramId, 50);
2. Промо-кампании:
JAVASCRIPT// Отправить Stars всем участникам конкурса
const winners = [143594291, 987654321, 456789123];
for (const userId of winners) {
await sendStars(userId, 100);
}
3. Кэшбек программы:
JAVASCRIPT// Вернуть часть покупки в виде Stars
const cashbackAmount = Math.floor(purchaseAmount * 0.05); // 5% кэшбек
const starsAmount = Math.min(cashbackAmount * 100, 1000); // конвертируем в Stars
await sendStars(userTelegramId, starsAmount);
⚡ Performance и лимиты
- Rate limiting: 30 запросов в секунду на Telegram API
- Minimum amount: 1 Star
- Maximum amount: 2500 Stars за одну транзакцию
- Retry logic: Автоматические повторы при временных ошибках
- Delivery time: Мгновенная доставка (< 3 секунды)
🛡️ Безопасность
- Валидация Telegram User ID перед отправкой
- Проверка баланса GamesDrop перед созданием заказа
- Логирование всех операций для аудита
- Защита от дублированных транзакций через
transactionId