Design Payment System
Design a payment processing system: transactions, ledgers, compliance, and fraud detection.
What is a payment system?
A payment system turns a customer's instruction to pay into a controlled, auditable movement of money. It creates a durable payment intent, asks an external payment provider to authorize or capture funds, records the financial effect in a balanced ledger, and later verifies that provider and bank records agree.
A beginner can picture three records with different jobs:
- The payment intent tracks what the customer and merchant are trying to do.
- The provider attempt tracks one request to an external processor and its uncertain outcome.
- The ledger journal records money owed or moved; every journal must balance to zero.
The central rule is stronger than "the API returned success": one business operation may create at most one intended charge, and every completed monetary effect must be explainable from immutable records. Availability matters, but an ambiguous result must become processing and enter recovery rather than be guessed into success or failure.
This walkthrough sizes a card-payment platform for 100 million attempts per day and a 10x peak. It uses one currency per payment and delegates raw card collection to a tokenization provider. Marketplace splits, foreign exchange, subscriptions, and dispute evidence are extensions, not hidden assumptions.
Intent
Control the command
Authenticate the merchant, validate amount and currency, bind an idempotency key to the request fingerprint, and permit only legal state transitions.
Accounting
Separate truth
Operational status explains workflow. The append-only double-entry ledger explains balances. Neither a cache nor a provider webhook is the sole source of financial truth.
Recovery
Resolve uncertainty
Timeouts, duplicate messages, and late webhooks are normal. Stable provider references, monotonic handlers, and reconciliation turn them into bounded work.
What is the payment contract?
The payment contract states what callers may request, what result they can rely on, and which failures remain uncertain. Clarify it before choosing databases or providers because a small product change, such as delayed capture, adds states, timers, ledger effects, and recovery paths.
Functional
Customer and merchant actions
- Create and retrieve a payment intent.
- Confirm a tokenized card for authorization.
- Capture an authorization immediately or later.
- Cancel before capture and issue full or partial refunds after capture.
- Receive signed, replayable status webhooks.
Invariant
Correctness promises
- One merchant-scoped idempotency key maps to one request fingerprint and one result.
- State transitions are monotonic unless an explicit reversal creates a new operation.
- Every posted journal balances within one currency.
- A refund cannot exceed the captured amount minus earlier refunds.
- Unknown provider outcomes are reconciled, never guessed.
Non-functional
Service objectives
- 100 million attempts per day with a 10x peak-to-average factor.
- API availability target of 99.99%, measured separately from provider success.
- P99 platform overhead below 250 ms, excluding customer challenge time.
- No acknowledged ledger write may be lost; recovery point objective is zero for committed journals.
- Webhook delivery is at least once and normally begins within 30 seconds.
Scope
Version-one boundary
- Card payments through two payment service providers.
- One currency per payment; no internal foreign-exchange conversion.
- No marketplace split payouts, recurring billing scheduler, or cryptocurrency.
- Dispute intake is recorded, but evidence management is deferred.
- Hosted fields or provider tokens keep raw card numbers out of application services.
Define lifecycle terms precisely
- Authorize: ask the card network and issuer to reserve spending capacity. Authorization may expire and is not the same as settlement.
- Capture: request completion of an authorized payment. Capture creates the merchant-facing financial obligation represented in the ledger.
- Settle: exchange funds between institutions later. Settlement is asynchronous and can disagree temporarily with capture status.
- Refund: create a new reversal operation against captured value. It does not erase the original payment or ledger journal.
- Reconcile: compare internal attempts and journals with provider transactions and settlement reports, then investigate differences.
Establish compliance ownership
- Use provider-hosted fields or tokenization so application servers never receive the primary account number or card security code.
- Encrypt payment tokens and personal data, restrict access by service identity, and record administrative reads.
- Keep card security codes out of logs and storage. Apply retention and deletion policy to customer data without deleting required financial records.
- Treat PCI DSS, privacy, sanctions, anti-money-laundering, and strong-customer-authentication obligations as legal and security workstreams. Architecture can reduce scope; it cannot declare the organization compliant.
- Document which party owns cardholder authentication, fraud decisions, dispute handling, merchant onboarding, and regulatory reporting.
State the failure contract in the interview: succeeded and failed are final only with evidence; processing means the platform has durable ownership of an unresolved outcome.