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

Интеграция вебхуков FoxReload — HMAC-SHA256, ретраи, идемпотентность

Настройте надёжную обработку вебхуков FoxReload: проверка подписи, окно ретраев и идемпотентность.

Интеграция вебхуков FoxReload — HMAC-SHA256, ретраи, идемпотентность

Полить GET /v1/orders/{id} каждые несколько секунд — это пустая трата квоты и лишняя задержка. Вебхуки FoxReload пушат переходы статусов заказа на ваш эндпоинт в течение ~200 мс после события в нашем движке fulfilment. Этот гайд написан для инженеров, которым нужна боевая интеграция вебхуков — проверка подписи, семантика ретраев и идемпотентность.

1. Зарегистрируйте эндпоинт

В Settings → Webhooks зарегистрируйте HTTPS-эндпоинт (HTTP отбрасывается). Вы получите уникальный webhook_secret для каждого эндпоинта — 64-байтное случайное значение для подписи payload'ов. Подпишитесь только на нужные типы событий, чтобы избежать шума:

  • order.reserved
  • order.processing
  • order.delivered
  • order.failed
  • balance.low

На аккаунт можно зарегистрировать до 10 эндпоинтов (например, один для production, один для staging, один для внутренних Slack-алертов).

2. Проверьте подпись HMAC-SHA256

Каждый вебхук приходит с заголовком X-FoxReload-Signature вида t=1715990400,v1=5257a8.... Вычислите HMAC-SHA256 над строкой {timestamp}.{raw_body} с использованием вашего webhook_secret и сравните в constant time.

import hmac, hashlib, time

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=") for p in header.split(","))
    ts, sig = parts["t"], parts["v1"]
    if abs(time.time() - int(ts)) > 300:   # отбросить, если старше 5 минут
        return False
    signed = f"{ts}.{raw_body.decode()}".encode()
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

Любой запрос, не прошедший проверку, отбрасывайте с HTTP 401. Пятиминутное окно по timestamp блокирует replay-атаки.

3. Логика ретраев и идемпотентность

FoxReload ретраит неудачные доставки (любой ответ не-2xx или таймаут >10 с) по графику: 30 с, 2 мин, 10 мин, 1 ч, 6 ч, 24 ч — до 6 попыток. После последней попытки событие попадает в ваш Dead Letter Queue, доступный в дашборде в течение 30 дней.

Каждая доставка содержит X-FoxReload-Event-Id (UUID). Сохраняйте этот ID с уникальным ограничением в БД и игнорируйте дубликаты. Сетевые сбои регулярно заставляют наш слой ретраев доставлять одно и то же событие дважды — ваш обработчик должен быть безопасен для N вызовов.

4. Отвечайте быстро, обрабатывайте асинхронно

Отвечайте HTTP 200 в течение 5 секунд. Если ваша downstream-обработка (запись в БД, email, сверка) занимает больше, кладите payload в SQS/Kafka и отвечайте сразу. Медленные обработчики приводят к каскадным ретраям, дубликатам и rate-limit предупреждениям.

Если ваш эндпоинт лежит более 24 часов, FoxReload автоматически приостанавливает доставку и отправляет email-алерт — пропущенные события можно реплейнуть из дашборда после редеплоя.

Нужна готовая референсная реализация? FoxReload публикует open-source примеры обработчиков на Node.js, Python и Go, плюс хостинговый webhook-тестер — зарегистрируйтесь на foxreload.com и пропустите типичную неделю отладки крайних случаев проверки подписи.

Получить доступ к FoxReload API

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