Wallets & Fintechs

A wallet becomes difficult when money exists in more than one system.

Inside your product, a balance is a number the user trusts. Outside it, the money sits with banks, PSPs and payout providers that each report on their own schedule. Orangepill keeps the internal side authoritative and the external side accountable.

The problem

Internal transfers are easy. The edges are not.

Moving value between two users inside one ledger is a pair of entries. The hard part is every boundary with the outside world: a card top-up that is authorised but not yet settled, a bank deposit that arrives without a reference, a withdrawal that the payout provider has accepted but not completed. Each one is a moment where your balance and someone else's record can disagree.

Typical architecture today

A balance column, updated by whoever writes last.

Balances stored as numbers

A balance field is incremented and decremented by application code. When it is wrong, there is no history to explain why.

Provider state copied in

Webhook handlers translate each provider's statuses into the wallet's own, and each provider maps a little differently.

Holds handled ad hoc

Pending withdrawals and reservations live in separate tables, so "available" is computed differently in different places.

Where it breaks

Users notice drift before your team does.

  • A user spends funds from a top-up that is later reversed by the card network.
  • A withdrawal is debited, the payout fails, and the refund to the wallet is applied twice.
  • A reservation for a purchase is never released after the purchase is cancelled.
  • The wallet shows a balance the safeguarding or settlement account cannot support.
  • Support cannot explain a balance without engineering reading logs.

Orangepill model

The ledger is authoritative for internal money. Providers are authoritative for what they did.

Orangepill keeps those two authorities separate and makes them meet at defined points. A balance is derived from ledger entries. A provider confirmation becomes a ledger effect only through a governed execution. When the two disagree, the disagreement is recorded and handled, not absorbed.

Funding

External pay-in confirmed, then credited. Pending value is visible but not spendable.

Reservations

Holds are ledger states with a lifecycle: placed, captured, released or reversed.

Withdrawals

Funds are held while the payout is in flight, and released or settled when its outcome is known.

Reconciliation

Ledger state is compared with bank and provider reports. Divergence opens a case instead of a correction.

Example workflow

A withdrawal from wallet to bank account.

  1. Withdrawal requested Available balance checked from the ledger
  2. Withdrawal pending Shown as in progress; not spendable in your product
  3. Payout executed Attempt via payout provider
  4. Outcome verified Provider confirmation vs. ledger
  • Paid Hold settled; balance reduced
  • Failed, final Hold released once
  • Unknown Establish finality before acting

The user's balance should never show money as both withdrawn and available. If the provider's answer is unclear, the withdrawal stays open until the outcome is established, rather than being reversed on a guess. Today, payout reservations expire after one hour and do not move available balance, so long-running withdrawals are escalated rather than left to the hold.

Outcome

Balances you can explain to a user, an auditor and a partner bank.

  • Every balance traceable to the events that produced it.
  • One definition of available funds across product, support and finance.
  • Add a funding method or payout provider without touching balance logic.
  • Reconciliation that flags divergence before a user does.
  • Less glue code between provider webhooks and wallet state.

Show us where your balances come from today.

Walk us through funding, holds and withdrawals in your product. We will map which of them the ledger should own and where provider state needs to be verified.