Skip to content

Digital Wallet — Detailed#

flowchart TB
  subgraph Apps
    APP([Mobile wallet])
    WEB([Web])
  end

  subgraph Edge
    CDN
    GW
  end

  subgraph Core
    USERS([User / KYC])
    LINK[Link bank / card]
    BAL[Balance Service]
    TX[Transaction Service]
    CASHIN[Top-up / Cash in]
    CASHOUT[Cash out / Withdraw]
    P2P[Send to friend]
    MERCH[Pay to merchant]
    BILL[Bill pay]
    RECUR[Subscriptions]
  end

  subgraph Ledger[Ledger - source of truth]
    DBLEDGER[(Double-entry ledger)]
    ACCT([(Per-user account / sub-accounts)])
    LOCK[Pessimistic / OCC locking]
    JRN[Journal]
  end

  subgraph Rails[External rails]
    UPI
    SWIFT
    ACH
    SEPA
    CARD[Card network]
    NEFT_IMPS
  end

  subgraph Risk
    RISK[Fraud detection]
    LIMIT[Velocity limits]
    KYC[KYC / AML / sanctions]
    PEP[PEP screening]
  end

  subgraph Compliance
    AUD[Audit log immutable]
    REG[Regulator reporting]
    HOLD[Funds hold rules]
  end

  subgraph Webhooks
    EVT[[Event bus]]
    OUT[Outbound webhooks]
  end

  Apps --> CDN --> GW --> Core
  Core --> Ledger
  Core --> Rails
  Core --> Risk
  Core --> Compliance
  Core --> Webhooks

    classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
    classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
    classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
    classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
    classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
    classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
    classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
    classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
    classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
    classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
    class APP,WEB,USERS client;
    class LINK,BAL,TX,CASHIN,CASHOUT,P2P,MERCH,BILL,RECUR,LOCK,JRN,CARD,RISK,LIMIT,KYC,PEP,REG,HOLD,OUT service;
    class DBLEDGER,ACCT datastore;
    class EVT queue;
    class AUD obs;

Ledger correctness#

  • Every transfer = 2 entries (credit + debit) in atomic transaction.
  • Use SERIALIZABLE or SI with retry on conflict.
  • Never store balance as a single mutable row — compute or maintain via summary table with version.

Send-money flow#

  1. Idempotent POST /transfer { from, to, amount, idem_key }.
  2. Validate KYC + balance + limits.
  3. Lock both accounts (canonical order to avoid deadlock).
  4. Insert journal entries.
  5. Emit event.
  6. Notify both users.

External rails#

  • Each rail has its own latency + cutoff + reconciliation file.
  • Pending → settled state machine; reconcile statements daily.

Glossary & fundamentals#

Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.

Tag Concept What it is Page
HLD CDN edge caching for static assets cdn
HLD MVCC & isolation levels snapshot isolation, serializability, vacuum mvcc-isolation-levels
HLD Idempotency & retries safe re-execution, backoff + jitter idempotency-retries
LLD State machines FSM, HSM, transitions, guards state-machines
LLD Behavioural patterns Strategy, Observer, State, Command, Chain behavioral-patterns
LLD Concurrency primitives mutex, semaphore, RW lock, atomic, CAS concurrency-primitives
LLD Threading & deadlocks thread states, Coffman, lock ordering threading-and-deadlocks
LLD Immutability immutable types, persistent collections immutability