R27 — Payment processing: the checks, the accounts, the transactions and the platform

R0 to R16, plus R25 and R26, are the distributed-systems machinery. This section is the payments domain those mechanisms are built for: what a payment platform must check before it moves money, what accounts it moves money between, what the three transaction types actually do, and how the whole thing assembles into an architecture.

Read it before R28. Every design walkthrough there assumes this vocabulary.

The vocabulary, first

Payments has a large jargon surface, and most of it is shorthand for something simple. This is the reference for the whole pack — R28 uses it freely.

Parties and roles

Shapes of payment

Money movement and timing

Accounts

Balances

Ledger terms

Identifiers and messages

Controls and compliance

Operations

1. The checks a payment system must perform

A payment is not a database write with extra steps. Before money moves, a regulated institution must satisfy itself on several distinct questions, and confusing them is a common interview stumble — they have different owners, different consequences and different timing.

Check The question it answers When it runs On a hit
KYC / CDD Do we know who this customer is? Onboarding, then periodically Cannot transact until resolved
Sanctions screening Is a party on a restricted list? Every payment, in the path Park for review — never a silent decline
PEP and adverse media Is this person politically exposed or in the news? Onboarding and periodically Enhanced due diligence, not a block
Transaction monitoring (AML) Does the pattern look like laundering? Asynchronously, after the fact Alert → investigation → possible SAR
Fraud Is this payment against the customer's own interest? In the path, milliseconds Decline, challenge, or hold
TFR / Travel Rule Does the message carry the required payer and payee information? On construction and on receipt Reject, or request the missing data
Limits and entitlements Is this user allowed to send this much? In the path Decline, or route to an approver
Purpose and regulatory reporting Why is this money moving, and must it be reported? In the path for cross-border Reject if the purpose code is missing or invalid

Sanctions screening, in a little more detail

You are checking names and identifiers on the payment against restricted lists — OFAC's SDN list, the UK's OFSI list, the EU consolidated list, UN lists, and local ones. The engineering characteristics are what matter in an interview:

TFR and the Travel Rule

Often skipped by candidates, and worth knowing because it explains fields in the message rather than logic in your code. The EU's Transfer of Funds Regulation, and FATF Recommendation 16 more broadly, require that a payment carries identifying information about both the payer and the payee through the chain — name, account identifier, and address or an equivalent identifier above thresholds.

Three consequences for the platform: outbound messages must be constructed with those fields populated, inbound messages must be validated for their presence, and a payment arriving without them is rejected or sent back for repair rather than quietly applied. It is the reason an inbound payment can fail for a reason that has nothing to do with money or accounts.

Fraud versus AML — the distinction to state clearly

Fraud protects the customer. Someone is trying to take their money: account takeover, a scam, a stolen card. It is detected in the path, in milliseconds, and the customer is on your side.

AML protects the system. The customer may be a willing participant — laundering, mule activity, structuring. It is detected over days across many payments, and the customer must not be told.

Same data, opposite assumptions, different architectures: one is a synchronous scoring service with a feature store; the other is a batch and streaming analytics estate feeding an alert queue.

2. Accounts: the three meanings, and the types that matter

"Account" means three different things, and an interviewer will notice if you blur them.

A corporate might be given 10,000 virtual account numbers, one per customer of theirs, all pointing at one real account. When money arrives quoting a virtual account, attribution is automatic instead of a human matching a payment reference — which is why virtual account management is sold as a reconciliation product rather than a banking one.

The account types you should be able to name

