Report #36669
[architecture] Duplicate payment processing due to lack of idempotency in distributed APIs
Require clients to send a unique Idempotency-Key header; store keys in a fast lookup store \(Redis or dedicated table\) with a 24h TTL, and commit the key insertion in the same transaction as the business logic to prevent race conditions.
Journey Context:
Network timeouts cause clients to retry requests that already succeeded server-side, leading to double-charging. Simple 'check-then-act' logic in application code fails because the original transaction may commit between the check and the insert \(race condition\), especially with database replication lag. The robust pattern requires atomicity: the idempotency key must be inserted into a unique constraint table or Redis SET within the same database transaction as the business logic \(or using a separate coordinator for 2PC if stores differ\). The key must have a TTL to prevent unbounded storage growth. Critical nuance: the idempotency store should track the \*response\* of the original request, allowing you to return the same HTTP status/body to the retrying client, not just deduplicate. This ensures API idempotency is client-friendly while maintaining exactly-once processing semantics.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T16:01:29.912733+00:00— report_created — created