System Design LabSystem Design QuestionsDesign Digital Wallet

Design Digital Wallet

MediumPaymentspaymentstransactionsledgerdistributed

Question Overview

Design a stored-value wallet where users hold balances, pay each other instantly, and move money in and out through banks. The focus is correctness: a double-entry ledger, idempotent APIs, atomic transfers across database shards, and daily reconciliation with external payment providers.…

Sign up to see the full question and AI interviewer

Requirements

  • View balance and full transaction history for each wallet
  • P2P transfers, card or bank top-ups, and bank withdrawals, each carrying a client idempotency key
  • Double-entry, append-only ledger where every transaction's entries sum to zero
  • No negative balances, double spends, or money created or lost, even under retries and crashes
  • P2P transfer p99 under 1 second and balance reads under 100 ms
  • Daily reconciliation with processors and banks, and 7-year retention of ledger entries

Back-of-the-envelope numbers

  • P2P transfers: 50M/day ÷ 86,400 s ≈ 580/s average, ~2.9K/s at 5× festival peak
  • Top-ups and withdrawals: 10M/day ÷ 86,400 s ≈ 116/s average, ~580/s at peak, each waiting on an external processor
  • Ledger entries: 2 per transaction × 60M = 120M/day ÷ 86,400 s ≈ 1.4K/s average, ~7K/s at peak
  • Ledger storage: 120M × ~200 B = 24 GB/day ≈ 8.8 TB/year ≈ 61 TB over 7 years, plus indexes
  • Balance and history reads: 20M DAU × 10 = 200M/day ÷ 86,400 s ≈ 2.3K QPS average, ~11.6K at 5× peak
  • Idempotency keys: 60M/day × ~100 B kept 7 days ≈ 42 GB, stored on the same shard as the ledger rows they guard

Key components

  • Transfer API that requires a client-generated idempotency key and returns the stored result for any retry with the same key
  • Append-only double-entry ledger (transaction_id, account_id, amount, direction) where each transaction's entries sum to zero
  • Balance projection updated in the same database transaction as the ledger insert, with a conditional check that the balance stays non-negative
  • Relational database sharded by account_id: same-shard transfers are one ACID transaction, cross-shard ones an idempotent saga through an in-transit account
  • Processor integration as a state machine (created, pending, succeeded, failed) driven by webhooks plus polling, crediting funds only on confirmed success
  • Reconciliation jobs comparing the ledger with processor and bank settlement files daily and checking total wallet balances against funds held
  • Transactional outbox publishing ledger events to Kafka for notifications, history views, and fraud scoring without slowing transfers

Common mistakes

  • Keeping only a mutable balance column updated by read-modify-write, which causes lost updates and leaves no audit trail
  • Using floating-point amounts instead of integer minor units such as cents or paise with an explicit currency
  • Not persisting the idempotency key atomically with the ledger write, so a timeout followed by a retry moves money twice
  • Crediting the wallet when a top-up is sent to the processor instead of when the processor confirms it succeeded
  • Debiting and crediting through two service calls with no durable transfer state, so a crash in between loses money
  • Choosing an eventually consistent store for balances, letting concurrent requests on different replicas double-spend
  • Treating a busy merchant account as a single hot row, so every incoming payment serializes on one lock

Likely follow-ups

  • What happens if the sender's debit commits but the receiver's shard is down?
  • How would you support multiple currencies and foreign-exchange conversion?
  • The processor reports a top-up succeeded but your ledger never recorded it; how does reconciliation catch and fix it?
  • How would you run fraud checks without adding latency to every transfer?
  • How would you scale a merchant account receiving 5K payments per second?
  • How do you reverse a disputed transfer when ledger entries are immutable?

No community solutions yet

Be the first to publish your solution

Practice ‘Design Digital Wallet’ with an AI Interviewer

Get scored feedback on your diagram, scalability approach, and trade-offs. Free while we grow — up to 3 full interviews a day.