Сквозная идемпотентность вебхуков: где биллинг теряет деньги на дублях
Платежный вебхук почти никогда не приходит один раз и почти никогда не приходит в идеальном порядке. Ретраи шлюза, таймауты сети, дубли на стороне брокера, ручные повторы из админки — и одна и та же операция начинает жить в нескольких ветках процесса.
Идемпотентность должна быть сквозной: от входного HTTP-запроса до записи в ledger и смены статуса подписки. Нужны три уровня защиты: — уникальный ключ события от провайдера; — внутренний ключ бизнес-операции; — транзакционная проверка «видели/не видели» перед любым сайд-эффектом. Если сохраняете только payload, а статус обновляете отдельным вызовом, дубль легко проходит через разрыв между шагами.
Критическая ошибка — считать вебхук подтверждением факта оплаты без сверки состояния. Правильный паттерн: принять запрос, атомарно записать событие в таблицу дедупликации, затем в одной транзакции зафиксировать проводку, обновить entitlement и только потом отправить ACK. Если ACK ушел до commit, провайдер повторит доставку, а вы получите второй триггер на активацию или повторный refund.
Отдельно проверьте гонки: два одинаковых вебхука могут прийти параллельно на разные инстансы. Здесь спасают уникальные индексы, optimistic locking и строгая семантика статусов: pending -> posted -> settled, без двусмысленных переходов. Идемпотентность в биллинге — это не рекомендация, а базовый вопрос выживания системы.
Подписки: биллинг-лаб
@subscriptions_billing_lab_arb
Сквозная идемпотентность вебхуков: где биллинг теряет деньги на дублях
Этот пост опубликован в Telegram-канале Подписки: биллинг-лаб. Подписаться можно по ссылке: @subscriptions_billing_lab_arb.