Оптовая платформа цифровых товаров

Как подключить API поставщика цифровых товаров — пошаговая интеграция 2026

От первого ключа до продакшена — как построить надёжный слой интеграции между API поставщика и вашей витриной.

Как подключить API поставщика цифровых товаров

Подключение API поставщика — это не «сделать один curl и радоваться». Это отдельный сервисный слой, который переживает падения чужого API, не выдаёт клиенту чужой код дважды и не роняет вашу витрину, когда у поставщика идёт деплой. Ниже — рабочая последовательность шагов от первого ключа до чек-листа выхода в прод.

Архитектура — три слоя, не два

Единственная схема, которая нормально живёт в продакшене, выглядит так:

API поставщика → ваш middleware → витрина.

Middleware — это ваш собственный сервис (или набор фоновых задач и внутренних эндпоинтов), который знает ключ поставщика, хранит локальную копию каталога, создаёт заказы, опрашивает их статус и отдаёт витрине только уже нормализованные данные.

Чего делать нельзя категорически:

  • Вызывать API поставщика напрямую из браузера или мобильного приложения. Это означает, что ключ уехал на клиента. Ключ поставщика — серверный секрет, всегда.
  • Ходить в API поставщика на каждый рендер страницы каталога. Вы упрётесь в rate limit и сделаете доступность своего сайта заложником чужого аптайма.
  • Держать бизнес-логику выдачи в контроллере витрины. Выдача должна быть идемпотентной операцией в отдельном сервисе, иначе двойной клик клиента превратится в двойной заказ.

Шаг 1. Ключи и окружения

Первое, что вы получаете от поставщика, — ключ доступа. Уточните у него три вещи:

  1. Какой заголовок авторизации. Это может быть X-API-Key, может быть Authorization: Bearer, может быть подпись запроса. У FoxReload это X-API-Key: YOUR_API_KEY — никаких Bearer-токенов, OAuth или client_id/client_secret.
  2. Показывается ли ключ повторно. У большинства поставщиков — нет. У FoxReload ключ показывается один раз, поэтому сразу кладите его в секрет-менеджер (Vault, AWS Secrets Manager, Doppler), а не в .env в репозитории.
  3. Есть ли IP-allowlist. Если есть — включайте. У FoxReload ключ можно ограничить по IP или CIDR, до 10 записей; запрос с чужого IP вернёт HTTP 403, что гораздо лучше, чем утёкший и работающий отовсюду ключ.

Отдельный вопрос — тестовое окружение

Многие поставщики дают отдельный sandbox-домен. Многие — нет. У FoxReload отдельного sandbox-окружения не существует: тестирование делается флагом isMock: true в теле создания заказа — заказ возвращает мок-коды с той же структурой ответа, без реального списания с баланса.

Это принципиальный момент для проектирования: уточните у своего поставщика, как именно тестировать, до того как напишете первый интеграционный тест. Если тестовый режим — это флаг в теле запроса, ваш код должен уметь прокидывать этот флаг сквозь весь стек, а ваша база — отличать мок-заказы от реальных.

Шаг 2. Синхронизация каталога и цен

Каталог — это фоновая задача, а не запрос по требованию.

curl "https://public-api.foxreload.com/api/categories/?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Затем по каждой категории забираются товары:

curl "https://public-api.foxreload.com/api/products/?category_id_or_slug=gift-cards&limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Товар приходит с id, name и price. Поле id — это то, что вы позже передадите как itemId при создании заказа, поэтому его нужно сохранить в своей таблице как внешний ключ поставщика.

Практические правила синхронизации:

  • Храните supplier_product_id рядом со своим внутренним SKU. Никогда не привязывайте свою витрину напрямую к идентификаторам одного поставщика — иначе добавление второго поставщика превратится в переписывание половины кода.
  • Обновляйте цены отдельной, более частой задачей, чем полный обход каталога. Названия и описания меняются редко, цены — регулярно.
  • Никогда не удаляйте товар из своей базы по факту его отсутствия в одном ответе. Помечайте флагом unavailable. Частичный ответ или таймаут не должны обнулять ваш каталог.
  • Ведите наценку в своей системе, а не в закупочной цене. Закупочная цена от поставщика — входные данные; розничная цена вашей витрины считается вашим движком ценообразования.

