Payments and ledger
Design the payment system behind a marketplace. Customers pay, money is held, sellers are paid out, refunds happen, and the books must balance exactly. An external payment provider holds the real money.
Where’s the slack?
Authorisation: seconds. Capture: minutes. Settlement and payout: hours to days.A person is waiting to find out whether their payment worked, and that is the only part with no slack. Everything behind it (capture, ledgers, payouts, reconciliation) has hours, and the design uses those hours to be correct.
Authorisation has seconds of slack at most. A customer is on the checkout page and every second past about three feels broken, so this call is synchronous, it has a hard timeout, and it must give a definite yes or no. Here a queue is the wrong answer, because "we will let you know" is not an acceptable response to "did I buy it".
Capture, which takes the authorised money, usually has minutes or more, and often should not happen until the seller confirms the order. Payouts to sellers are on a schedule measured in days. Reconciliation against the provider runs nightly. All of that is background work, and it can retry patiently, because no user is waiting on any single step.
What has zero slack, and no way to buy any, is correctness. A payment recorded twice, or money moved with no matching ledger entry, does not fix itself with time. It stays wrong until someone finds it, perhaps weeks later during an audit, and the longer it exists the harder it is to explain.
So: A short synchronous authorisation path with a hard timeout, and everything after it asynchronous, idempotent and reconciled. The ledger is append-only so history cannot be rewritten, and a nightly job compares our books against the provider's.
Work it through
Five stages, gated. You write your answer for each stage before its model answer unlocks. That is the core of the method.
Reference material for this problem. The diagrams below are here to check your own against once you have drawn it, not to read first.
The lifecycle
The numbers
So the hard part is exactly-once effects and reconciliation, not scale. At 40 a second I can afford a single strongly consistent primary, synchronous replication and a nightly full reconciliation. None of that would be affordable at a million a second.
The architecture
Follow-ups you should expect
Many interviews are decided in the follow-ups, not the first diagram.
Same shape, other products
Being fast is worthless if the number is wrong, and every mistake is somebody's actual money.
The design is dominated by exactly-once effects, audit trails and reconciliation with a third party who holds the authoritative record. Availability is negotiable here; correctness is not.
Others with this shape: Payments · Digital wallet · Ledger · Billing and invoicing
How it is really built
Write your own answer first. Then read how teams who run this at scale describe it. Their constraints were real, and the write-ups often say what their choices cost.
- Stripe — Idempotent requests ↗How a production payments API stops you charging someone twice.
- PostgreSQL — Transaction Isolation ↗The isolation guarantees a ledger depends on.