How the interviewer opens it
“Design a payment system like Stripe that lets merchants charge customers' cards, issue refunds, and receive payouts. A customer must never be charged twice for the same purchase.”
The prompt is vague on purpose. The first few minutes are yours: narrow it to the core features and agree on the numbers before you draw anything.
What to clarify first
- product boundary
- scale
- read:write mix
- latency
- correctness, availability, and durability
- client retry contract
- external provider contract
- refund rules
- payout rules
The answers stay with the interviewer. In a SysRound round, Alex answers them as an interviewer would.
Scope of a strong answer
Core requirements
- Create a card charge and retrieve its status, safely handling retries
- Issue full or partial refunds without exceeding the original charge
- Pay out settled merchant funds without overspending their balance
- Maintain auditable financial records and recover from uncertain external outcomes
Usually out of scope
- Building card networks, acquiring banks, or bank-transfer rails
- Fraud detection, disputes, and chargebacks
- Subscriptions, separate authorization and capture, and card authentication challenges
- Foreign exchange, platform fees, and merchant credit
- Merchant onboarding and compliance workflows
What interviewers probe
- Preventing duplicate charges across ambiguous failures
- A local database transaction cannot atomically include a card processor. The processor may charge the card even when our worker sees a timeout or crashes before recording success.
- An auditable ledger and spendable merchant balances
- A successful card charge is not yet settled cash. Pending, available, reserved, and paid-out funds have different meanings, and every crash boundary must leave the ledger and spendable balance consistent.
- Concurrent partial refunds and payouts
- A refund consumes both the charge's remaining refundable amount and merchant funds. A concurrent payout competes for those same funds while external refund completion may remain unknown.
- Payout settlement, returns, and reconciliation
- An accepted payout is not necessarily a completed bank transfer. Missing or contradictory provider evidence must be reconciled without paying twice, losing reservations, or rewriting history.
Common mistakes
- Treating never charge twice as a local deduplication problem while ignoring the crash between the provider call and the database commit.
- Claiming exactly-once execution from a message broker or distributed lock.
- Equating captured funds with settled, withdrawable merchant money.
- Handling charges carefully but omitting idempotency and reservations for refunds and payouts.
- Using cached balances or unlocked read-then-write checks to authorize money movement.
- Ignoring provider idempotency expiry, delayed callbacks, bank returns, and reconciliation.
The bar by level
- Senior (L5/E5)
- Defines the client and provider idempotency contracts, handles the external-call crash window, and models pending versus settled funds. Designs an append-only balanced ledger with transactional reservations, guarded state transitions, outbox/inbox processing, and a concrete reconciliation path. Walks through concurrent refunds and payouts without relying on locks across network calls.
- Staff (L6+/E6+)
- Makes the limits of the never-charge-twice guarantee explicit, including different client keys and expired provider deduplication. Establishes financial invariants and ownership across workflows, explains evidence-based repair and bank returns, and addresses recovery from database or regional failover without creating a second money-moving owner. Uses the stated scale to justify a simple transactional core, with clear boundaries for later partitioning, retention, operational investigation, and safe degradation.