Шаг 3. Проверка баланса

Оптовые API цифровых товаров чаще всего работают с предоплаченного баланса: вы пополняете счёт, заказы списывают с него. Значит, у вас появляется новый класс отказов — заказ не выполнился не потому, что сломался код, а потому что кончились деньги.

Что нужно сделать:

  • Читать баланс перед созданием заказа, если сумма заказа заметная.
  • Держать фоновый мониторинг баланса с двумя порогами — «предупреждение» и «критично», с алертом в тот канал, который реально читают ночью.
  • Корректно обрабатывать ошибку недостатка средств. У FoxReload это BalanceNotEnough; пополнение делается через POST /api/topups/crypto/. Уточните у своего поставщика, какие способы пополнения он поддерживает и сколько времени занимает зачисление — это напрямую определяет, какой запас вам нужно держать.

Отдельно продумайте, что видит клиент. Если баланса не хватило, клиент не должен получить «ошибка 500». Он должен получить понятный отказ — а лучше вообще не иметь возможности оформить заказ по позиции, которую вы прямо сейчас не можете выкупить.

Шаг 4. Создание заказа

Заказ создаётся POST-запросом с массивом позиций:

curl -X POST "https://public-api.foxreload.com/api/orders" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "itemId": "product_01krgfgww8eth9xvvysd6y7r4j",
        "quantity": 1
      }
    ],
    "isMock": false
  }'

Ответ — объект заказа с id, price, status, createdAt, paymentExpiresAt и массивом items[].

Про идемпотентность — важная оговорка

Некоторые API принимают заголовок Idempotency-Key, чтобы повторная отправка того же запроса не создала второй заказ. Обязательно проверьте, реализует ли это ваш конкретный поставщик — далеко не все. FoxReload заголовок Idempotency-Key не поддерживает.

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

  1. Генерируете на своей стороне уникальный ключ операции и сохраняете его в своей базе до вызова поставщика.
  2. При сетевой ошибке или таймауте не создаёте заказ повторно вслепую — сначала запрашиваете список заказов у поставщика и проверяете, не создался ли он на самом деле.
  3. Только убедившись, что заказа нет, повторяете попытку.

Таймаут при создании заказа — это неопределённость, а не отказ. Считать его отказом и сразу ретраить — самый дорогой способ научиться разнице.

Шаг 5. Получение статуса — опрос как базовый механизм

Опрос (polling) — это механизм, который работает всегда. Вебхуки — это опция, которая есть не у всех.

Проверьте, отдаёт ли ваш поставщик вебхуки и подписывает ли он их (HMAC или иная схема). Если отдаёт — вебхук можно использовать как ускоритель, но опрос всё равно должен остаться в качестве страховки: доставка вебхуков не гарантирована, а ваш эндпоинт может быть недоступен в момент отправки. У FoxReload вебхуков нет — результат заказа получается исключительно опросом.

curl "https://public-api.foxreload.com/api/orders/{order_id}" \
  -H "X-API-Key: YOUR_API_KEY"

Рабочая схема опроса:

Фаза Что делать
Первая минута Частый опрос — каждые несколько секунд
Далее Постепенно увеличивающийся интервал (backoff)
Предельный срок Свой таймаут, после которого заказ помечается «требует внимания»
Терминальные статусы Опрос прекращается — результат зафиксирован в вашей базе

У FoxReload заказ проходит статусы activepaidprocessingcompleted, с терминальными ветками cancelled (с полем cancelReason) и failed (с ошибкой по каждой позиции в items[].error). Коды при completed лежат в items[].externalData. Подробный разбор состояний — в статье схема обработки заказа FoxReload.

Шаг 6. Обработка ошибок

