Back to blog

Product thinking

Billing Orchestration

·8 min read

Umair Malik

By Umair Malik ·Principal Software Engineer at Techfoot

Umair leads engineering on Billspree—billing and AR for recurring-service businesses across utilities, submetering, telecom, and subscriptions.

TL;DR — A bill does not make itself. Something has to decide who falls due today, what arrives as one bill and what arrives as three, gather everything the bill depends on — readings, balances, sitting credit — and decide at what point the bill is locked and can no longer be edited. Bills come in two opposite shapes, one subscription told exhaustively or many told briefly, and each demands something different. That work is the billing engine.

A quick note on words. A billing system is the whole application: customers and contracts, pricing, invoicing, receivables, collections, reporting. A billing engine is one component inside it — and it is the component that drives the others.

It calculates nothing itself. What it does is coordinate. It works out who falls due today. It brings in the pricing engine — the subject of the last article — to produce the charges for them. It gathers everything else the bill depends on. And it assembles what comes back — deciding which bill each charge belongs on, and at what point that bill is locked and can no longer be edited.

The Billing Orchestra

Suppose every rate is settled. Every tariff correct, every tier right, every tax rule pointing at the charge it is meant to read. A thousand customers, each enrolled on exactly the plan they should be on.

You still do not have a single bill.

Something has to decide which customers are due today and which are not. Something has to decide that these four charges arrive as one bill and those two arrive as two. Something has to find out how much electricity one flat actually used, and what to do about the one next door whose meter nobody could read this month. And when all of that is settled, something has to make it financially real — locked, numbered, written to the books.

All of that is billing.

An orchestra is a room full of players who can each make sound on their own. The conductor adds no notes. What the conductor decides is when each one comes in, and how what they play combines into a single piece.

Billing works the same way, and the comparison is more literal than it sounds. Time passes whether or not you bill. Meters accrue whether or not you bill. A pricing engine can compute a charge the moment you ask it to. Every player is already capable of sound. Billing is the decision about when they play together, and what the result adds up to.

Five players sit in that room.

The clock

Time itself. Without it nothing ever bills. An arrangement can say monthly, on the 15th for years and nothing happens; it is the 15th actually arriving that turns a standing arrangement into an event.

Subscriptions

The billable units, and what each one is enrolled on. A subscription is the smallest thing that can be billed: one service, one set of rates, one customer. It is not the same as a customer, and it is not the same as a bill — a point that causes more confusion than any other in this domain.

Usage

What was actually consumed this period. For some businesses this arrives on its own, as events streaming in from a product. For others it has to be gone and collected: meters read, readings compared against last month’s, gaps filled where a reading could not be taken.

The pricing engine

Rates and usage in, charges out. This was the whole subject of the last article, and here it is one player among five — something the billing engine calls on, per subscription, when it needs the numbers for a period.

The customer ledger

A separate system again, holding what is already owed and what is already held — last cycle’s unpaid balance, and the credit sitting on an account from an overpayment. The billing engine asks it for both while assembling a bill, the same way it asks the pricing engine for charges. It does not keep those balances itself. And when a bill is finally locked, it tells the customer ledger, which posts its own transactions from there.

Those five are what a billing engine has to work with. What it does with them is the rest of this piece.

What it draws on
ClockwhenSubscriptionswhat is billableUsagewhat was consumedPricing enginethe numbersCustomer ledgerbalances and credit
The billing engine
Calculates nothing. Decides six things, in order.
Who is dueWhat groupsinto one billWhich datesWhat to bill forHow totals assembleWhen it commits
A bill
Locked, numbered, on the books
Five players, six decisions, one bill. The engine adds no numbers of its own — it decides when each player comes in, and what the result adds up to.

The Bill, and What It Has to Carry

Abstractions are easy to agree with. Here is what those five players have to produce.

Bills come in two shapes, and they are close to opposites.

One subscription, told exhaustively

A retail energy provider sells one thing: electricity. A customer has one subscription. The bill still looks like this:

Residential Electricity — one subscription
Consumption — 1,400 kWhtiered$207.00
Standing charge$12.00
Capacity charge$18.50
Fuel surcharge$6.20
Distribution levy$4.10
State tax6% of consumption + surcharge$12.79
Local taxflat$2.50

Total Due$263.09

One subscription, seven charge components — tiers inside a rate, a tax that reads two other charges and ignores the rest, a levy that applies only in one jurisdiction. Every figure on this bill came from that single subscription.

Nothing here needs summing across anything. It needs depth inside a single thing.

Many subscriptions, told briefly

