Назад к блогу

Отказоустойчивые заказы через API: руководство разработчика

FazerCards
Отказоустойчивые заказы через API: руководство разработчика

Каждый реселлер, автоматизирующий выдачу gift cards, рано или поздно сталкивается с тремя сценариями отказа: таймаут, после которого непонятно, прошёл ли заказ, сетевой сбой, вызывающий повторный запрос и двойное списание со счёта, или вебхук, который приходит во время перезапуска сервера. При небольших объёмах это неудобство. При высоких оборотах каждый такой сбой стоит реальных денег. Разница между хрупким прототипом и production-системой — в том, насколько осознанно вы строите защиту от этих ситуаций.

Необходимые условия

Вам нужен активный аккаунт FazerCards с API-ключами, серверный бэкенд с HTTP-клиентом и криптобиблиотекой, а также доступный извне HTTPS-эндпоинт для приёма вебхуков. Документация по API содержит сигнатуры эндпоинтов и коды статусов. В cookbook есть готовые паттерны для распространённых сценариев. Если вы только знакомитесь с платформой, раздел для кого FazerCards и страница тарифов дадут быстрый обзор.

Что вы получите в итоге: отказоустойчивый процесс заказа с идемпотентностью, экспоненциальным откатом и HMAC-верификацией вебхуков — три паттерна, которые переводят интеграцию с демо-уровня на production-уровень.

Шаг 1: Составьте карту автомата состояний заказа

Заказ в FazerCards проходит через небольшой набор статусов: processing (выполняется), затем финальный completed (коды готовы) или failed (заказ выполнить не удалось). Многие мгновенные товары приходят со статусом completed уже в первом ответе, остальные завершаются асинхронно. Опасное предположение многих интеграций — что не-200 ответ означает: ничего не произошло. TCP-таймаут в момент, когда сервер уже принял запрос, оставляет вас без подтверждения с живым заказом на стороне FazerCards. Наивный повтор создаёт дублирующий платёж и дублирующий код.

Отображайте свою базу данных на те же состояния. Перед любым заказом записывайте строку со статусом placing и временной меткой. Если процесс упадёт и перезапустится, эта строка подскажет, что нужно проверить существование заказа, прежде чем повторять. Введение в API заказов и модель событий — в статье Wholesale Gift Cards: REST API и вебхуки для реселлеров.

Три категории отказов

  • Транзиентные (5xx, таймаут, сброс соединения): запрос мог прийти или не прийти. Безопасно повторять только с ключом идемпотентности.
  • Ошибки клиента (4xx): запрос некорректен. Не повторяйте без исправления данных.
  • Неоднозначные (пустой ответ, TCP-сброс в середине): обрабатывайте как транзиентные — безопасно повторять только с ключом идемпотентности.

Шаг 2: Добавьте ключ идемпотентности к каждому заказу

Ключ идемпотентности — это уникальная строка, которую вы формируете до отправки запроса и передаёте в заголовке Idempotency-Key — любая уникальная строка из видимых ASCII-символов длиной до 255, например UUID. Если FazerCards получит два запроса с одним ключом в пределах окна дедупликации, второй вернёт заказ, созданный первым, — без повторного списания и дублирующего кода. Заголовок необязательный: без него каждый запрос создаёт новый заказ, ведь реселлеры законно отправляют одинаковые заказы для разных покупателей. В документации по API перечислены эндпоинты заказа, которые его принимают.

Ключ должен быть уникальным для логического заказа, а не для HTTP-попытки. Формируйте его из внутреннего ID заказа и короткого префикса — например, order-7841-v1. Сохраняйте его в базе данных до первого запроса. При каждом повторе используйте тот же ключ. API гарантирует идемпотентное поведение.

Правила надёжного ключа

  • Генерируйте один раз, до первой попытки, и сразу сохраняйте.
  • Никогда не создавайте новый ключ для повторной попытки — он должен оставаться стабильным.
  • Суффикс -v2 добавляйте только после того, как подтвердили реальный сбой заказа и нужно принципиально новое размещение.

С ключами идемпотентности агрессивный цикл повторов безопасен: сколько бы раз вы ни повторяли запрос по таймауту, API дедуплицирует по ключу, а не по HTTP-соединению.

Шаг 3: Реализуйте экспоненциальный откат с джиттером

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

Надёжный паттерн: 1 секунда перед первым повтором, 2 секунды перед вторым, 4 — перед третьим. К каждой задержке добавляйте случайный джиттер — от 0 до 500 миллисекунд — чтобы предотвратить шторм повторов при одновременном перезапуске множества воркеров. Для синхронных вызовов заказа ограничивайте общее число попыток четырьмя.

