Если одно событие webhook приходит несколько раз, это не всегда ошибка провайдера. Многие сервисы специально повторяют доставку, пока не получат быстрый успешный ответ.

Webhook-обработчик должен быть готов к повторам. Ключевое правило: одно внешнее событие должно менять систему только один раз.

Коротко: что сделать

  • Проверить event_id или transaction_id во входящем webhook
  • Проверить, какой HTTP-ответ возвращает обработчик
  • Проверить таймауты и 500 ошибки
  • Проверить создание дублей в базе
  • Проверить подпись webhook и источник

Основные причины

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

  • Обработчик долго отвечает, и провайдер делает retry
  • При 500 или timeout событие отправляется повторно
  • В базе нет уникального event_id
  • Обработка не проверяет уже выполненное действие
  • Повторное событие запускает ту же бизнес-операцию

Пошаговая диагностика

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

  • Сгруппировать webhook-логи по event_id
  • Проверить время ответа endpoint
  • Проверить, совпадают ли payload повторов
  • Проверить таблицу заказов, оплат или задач на дубли
  • Проверить документацию провайдера по retry

Как исправить проблему

Исправление должно закрывать первопричину. Если затронуты платежи, доступы, персональные данные, уведомления или рабочие заказы, сначала проверьте решение на тестовом сценарии и сохраните возможность отката.

  • Сохранять event_id с уникальным индексом
  • Делать обработку идемпотентной
  • Быстро отвечать 200 после приема события
  • Тяжелую работу переносить в очередь
  • Логировать статус обработки каждого события

Безопасный план решения

Сначала добавьте защиту от повторной обработки, затем разбирайте уже созданные дубли. Иначе новые повторы продолжат портить данные.

Чего не стоит делать

  • Не считать повтор webhook ошибкой провайдера
  • Не создавать заказ или платеж без проверки внешнего ID
  • Не отвечать 200 до базовой проверки подписи
  • Не выполнять тяжелые операции прямо в HTTP-запросе

Что подготовить перед исправлением

  • Пример webhook payload
  • HTTP-логи endpoint
  • event_id или payment_id
  • Какие дубли появились
  • Документация провайдера

FAQ

Нужно ли игнорировать повторное событие?

Не просто игнорировать, а распознать его по event_id и вернуть успешный статус без повторного действия.

Почему провайдер шлет повтор, если первый запрос дошел?

Если ответ был медленным, 500 или соединение оборвалось, провайдер не уверен, что событие обработано.

Где хранить event_id?

В отдельной таблице входящих событий или рядом с объектом, который был создан по webhook.

Когда стоит обратиться за помощью

Помощь нужна, если webhook связан с оплатами, заказами, доставкой, CRM, подписками или документами.

Итог

Проверьте event_id, HTTP-ответ, таймауты и уникальность обработки. Если нужно настроить надежные webhook без дублей, пишите в Telegram @rabotator_support.