Идемпотентность: почему 90% разработчиков ломают её в платежах
Почти все «идемпотентные» интеграции держатся на честном слове и надежде, что сеть не моргнёт. А потом прилетает ретрай, webhook приходит дважды, и ваш мерчант внезапно продаёт один товар два раза. Идемпотентность или смерть.
Главная ошибка — привязывать ключ к телу запроса «как есть». Любая мелочь: разный порядок полей, лишний пробел, новый timestamp — и для системы это уже «другой» платёж. Правильный ключ должен быть стабильным и жить вокруг бизнес-операции: order_id, attempt_id, transfer_id. Не вокруг JSON-хаоса.
Вторая дыра — хранить ключ без состояния. Мало сказать «этот запрос уже был». Нужно помнить, какой ответ был отдан, на каком этапе завис платёж, ушёл ли он в холд, был ли capture, не прилетела ли повторная отправка в момент сеттлмента. Иначе вы не идемпотентность строите, а костыль на костыле и финтехом погоняете.
Третья ошибка — путать идемпотентность с дедупликацией входящих запросов. Настоящая схема должна защищать весь жизненный цикл: создание, ретраи, асинхронные статусы, вебхуки, отмены, частичные списания. Документация — это ложь, логи — истина. Если по логам нельзя восстановить один и тот же outcome на повторный запрос, интеграция кривая.
Закладывайте не «антидубль», а контракт: один бизнес-ключ, одно состояние, один ответ. Всё остальное — путь к двойным списаниям и фразе «у нас это не воспроизводится».
Интеграция платежных решений
@payment_integration_ops_arb
Идемпотентность: почему 90% разработчиков ломают её в платежах
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.