Double-entry ledgers for payment systems

Your balances live in a table that was fine until a refund or a payout made it disagree with your processor.

Symptoms in your system

  • Retried webhooks refunded the same customer twice, and you found out from the customer.
  • Balances and processor totals disagree, and nobody can say when the two started drifting apart.
  • Month end takes a week of manual matching before anyone will sign off on the numbers.
  • Chargebacks land after the payout has gone out, against money that is already spent.
  • Adding a second currency turned into an argument about rounding that nobody has settled.

What we build

  • Money cannot be created or lost by accident. Every balance can be explained, down to the movement that made it.
  • No more double spending caused by concurrency. A second click on Capture settles once, and a replayed webhook is recognized as the same instruction.
  • Funds are reserved at authorization and released or captured on your terms.
  • Flexible yet precise rounding and allocation rules that support features such as commission distribution and proportional partial refunds.
  • One rounding policy across every currency, applied the same way everywhere the ledger returns a total.
  • You find out the moment your ledger and your processor disagree, and by how much.

Failures that surface a year later

  • Sub-cent losses on conversion that surface at year end, after twelve months of accumulating.
  • Account pages that take a little longer to load each month, because every visit re-adds the whole history.
  • Refunds that quietly change what the merchant is owed and what tax was collected.
  • Nothing watching for an account that has gone negative, so the first report comes from the customer.
  • Idempotency left to the payment provider, until the day a key is reused.

Ledger work we have done

We built the same ledger several times over for different fintechs, then built one that carries all of it: double-entry, authorization holds, full and partial reversals, per-currency precision.

Those earlier builds sat inside a payment facilitator, together with the reconciliation that compares it against the processor line by line, and inside a multi-currency banking platform carrying ISO 20022 and ISO 8583 message flows and routable account numbers.

Integrity is enforced by the system rather than hoped for in the code around it. Going negative, charging twice or moving money into the wrong tenant cannot commit.

Stand up a SaaS, a wallet or a bank on it. Put it in front of your processor as the source of truth, and an overpayment, a double charge or an underpayment stops before it lands.

Use it as a system of record, where finance traces and audits every money flow. Use it in the path of a payment, where it decides whether a transaction can proceed and then records the result. Or both, on separate ledgers for separate purposes.

Embed the library, connect over our Go and Node SDKs, or host it yourself as a white-labeled ledger with its own users, access control and API.

Related work: Payment rails and direct bank integration. KYC, AML and fraud decisioning.