A platform moves money it does not own. Buyers pay in, sellers get paid out, fees and refunds and chargebacks pull in different directions, and at every instant the platform has to answer one question with certainty: who is owed what, right now. The platform ledger is the system that answers it. Get it wrong and the symptoms are familiar: a seller paid twice, a balance that goes negative without explanation, a reconciliation that drifts a few cents a day until it is thousands of dollars off and nobody can say why.

Your processor (Stripe, Adyen, a bank partner) keeps its own ledger of what it owes your platform. That is not your ledger. The processor sees one merchant: you. Your ledger has to break that single settlement balance down into the per-seller balances, holds, and obligations that the processor never models. This module is about building that internal ledger so it holds up under load and under audit.

What the ledger actually records

A platform ledger is not a balances table. A balances table tells you the current number; it cannot tell you how you got there, and a number you cannot reconstruct is a number an auditor will not accept.

The ledger is the log of movements. Each movement is an entry, entries are grouped into transactions, and the balance of any account is the sum of its entries. You store the events, then derive the balances. You never store the balance and hope the events agree with it.

Double-entry, because it is the only thing that proves out

Every transaction records at least one debit and at least one credit, and within a transaction debits and credits must sum to zero. This is the same double-entry method that has underpinned bookkeeping for centuries, and the reason it survives is that it makes a whole class of bugs impossible: money cannot appear or vanish, it can only move from one account to another.

Model the obvious accounts (each seller's balance, your platform fee account, a clearing account for funds in transit) and the less obvious ones (a holds account, a chargeback liability account). A $100 sale is not "seller gets $100." It is a set of balanced entries: credit the seller $97.50, credit your platform fee account $2.50, debit the clearing account $100. The entries net to zero, and the seller's available balance is now the sum of every entry against their account, not a field someone remembered to update.

Available versus pending is a ledger fact, not a UI label

Funds arrive in two states. When a card payment is captured, the money is real but not yet settled to the processor. Stripe, for example, holds incoming card funds in a pending balance and transitions each transaction to available at its own settlement time; a US card payment captured Monday typically becomes available two business days later. Your ledger has to mirror this, because paying a seller out of money that has not settled is how you fund your own losses.

Model pending and available as separate balances on the same seller account, or as a pending account that sweeps into the available account on the settlement date. A payout engine should only ever draw against available. The distinction is not cosmetic. It is the difference between a payout you can fund and one you cannot.

Holds and reserves: money you are choosing not to release

A hold is a deliberate freeze on funds the seller has otherwise earned. Reserves are the policy version of the same thing: a rolling percentage held back to cover future refunds and disputes, common for new or higher-risk sellers.

Holds belong in the ledger as their own entries, not as a flag on the seller row. When you place a $200 hold, you move $200 from the seller's available balance to a holds account with a transaction that references why (a pending dispute, a manual review, a reserve rule). Releasing the hold is another balanced transaction in the opposite direction. Now "available" is always the truthful number a payout can draw on, and every hold has a paper trail showing who placed it, when, and on what grounds.

Reversals: append, never edit

The single most common way platform ledgers fail audit is editing or deleting entries to "fix" a mistake. Do not. A ledger should be append-only and immutable: once an entry is written it is never changed, and any previous state can be reconstructed by replaying the log.

A refund is not the deletion of the original sale. It is a new, balanced transaction that reverses the economic effect: debit the seller, credit the clearing or processor account, and crucially reverse the platform fee if your refund policy returns it. A correction to a mistaken entry is itself a new entry. The wrong number stays in the log, visible, with a compensating entry beside it. This is what lets you answer "why is this balance what it is" months later, which is exactly the question reconciliation and audit exist to ask.

Negative balances are not an error state, they are a fact you must hold

A seller's balance goes negative when reversals outrun their available funds. A buyer disputes a $500 charge after the seller has already been paid out and spent the money; the chargeback debits a seller account that no longer has $500 in it. The balance is now negative $500, and your ledger must be able to represent that honestly rather than clamping at zero.

The clamp-at-zero instinct is the bug. If the ledger refuses to go below zero, the $500 you are owed simply disappears from your books, and you have quietly converted a recoverable debt into an untracked loss. Let the balance go negative, record it as a real obligation, and let your collection logic work against it (recover from the seller's next sales, draw on their reserve, or escalate).

Know where the liability actually lands, because it is contractual, not automatic. On Stripe Connect, a platform can either take responsibility for connected-account negative balances or assign that responsibility to Stripe; when the platform takes it, Stripe holds platform funds in reserve and, if a connected account stays negative for 180 days, transfers from that reserve to cover it. Whatever your processor's terms, your ledger has to model the negative balance, the reserve backstop, and the eventual write-off as distinct, dated entries. Module 8 covers the compliance obligations that ride on top of this; here the job is to make sure the money is tracked truthfully before anyone asks who is liable.

The takeaway

The platform ledger earns its keep on the bad day, not the normal one. Build it as an immutable, append-only, double-entry log; derive balances from entries rather than storing them; separate available, pending, and held funds as distinct balances; reverse with new entries instead of edits; and let negative balances exist as the real, dated obligations they are. A ledger built this way reconciles to the cent and answers every "why" an auditor can put to it. One built any other way will pass every demo and fail the first dispute.

← Previous
Seller Onboarding: KYB as a Gate, Not a Wall
Next →
The Payout Engine: Timing, Rails, and Mass Money-Out