wtf( )unctionsystem design, drawn
← all problemsPaymentsHard

Twenty seconds, or it never happened

The bank is joining a national instant-payments rail. Money moves at three in the morning on a Sunday, arrives in seconds, and cannot be pulled back — there is no dispute, no chargeback, no clawback. For every incoming payment the rail asks the bank one question: do you accept it. The rail settles inside twenty seconds or it settles never.

The back office runs a nightly cycle. It is very good at finding, the next morning, everything that went wrong.

  1. R1The rail hands messages over its own queues and expects them pulled off quickly. Once a message is off the rail it is the bank's responsibility, and the bank has already answered for some of them — so whatever holds a pulled message must still hold it after a process restarts, and must keep one account's payments in the order they arrived.
  2. R2Screening must reach a verdict inside the twenty-second budget, and it calls a service that has been slow before. A check that waits is a check that spends the whole budget and answers nothing; a check that keeps calling a service which is already failing spends every remaining payment's budget on it too.
  3. R3The bank sets value ceilings and velocity limits per customer segment, and must be able to block named accounts outright. A payment naming a recipient the bank has no policy for — an account it does not hold, a segment nobody configured — must not be accepted on the grounds that nothing said no.
  4. R4Every message the bank sends the rail is signed with the bank's own private key, whose confidentiality is a contractual obligation, and several keys must be held in rotation. The signing material must not be readable by anything that merely needs a signature.
Compose the path an incoming payment takes. Tier 1 is where a message rests once it is off the rail, tier 2 is the two checks that must finish before the bank answers, tier 3 is what signs the answer.
Components — tap one, then tap a slot on the diagram
!A payment for the full daily limit was accepted at 02:14 on a Sunday. The overnight review flagged it at 06:00. By then it had been withdrawn, and there is no mechanism on this rail to ask for it back.Every instinct this team has was learned on card payments, where a bad decision can be reversed on Monday. Nothing here can be reversed on Monday. Anything the bank wants to stop, it must stop before it answers.

Boundaries, outermost first: THE BANK: Payments decision (accept, reject, or hold), Core ledger (funds available at once), Overnight cycle (finds it in the morning), Queue drain (pulls, never decides), an empty slot for the where a pulled message waits, tier 1, an empty slot for the must answer, or decline, in time, tier 2, an empty slot for the the ceiling and the block list, tier 2, an empty slot for the signs what goes back, tier 3 Outside every boundary: The rail (its queues, 24x7) Connections: The rail calls Queue drain — pulled off fast (step 1) Queue drain publishes to where a pulled message waits (step 2) where a pulled message waits calls Payments decision (step 3) Payments decision calls must answer, or decline, in time — inside the budget (step 4) Payments decision calls the ceiling and the block list (step 4) Payments decision calls signs what goes back (step 5) signs what goes back sends outbound traffic to The rail — the answer, signed (step 6) Payments decision calls Core ledger — funds available (step 7) Core ledger publishes to Overnight cycle — next morning

Payments decisionaccept, reject, or hold
Core ledgerfunds available at once
Overnight cyclefinds it in the morning
The railits queues, 24x7
Queue drainpulls, never decides