Reversal and retry: designing inverse operations that don't lie
Retry-safe means idempotency-key aware. Reversal-safe means preserving the original approval alongside the reversal. Neither is the default.
Two of the trickier operations in a transaction platform look symmetric on paper but are not: retry (do the same thing again) and reversal (undo the thing you did). Both fail in production in ways that are frustrating and specific.
Based on architecture reviews from 2024–2025; written October 2026.
Retry: idempotency is a contract, not a habit
A retry that isn't idempotent is a duplicate transaction. Retry requires three things that must all hold:
- The receiving side accepts and honors an idempotency key.
- Your retry preserves the same logical-operation key across attempts, and generates a new attempt id.
- The receiver is trusted to deduplicate at least within some window.
If any of those are false, you don't have a retry. You have two transactions.
Reversal: what you're allowed to undo
A reversal, once dispatched, is not a fait accompli. You are not allowed to display "REVERSED" to a merchant until you observed a positive response for the reversal or reconciliation established the modeled outcome.
Both branches must be preserved as events, not overwritten.