Вебхуки: подписанные данные и повторы

Backend2026-10-08TryQuickToolBox

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

Что такое вебхуки?

Вебхуки — это определяемые пользователем HTTP-колбэки. Когда в исходной системе происходит событие (например, обрабатывается платёж), она отправляет HTTP POST-запрос на указанный вами URL с данными события. В отличие от опроса, вебхуки передают данные почти в реальном времени, снижая задержку и нагрузку на сервер.

Однако вебхуки создают проблемы: проверка подлинности, обработка сбоев и обеспечение однократной обработки. Разберём каждую.

Подписанные данные: проверка подлинности

Поскольку конечные точки вебхуков общедоступны, любой может отправить поддельные запросы. Чтобы предотвратить это, провайдеры подписывают данные секретным ключом. Вы проверяете подпись, чтобы убедиться в подлинности запроса.

Как работают подписи HMAC

Большинство провайдеров используют HMAC (код аутентификации сообщений на основе хэша) с SHA-256. Провайдер вычисляет подпись, используя тело запроса и общий секрет, затем включает её в заголовок (например, X-Signature). Вы пересчитываете подпись на своей стороне и сравниваете.

Пример на Python:

import hmac
import hashlib

def verify_signature(payload, secret, received_signature):
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received_signature)

Важно: Используйте необработанное тело запроса, а не разобранный JSON, так как парсинг может изменить пробелы и нарушить подпись.

Распространённые ошибки

Повторы: изящная обработка сбоев

Ваша конечная точка может быть временно недоступна, или сетевые проблемы могут вызвать сбои. Надёжные системы вебхуков повторяют неудачные доставки с экспоненциальной задержкой.

Стратегии повторов

Провайдеры обычно повторяют при ответах не 2xx или тайм-аутах. Распространённые шаблоны:

СтратегияОписаниеПример
Фиксированный интервалПовтор каждые N секундКаждые 30 с, до 5 раз
Экспоненциальная задержкаУдвоение задержки при каждой попытке1 с, 2 с, 4 с, 8 с...
Экспоненциальная с джиттеромДобавление случайности для избежания эффекта стада1 с ± 0,5 с, 2 с ± 1 с...

Как получатель, вы не можете управлять политикой повторов отправителя, но можете спроектировать свою конечную точку устойчивой.

Лучшие практики для получателей

  1. Отвечайте быстро: Возвращайте 2xx в течение нескольких секунд. Передайте обработку фоновой задаче.
  2. Будьте идемпотентны: Используйте ключ идемпотентности из данных, чтобы избежать дублирующей обработки.
  3. Логируйте всё: Сохраняйте входящие вебхуки для отладки и воспроизведения.
  4. Мониторьте сбои: Настройте оповещения о повторяющихся сбоях.

Реализация идемпотентности

Дубликаты случаются: отправитель может повторить попытку из-за медленного ответа, или вы можете случайно обработать одно и то же событие дважды. Идемпотентность гарантирует, что многократная обработка события имеет тот же эффект, что и однократная.

Используйте уникальный ID события (часто предоставляется в данных или заголовках) и сохраните его в базе данных с уникальным ограничением. Перед обработкой проверьте, существует ли ID; если да — пропустите.

def process_event(event_id, data):
    if EventLog.exists(event_id):
        return  # already processed
    EventLog.create(event_id)
    # process data...

Для высоконагруженных систем используйте распределённую блокировку или транзакцию базы данных, чтобы избежать состояний гонки.

Вопросы безопасности

Помимо проверки подписи, учитывайте:

Тестирование вебхуков локально

Во время разработки вам нужен публичный URL для получения вебхуков. Инструменты вроде ngrok или localtunnel открывают ваш локальный сервер. Альтернативно, многие провайдеры предлагают CLI для пересылки событий на ваш localhost.

Симулируйте сбои для проверки обработки повторов: намеренно возвращайте ошибки 500 и наблюдайте за шаблоном повторов провайдера.

FAQ

Как проверить подпись вебхука?

Используйте HMAC с общим секретом. Вычислите хэш необработанного тела запроса и сравните его с заголовком подписи, используя функцию сравнения с постоянным временем.

Что делать, если я получаю дублирующиеся вебхуки?

Реализуйте идемпотентность, сохраняя ID событий. Проверьте, было ли событие уже обработано, прежде чем выполнять бизнес-логику.

Можно ли полагаться только на повторы вебхуков для надёжности?

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

При отладке данных вебхуков вам может понадобиться просмотреть JSON-данные. Используйте наш JSON Formatter для быстрого форматирования и валидации данных.