Как автоматизировать доставку цифровых кодов
Краткий ответ
Автоматизация доставки цифровых кодов означает замену ручной обработки заказов конвейером: оплата покупателем запускает API-вызов к поставщику, поставщик выполняет заказ, а система получает коды опросом и доставляет покупателю — всё в течение секунд или минут. Шесть компонентов: слушатель события оплаты, вызов API создания заказа, опрос статуса до завершения, разбор кода из ответа, доставка покупателю (email/страница/сообщение) и обработка ошибок для неудачных заказов. Рабочая автоматизация обрабатывает неограниченное количество заказов без ручных шагов.
Определение: Автоматизированная доставка цифрового кода — конвейер фулфилмента, соединяющий оплату покупателем с доставкой кода без вмешательства человека — с использованием создания заказов через API, опроса статусов до завершения и программной раздачи кодов.
Главный вывод: Ручная доставка кодов не масштабируется: она создаёт задержки, человеческие ошибки и нагрузку на поддержку. Автоматизация устраняет все три проблемы. Один разработчик может построить систему, обрабатывающую тысячи ежедневных заказов с теми же усилиями, что и десяток.
Для кого это руководство
- Разработчики, создающие магазины цифровых товаров и реализующие конвейер доставки
- Владельцы магазинов, доставляющие коды вручную и желающие автоматизироваться
- Разработчики Telegram-ботов, желающие автоматизировать доставку пополнений и подарочных карт
Почему ручная доставка не масштабируется
| Проблема | Ручная | Автоматизированная |
|---|---|---|
| Скорость доставки | Часы (или на следующий день) | Секунды |
| Объём заказов | ~50/день на человека | Неограниченно |
| Риск человеческой ошибки | Ошибки копирования | Устранён |
| Нагрузка на поддержку | Высокая (запросы о пропавших кодах) | Низкая |
| Покрытие в нерабочее время | Нет | Постоянная работа |
| Стоимость масштабирования | Линейная (больше заказов = больше сотрудников) | Близко к нулю |
При 20 заказах в день ручная работа справляется. При 200 — становится узким местом. При 2 000 — ломается.
Конвейер автоматизированной доставки
[Покупатель платит]
│
▼
[Вебхук/коллбэк платёжного шлюза срабатывает]
│
▼
[Обработчик заказа: валидация платежа, построение запроса заказа]
│
▼
[POST /api/orders/ в API поставщика]
[{ "items": [{ "itemId": "product_01k...", "quantity": 1 }] }]
│
├─[Успех]──▶ [Опрос GET /api/orders/{order_id} до status=="completed"]
│ │
│ ▼
│ [Разбор кода из items[].externalData]
│ │
│ ▼
│ [Доставка кода покупателю]
│ (email / страница заказа / сообщение бота)
│
└─[Ошибка]──▶ [Логировать, оповестить ops, вернуть деньги при необходимости]
Компонент 1: Слушатель события оплаты
Конвейер фулфилмента начинается, когда оплата подтверждена — не когда она инициирована.
Правила:
- Запускать фулфилмент только на подтверждённое событие оплаты (не на создание заказа)
- Обрабатывать идемпотентность: если одно и то же событие оплаты срабатывает дважды, не создавать два заказа
- Валидировать, что сумма оплаты совпадает с ожидаемой стоимостью продукта
Большинство платёжных шлюзов (Stripe, PayPal и др.) отправляют вебхук-событие при подтверждении оплаты. Подпишитесь на правильный тип события:
- Stripe:
payment_intent.succeeded - PayPal:
PAYMENT.CAPTURE.COMPLETED
Никогда не запускайте вызов API поставщика со стороны клиента (браузера). Всегда со своего сервера.
Компонент 2: Вызов API создания заказа
После подтверждения оплаты вызовите эндпоинт создания заказа поставщика:
POST /api/orders/
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{
"items": [{"itemId": "product_01k...", "quantity": 1}]
}
Сохраните возвращённый id заказа. Это позволяет опрашивать статус через GET /api/orders/{id}. FoxReload не имеет idempotency-ключей — перед повторным созданием проверяйте статус существующего заказа, чтобы не задвоить.
Действия по ответам:
| Статус ответа | Действие |
|---|---|
completed |
Разобрать код и доставить покупателю |
pending |
Опросить статус заказа или ждать вебхука |
failed |
Логировать ошибку, не списывать с покупателя, оповестить ops |
| Таймаут / сетевая ошибка | Повторная попытка с экспоненциальным откатом (2–3 попытки) |
Компонент 3: Разбор кода
При status == "completed" коды находятся в items[].externalData. Разберите и валидируйте перед доставкой:
{
"id": "order_01k...",
"status": "completed",
"items": [
{
"itemId": "product_01k...",
"externalData": ["XXXXX-YYYYY-ZZZZZ"],
"error": null
}
]
}
Валидируйте:
statusравенcompleted(неactive,paid,processingилиfailed)- Поле
externalData— непустой массив items[].error— null (не ошибка позиции)
Для продуктов пополнения ответ может содержать подтверждение доставки вместо кода.
Компонент 4: Доставка покупателю
Доставьте код через канал, который используют ваши покупатели:
| Канал | Реализация | Когда использовать |
|---|---|---|
| Страница подтверждения заказа | Показать код на URL успеха после редиректа | Веб-магазины |
| Транзакционный email | Отправить письмо с кодом + инструкциями | Все каналы как резерв |
| Сообщение Telegram-бота | bot.sendMessage() с кодом | Telegram-боты |
| Кошелёк в аккаунте | Хранить код в разделе аккаунта пользователя | Платформы с аккаунтами |
| SMS | Twilio / локальный SMS-шлюз | Дорогие заказы, мобильно-ориентированные рынки |
Всегда включайте с кодом:
- Сам код (в удобном для копирования формате)
- Название продукта и номинал
- Инструкции по активации или ссылку
- Контакт вашей поддержки
Компонент 5: Опрос статусов для асинхронных заказов
Для заказов, не выполненных мгновенно (статус active, paid, processing), опрашивайте статус до завершения:
Правильная архитектура опроса:
1. POST /api/orders/ → получить order_id, сохранить в БД
2. Поставить задачу опроса в очередь (BullMQ, Celery и т.п.)
3. Фоновый воркер:
GET /api/orders/{id}
→ status == 'completed' → извлечь externalData → доставить код покупателю
→ status == 'failed'/'cancelled' → уведомить ops, обработать ошибку
→ иначе → повторить через 3–5 с (экспоненциальный откат при 429)
Не делайте:
- Опрос в синхронном запросе клиента (блокирует HTTP-соединение)
- Создавать повторный заказ без проверки статуса существующего (FoxReload не имеет idempotency-ключей)
- Игнорировать ошибку BalanceNotEnough — она означает нехватку средств на аккаунте
Компонент 6: Обработка ошибок
Пути ошибок требуют столько же проектирования, сколько и «счастливый путь».
| Сценарий ошибки | Правильный ответ |
|---|---|
| Оплата подтверждена, вызов API не удался | Повторить до 3 раз; если все неудачны, отметить для ручного разбора и уведомить ops |
API возвращает статус failed |
Не доставлять; не списывать с покупателя; вернуть деньги, если уже списано |
| Поле code пустое в ответе | Считать ошибкой; не доставлять пустую строку |
| Опрос не показывает изменений долго | Продолжать опрашивать с откатом; при аномальной задержке уведомить ops и обратиться в поддержку |
| Дублированное событие оплаты | Проверять существующий заказ в БД перед созданием нового (FoxReload не имеет idempotency-ключей) |
Мониторинг и оповещения
Настройте мониторинг по:
| Метрика | Порог оповещения |
|---|---|
| Время ответа API поставщика | Оповестить при >3с в среднем |
| Процент неудачных заказов | Оповестить при >2% за любые 30 минут |
| Баланс аккаунта реселлера | Оповестить при 20% от типичных дневных расходов |
| Незаконченные заказы (pending >10 мин) | Оповестить немедленно |
| Ошибки BalanceNotEnough | Оповестить при первом появлении — означает нехватку баланса |
Чек-лист интеграции
- Обработчик события подтверждения оплаты реализован и протестирован
- Проверка существующего заказа перед созданием нового (защита от дублей, FoxReload не имеет idempotency-ключей)
- Вызов
POST /api/orders/с заголовкомX-API-Keyреализован - Все статусы ответов обработаны: completed, failed, cancelled, а также BalanceNotEnough
- Разбор кода:
items[].externalDataнепустой массив,items[].errorотсутствует - Доставка покупателю реализована для вашего основного канала
- Доставка включает код + название продукта + инструкции по активации + контакт поддержки
- Фоновый воркер опрашивает
GET /api/orders/{id}до завершения - Экспоненциальный откат при 429/сетевых ошибках в опросе
- Планировщик для застрявших заказов (>5 мин в processing) настроен
- Логирование ошибок с оповещениями
- Мониторинг ошибок BalanceNotEnough с оповещением
- Нагрузочное тестирование при ожидаемом пиковом объёме
