Skip to content

Programmable Wallets: Architecture & Ledgers

When a buyer pays $100 on your platform, three numbers have to agree: the payment service provider (PSP) settlement, the seller's wallet balance, and the platform fee account. In most fintech stacks, they don't. Balance logic ends up spread across application code, a PSP dashboard, and a month-end reconciliation process that pulls in engineers and spreadsheets. The wallet works for users, but the underlying money movement architecture doesn't.

In fintech and embedded finance, wallets are part of a broader money movement architecture, and engineering teams need to decide what belongs in the wallet and what supports it.

Formance's position is that the wallet should reflect product behavior, the ledger should reflect financial truth, and the two should be separate systems, with the ledger as the durable system of record built alongside the wallet.

What is a Programmable Wallet?

A programmable wallet is a wallet whose behavior is defined in code rather than in a payment provider's dashboard. Instead of a fixed set of hold-and-send operations, a programmable wallet exposes APIs and rule hooks that let engineering teams shape how value is stored, who can move funds, which rails are used for money movement, and what conditions must hold before a transfer executes.

Moving wallet behavior out of a provider dashboard and into code is what separates a standard wallet from a programmable one. The former is a feature your team turns on inside a payment provider's product, while the latter is infrastructure your team builds, where the rules for holding and moving money are defined.

Why Programmable Wallets Matter in Fintech and Embedded Finance

Modern financial products demand more from wallets than balances and transfers.

Embedded finance platforms may need per-customer sub-balances inside an omnibus account, marketplaces may need hold-and-release escrow with programmatic fee capture, and treasury teams may need multi-bank visibility with approval workflows tied to payment objects.

Each requirement involves money-movement logic that spans the wallet product, external payment rails, and internal accounting.

A common failure mode is wallet logic spread across application code, payment provider APIs, and internal scripts. Balances fragment across systems, and reconciliation becomes a forensic exercise, leading to operational bottlenecks that compound with each new provider or product feature.

In October 2025, Paxos minted $300 trillion in PYUSD on Ethereum, roughly 300 times global GDP, because a single key held unrestricted minting rights with no rate limits, no amount caps, and no multi-party approval requirement. Paxos burned the tokens within 22 minutes, but not before Aave froze its PYUSD markets as a precaution.

No user funds were lost, but the incident illustrates what happens when programmable wallet logic operates without controls that belong in a separate, durable layer underneath it. The on-chain ledger recorded the error immediately. The internal controls that should have prevented it were absent entirely.

Designing the wallet architecture requires distinct infrastructure layers so that wallet logic can fail or change without taking the system of record down with it.

Core Components of Programmable Wallet Architecture

Programmable wallet architecture has four coordinated infrastructure layers: wallet experience, policy and permissions, orchestration and connectivity, and core ledger.

Wallet experience

The control surface for users, admins, and workflows. Spending limits, approval chains, balance views, and product-specific behavior live in the wallet experience layer.

Policy and permissions

Rules governing who can move money, under what conditions, and with what approval requirements. Spend controls, velocity checks, Know Your Customer (KYC) gates, and multi-user access sit in the policy and permissions layer.

Orchestration and connectivity

The layer that translates business events into payment orders dispatched across external rails such as Automated Clearing House (ACH), Single Euro Payments Area (SEPA), card networks, and on-chain rails. Provider abstraction and multi-step workflow coordination belong in the orchestration and connectivity layer.

Core ledger (system of record)

The append-only, immutable, double-entry accounting system that records every posting, computes balances from entry history, and provides traceability for audits and regulatory reporting.

Teams that separate the four layers can swap PSPs, update controls, and ship new product logic without rebuilding the stack. Teams without that separation usually discover its importance during an audit, a provider migration, or a reconciliation failure, focusing on the wallet and the ledger.

The Wallet Layer vs. the Ledger Layer

The wallet is the control surface for product behavior and defines how money should move through rules, permissions, and workflows. The ledger is the durable system that records what actually happened through postings, balances, and the audit trail.

