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

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

Практическое решение · 3 мин чтения
Как сделать обработку вебхуков устойчивой к повторам — tarasovcode
ИнтеграцииКак сделать обработку вебхуков устойчивой к повторам

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

Что подготовить

  • Документированный идентификатор события, тип уведомления, правило проверки подлинности и допустимый порядок доставки.
  • Схема бизнес-операции и границы транзакций получателя.
  • Примеры оригинального события, его повтора и другого события для того же объекта.

Порядок работы

  1. Проверьте источник и формат события до изменения данных. Не используйте присланный клиентом текст как доверенное описание выполненной операции.
  2. Выберите ключ дедупликации, включающий источник и идентификатор события. Одинаковый объект может законно получать несколько разных событий.
  3. В одной согласованной транзакции зарегистрируйте событие и примените изменение. Уникальность ключа должна проверяться хранилищем.
  4. При повторе верните согласованный ответ по сохраненному состоянию. Незавершенное событие должно иметь понятный путь восстановления.
  5. Проверьте события, пришедшие не по порядку. Используйте версию состояния или допустимые переходы, если простая дедупликация не защищает от устаревших данных.

Разобранный пример

Событие payment-42 получено дважды. Первый запрос записал начисление и событие, затем соединение оборвалось. Повтор находит payment-42 и подтверждает уже сохраненный результат. Событие refund-43 относится к той же оплате, но имеет другой ключ и проходит отдельный переход состояния.

Как проверить результат

  • Два параллельных экземпляра одного события создают одно бизнес-изменение.
  • Падение между сохранением и ответом не приводит к повторному эффекту.
  • Новое событие того же объекта не отбрасывается как дубль предыдущего.

Если что-то пошло не так

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

Промпт для разбора ваших материалов

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

Частые вопросы

Можно ли хранить ключ только в памяти?

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

Достаточно ли хеша тела?

Не всегда: представление одного события может меняться, а два законных события — иметь одинаковые данные. Предпочтителен контрактный идентификатор.

Материал библиотеки решений Ильи Тарасова / TarasovWeb.

Что происходит между приёмом и побочным действием

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

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

Отдельно разберите падение после отметки «получено», но до выполнения действия. Если такая отметка навсегда запрещает повтор, событие потеряется. Нужна процедура возобновления незавершённой работы, а для внешнего побочного эффекта — собственный способ сверки или ключ повторяемости, если сервис его поддерживает.

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

О проекте

Практическая библиотека Ильи Тарасова и TarasovWeb. Telegram-канал · Личная страница · ВКонтакте.

#tarasovweb #ИльяТарасов