hard general · part of Practice Questions · Senior SWE Roadmap
Requirements to clarify
- Functional: initiate a payment between two parties, integrate with external payment processors, handle refunds.
- Non-functional: correctness over speed — money must never be lost, duplicated, or double-processed; auditability (every state change traceable) is mandatory.
Core components
- Idempotency: every payment request carries a client-generated idempotency key; retrying the same request (e.g., after a timeout) must not double-charge — the server recognizes the key and returns the original result.
- Ledger: an append-only, immutable record of every transaction/state change — never mutate historical records, only append new entries; this is what makes the system auditable and recoverable (see Design a Digital Wallet).
- State machine: a payment moves through explicit states (created → processing → succeeded/failed → refunded), with the state transitions themselves being the source of truth, not scattered boolean flags.
- Saga pattern for multi-step flows: e.g., reserve funds → charge → confirm order — each step has a compensating action if a later step fails, since this can’t be one ACID transaction across services (see Microservices vs Monolith).
Key tradeoffs
- Strong consistency is non-negotiable here even at some latency cost — this is one of the rare system design answers where “eventual consistency” is the wrong default.