Payment Systems: Ledgers, Double-Entry Accounting and Reconciliation

How payment systems stay correct: double-entry ledgers, payment state machines, idempotent PSP calls, webhooks and daily reconciliation, step by step.

Advanced 3 min read · Updated

A payment system must never lose money, create money, or charge a customer twice, even when networks time out and services crash halfway through. The designs that achieve this share a few ideas: a double-entry ledger as the source of truth for balances, an explicit payment state machine, idempotency keys on every external call, asynchronous webhooks from payment service providers (PSPs), and daily reconciliation that compares your records with the provider's and the bank's.

The flow of a card payment

pay (idem key)authorise / captureCheckoutPayment servicestate machinePSP / gatewaycard networkLedgerdouble-entry, append-onlyWebhooksstatus updatesReconciliationdaily settlement files
Checkout creates a payment with an idempotency key; the payment service calls the PSP, records ledger entries, and confirms asynchronously through webhooks and reconciliation.

A payment state machine

StateMeaningNext states
createdIntent recorded with amount, currency and idempotency keyauthorising
authorisingRequest sent to the PSP; outcome may be unknownauthorised, failed, unknown
authorisedFunds reserved on the cardcaptured, voided
capturedFunds taken; will settle to the merchantrefunded (partially or fully)
failed / voidedNo money movedterminal
unknownTimed out; outcome must be queried, never assumedresolved by status query or webhook

Only allow valid transitions, store every transition with a timestamp and reason, and never move from unknown to failed just because a timeout happened. The charge may have succeeded. See partial failure.

Idempotency everywhere

  • The client sends an idempotency key with the payment request; retries with the same key return the same payment instead of creating another. See idempotency.
  • The payment service passes its own idempotency key to the PSP, so retrying a timed-out authorisation can't charge twice.
  • Webhooks can arrive more than once and out of order; handlers deduplicate by event ID and apply state transitions only if valid from the current state.

Double-entry ledger

Instead of storing a balance and updating it, record every movement of money as a transaction with at least two entries that sum to zero: a debit from one account and a credit to another. Balances are derived by summing entries. The ledger is append-only: mistakes are corrected with new reversing entries, never by editing history.

TransactionAccountDebitCredit
Customer pays ₹1,000 for an orderCustomer funds receivable (PSP)₹1,000
Merchant payable₹970
Platform fee revenue₹30
Payout to merchantMerchant payable₹970
Bank cash₹970
  • Invariant: the entries of every transaction sum to zero, enforced by the database or the ledger service, so money can't appear or vanish.
  • Amounts as integers in minor units (paise, cents) with a currency; never floating point.
  • Auditability: every balance can be explained by its entries, which regulators and finance teams require.
  • Strong consistency: ledger writes use transactions in a relational or distributed SQL database.

Reconciliation

Every day, compare internal records with the PSP's settlement reports and bank statements: each captured payment should appear in settlement with the expected amount and fees, and each payout should appear in the bank. Mismatches (missing, duplicated, wrong amount) go to an exceptions queue for investigation and correcting entries. Reconciliation catches what idempotency and state machines miss, such as a webhook that never arrived.

For events to other systems (emails, order fulfilment), publish them with a transactional outbox in the same database transaction as the state change, so a crash can't leave the payment captured but the order unfulfilled.

Where it’s used

E-commerce checkout

Idempotent payment creation, a state machine for card and UPI flows, and webhook-driven confirmation.

Marketplaces

Double-entry ledgers split each payment between seller payable, platform fees and taxes, then track payouts.

Wallets and fintech

Balances derived from append-only ledger entries with daily reconciliation against bank statements.

In an interview

  • Model payments as a state machine, including an unknown state after timeouts.
  • Use idempotency keys from client to PSP and deduplicate webhooks.
  • Store money movements in an append-only double-entry ledger with integer amounts.
  • Reconcile daily with PSP and bank reports.

Further reading