Skip to main content
BLUEPRINT #02Financial & Transactional

Design a Digital Wallet System

Target AWS Architecture:DynamoDBS3AuroraElastiCache
10-Stage Structure:1. Requirements→2. Sizing→3. Topology→4. Data Model→5. AWS Topology→6. Deep-Dive→7. Failures→8. SRE Playbooks

1. Problem Statement & Scope Clarification

System Mission

Design a bank-grade, globally distributed digital wallet backend platform (similar to PayPal, Venmo, and Cash App) capable of supporting instant peer-to-peer (P2P) transfers, multi-currency balances, strict double-entry immutable accounting ledgers, and sub-10 millisecond balance inquiries with absolute mathematical consistency (zero currency inflation).

Functional Requirements

  1. Peer-to-Peer (P2P) Transfer (ExecuteTransfer): Atomically transfer money between two user wallets within a single ACID transaction.
  2. Deposit & Withdrawal (TopUp / Withdraw): Settle funds between the internal wallet ledger and external banking rails (FedNow, ACH, Stripe).
  3. Double-Entry Immutable Accounting: Every financial operation must record balanced debit and credit entries (βˆ‘Debits=βˆ‘Credits\sum \text{Debits} = \sum \text{Credits}); account balances are strictly derived from the audit log.
  4. Multi-Currency Conversion: Support atomic FX conversion with locked exchange rate quotes.
  5. Real-Time Balance Inquiry: Retrieve current available, pending, and reserved balances in <5Β ms< 5\text{ ms}.

Non-Functional Requirements (SLAs & SLOs)

  • Consistency: Strict ACID Serializability. Zero lost updates, zero negative balance overdrafts, zero Phantom reads.
  • Availability: 99.999%99.999\% uptime for balance queries and transfers.
  • Throughput: Support peak throughput of >5,000Β financialΒ transactions/secΒ (TPS)> 5,000\text{ financial transactions/sec (TPS)}.
  • Auditability: 100% immutable transaction ledger with 7-year regulatory retention.

2. Capacity & Scale Estimation (Back-of-the-Envelope Math)

Traffic & Transaction Volume

  • Total Registered Wallets: 50,000,00050,000,000 (50MΒ wallets50\text{M wallets}).
  • Daily Active Wallets (DAU): 10,000,00010,000,000 (10MΒ DAU10\text{M DAU}).
  • Daily P2P Transactions: 20,000,000Β transfers/day20,000,000\text{ transfers/day} (20MΒ TPS/day20\text{M TPS/day}).
  • Average Transfer : AverageΒ QPS=20Γ—106Β transactions86,400Β secβ‰ˆ231.5Β TPS\text{Average QPS} = \frac{20 \times 10^6\text{ transactions}}{86,400\text{ sec}} \approx \mathbf{231.5\text{ TPS}}
  • Peak Transfer (20Γ—20\times surge during Black Friday / Super Bowl): PeakΒ QPS=5,000Β TPS\text{Peak QPS} = \mathbf{5,000\text{ TPS}}
  • Read Balance Inquiry : PeakΒ ReadΒ QPS=50,000Β reads/sec\text{Peak Read QPS} = \mathbf{50,000\text{ reads/sec}}

Storage Footprint (7-Year Regulatory Retention)

Every P2P transfer generates:

  • 1 Transaction header record (β‰ˆ200Β bytes\approx 200\text{ bytes})
  • 2 Ledger entries: 1 Debit + 1 Credit (β‰ˆ150Β bytes\approx 150\text{ bytes} each =300Β bytes= 300\text{ bytes})
  • Index & metadata overhead (β‰ˆ100Β bytes\approx 100\text{ bytes})
  • Total per Transfer: β‰ˆ600Β bytes\approx 600\text{ bytes}.

DailyΒ Storage=20Γ—106Γ—600Β bytes=12Β GB/day\text{Daily Storage} = 20 \times 10^6 \times 600\text{ bytes} = 12\text{ GB/day} 7-YearΒ TotalΒ LedgerΒ Storage=12Β GB/dayΓ—365.25Γ—7β‰ˆ30.7Β TB\text{7-Year Total Ledger Storage} = 12\text{ GB/day} \times 365.25 \times 7 \approx \mathbf{30.7\text{ TB}} This volume fits cleanly within an Amazon Multi-AZ Cluster backed by continuous automated replication and tiered Glacier archival.


3. High-Level Architecture & AWS Component Mapping

Interactive Architecture Diagram
Synthesizing vector architecture diagram...

4. Double-Entry Accounting Model & Ledger Schema

1. Fundamental Accounting Invariant

In a formal double-entry system, money cannot be created or destroyed. Every transaction must satisfy: βˆ‘Debitsβˆ’βˆ‘Credits=0\sum \text{Debits} - \sum \text{Credits} = 0