ResponsibilityWallet layerLedger layer
Business rules (spend limits and velocity checks)Owns and enforcesRecords resulting from postings
Permissions and access controlOwns and enforcesRecords authorized activity
Workflow fund state (hold, approve and release)Owns and managesRecords postings for state transitions
Balance computationReads from the ledger; may cache for performanceComputes from entry history
Posting integrityCalls ledger APIsEnforces double-entry accounting, immutability and idempotency
Audit trailGenerates business eventsMaintains an immutable, hash-chained record
ReconciliationTriggers verificationProvides authoritative data for comparison

Wallet products need ledger support when teams need fund attribution across an omnibus account, internal transfers between product-level sub-accounts, reconciliation against external bank statements, or auditability that satisfies regulators.

Ultimately, the wallet should reflect product behavior, the ledger should reflect financial truth, and the two should be separate systems, with the ledger serving as the durable system of record that supports the wallet.

The Wallet & Ledger working together: a marketplace purchase with a fee

A $100 marketplace purchase with a 10% platform fee is recorded in the ledger as three distinct events. A buyer pays $100, the platform takes $10, and the seller receives $90.

Event 1: Buyer pays $100; funds enter escrow.

AccountDebitCredit
platform:omnibus_bank$100.00
escrow:holding (Order #4421)$100.00

Net: $0.00. The escrow account is named to the specific order, so the ledger can answer at any point: whose money is in escrow, and under what conditions does the money move?

Event 2: Buyer confirms delivery; escrow releases with atomic fee capture.

The split runs as a single transaction, so the seller credit and the platform fee either both post or neither does. In Numscript, that looks like this:

send [USD/2 10000] (
	source = escrow:holding
	destination = {
		90/100 to seller:wallet
		10/100 to platform:fee_revenue
})

That single instruction produces the following ledger postings:

AccountDebitCredit
escrow:holding (Order #4421)$100.00
seller: wallet$90.00
platform:fee_revenue$10.00

Net: $0.00. The $10 fee has its own entry with its own timestamp and reference, making it queryable, auditable, and reconcilable as a line item.

Event 3: Seller payout settles to the bank.

With $90.00 now sitting in the seller's wallet from Event 2, the seller requests a payout. Within the platform's internal ledger, the seller wallet is debited when the payout is initiated, and an external bank transfer is created. When the seller requests payout, the internal ledger debits seller.wallet and credits a payout clearing account; after the external bank transfer settles, the platform’s omnibus bank cash is reduced by $90, leaving the platform with only its $10 retained fee.

AccountDebitCredit
seller:wallet$90.00
payouts:payable (or payout_clearing)$90.00

Net: $0.00 on the platform ledger. The seller wallet balance drops to zero as funds move to the seller's external bank account (outside this ledger), and the omnibus account's net position across the three events leaves exactly the platform's $10 fee on the books.

Final balances:

AccountBalance
platform:omnibus_bank+$10.00
escrow:holding (Order #4421)$0.00
seller:wallet$0.00
platform:fee_revenue+$10.00

The platform retains its $ 10 fee exactly. Every other dollar exited through a traceable chain of entries. Summing entries over time reconstructs balances from the posting history, which then becomes the balance source.

Where Programmable Wallets Sit in the Money Movement Stack

Programmable wallets sit atop a programmable core ledger that connects to banks, PSPs, card processors, and stablecoin rails through an abstraction layer. The wallet is the product surface, the ledger is the system of record, and external providers are interchangeable connections behind the abstraction. The marketplace example showed that the ledger in isolation; in production, it sits inside this larger stack.

This under-the-wallet pattern gives engineering teams four architectural outcomes:

  1. Product flexibility: New financial products extend the chart of accounts and define new transaction models, rather than rebuilding balance logic from scratch.
  2. Provider portability: Adding or replacing a PSP, bank, or stablecoin rail becomes a connectivity change. The ledger stays authoritative regardless of which provider handles the external leg.
  3. Auditability: Each posting includes a cryptographic hash of the previous posting, so altering an earlier entry invalidates every hash downstream of it. Point-in-time balance reconstruction, fund attribution in omnibus accounts, and regulatory reporting all involve querying the posting history.
  4. Operational control: Continuous reconciliation matches each ledger posting to its corresponding line in the provider settlement file as the file arrives. Each posting carries a provider reference ID, so a mismatch surfaces for the specific transaction the moment the settlement line lands, rather than as an aggregate variance discovered weeks later.

These outcomes compound when teams design wallet products with the ledger as the foundation from the start. The Formance Ledger is built around this model: a programmable core ledger that supports the wallet, abstracts external providers, and makes flexibility, portability, auditability, and operational control properties of the infrastructure instead of ongoing engineering work.

Programmable Wallet Use Cases Worth Designing For

Four common use cases share the same ledger foundation while expressing different product behavior with programmable wallets.

Embedded customer wallets

Embedded customer wallets serve SaaS and fintech products that embed balances for their users. They need per-customer sub-balance isolation within a pooled omnibus account, atomic fee capture on inbound flows, and spend controls tied to identity-verification status.

Without proper ledger infrastructure, common risks include non-atomic splits, limited fund-state history, and balance logic that surfaces months into production. Notably, when teams add a second market, a new payment rail, or a regulatory reporting requirement that the original balance model cannot accommodate.

Marketplace and platform wallets

Marketplace and platform wallets route funds among buyers, sellers, and the platform using programmatic rules governing fees, holds, and payout timing.

The ledger often needs to represent a HELD state that is formally distinct from both AVAILABLE_TO_SELLER and RETURNED_TO_BUYER. When a buyer disputes a charge, the ledger may need to reverse the original split atomically.

The reversal is far easier when the original split was recorded as linked postings sharing a parent transaction ID, because a chargeback handler can query the ledger by the parent ID, retrieve all child postings in the split, and issue an inverse transaction in a single operation.

Treasury and internal operations wallets

Treasury and internal operations wallets manage corporate balances across multiple bank accounts and legal entities for operational purposes. Approval workflows often need to be tied to the payment object itself, so the approval state is part of the same record as the payment instruction.

For example, the payment record carries an approval_status field and an approved_by reference, and the ledger does not post the payment until both fields are set. Metadata such as cost center, entity ID, and purpose code must carry over from the payment object to the corresponding ledger postings. This removes the post-hoc step of matching payment records to accounting records.

Stablecoin and multi-currency wallets

Stablecoins and multi-currency wallets hold balances in multiple currencies, both fiat and digital. They often need rail selection based on cost, settlement speed, and corridor availability, stablecoin-to-fiat foreign exchange (FX) management, and automated reconciliation matching on-chain transaction hashes to internal payment IDs.

Without a unified ledger across asset types, teams end up relying on manual consolidation to understand net FX position. Stablecoin rails need the same posting model, reconciliation workflow, and audit trail as any fiat rail.

What Should You Actually Build Into the Wallet, and What Belongs Underneath It?

Across all four use cases, the pattern is the same: product behavior at the wallet layer, financial truth at the ledger layer.

Fintech and embedded finance teams must build product behavior into the wallet. Put balances, transfers, and financial truth in a core ledger to support it. That means spend limits, approval chains, balance views, and payout triggers belong in the wallet layer; postings, balance computation, and the audit trail belong in the ledger layer.

Teams that get the wallet-ledger separation right keep iterating on wallet products and swap providers without having to rebuild money movement each time. Teams that get it wrong end up with fragmented balances across systems, month-end reconciliations that cannot tie a posting to a specific provider transaction, and audit findings related to unmatched omnibus balances. The cost grows with every new product, market, and payment rail.

Formance gives engineering teams a programmable core ledger built around the wallet-ledger separation. The platform uses an open-source core to move wallet and balance logic that today lives in application code, provider dashboards, and internal scripts into a system of record with double-entry accounting enforcement, hash-chained immutability that detects retroactive edits on read, and the Numscript language for expressing money movement logic as a single atomic transaction the ledger either commits in full or rejects.

Clone the Formance Ledger on GitHub, spin up the quickstart with Docker Compose, and post your first split transaction against the marketplace example above.