Account What it is Where it appears
DDA / current account The customer's actual account with us Every customer payment
Nostro Our account at another bank, usually abroad Cross-border settlement
Vostro Their account with us — the mirror image We act as correspondent for another bank
Clearing / settlement What we owe or are owed with a scheme, between settlement cycles Every rail with deferred settlement
Suspense Money we hold but cannot yet attribute Inbound payments, repairs, investigations
Escrow Money held for a purpose, released on a condition Marketplaces, property, conditional payments
Pool / omnibus One real account holding many parties' money, split in our ledger Wallets, brokers, fintechs on a sponsor bank
Fee / revenue Our income Any priced transaction
Position / exposure Net exposure per currency FX (R28's walkthrough 3)
Wash / internal transfer Deliberately transient, must end at zero daily Internal moves audited separately

Two rules that come up repeatedly. Suspense must age out — an unattributed balance that sits for weeks is a regulatory problem, so the oldest item in suspense is a reported number, not just an ops queue. And pool accounts make the ledger the only record of ownership — the bank sees one balance, so if your ledger is wrong, nobody else can tell you who owns what.

3. The three transaction types

Every customer-initiated payment is one of three shapes. The orchestrator is a black box for now — what matters is the list of activities it drives, and the postings that result.

Interactive — the three transaction types, activity by activity and posting by posting drag the corner to resize, the middle bar to re-split

Book payment (on-us)

Both parties bank with us, so no money leaves the institution.

Activities: intake and idempotency check → validate → resolve both accounts (virtual to ledger) → limits → screen both parties → fraud score → funds check → post → notify both sides. No message is built, no rail is involved, nothing settles.

Postings:

Debit Credit
Book transfer Customer A ₹1,000 Customer B ₹1,000

What to notice: our assets never move. Only the claim on them changes hands — we owed A, now we owe B. This is why on-us payments are instant, free to us, and carry no counterparty risk, and it is also why they are the highest-margin traffic a wallet or a bank has.

Some institutions route it through an internal clearing account — DR A, CR clearing, then DR clearing, CR B — purely so each side is separately auditable. Same money, one more hop.

Inbound payment

Someone else's customer is paying ours. Inbound is reactive: we did not initiate it and cannot refuse it, and the money arrives before we know who it belongs to.

Activities: receive message → parse and validate → duplicate check on the sender's reference → post to suspense → screen the payer → validate TFR fields → resolve the beneficiary → apply to the customer → notify → reconcile against the settlement file.

Postings:

Debit Credit
1. Funds received, unapplied Nostro ₹1,000 Suspense ₹1,000
2. Applied to customer Suspense ₹1,000 Customer B ₹1,000

Why two postings rather than one: "we received money" and "we know whose it is" are different facts, sometimes minutes apart and sometimes days. Posting straight to a customer would mean trusting a message you have not yet validated.

When resolution fails — closed account, name mismatch, missing TFR data — the money stays in suspense and becomes a repair item: an ops queue, an investigation, possibly a request to the sending bank. If it cannot be repaired inside the return window, it is returned: DR suspense, CR nostro. Nothing was ever posted to a customer, which is exactly what the suspense account exists for.

Outbound payment

Our customer pays someone at another bank. The longest path, because every control must complete before the money leaves.

Activities: intake and idempotency → validate beneficiary details → limits → screen beneficiary, purpose and country → fraud score → check and reserve funds → check the rail cut-off → post → build the ISO 20022 message → submit → acknowledgement → settlement → notify.

Postings:

Debit Credit
1. Instructed (payment) Customer A ₹1,000 Outbound payable ₹1,000
1. Instructed (fee) Customer A ₹20 Fee income ₹20
2. Settled Outbound payable ₹1,000 Nostro ₹1,000

Three things to say about this one. Funds are reserved, not merely checked, because between the check and the posting another payment could spend the same money (R5). The message is derived from the ledger, never the reverse — the posting is the fact, and pacs.008 is a description of it. And an acknowledgement is not settlement: the rail accepting the message says nothing about the beneficiary being paid, and treating the two as the same is a classic error.

If the payment is returned days later, it arrives as an inbound: cash into nostro, into suspense, then a reversing credit to the customer. You never edit the original entries (R6).

4. The platform architecture

Put the three flows together and the components fall out of them.

flowchart TB
  subgraph CH["Channels"]
    A1["Mobile / web"]; A2["Corporate API"]; A3["Bulk file"]; A4["Rail inbound"]
  end
  subgraph EDGE["Edge"]
    G["API gateway<br/>authn · rate limits · idempotency keys"]
  end
  subgraph CORE["Payment core"]
    O["Orchestrator<br/>state machine per payment"]
    V["Validation + enrichment"]
    ACC["Account resolution<br/>virtual → ledger"]
    LIM["Limits + entitlements"]
    RSK["Risk<br/>fraud score · feature store"]
    SCR["Screening<br/>sanctions · PEP"]
    LED["Ledger<br/>double-entry, append-only"]
  end
  subgraph RAILS["Rail layer"]
    MSG["Message construction<br/>ISO 20022 · NACHA"]
    AD["Rail adapters"]
    SCH["Scheduler<br/>cut-offs · warehouse · kick-off"]
  end
  subgraph BACK["Back office"]
    REC["Reconciliation"]; INV["Investigations + repair"]; RPT["Reporting + regulatory"]
  end
  CH --> EDGE --> O
  O --> V --> ACC --> LIM --> RSK --> SCR --> LED
  LED --> MSG --> AD --> SCH
  LED --> REC --> INV
  LED --> RPT

The layers, and what each owns:

The cross-cutting mechanisms, and where they come from:

Concern Mechanism Section
Duplicate requests and retries Idempotency keys, per client R3
Telling other services what happened Outbox, relay, inbox R4
Multi-step work that must be undone Saga with compensation R5
Proving the books are right Reconciliation, break lifecycle R6, R7
One writer for a singleton job Lease with fencing token R8
Ordering per account Partition key = account R9
Growth Shard by account, single-writer per account R13
Knowing money is stuck Business metrics, not system metrics R15
Changing it while it runs Expand-contract, canary by corridor R16
The rails' own rules ISO 20022, irrevocability, returns R25
Time as business state Cut-offs, kick-off, warehousing R26

And the three design rules that hold the whole thing together:

  1. The ledger is the only source of truth. Messages, read models, dashboards and reports are all derived from it, and all rebuildable.
  2. Nothing irreversible happens before every control has passed. Sequence the pipeline so screening, limits and funds reservation all complete before the pivot (R5).
  3. Every external boundary is at-least-once and therefore idempotent, and whatever slips through is caught by reconciliation rather than assumed away (R0).

What to say in the interview

"I'd separate the controls first, because they behave differently: sanctions screening is in the path and a hit parks rather than declines, fraud is in the path in milliseconds, AML monitoring is asynchronous over days, and TFR is a message-content rule that makes inbound payments fail for non-money reasons. Then the accounts: customer DDAs, nostro for cross-border, clearing for what we owe a scheme between settlement cycles, and suspense for money we hold but cannot yet attribute. Book payments are two ledger entries and nothing else; inbound is always two postings, because received and applied are different facts; outbound is instruction and settlement as separate postings, with funds reserved rather than merely checked. And the ledger is the source of truth throughout — the ISO message is derived from the posting, never the other way round."