Use a computer

For full performance and fluidity, please open Pay Engineers on a desktop or laptop. On mobile, the experience is limited — especially authenticated sections and advanced tools after login.

Payment infrastructure

Designing ledgers for wallets and stored-value products

Double-entry fundamentals, hold states and why "just a balance column" fails under audit. A deep dive into account typing, journal design and the reconciliation guarantees regulators and auditors expect from any product that stores customer value.

Jul 11, 2026 5 min 4,462 0

Wallet products almost always start the same way: a single integer column called balance on a users table, incremented and decremented as money moves. It works perfectly in a demo. It fails quietly in production, and it fails loudly the first time a regulator, auditor or dispute team asks a question the schema cannot answer: "show me exactly how this balance was constructed, entry by entry, at any point in history."

Why a balance column is not a ledger

A mutable balance column has no memory. It tells you the current state but nothing about how that state was reached, whether an update was applied twice, or whether a refund correctly reversed the original transaction rather than creating an unrelated adjustment. Regulators overseeing electronic money and payment institutions expect safeguarding evidence that can be reconstructed independently of your application logs — a balance column simply cannot provide that.

Auditors ask a deceptively simple question every reporting cycle: can you prove that customer balances reconcile, in aggregate, to the funds actually held in safeguarding accounts? Without an immutable ledger, answering that question means manually reconstructing history from application logs, which is slow, error-prone, and unconvincing to anyone who has seen a real audit.

Double-entry fundamentals for payments

We recommend a double-entry ledger with explicit, typed account categories: customer accounts, suspense accounts, settlement accounts, fee accounts, and safeguarding accounts. Every movement of value is represented as a journal entry with at least two postings that net to zero, tagged with a type — top-up, transfer, capture, refund, fee, chargeback, adjustment — so that reporting can slice activity by cause, not just by amount.

Typed journals

A top-up journal debits an incoming-funds account and credits the customer account. A capture journal moves value from a hold state into a merchant-facing settlement account. A refund journal must reference the original capture journal explicitly — never simply create a new, unrelated debit — so that the full lifecycle of a transaction remains traceable from initiation to resolution.

Hold and release semantics

Holds are where most wallet implementations go wrong. A hold should never simply "disappear" from a balance; it must transition through explicit states — placed, captured, released, expired — each represented by its own journal entry. If a hold silently vanishes without a corresponding release or capture entry, you have lost the audit trail for that money, and no amount of application-level testing will catch it because the bug lives in the data model, not the code path.

Reconciliation as a first-class process

An immutable ledger is only half the solution; the other half is a reconciliation process that continuously proves the ledger matches external reality — bank statements, card scheme settlement files, and safeguarding account balances. Reconciliation breaks should generate exceptions that a human reviews, not silent auto-corrections that hide underlying partner or integration issues.

Design your reconciliation cadence around your settlement rhythm: daily for most card and account-to-account flows, intraday for high-volume wallet top-ups, and always with a clear escalation path when a break exceeds a defined threshold.

An implementation checklist

  • Model accounts by type (customer, suspense, settlement, fee, safeguarding) rather than a single generic table.
  • Every balance change must be represented as a journal entry with matching debits and credits.
  • Holds transition through explicit states — never delete or silently zero a hold.
  • Refunds and reversals must reference their originating journal entry, not stand alone.
  • Build automated reconciliation against safeguarding and settlement accounts from day one.
  • Keep the ledger append-only; corrections are new entries, never edits to history.

The cost of getting it wrong later

Remediating money-movement bugs after launch is among the most expensive engineering exercises in fintech, because it usually requires reconstructing historical customer balances from incomplete data while the product is live and customers are actively transacting. Every week of delay compounds the reconciliation gap.

If you cannot reconstruct every customer's balance from an append-only journal, you do not have a ledger — you have a number that regulators will eventually ask you to explain.

Performance considerations for append-only ledgers

Teams sometimes worry that a strict double-entry, append-only design will be too slow for high-frequency wallet activity. In practice, the performance cost is manageable with the right indexing and periodic balance snapshotting — materialising a customer's current balance as a cached, derived value that is recomputed from the journal on a schedule and verified against it, rather than requiring a full journal replay on every read.

The key discipline is that the cache is always demonstrably derived from the journal, never the other way around. If the two ever disagree, the journal wins, and the discrepancy becomes a reconciliation exception rather than a silent overwrite. This preserves both the audit guarantees of double-entry accounting and the read performance a consumer-facing wallet product needs.

Key takeaways

  • Mutable balance columns cannot answer the audit and safeguarding questions regulators will ask.
  • Double-entry journals with typed accounts give you a reconstructable, provable history.
  • Holds must move through explicit states — placed, captured, released, expired.
  • Reconciliation against external reality should surface exceptions, not hide them.
  • Fixing ledger design after launch is dramatically more expensive than getting it right first.

Comments

0 comments

Sign in to leave a comment.

تسجيل الدخول

No comments yet. Be the first to comment.

Keep reading

Related articles

More content that may interest you

View all posts
Featured
Payment infrastructure

What a modern payment processor actually contains

Beyond "accepting cards": the modules, data flows and operational surfaces that define a production-grade processor. We break down the acquiring core, risk engine, ledger, settlement pipeline and partner connectivity layers most roadmaps forget about until launch is already running late.

17/07/2026 5 min 4,209 0
Featured
Payment infrastructure

Payment gateway vs payment processor: choosing the right layer

A practical decision framework for fintech founders deciding what to build, buy or white-label. We unpack where gateways end and processors begin, why the distinction gets blurry in real products, and how hybrid architectures let you keep optionality while you scale.

14/07/2026 5 min 4,553 0