A cloud provider sells a catalogue of services, and a customer subscribes to as many as they need. Here is one month, complete:

Cloud Account — six subscriptions, one bill
SubscriptionRateQtyAmount
Compute$0.42 / hr720 hr$302.40
Object storage$0.023 / GB2,400 GB$55.20
Bandwidth$0.09 / GB1,850 GB$166.50
Managed database$260.001$260.00
Load balancer$18.001$18.00
Support plan$99.001$99.00
Subtotal$901.10
Tax — 8%$72.09
Total Due$973.19

Six subscriptions, one bill. Each one contributes far less than the electricity subscription did — but there are six of them, and the bill has to hold all six at once.

And they are not the same kind of thing. Compute, storage and bandwidth are metered — a real rate, a real quantity, and an amount that is the product of the two. The managed database, the load balancer and the support plan are flat: an amount, and nothing to multiply it by. Nobody consumed one load balancer.

So one bill is carrying two different kinds of subscription at the same time — and it still has to produce a single total across all of them.

And a third thing that looks like billing but isn’t

An organisation has forty sites, all on the same service. Head office wants to see the whole picture.

There are two honest ways to read that. If head office is the one being billed, this is simply a bill with forty subscriptions on it — the second shape above, nothing new. If each site is billed separately, because each has its own budget and its own payable, then forty bills genuinely exist, and what head office wants is a view across them.

That second case is not a billing problem. Forty bills were correctly produced for forty entities. Wanting to see them together is reporting — and the customer hierarchy is what makes it possible, by recording that those forty entities sit under one parent.

The industry usually markets this as “consolidated billing,” which muddles two different things. A consolidated invoice is one document the customer pays from. A consolidated statement is a summary of documents that already exist, usually with aging attached, and nobody pays from it. Only the first is billing.

Two shapes, then, and a third that only looks like one. What a system has to do to produce any of them is the next question.

What This Demands From a System

Strip away implementation and the same six decisions appear in every billing system, whatever it bills for.

1 — Who is due

Out of a thousand customers, which ones bill today? The clock produces dates; something has to turn a date into a cohort, and leave everyone else alone.

2 — What becomes one bill

A customer with electricity, water and gas might want one bill or three. The charges are identical either way. The grouping is a separate decision, and it belongs to the customer relationship rather than to the pricing.

3 — Which dates are being billed

A billing arrangement repeats — every month, on a set day. A run needs more than that: the actual dates this one covers, and the date payment falls due. The 1st to the 31st, payable on the 14th of next month.

Every reading, adjustment and charge has to belong to exactly one of those spans. Belong to none and it never gets billed; belong to two and it gets billed twice.

4 — What there is to bill for

A meter reports 15,000 kWh. That figure is useless on its own — what matters is 15,000 minus last month’s 14,200, so 800. Something has to hold the previous reading, work out the difference, and hand a billable quantity to the pricing engine. When the reading never arrives it has to estimate one and mark the bill as estimated; when a meter was replaced mid-cycle it has to reconcile the two so the reset does not produce negative consumption. Events behave the same way — raw calls or records in, one billable quantity out.

The customer’s existing position has to be established too. This period’s charges are not what they owe: they may not have paid last month, or may be holding a credit from an overpayment. Both have to be read and applied, so the figure on the bill is a position rather than a month’s arithmetic.

5 — How the totals assemble

Look again at the two bills. The electricity one carries consumption, a standing charge, capacity, a surcharge, a levy and two taxes. The cloud one carries compute, storage, bandwidth, a database, a load balancer and a support plan. Now suppose one customer has both and wants one bill.

What gets added together? Not consumption and compute — different things, different units, different meaning. There is no pair of lines across those two lists that belongs in a sum.

There is only one way out. Something has to exist on every subscription regardless of what it sells: a subtotal, a tax line, somewhere a late charge can land, a net total. If those are guaranteed everywhere there is something to add. Everything specific to electricity stays on the electricity lines, and the total is built from the handful of things both sides are certain to have — which means a combined total can only ever be as detailed as what the subscriptions have in common.

6 — When it can no longer be edited

At some point the number ceases to be an opinion. Values lock, the bill takes a number, and the customer ledger is told it may now post against it. Before that moment a bill can be corrected freely. After it, corrections need their own paper trail.

And these six do not happen independently. Each depends on the answer before it: you cannot pick a cohort without a date, cannot assemble without knowing what grouped together, cannot commit without assembling. Something has to drive them in order and hold a run together from the first decision to the last.

That is what makes this orchestration rather than a list. Not six things that happen to follow one another, but a conductor that runs them.

How Billspree’s Billing Engine Helps

Billspree makes each of those decisions an object you can point at.

A cycle and a billing day together make a Billing Period. Monthly on the 15th. Weekly on a Tuesday. Neither half means anything alone — a cycle without a day never lands, and a day without a cycle never repeats. It is attached to a plan, and from there it is inherited: every subscription created against that plan carries it, so does the billing account that subscription sits in, and so does the group that account belongs to. The period is decided once and never restated.

What becomes one bill is a Billing Account. One account produces one bill. A customer who wants three separate bills does not need three customer records — they need three billing accounts. This is the decision that most often surprises people, because it sounds like a formatting preference and is actually a structural one.

Who is due is a Billing Group. A Billing Group is a set of billing accounts that run together, and how they are grouped is decided in advance, by the operator. One property owner’s thousand tenants in one group. Two owners in one group, if that suits how the billing team works.

One rule holds it together: every account in a group shares the same Billing Period. Because of that, the scheduler never has to work out which accounts belong together — the group already answered that. It only has to work out when.

The dates are a Bill Term. When a group’s billing day arrives, the orchestrator opens a term over it automatically. The term carries the start, end and due dates, and every reading, adjustment, draft and posted bill for that cycle belongs to it.

And a term has two sections, which is the assembly problem made concrete. The subscription section holds every subscription in the term’s billing accounts, each rated against its own plan; these become the bill’s line items. The summary section holds those subscriptions’ values, summed — then calculated by the billing account’s own pricing module. That is how a late payment charge applies once, to a whole outstanding balance, rather than separately to each subscription and then added up.

Notice that the pricing engine is brought in twice, for two different purposes: once per subscription to produce the line items, once at account level to produce the totals. Same player, two entrances, and the conductor decides both.

Billing Period
A cycle and a billing day — monthly on the 15th
Subscriptionthe billable unitBilling Accountone account, one billBilling Groupwhat runs together
Bill Term
Subscription section
Every subscription rated on its own plan → the bill's line items
Summary section
Those values summed, then calculated by the billing account's own pricing module → the bill's totals
A bill
Locked — and the customer ledger is told to post it
One period decided at the top, inherited all the way down — which is why the orchestrator only ever has to work out when, never who belongs with whom.

What the summary can do depends entirely on whether the subscriptions share a vocabulary. If every subscription in an account is on the same plan, they carry the same components and all of them sum through — the summary can work with the full set. If they sit on different plans, only the components guaranteed to exist everywhere can be summed: subtotal, late payment, net total, and the tax lines. Those are compulsory on every pricing structure in Billspree, and not for tidiness. They are the shared vocabulary, and without them a consolidated bill would not be possible at all.

Collecting the inputs is a stage, not an assumption. Readings upload, previous readings are pulled forward, deltas computed, missing readings estimated by a configurable method, and meters that were physically replaced mid-cycle reconciled so a replacement never produces negative consumption. Arrears from prior cycles and any credit sitting on the account are both read from the customer ledger and applied to the drafts before anything is issued.

And commitment is two steps. Processing calculates the drafts, and nothing is final — a term can be reviewed, corrected and re-processed as often as it needs. Posting is the moment values lock and the customer ledger is told the bill is final, so it can write its own entries. Only then is the bill a financial record. Publishing, separately, is what makes it visible to the customer.

One run, start to finish

The 15th arrives. The orchestrator opens a term over every billing group falling due that day, pulls in their billing accounts, and their subscriptions land inside it.

Readings upload. Previous readings are pulled forward and the deltas worked out; where a reading never came, an estimate stands in and the bill is marked. For each subscription the engine calls the pricing engine and gets charges back. It asks the customer ledger what each account already owes and what credit it is holding, and applies both.

The drafts sit there while the checks run — consumption against last month, readings that came back zero or negative, anything that moved further than it should have. Someone looks at what failed, corrects it, and the term is processed again.

Then it posts. Values lock, the bills take their numbers, and the customer ledger is told it may write its entries.

Five players, none of which knew about the others. One thing deciding when each of them came in.

None of this is the part anyone demonstrates. A demo shows rates and formulas, because that is where the business decisions are visible. The conductor never gets a slide.

But something has to decide who plays, when, alongside whom — working from facts it often has to go and collect first, and deciding, finally, when the number stops being an opinion. That is at least half the work of getting a bill out of a door.

Full detail on the objects described here is in the docs: Billing Period, Billing Group, Billing Account, Bill Term and Bill Run.