CASE STUDY

Mobile Banking App Backend

3 min read·538 words·Intermediate

Asked at

1 candidate report in Feb 2026

How to use this case study

SDE-2 / Mid

Design the services for accounts, balances, transaction history, transfers and bill pay, and the APIs the app uses.

SDE-3 / Senior

Go deeper on transfer correctness (double-entry ledger, idempotency), authentication (MFA, device binding), fraud checks and notifications.

Staff / Principal

Discuss integrating with a core banking system, high availability across regions, regulatory needs (audit, data retention), and peak-day scaling.


0) Problem Restatement

Capital One asked: design a secure, highly available backend for a mobile banking app. Customers log in, see accounts and balances, browse transaction history, transfer money (between their own accounts and to others), pay bills, and get notifications. The system must be correct with money, secure against fraud and account takeover, and always available.


1) Requirements

  • Login with strong authentication (password/biometrics + MFA, trusted devices).
  • Accounts, balances (available vs current), and transaction history with search.
  • Transfers: internal (instant), external (ACH/wire, takes time), scheduled and recurring. Bill pay.
  • Push notifications (large transactions, low balance, login from a new device).
  • Audit trail. 99.99% availability.


2) Architecture

Architecture Diagram

flowchart LR
    APP["Mobile app"] --> GW["API gateway - TLS, WAF, rate limits"]
    GW --> AUTH["Auth service - MFA, device binding, sessions"]
    GW --> BFF["Mobile BFF"]
    BFF --> ACC["Accounts service"]
    BFF --> TX["Transactions service"]
    BFF --> TRF["Transfers service"]
    TRF --> RISK["Fraud / risk scoring"]
    TRF --> LED[("Ledger - double entry")]
    TRF --> RAIL["Payment rails - ACH, wire, RTP"]
    ACC --> CORE["Core banking system"]
    LED --> K[("Events")]
    K --> NOTIF["Notifications"]
    K --> TX

3) Key Parts

  • Auth: biometrics unlock a device-bound key (the device is registered after MFA). Short-lived access tokens, refresh token rotation, and step-up auth for risky actions (new payee, big transfer). Detect new devices and locations.
  • Accounts and balances: the core banking system is often the source of truth. We keep a read-optimized cache of balances updated by events, and label balances "available" (after pending holds) vs "current".
  • Transaction history: stored in a read store (partitioned by account and date) fed by ledger and core events, with search by merchant, amount and date.
  • Transfers (the correctness core):
1. The client sends a transfer with an idempotency key.

  1. Validate (limits, payee, balance), and run a fraud check (amount vs history, a new payee, device risk). If risky, step-up auth or hold for review.
  2. Internal transfer: one DB transaction writes double-entry ledger lines (debit A, credit B) and updates balances atomically.
  3. External transfer: place a hold on funds, send to the payment rail (ACH/wire), and track states (pending → sent → settled | returned). Returns release or reverse the hold.
  4. Emit events → notifications, and history updates.
  • Bill pay and scheduled transfers: a scheduler creates transfers on due dates (idempotent per schedule + date).


4) Security and Compliance

  • Encryption everywhere, secrets in an HSM/KMS, and PII masked in logs.
  • Rate limiting and bot detection on login, and account lockout with safe recovery.
  • Every money movement and profile change is in an append-only audit log.
  • Data retention per regulation. Customer notifications for sensitive changes (new device, new payee).


5) Availability

  • Stateless services, multi-AZ, active-active across two regions for read paths. The ledger uses a strongly consistent database with synchronous replication within the region and a failover plan.
  • If core banking is down: show cached balances ("as of"), accept transfers into a queue where allowed, and clearly show pending status.
  • Pre-scale for payday and month-end peaks.


6) Wrap-Up

Put strong device-bound authentication with step-up MFA in front of a mobile BFF that talks to accounts, transactions and transfers services. Make every transfer idempotent, fraud-checked and recorded in a double-entry ledger (instantly for internal transfers, with holds and tracked states for external rails), and feed history and notifications from ledger events. Mirror core banking data into read-optimized stores, keep a full audit trail, and design for multi-region availability with graceful behavior when core systems are slow.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →