Every travel business that sells through agents ends up extending credit. Usually by accident: an agent needs to confirm before their client pays, you say yes, and six months later there is an arrangement nobody wrote down.

There is a better shape for this, and it is not complicated. But the details are unforgiving.

Why a spreadsheet stops working

A balance in a spreadsheet has one field per agent. Somebody edits it after each booking and each payment.

It works until one of these happens, and eventually all of them do:

  • two people edit it in the same hour
  • a booking is cancelled and the credit back is calculated by hand
  • an agent disputes a figure and there is no history to show
  • somebody types 1,500 where they meant 15,000
  • the person who maintained it leaves

The failure is not that the number goes wrong. It is that when it goes wrong, you cannot prove what it should have been. A single field has no memory.

The shape that works: an append-only ledger

Instead of storing a balance, store movements, and never delete one.

Every row records what happened, when, how much, in which currency, why, and against what — a booking reference, a top-up reference, an adjustment note. The balance is the sum of the rows. It is not stored; it is derived.

That one change buys you a lot:

  • The balance is always explainable. Any figure can be walked back to the movements that produced it.
  • Disputes end quickly. You show the agent the rows.
  • Mistakes are corrected, not overwritten. A wrong entry is fixed by a reversing entry, and both stay visible. The history remains true.
  • Reconciliation is arithmetic, not archaeology.

The discipline that makes it work is simple and absolute: one code path writes to the ledger. Not one for bookings and another for top-ups and a third for a quick fix. One. Everything that moves money goes through it, or the guarantees are worthless.

Holds: the part everyone skips

An agent starts a booking. Between "confirm" and the supplier answering, the money is in a strange state — not spent, but not available either.

If you ignore that state, one of two things happens. Either you debit immediately and have to refund on failure, or you debit at the end and the agent can spend the same money twice in the meantime.

The fix is a hold: a zero-value marker that reserves funds without moving them.

  • Available balance = balance − active holds. Every spend check uses the available balance, never the raw one.
  • A hold has an expiry, and something sweeps up the expired ones, because a hold that outlives its booking is money the agent cannot use and will call you about.
  • On success, the hold is released and a debit is written in the same transaction. Never one without the other.

This is the single most common thing missing from home-built systems, and the failure mode — an agent whose balance is quietly short by the value of an abandoned booking — is invisible until they complain.

Prepaid or credit limit?

Two models, and the difference is who carries the risk.

Prepaid float. The agent tops up before they book. You hold their money; they draw it down. No credit risk, and no collections. The cost is friction: a new agent has to send money before they can do anything, and an agent who runs out at 11pm on a Friday is blocked until Monday.

Credit limit. The agent books up to a ceiling and settles later. Easier to sell, and it matches how a lot of the trade already works. It also means you are lending, with everything that implies: limits per agent, terms, ageing, and an awkward conversation.

Most operators start prepaid because it is safe and simple, then extend limits to a handful of agents they know well. That progression is sensible. The thing to avoid is informal credit — an agent who is effectively on terms because nobody enforced the balance check.

Handling the ordinary problems

Top-ups by bank transfer. Most B2B money arrives as a wire, which means a human confirms it. Make that a two-step flow: the agent declares the transfer with a reference, somebody matches it against the bank, and only then is it credited. The declaration is not the money.

Cancellations. What comes back is decided by the cancellation policy that applied at booking time — which means the policy has to be stored on the booking, not looked up from the product today. Any non-refundable element should be recorded explicitly as its own movement, so the agent can see exactly what was returned and what was not.

Currency. One currency per agency, fixed at setup. Changing it later means re-expressing history at rates that may no longer exist. If it has to change, it should only be possible while the ledger is genuinely empty.

Negative balances. Decide deliberately whether a balance may go below zero, and for what. A common answer: a booking may not, but a fee charged after the fact may — because refusing to record a fee does not make it disappear, it just makes your books wrong.

Proving it is right

The last piece is the one that lets you sleep: a job that runs on a schedule, replays every ledger row from zero, and compares its result to the stored balance.

If they ever differ, that is not a bug to triage next sprint. It is the highest-priority thing in the business, because everything downstream — invoices, statements, the agent's trust — is derived from a number you can no longer vouch for.

Run it nightly. Make it shout.