Skip to content
Wallets and stored value

Wallet balances that stay exact under retries, holds and refunds

Give every customer, merchant or sub-account its own balance. Every movement posts as a balanced double entry in integer units, and a retry with the same reference can never move the money twice.

BalancesReferencesInflight holdsRefunds
bln_df56a248… · USDprecision 100
Committed balance
12.50
1 hold
credit_balance1250
inflight_debit_balance3000
overdraft_limit50.00
available−17.50
order-1042 APPLIED +12.50
order-1042 retry 409 unchanged
Illustration using captured values for one balance: a 12.50 credit and a 30.00 hold.
The problem

Where this usually goes wrong

  • Floating-point balances drift

    A wallet that adds 0.1 and 0.2 in floating point will, sooner or later, disagree with the bank. Small errors compound across millions of postings.

  • Retries double-post

    A mobile client times out and resubmits. Without a stable idempotency key enforced by the ledger, the same top-up or transfer lands twice.

  • Edits erase history

    When support fixes a balance in place, nobody can explain the number later. Auditors and regulators expect the original entry and its correction.

API example

A 12.50 USD wallet transfer, and its retry

Captured from a local LedgerForge build. The transfer posts 1250 units on both sides; sending the same reference again is refused and changes nothing.
POST /transactionsRequest
{  "source": "bln_e0f81b15-bd0a-43c5-9e84-7fd4394192e8",  "destination": "bln_df56a248-7d7e-4c0c-8fbf-a5215c87b603",  "currency": "USD",  "precise_amount": 1250,  "precision": 100,  "reference": "order-1042",  "description": "Order 1042",  "skip_queue": true,  "allow_overdraft": true,  "overdraft_limit": 12.5}
Response201 Created
{  "rate": 0,  "precise_amount": 1250,  "amount": 12.5,  "amount_string": "12.5",  "precision": 100,  "overdraft_limit": 12.5,  "transaction_id": "txn_c493a7e3-ac39-4456-90c3-ac43f00c5e0d",  "parent_transaction": "",  "source": "bln_e0f81b15-bd0a-43c5-9e84-7fd4394192e8",  "destination": "bln_df56a248-7d7e-4c0c-8fbf-a5215c87b603",  "reference": "order-1042",  "currency": "USD",  "description": "Order 1042",  "status": "APPLIED",  "hash": "9b7d7ad924e2e626055e3b33edcf194142e3fcd562de1807dd738d9afd7c1f87",  "allow_overdraft": true,  "inflight": false,  "skip_queue": true,  "atomic": false,  "created_at": "2026-10-10T05:54:45.691597464Z",  "effective_date": "2026-10-10T05:54:45.691597464Z",  "scheduled_for": "0001-01-01T00:00:00Z",  "inflight_expiry_date": "0001-01-01T00:00:00Z",  "inflight_commit_date": "0001-01-01T00:00:00Z",  "meta_data": {    "allow_overdraft": true  }}
POST /transactions (same reference)409 Conflict
{  "error": "reference has already been used",  "error_detail": {    "code": "TXN_DUPLICATE_REFERENCE",    "message": "reference has already been used"  }}

Put a provable ledger under your money movement

Start with the open-source core, or let the LedgerForge team run it for you on dedicated infrastructure.