Разделите ошибки на три группы и обращайтесь с ними по-разному:

  • Не ретраить никогда. HTTP 400, 401, 403, 404 — это ваша ошибка или ошибка конфигурации. Повторный запрос вернёт то же самое. Логируйте и разбирайтесь.
  • Ретраить с backoff. HTTP 429 (rate limit) и 5xx. Экспоненциальный backoff с джиттером, ограниченное число попыток, потолок интервала.
  • Проверять перед ретраем. Сетевые таймауты на изменяющих операциях. Сначала выясняем, что произошло на стороне поставщика, потом действуем.

Ошибки по позициям внутри заказа — отдельный случай. Заказ может завершиться частично: одна позиция выдана, другая нет. Ваша модель данных должна уметь описывать частичное выполнение, иначе логика возвратов будет неверной.

Шаг 7. Чек-лист выхода в продакшен

  • Ключ лежит в секрет-менеджере, в git его нет, история репозитория проверена.
  • IP-allowlist включён, если поставщик его поддерживает.
  • Мок-заказы (или sandbox) прогнаны по всем типам товаров, которые вы продаёте.
  • Каталог синхронизируется по расписанию и не обнуляется при частичном ответе.
  • Баланс мониторится, алерты настроены на два порога.
  • Создание заказа защищено от дублей на вашей стороне.
  • Опрос имеет таймаут и очередь «зависших» заказов с алертом.
  • Ретраи стоят только на 429 и 5xx.
  • Все запросы и ответы поставщика логируются с привязкой к вашему внутреннему order_id — это ваша доказательная база при спорах.
  • Есть ручной сценарий: что делает оператор, когда заказ завис, а клиент уже пишет в поддержку.

Где брать товар

Слой интеграции имеет смысл строить один раз и под каталог, который закроет большую часть ассортимента. FoxReload — оптовый поставщик цифровых товаров с 900+ SKU: игровые ключи, подарочные карты, пополнения игровых аккаунтов, eSIM и лицензии на софт, всё через один REST API с автоматической выдачей и мультирегиональными SKU. Один ключ, один формат ответа, одна модель заказа на весь ассортимент — вместо пяти разных интеграций с пятью разными схемами авторизации.

Читать дальше

Часто задаваемые вопросы

С чего начать интеграцию API поставщика цифровых товаров?
Начните с проверки авторизации — сделайте один запрос к самому простому эндпоинту (обычно это профиль аккаунта или список категорий) и убедитесь, что получаете HTTP 200. Только после этого переходите к каталогу. Такой порядок отсекает половину проблем на старте — неверный заголовок, не тот домен, ключ вне IP-allowlist. Затем синхронизируйте каталог и лишь потом переходите к заказам.
Нужно ли кэшировать каталог поставщика у себя?
Да, обязательно. Витрина должна читать товары и цены из вашей собственной базы, а не дёргать API поставщика на каждый рендер страницы — иначе вы упрётесь в rate limit и получите зависимость доступности вашего сайта от доступности чужого API. Фоновая задача обновляет локальную таблицу с нужной вам частотой. Цены и наличие при этом всё равно проверяются повторно в момент создания заказа.
Как получить результат заказа, если у поставщика нет вебхуков?
Опросом — периодическим запросом статуса заказа по его идентификатору. Это базовый механизм, который работает у любого REST-поставщика, включая FoxReload, где вебхуков нет. Разумная схема — частый опрос в первую минуту, затем реже, до достижения терминального состояния. Обязательно ставьте предельный срок опроса и алерт на заказы, застрявшие дольше него.
Что проверить перед выходом в продакшен?
Ключ лежит в секрет-менеджере и не попал в git; каталог синхронизируется по расписанию и переживает падение API; создание заказа проверяет баланс; опрос имеет таймаут и алерт на зависшие заказы; ретраи стоят только на 429 и 5xx; все ответы поставщика логируются с order_id для разбора споров. Отдельно протестируйте поведение при нулевом балансе и при недоступном каталоге.
Смотреть оптовые цены FoxReload

Похожие статьи