Когда все повторы исчерпаны

Помещайте заказ в dead-letter-таблицу в базе данных, отправляйте алерт и давайте recovery job или дежурному инженеру разобраться. Никогда не отбрасывайте неудавшийся заказ молча. Если частичный ответ содержал ID заказа, вызовите эндпоинт статуса, чтобы убедиться в существовании заказа, прежде чем решать: повторить или сделать возврат. Паттерн восстановительного запроса подробно описан в API cookbook.

Шаг 4: Верифицируйте подписи вебхуков

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

Каждый webhook-запрос несёт заголовок X-Webhook-Signature: префикс sha256= и hex-дайджест HMAC-SHA256 от сырого тела запроса, вычисленный с вашим секретом вебхука. В документации по вебхукам есть готовые примеры проверки на Node.js и Python. Для верификации вычислите тот же дайджест на своей стороне — из сырых байт, до обработки любым middleware — и сравните результат со значением заголовка функцией с постоянным временем выполнения.

Почему важно сравнение с постоянным временем

Обычная проверка равенства прерывается на первом несовпадающем байте, раскрывая информацию о времени, которую атакующий может эксплуатировать. Функция с постоянным временем — есть в стандартной криптобиблиотеке каждого популярного языка — устраняет этот side-channel. Всегда используйте её при сравнении HMAC-дайджестов.

Если верификация не проходит — верните HTTP 401 и залогируйте IP источника. Никогда не обрабатывайте такой payload. Всплеск ошибок на легитимном трафике чаще всего означает, что обратный прокси перекодирует тело до того, как оно достигает вашего обработчика — читайте сырые байты до любого слоя парсинга.

Шаг 5: Моделируйте асинхронную доставку как автомат состояний

Некоторые категории продуктов — определённые пополнения игр и региональные gift cards — асинхронны: API возвращает processing, а через несколько минут вебхук сообщает о смене статуса. Тело вебхука намеренно минимальное — ID заказа и статус, — поэтому коды забирайте из эндпоинта заказа тем же API-ключом. Такие процессы нельзя строить как синхронные вызовы.

Структурируйте логику выполнения как автомат состояний: placed → processing → webhook received → completed. Каждое состояние хранится в строке базы данных. Фоновый воркер мониторит заказы, застрявшие в processing дольше порога для конкретного продукта — пять минут для мгновенных SKU, тридцать для асинхронных — и отправляет алерт при превышении.

Не блокируйте клиентский ответ на вызов API. Принимайте заказ, записывайте строку со статусом placing, сразу возвращайте подтверждение покупателю и отправляйте код, когда придёт вебхук и вы заберёте выполненный заказ. Это сохраняет отзывчивость интерфейса независимо от задержек API.

Шаг 6: Наблюдайте за состоянием заказов в production

Три метрики должны быть доступны с первого дня. Успешность размещения: успешные POST-ответы к общему числу попыток — ниже 99% требует немедленного расследования. Процент доставки: заказы с доставленным кодом к успешно размещённым — ниже 98% обычно сигнализирует о нехватке поставки по конкретному продукту. Задержка обработки вебхуков: дельта между временной меткой события в payload и отметкой processed-at — нарастающая задержка означает отставание потребителя.

Перед открытием тикета поддержки сверяйте падение процента доставки с конкретным SKU. Каталог FazerCards показывает актуальную доступность по категориям. Настройте пороговые алерты: если любая метрика падает ниже нижней границы десять минут подряд — пейджите дежурного инженера.

Что у вас теперь есть

С ключами идемпотентности, исключающими дублирующие платежи, экспоненциальным откатом, поглощающим транзиентные сбои, HMAC-верификацией, блокирующей поддельные события, и моделью автомата состояний для асинхронной доставки — ваша интеграция покрывает всю поверхность отказов реального gift-card-сервиса. Вопрос меняется с того, сломается ли система, на то, обнаружите ли вы поломку раньше покупателя — а при больших объёмах эта разница напрямую конвертируется в выручку.

Проверьте каждый паттерн с бесплатным 5-дневным Gold-триалом: полный доступ к API и вебхукам, более 10 000 продуктов в каталоге, без карты и без KYC. Триал работает на том же боевом API, поэтому проверьте логику повторов и идемпотентность на нескольких небольших заказах, прежде чем переходить к полным партиям.