Case study 02 · Payment reliability

Designing transaction recovery for the unhappy path.

A timeout cannot tell a merchant whether money moved. Payment APIs need explicit recovery semantics for retries, reversals, voids, and refunds.

IdempotencyRefundsAPI designDistributed systems
RoleSystem designer and technical lead
ScopeIdempotency · reversals · refunds
BoundaryMerchant API through processor actions

Constraints

  • Network timeouts can leave the caller unsure whether a payment completed.
  • A single merchant intent can map to several processor actions.
  • Refunds may arrive while the original transaction is still settling.
  • The API must stay understandable to enterprise integrations.

What I owned

  • Designed transaction lookup by idempotency key so callers could recover the original transaction after a timeout.
  • Designed a reverse-transaction API covering auth adjustment, partial reversal, void, partial refund, full refund, and queued refund paths.
  • Kept transaction semantics explicit at the merchant-facing API boundary.
  • Traced the end-to-end flow across reader, unified API, gateway, and tokenizer components.

Outcome

  • Enterprise integrations gained a recovery path for uncertain requests.
  • One merchant operation could express the required reversal or refund intent without exposing internal service choreography.
  • The design addressed duplicate-processing risk without claiming exactly-once behavior from unreliable networks.

What this teaches

  • Model payment commands and transaction states explicitly; do not reduce every failure to a generic error.
  • Idempotency is a recovery contract, not just a database field.
  • Keep processor-specific actions behind a stable merchant-facing intent such as reverse or refund.
Confidentiality note. This is a sanitized account. Company-internal names, merchant details, ticket IDs, and private implementation data are intentionally omitted.

Have a similar problem?

Start with the failure mode.

Start a conversation ↗