Идемпотентность ломают не в коде, а в голове: вот где сгорают платежи
90% команд путают идемпотентность с «повторно отправили тот же запрос — и вроде не упало». Нет, этого мало. Идемпотентный endpoint должен переживать ретраи, дубли вебхуков, таймауты сети и кривой клиент, который нажал кнопку дважды. Если у вас повтор запроса может создать новую оплату, новый холд или второй refund — это не API, а генератор инцидентов.
Типовые косяки:
— ключ идемпотентности живёт в памяти, а не в БД;
— ключ привязан к телу запроса, но не к бизнес-операции;
— на retry возвращают 200, но с другим payment_id;
— webhook и sync-call обрабатываются как две разные сущности вместо одного события.
Правильная схема скучная, зато не горит: один бизнес-ключ на одну операцию, жёсткая запись результата в хранилище, одинаковый ответ на повтор, отдельная защита от гонок. Идемпотентность или смерть. Документация — это ложь, логи — истина: именно там видно, что клиент не «спамит», а вы сами не умеете закрывать повторную обработку.
Не пытайтесь лечить это фронтом, кнопкой «disabled» или магией ретраев у провайдера. Если у вас нет дедупликации на входе, уникального ограничения в БД и понятного статуса операции, ваш мерчант забанен без объяснения причин по собственной вине.
Интеграция платежных решений
@payment_integration_ops_arb
Идемпотентность ломают не в коде, а в голове: вот где сгорают платежи
Этот пост опубликован в Telegram-канале Интеграция платежных решений. Подписаться можно по ссылке: @payment_integration_ops_arb.