2. Relational PostgreSQL DDL Schema

sql
-- 1. Accounts Table (Stores Current Balance Snapshot)
CREATE TABLE accounts (
    account_id VARCHAR(64) PRIMARY KEY,
    user_id VARCHAR(64) NOT NULL,
    currency CHAR(3) NOT NULL DEFAULT 'USD',
    balance_cents BIGINT NOT NULL DEFAULT 0,
    locked_cents BIGINT NOT NULL DEFAULT 0,
    version BIGINT NOT NULL DEFAULT 1,
    status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT chk_balance_non_negative CHECK (balance_cents >= 0),
    CONSTRAINT chk_locked_non_negative CHECK (locked_cents >= 0)
);

-- 2. Transaction Headers Table
CREATE TABLE transactions (
    transaction_id VARCHAR(64) PRIMARY KEY,
    idempotency_key VARCHAR(128) UNIQUE NOT NULL,
    type VARCHAR(32) NOT NULL, -- P2P_TRANSFER, DEPOSIT, WITHDRAWAL
    status VARCHAR(16) NOT NULL, -- PENDING, POSTED, REJECTED
    amount_cents BIGINT NOT NULL,
    currency CHAR(3) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 3. Immutable Double-Entry Ledger Lines Table
CREATE TABLE ledger_entries (
    entry_id BIGSERIAL PRIMARY KEY,
    transaction_id VARCHAR(64) NOT NULL REFERENCES transactions(transaction_id),
    account_id VARCHAR(64) NOT NULL REFERENCES accounts(account_id),
    direction VARCHAR(6) NOT NULL, -- 'DEBIT' or 'CREDIT'
    amount_cents BIGINT NOT NULL,
    currency CHAR(3) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT chk_positive_amount CHECK (amount_cents > 0)
);

CREATE INDEX idx_ledger_account_created ON ledger_entries(account_id, created_at DESC);

5. Core Atomic Transfer Engine & Deadlock Elimination

Deterministic Lexicographical Lock Ordering

When Alice sends 25toBobandBobsends25 to Bob and Bob sends 10 to Alice concurrently, arbitrary row locking causes circular transaction deadlocks:

  • Transaction 1: Locks Alice β†’\to Waits for Bob
  • Transaction 2: Locks Bob β†’\to Waits for Alice β€…β€ŠβŸΉβ€…β€Š\implies DEADLOCK!

Mitigation: Always lock accounts in lexicographically sorted order before updating balances.

sql
BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 1. Verify Idempotency
INSERT INTO transactions (transaction_id, idempotency_key, type, status, amount_cents, currency)
VALUES ('tx_998124', 'idemp_key_alice_bob_102', 'P2P_TRANSFER', 'PENDING', 2500, 'USD')
ON CONFLICT (idempotency_key) DO NOTHING;

-- 2. Lock Source and Destination Rows in Lexicographical Order
SELECT account_id, balance_cents 
FROM accounts 
WHERE account_id IN ('acc_alice_101', 'acc_bob_202')
ORDER BY account_id ASC 
FOR UPDATE;

-- 3. Verify Source Account Sufficiency
-- Application verifies Alice has balance >= 2500 cents

-- 4. Execute Atomic Balance Mutations
UPDATE accounts 
SET balance_cents = balance_cents - 2500, version = version + 1 
WHERE account_id = 'acc_alice_101';

UPDATE accounts 
SET balance_cents = balance_cents + 2500, version = version + 1 
WHERE account_id = 'acc_bob_202';

-- 5. Record Balanced Double-Entry Ledger Entries
INSERT INTO ledger_entries (transaction_id, account_id, direction, amount_cents, currency)
VALUES 
  ('tx_998124', 'acc_alice_101', 'DEBIT', 2500, 'USD'),
  ('tx_998124', 'acc_bob_202', 'CREDIT', 2500, 'USD');

-- 6. Finalize Transaction Status
UPDATE transactions SET status = 'POSTED' WHERE transaction_id = 'tx_998124';

COMMIT;

Part 2: Production Deep-Dive Locked1 Coin = 24 Hours

Unlock Complete Architecture & Production Runbooks

Your Balance:40 Coins

You have explored the free architectural preview (~47%). Spend 1 Coin to unlock the remaining 6 production deep-dive sections for a full 24 hours.

Sections Included in This 24-Hour Pass:
6. Detailed Request Flow & Settlement Workflows
7. Digital Wallet Architecture Trade-Off Matrix
8. Failure Modes, Resiliency & Critical Edge Cases
9. Production Pitfalls & Anti-Patterns (The "Gotchas")
10. Production Runbook & Observability Guide
11. Interview Strategy & System Design Rubric
Keeps page unlocked for exactly 24 hoursSpend coins to fund LLM & compute infrastructure