Digital Wallet & Stored Value
Problem statement
Users hold wallet balance, P2P transfers, merchant payments, with strong consistency, ledger, KYC, and fraud controls.
How it works
- Double-entry ledger is source of truth; wallet balance is materialized view or cached aggregate with strict invariants.
- External funding via bank rails (ACH, UPI) asynchronous.
Analogy: Prepaid campus card — every swipe creates two ledger lines (meal plan debit, vendor credit) even if the display balance updates a millisecond later.
High-level design
Rendering diagram…
Components explained — this design
| Component | What it is | Why we use it here |
|---|---|---|
| Wallet API | Validates transfers; orchestrates ledger + external rails. | Single entry for compliance logging and rate limits. |
| Ledger service | Double-entry accounting (see payments doc). | Money correctness > microservice purity. |
| PostgreSQL SERIALIZABLE / Cockroach | Strong transactional guarantees for balances. | Prevents lost updates on concurrent transfers without ad-hoc application locks everywhere. |
| PSP webhooks | Bank/payment partner async status. | ACH settles slowly; webhook is truthier than polling. |
| Fraud rules + ML | Risk scoring gate before ledger commit. | Velocity checks + model scores reduce stolen instrument abuse. |
Shared definitions: 00-glossary-common-services.md
Low-level design
Invariants
- Sum of all accounts == 0 in closed system; external clearing accounts bridge real money.
Concurrency
- Per-user serialization — row lock
SELECT ... FROM wallets WHERE user FOR UPDATEfor transfers touching two users order IDs to prevent deadlock (min_idfirst).
Idempotency
- Client transfer UUID unique constraint; webhook event id dedupe table.
Compliance
- KYC provider (Jumio, Onfido); AML transaction monitoring thresholds → SAR filing workflow (human).
E2E: P2P transfer
Rendering diagram…
Tricky parts
| Problem | Solution |
|---|---|
| Partial failure | Saga outbox pattern; never mark success before commit |
| Negative balance race | DB constraint balance >= 0 + application precheck |
| Chargeback on funding | Reversal entries + block payouts until resolved |
Caveats
- Not a replacement for licensed banking without legal review — e-money license regimes (EU EMI, India PPI).
- Interest on float — regulatory and ethical disclosure.
Azure
- Dynamics 365 Finance hooks; SQL ledger feature (immutable tables) preview patterns.