Authorization and Settlement
In one line: a card payment is not one operation. It is two, separated by days, with different failure modes — and confusing them is the single most common error in payment system design.
Why this system is different
Everywhere else a duplicate is noise; here it is a stolen dollar
Every system in this module has dealt with retries, at-least-once delivery, and duplicate messages. The stakes have been mild.
| System | A duplicate causes |
|---|---|
| Newsfeed | A post appears twice — annoying |
| Web crawler | A page fetched twice — wasted bandwidth |
| Google Docs | A character inserted twice — fixed by idempotency |
| Code deployment | A build run twice — probably equivalent artifacts |
| Payment system | A customer charged twice |
That last row changes the engineering. "Probably equivalent" was an acceptable answer for a build artifact in the previous chapter. Here there is no version of the argument where charging someone twice is tolerable, and the failure is not detected by a monitoring alert — it is detected by a customer, a chargeback, and a regulator.
Two consequences run through the whole chapter:
Correctness beats availability. Almost every system in this module chose availability under partition. Payments is one of the few domains that chooses the other way — refusing a payment is vastly better than double-charging one, because a refusal is recoverable by retrying and a double charge is recoverable only by a refund, a dispute process, and a damaged relationship.
Every operation must be idempotent, at every layer. Not just the client-facing API — between every pair of services in the chain.
When the cost of a duplicate is money, idempotency stops being a technique and becomes a requirement of every interface.
The entities
| Entity | Role |
|---|---|
| Customer | The cardholder making a purchase |
| Merchant | Provides the goods or services |
| Issuer bank | Holds the customer's account; issues the card |
| Acquiring bank | Holds the merchant's account |
| Merchant's online store | Where the customer enters card details |
| Payment gateway | Facilitates and authorizes transactions; requests payment from the customer's account |
| Cards network | Validates card information, facilitates payment, and sets the terms for transactions |
The two banks are the reason this is hard, and the network is the reason it works at all
Notice what the entity list implies: the money starts in one bank and must end in a different one, and those two banks have no direct relationship. Your issuer has never heard of the merchant's acquirer.
The cards network exists to solve exactly that. It is the routing and clearing layer that lets any issuer transact with any acquirer without bilateral agreements — which is why it also "sets the terms", since the rules of engagement have to come from somewhere neutral.
Two things follow that matter for the design:
Almost nothing in this system is under your control. Your payment service talks to a gateway, which talks to a network, which talks to a bank. Three external hops, each with its own latency, failure modes, and retry semantics — and none of which you can debug. That is why the entire second half of this chapter is about handling failures you cannot see inside.
You are an orchestrator, not a custodian. The funds never sit in your system. Recognizing that boundary is what separates a payment service from a money transmitter, and it is a regulatory distinction as much as an architectural one.
When most of your dependencies are external and opaque, the design problem shifts from computation to failure handling — which is the opposite of every other chapter in this module.
Phase 1: authorization
The authorization phase's purpose is to verify whether the customer's payment method is valid, has sufficient funds or credit available, and can be used to make the intended purchase.
- Customer provides payment details via a payment gateway.
- The gateway requests authorization from the customer's issuer bank.
- The issuer validates the card and checks for fraud and the available credit limit.
- If approved, the issuer sends an authorization code to the gateway.
- The gateway relays the code to the merchant.
Successful authorization reserves the amount on the customer's card but does not immediately transfer funds.
'Reserves the amount' is the whole idea, and it is a lease
Authorization does not move money. It places a hold on the customer's available credit — the funds are reduced but not transferred.
That is a familiar shape by now: it is a lease. that building block's build workers held a lease on a job; here the merchant holds a lease on a portion of the customer's credit line. And leases have the property this chapter's own question is fishing for:
Authorization codes EXPIRE — commonly around 7 days. Capture after expiry: the hold is gone, and the capture may be declined.
The design asks "in what scenarios could authorization succeed but settlement fail?" and never answers. Expiry is the most common answer, alongside the customer's card being cancelled, the account being closed, or the credit line being exhausted by other purchases in the interval.
This is why the two-phase structure exists at all. A merchant authorizes at checkout and captures when the goods ship — which for physical retail can be days later. The hold is what keeps the money available across that gap without committing to it.
A hold is a lease on funds: it reserves without transferring, and it expires. Everything about the phase separation follows from that.
Phase 2: settlement
- The merchant accumulates authorized transactions over a period (e.g. daily).
- The merchant sends a batch of transactions to the payment processor or acquiring bank.
- The processor verifies transactions and transfers funds from issuing banks to the merchant's bank.
- The processor reconciles the transactions to ensure accuracy.
- Funds are deposited into the merchant's account.
Note: Authorization is typically immediate, while settlement often occurs in batches.
| Authorization | Settlement | |
|---|---|---|
| Timing | Immediate — sub-second, synchronous | Batched — hours to days later |
| What moves | Nothing — funds are reserved | The money |
| Who initiates | The customer, by clicking pay | The merchant, in bulk |
| Failure means | The purchase is declined at checkout — visible, recoverable | Money is owed and not transferred — invisible to the customer |
| User waiting? | Yes — this is a latency-critical path | No — throughput matters, latency does not |
Why settlement is batched, and why that is a good design rather than legacy inertia
It is easy to read "batches" as a relic of banking systems built in the 1970s. There are real reasons.
Cost. Interbank transfers carry per-transfer costs and settlement-network fees. Netting a day's transactions into one movement per merchant is dramatically cheaper than a thousand individual transfers.
Netting. Within a batch, refunds cancel against charges before any money moves. A merchant with $10,000 of sales and $800 of refunds settles once, for $9,200, rather than moving $10,800 in two directions.
Correction window. The gap between authorization and settlement is when errors get caught — a fraudulent transaction flagged after checkout can be voided before funds move, which is far cheaper than reversing a completed transfer.
Different latency budget. The customer is waiting during authorization and is not waiting during settlement. The phase where nobody is waiting is the phase you batch.
That last one is the reusable idea, and it is the same split as every fast-path/slow-path decision in this module — that building block's edit path versus format conversion, that building block's suggestion service versus assembler. Split by who is waiting, and the batching decisions make themselves.
The design in this chapter implements authorization and never implements settlement
This introduction defines the two phases carefully, states that settlement is batched, and asks its own question about settlement failing.
Then the detailed design does none of it. Its high-level flow is:
"The issuer's bank processes the request and sends the payment to the merchant's account via the payment service. The merchant's account balance is updated to reflect the successful transaction."
One synchronous step, in which authorization and settlement are collapsed into each other. There is no capture, no batching, no settlement file, no gap during which a hold exists.
And capturePayment(authorization_code, amount) is specified in the API list — and nothing in the workflow ever calls it. That is the same shape as the previous chapter, where validateAndTest was specified and never invoked: the API list is more complete than the workflow.
Worse, that sentence is factually wrong about how card payments work. Funds do not flow through the payment service. They move issuer → cards network → acquiring bank → merchant. The payment service orchestrates; it never holds the money. That distinction is not pedantry — holding customer funds makes you a money transmitter, with an entirely different regulatory burden.
Lesson 4 traces what the design actually builds. The reason to flag it here is that the two-phase model is the right mental checklist, and an interviewer asking "what happens between authorization and settlement?" is checking whether you know there is a between.
Key takeaway
A card payment is two operations separated by days: authorization, which is immediate, synchronous, latency-critical, and reserves funds without moving them — a lease on credit that expires, which is the answer to how authorization can succeed while settlement fails — and settlement, which is batched because nobody is waiting, which enables netting, cost amortization, and a correction window. Split by who is waiting and the batching decisions follow. The chapter defines both phases and then implements only the first, collapsing them into one synchronous step and describing funds as flowing through the payment service, which they never do. And the domain's defining constraint: when the cost of a duplicate is money, idempotency stops being a technique and becomes a requirement of every interface — and correctness beats availability, which is rare in this module.
Next: requirements, and a server estimate 36,000× off the chapter's own number.