Идемпотентность ломают не баги, а кривой контракт между API и реальностью
Почти все делают одну и ту же ошибку: считают, что idempotency key — это магическая кнопка «не списывать дважды». Нет. Это всего лишь ключ дедупликации на стороне провайдера, а не гарантия вашей бизнес-логики. Если у вас повторяемый запрос меняет состояние без проверки статуса, поздравляю: у вас не идемпотентность, а костыль на костыле и финтехом погоняет.
Типовые провалы:
— Ключ живёт меньше, чем ваш retry-loop, и повтор прилетает уже в пустоту.
— Один и тот же ключ используют для разных payload’ов. Потом начинается цирк: ответ «как бы успешный», а данные уже другие.
— Дедуп строят только на входящем запросе, забывая про downstream: вебхук, сеттлмент, холд, отмену.
Правильная схема скучная и злая:
— ключ генерируется на уровне бизнес-операции, а не HTTP-обёртки;
— один ключ = один payload = одно состояние;
— хранилище должно возвращать не «200 OK», а тот же результат, что и первый раз, включая ошибки бизнес-валидации;
— после успешного ответа все асинхронные хвосты тоже должны быть защищены от дублей. Идемпотентность или смерть.
Если у вас идемпотентность заканчивается на POST /pay, то ночью вас добьёт webhook retry, а утром — reconciliation. Документация — это ложь, логи — истина.
Интеграция платежных решений
@payment_integration_ops_arb
Идемпотентность ломают не баги, а кривой контракт между API и реальностью
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.