Payments

One Wallet, Six Rails: Reconciling Mobile Money at Scale

Why a single ledger — not six separate integrations — is what keeps a multi-currency wallet honest.

Payments
One Wallet, Six Rails: Reconciling Mobile Money at Scale</picture>
Payments·3 min read·from Zuma Wallet

A wallet that can hold KES, UGX, TZS and other currencies at once sounds like a UI feature. It is actually a ledger-design problem, and it's the part of Zuma's architecture that took the most iteration to get right.

The naive approach — a running balance per currency, updated directly whenever a transaction happens — works fine until two transactions hit the same balance at nearly the same moment, or until a mobile money callback arrives out of order relative to the app's own record of the transaction. At scale, that naive approach produces balances that quietly drift from reality, and nobody notices until a support ticket says "my money is missing."

The wallet instead runs as an append-only ledger: every top-up, spend, refund and transfer is a discrete, immutable entry, and the "balance" shown to a user is a computed sum, not a stored field that gets directly edited. Reconciliation against each payment rail's own settlement report becomes a matter of comparing ledger entries to rail statements line by line, rather than trying to explain a single mutable number. This is the exact pattern I recommend to any hosting or billing client asking "why doesn't our account balance match what the client actually paid" — the fix is almost never a bug hunt, it's replacing a mutable balance with an immutable ledger.

3+
currencies held simultaneously
100%
transactions immutable & auditable
0
directly-edited balance fields
Live module

Zuma Wallet

Explore on Zuma →
Consult Me