This document compiles five standard architecture views for the Mobile Wallet System:
- Use Case View
- Logical View
- Process View
- Development View (modular)
- Physical View
##Context (C4-style, high level)
flowchart LR
subgraph Users
C["Customer (Mobile App)"]
M["Merchant (POS/App)"]
A["Agent (Branch/Agent App)"]
end
subgraph Wallet["Mobile Wallet System"]
GW(API Gateway)
SVC[App Services]
LED[Ledger Service]
PAY[Payments Service]
KYC[E-KYC Service]
NOTI[Notification Service]
RPT[Reporting & Analytics]
ADM[Admin & RBAC]
MSG[(Message Broker)]
DB[(Operational DBs)]
end
EXT1[(Bank Core / CASA)]
EXT2[(MMQR National Switch)]
EXT3[(KYC Provider)]
EXT4[(SMS/Email/Push Gateways)]
C -->|REST/GraphQL| GW
M -->|Merchant API| GW
A -->|Agent API| GW
GW --> SVC
SVC --> PAY
SVC --> LED
SVC --> KYC
SVC <--> NOTI
SVC <--> RPT
SVC <--> ADM
SVC <--> MSG
SVC <--> DB
PAY <--> EXT1
PAY <--> EXT2
KYC <--> EXT3
NOTI <--> EXT4
Actors and primary use cases for the Mobile Wallet. (Mermaid approximation of a use‑case diagram.)
flowchart LR
%% Actors
C([Customer])
MR([Merchant])
BA([Bank Account])
AG([Agent])
SW([MMQR National Switch])
KP([KYC Provider])
%% System boundary
subgraph SYS[Mobile Wallet System]
UC1[[Register & eKYC]]
UC2[[Login]]
UC3[[Cash In]]
UC4[[Cash Out]]
UC5[["Pay Merchant (QR)"]]
end
%% Associations
C --- UC1
C --- UC2
C --- UC3
C --- UC4
C --- UC5
MR --- UC5
BA --- UC3
AG --- UC4
SW --- UC5
KP --- UC1
Notes
- Register & eKYC covers identity capture, OCR, liveness, blacklist check, and decisioning.
- Cash In involves linking bank account/cards and authorizing top-up.
- Cash Out supports agent/ATM cash-out with OTP and risk checks.
- Pay Merchant (QR) supports dynamic/static MMQR with online authorization, tips, and partial refunds.
Key domain entities and relationships.
classDiagram
class Customer{
+id: Snowflake
+name
+phone
+kycStatus: enum
+primaryWalletId
}
class WalletAccount{
+id: Snowflake
+customerId
+balance: decimal
+status: enum
+limitsProfileId
}
class Merchant{
+id: Snowflake
+name
+category: MCC
+qrType: enum
}
class Agent{
+id: Snowflake
+name
+location
}
class KYCVerification{
+id
+customerId
+providerRef
+result: enum
+score: number
}
class QRCode{
+id
+merchantId
+type: static|dynamic
+payload
}
class Transaction{
+id
+type: enum
+amount: decimal
+currency
+status: enum
+rrn
+authCode
}
class LedgerEntry{
+id
+txnId
+debitAccountId
+creditAccountId
+amount
+narration
}
class SettlementBatch{
+id
+merchantId
+cutoffAt
+totalAmount
+status
}
class LimitsProfile{
+id
+dailyTxnLimit
+perTxnLimit
+monthlyTxnLimit
}
class Role{
+id
+name
}
class Permission{
+id
+name
+resource
+action
}
Customer --> WalletAccount : owns 1..*
Customer --> KYCVerification : has 0..*
Merchant --> QRCode : issues 1..*
Transaction --> WalletAccount : affects 1..*
Transaction --> Merchant : optional
Transaction --> Agent : optional
Transaction --> QRCode : optional
LedgerEntry --> Transaction : posts 1..*
SettlementBatch --> Merchant : for 1
LimitsProfile <.. WalletAccount : applies
Role "1" -- "many" Permission : grants
sequenceDiagram
autonumber
actor Customer
participant App as Mobile App
participant API as API Gateway
participant KYC as E-KYC Service
participant Prov as KYC Provider
participant LED as Ledger/Wallet
Customer->>App: Submit phone, ID, selfie
App->>API: POST /auth/register
API->>KYC: Create verification (OCR+liveness)
KYC->>Prov: Verify(ID data, selfie)
Prov-->>KYC: result(score, status)
KYC-->>API: decision(Approved/Pending/Rejected)
API-->>App: registration status + token (if approved)
API->>LED: Create Wallet Account (on approval)
LED-->>API: walletId
sequenceDiagram
autonumber
actor Customer
participant App
participant API as API Gateway
participant PAY as Payments Service
participant SW as MMQR Switch
participant LED as Ledger
participant NOTI as Notification
Customer->>App: Scan QR (static/dynamic)
App->>API: POST /payments/qr {amount, qrData}
API->>PAY: validate & authorize
PAY->>SW: route/notify (if scheme requires)
PAY->>LED: post double-entry (debit wallet, credit merchant holding)
LED-->>PAY: posted + authCode
PAY-->>API: response(approved/declined)
API-->>App: show receipt
API->>NOTI: push receipt to customer/merchant
sequenceDiagram
autonumber
participant App
participant API
participant PAY as Payments
participant EXT as Bank Core/Agent
participant LED as Ledger
App->>API: POST /wallet/cashin {amount, source}
API->>PAY: request top-up
PAY->>EXT: debit source (bank/card/agent)
EXT-->>PAY: success
PAY->>LED: credit wallet
LED-->>PAY: posted
PAY-->>API: ok
API-->>App: Top-up success
App->>API: POST /wallet/cashout {amount, agentId}
API->>PAY: initiate cash-out
PAY->>LED: debit wallet
LED-->>PAY: posted
PAY->>EXT: notify agent for payout
PAY-->>API: token/otp
API-->>App: present token to agent
Cross-cutting: risk checks (velocity, blacklist), idempotency keys, retries, audit events, and compensation for partial failures.
Modules and boundaries. This view focuses on modularity: each module exposes interfaces; internal implementation can vary (Laravel/NestJS/Go).
flowchart TB
subgraph Entry
API["API Layer (REST/GraphQL)"]
JOB[Job Scheduler / Workers]
EVT[Event Subscriptions]
end
subgraph Identity
ID_CTRL[Controllers]
ID_FEAT[Features: Register, Login, OTP]
ID_REQ[Requests/Validators]
ID_INT[Integrations: KYC Provider]
ID_DOM[Domain: Customer, KYCVerification]
end
subgraph Wallet
WL_CTRL[Controllers]
WL_FEAT[Features: Balance, Limits, Statements]
WL_DOM[Domain: WalletAccount, LedgerEntry]
WL_SVC["Ledger Engine (double-entry)"]
end
subgraph Payments
PM_CTRL[Controllers]
PM_FEAT[QR Pay, Refund, Reversal]
PM_INT[MMQR/Switch, Bank Core]
PM_DOM[Txn Domain]
end
subgraph MerchantAgent
MC_FEAT[Merchant Onboarding, QR Mgmt]
AG_FEAT[Agent Ops, Cashout]
end
subgraph AdminRBAC
ADM_CTRL[Admin APIs]
RBAC[Roles, Permissions, Policy]
AUD[Audit & Activity Log]
end
subgraph Support
CFG[Config]
MSG[(Message Broker)]
CACHE[(Cache)]
DB[(Datastores)]
NOTI[Notification Adapters]
OBS[Observability]
ALL[(All Services)]
end
API --> ID_CTRL
API --> WL_CTRL
API --> PM_CTRL
API --> ADM_CTRL
ID_CTRL --> ID_FEAT
ID_FEAT --> ID_DOM
ID_FEAT --> ID_REQ
ID_FEAT --> ID_INT
WL_CTRL --> WL_FEAT
WL_FEAT --> WL_DOM
WL_FEAT --> WL_SVC
PM_CTRL --> PM_FEAT
PM_FEAT --> PM_DOM
PM_FEAT --> PM_INT
PM_FEAT --> MC_FEAT
PM_FEAT --> AG_FEAT
ID_FEAT --> MSG
PM_FEAT --> MSG
WL_SVC --> DB
ID_DOM --> DB
PM_DOM --> DB
ADM_CTRL --> RBAC
RBAC --> DB
NOTI --> MSG
OBS -.-> ALL
Module Contracts (examples)
IdentityexposesPOST /auth/register,POST /auth/login,POST /auth/otp/resend.PaymentsexposesPOST /payments/qr,POST /payments/refund, idempotentPUT /payments/{id}.WalletexposesGET /wallet/balance,POST /wallet/cashin,POST /wallet/cashout.Admin & RBACexposes policy evaluation (/admin/policy/check) and audit feed.
Quality Attributes
- Modularity > separate deployables possible.
- Observability baked in: trace IDs flow end-to-end.
- Resilience via retries, SAGA/compensation on cross-module operations.
- Security: OAuth2/OIDC, mTLS between services, request signing to external rails.
Target deployment with HA and external dependencies.
flowchart LR
subgraph Client["Client Layer"]
iOS[iOS App]
And[Android App]
POS[Merchant POS/App]
end
subgraph Edge["Edge & Security"]
WAF[WAF/CDN]
APIGW[API Gateway]
OIDC["Identity Provider (OIDC)"]
end
subgraph Cluster["Kubernetes Cluster (Prod)"]
subgraph NS1["Namespace: wallet"]
SVC1[Identity & eKYC Service x2]
SVC2[Payments Service x2]
SVC3[Wallet/Ledger Service x2]
SVC4[Admin & RBAC x2]
NOTIF[Notification Worker x2]
RPT[Analytics Worker]
MSG[(Kafka/RabbitMQ HA)]
CACHE[(Redis HA)]
end
subgraph NS2["Namespace: data"]
DBOLTP[(PostgreSQL Primary/Replica)]
DWH[(Data Warehouse)]
OBJ[(Object Storage)]
end
subgraph NS3["Namespace: obs"]
LOGS[(ELK/Cloud Logs)]
METRICS[(Prometheus/Grafana)]
TRACES[(OpenTelemetry/Jaeger)]
end
end
subgraph External["External Systems"]
CORE[(Bank Core / CASA)]
SWITCH[(MMQR National Switch)]
KYCP[(KYC Provider)]
MSGGW[(SMS/Email/Push)]
end
iOS --> WAF
And --> WAF
POS --> WAF
WAF --> APIGW --> OIDC
APIGW --> SVC1 & SVC2 & SVC3 & SVC4
SVC1 --- KYCP
SVC2 --- SWITCH
SVC2 --- CORE
SVC1 & SVC2 & SVC3 & SVC4 --- MSG
SVC1 & SVC2 & SVC3 & SVC4 --- CACHE
SVC3 --- DBOLTP
RPT --- DWH
NOTIF --- MSGGW
LOGS -.-> All
METRICS -.-> All
TRACES -.-> All
- Performance: p95 API < 300ms for read, < 600ms for write under 2k RPS.
- Availability: ≥ 99.9% monthly; active-active services; DB primary/replica.
- Security: OIDC/OAuth2, mTLS, JWT audience checks, data encryption at rest (KMS) and in transit.
- Compliance & Audit: immutable audit log; retention ≥ 7 years for financial transactions.
- Scalability: horizontal auto-scaling on CPU/RPS; topic-based backpressure on async jobs.
- Observability: trace_id in logs/metrics; SLO dashboards; alerting on error budgets.
POST /auth/register
POST /auth/login
POST /auth/otp/resend
GET /wallet/balance
POST /wallet/cashin
POST /wallet/cashout
POST /payments/qr
POST /payments/refund
GET /payments/{id}- Customer(id, phone, name, kycStatus, primaryWalletId, createdAt)
- WalletAccount(id, customerId, balance, status, limitsProfileId, createdAt)
- Transaction(id, type, amount, currency, status, rrn, authCode, walletId, merchantId, createdAt)
- LedgerEntry(id, txnId, debitAccountId, creditAccountId, amount, narration, createdAt)
- Merchant(id, name, MCC, qrType, createdAt)
End of document.