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 — Real bills are rarely one line. Submetering and RUBS bill the same utility completely differently. Tiered rates, taxes that read different charges, and late fees that fire only sometimes are all normal, not edge cases. A pricing engine needs five specific capabilities to model this correctly — and Billspree’s Pricing Template and Pricing Module architecture is built to satisfy exactly them.
A quick note on words. In a billing system, “pricing” or “rating” means something narrower than it might elsewhere: not deciding what something should cost — that decision, based on production cost, margin, or the market, already happened somewhere else — but taking a rate that is already set, and a customer’s actual usage, and calculating the number they actually owe.
The Pricing Ecosystem
A bill is not always one simple line — a usage, a rate, a tax, and done. Here is a more realistic one:
Commercial Account — Electricity + Water
Electricity Usagemetered1,400 kWh
Electricity Chargetiered rate$207.00
Water Usagemetered8,000 gal
Water Chargeflat rate$48.00
State Tax6% of electricity$12.42
Local Tax3% of water$1.44
Total Taxstate + local$13.86
Total Due$268.86
Look at everything on it. Two different things are measured — electricity and water — each with its own usage and its own rate. The electricity rate is not even one number. It is tiered, priced in blocks. Tax is not one line either. A state tax applies to the electricity charge. A separate local tax applies to the water charge, on its own base. The two are added into a single tax total, so the bottom line means something. And this is a quiet month. Some months there is also a late fee, once a previous bill goes unpaid past its grace period.
None of this is unusual. Nobody designed a bill to look this way on purpose. This is just what billing looks like once it reflects how a real service, in a real place, actually gets used, priced, and taxed.
Solving it, though, is not one problem. The industry that deals with this kind of billing splits it into two separate decisions: a strategy for what to base a customer’s bill on, and then the actual mechanism that turns that into numbers. The first is the billing method. The second, whatever form it takes, is the pricing model.
Billing Methods
A billing method is a strategy, not a number. It decides what a business will use as the basis for a customer’s bill, before any actual number gets generated. There is more than one real billing method. Submetering’s strategy is to measure usage directly, with a real meter, per customer. RUBS’s strategy is to allocate a shared, already-fixed cost across several customers, using factors like square footage or occupancy. Flat Fee’s strategy is to charge every customer the same amount, regardless of usage. These are not three versions of the same idea. They set up entirely different bases for a pricing model to work from.
Pricing Models
A pricing model is where the actual number gets generated, inside whatever basis the billing method set up. Under Submetering, that can be a flat rate multiplied by usage, or a graduated rate that changes as usage crosses a threshold. Under RUBS, the pricing model is what this piece will call a Ratio Pricing Model: a ratio, applied to the master bill. Under Flat Fee, the pricing model is the simplest kind there is, a constant, the same number every cycle. Different billing methods call for different kinds of pricing models. Every one of them still needs one.
Both are real decisions, and every business makes both, whether or not it thinks about them in those terms. The billing method sets the frame. The pricing model, however simple or complex, is what actually fills a number into it.
The Moving Parts
Within whatever a pricing model actually produces, the same small cast keeps showing up. No two businesses put it together the same way, but the pieces repeat: Usage — whatever actually gets measured. A rate — sometimes one number, sometimes a slab. The charges a business is actually owed for the cycle. Tax — sometimes more than one, each reading whatever it is meant to tax. A discount, when there is one to give — loyalty, volume, negotiated. A late fee, active only when it needs to be. A total — the one number that adds it all up into something a customer can read. This list is not closed. A business can always need something not on this list. A real bill needs room to add more.
That same cast does not produce the same numbers for every customer. The same service — electricity, say — can be billed under one rate for a residential account and a different rate for a commercial account. Same pieces, same bill structure, different numbers, because the customer is different. Tax can work the same way. The examples below show this directly: the residential account’s tax is one flat percentage, but the commercial account’s tax is two separate taxes, calculated two different ways. Who is being billed is not itself a line on the bill. But it decides which version of every other line applies.
From Billing Methods to Pricing Formulas
Two of those three billing methods are worth seeing with real numbers: Submetering and RUBS, both used for the exact same kind of residential utility account.
Submetering
Submetering measures a unit’s usage directly, with a real meter, per customer. Once that number exists, more than one real pricing formula can turn it into a charge: a flat rate, one number multiplied by usage, or a tiered rate, where the rate itself changes as usage crosses a threshold. Here is what that looks like on an actual invoice, starting with the flat case:
Residential Electric — Submetered Unit
Usagemetered620 kWh
Rateper unit$0.14 / kWh
Chargeusage × rate$86.80
Discountloyalty−$5.00
Tax6%$4.91
Total$86.71
A real meter sits on this specific unit. It is not a master meter shared across the whole property. Look at where each number comes from. One number stands apart: usage. Nobody set “620 kWh” in advance. It is just what this meter reported that month. Everything else on that line — the rate, the charge, the discount, the tax — is something the plan has to produce on its own, no matter what usage shows up.
Submetering ranges from that simple case to something much more layered. The utility did not change — the customer did. Here is a residential account and a commercial account, on the same service, billed under two different rates:
Plan A — Submetered Residential
Usagemetered620 kWh
Rateflat$0.14 / kWh
Chargeusage × rate$86.80
Discountloyalty−$5.00
Tax6%$4.91
Total$86.71
Plan B — Commercial Electric
Usagemetered1,400 kWh
Ratetieredrule-based
Chargeusage × rate rule$207.00
Surchargegrid infra, 2% of Tier 1$1.20
State Tax6% of charge+surcharge$12.49
Local Taxflat$2.50
Total$223.19
Plan B’s Rate row is a single component, but that one component holds a rule with three conditions. Here is what that rule actually contains:
Plan B — Rate Rule (3 conditions, first match wins)
Both plans have a Rate component. But the two Rates work in completely different ways. Plan A’s rate is a fixed value: one number, filled into one component. Plan B’s rate is a rule. It is still one component, but it has three conditions, checked in order, first match wins. Usage up to 500 kWh matches the first condition. Usage between 500 and 1,000 kWh matches the second. Anything past that matches the third. What changes between conditions is not just the rate, it is the formula: each one after the first carries the earlier tiers’ cost forward as a fixed amount, then adds the current tier’s rate applied only to the usage inside that tier. That is how one component, with one rule, produces a genuinely graduated result: $60.00 for the first 500 kWh, plus $75.00 for the next 500, plus 400 kWh at $0.18 for the rest, totaling $207.00, without ever billing the whole 1,400 kWh at the top tier’s rate. The tiers live inside the rule, not as three separate line items. This is what “rule-based” gives you: one component can hold something as layered as a three-tier slab, without needing a separate component for each tier. A rule can also look beyond its own usage or its own conditions. It can reach into other components. Plan B’s State Tax is not computed from usage at all. It takes the Charge, adds the Surcharge, and applies 6% to the sum. Local Tax, right below it, ignores all of that. It is not a percentage of anything — just a flat $2.50. Three components. Three different formulas. Three different things each one actually looks at. State Tax’s rule, spelled out:
Plan B — State Tax Rule
State Tax(Charge + Surcharge) × 6%
RUBS
A RUBS unit has no meter at all. There is nothing to multiply a rate against. What it has instead is a share: a ratio applied against the property’s master bill. That ratio itself can be worked out more than one way, the same way Submetering had more than one real rate to choose from. It can be based on square footage alone, on occupant count alone, or on a blend of both. Our example uses a blended ratio, 50% square footage and 50% occupant count. The master bill itself is not set once, like a rate card value. It has to be entered fresh every cycle, because the real utility cost behind it changes every cycle too.
Unit 204 — RUBS Allocation
Square Footageof property900 / 18,000 sqft
Occupantsof property3 / 60
Ratioblended5.0%
Master Billthis cycle$3,400.00
Unit Share$170.00
Unit 112 — RUBS Allocation
Square Footageof property600 / 18,000 sqft
Occupantsof property1 / 60
Ratioblended2.5%
Master Billthis cycle$3,400.00
Unit Share$85.00
Both units use the same blended formula, just with different inputs:
Same building. Same master bill. The same $3,400.00 number feeds both units. But the two results are completely different. What is actually fixed here is not the bill — it is each unit’s ratio. Unit 204 is bigger and has more occupants, so it absorbs more of a cost that neither unit actually metered. That is the whole mechanic: no usage anywhere in the chain, just each unit’s ratio applied to a shared master bill.
The choice of formula is not neutral, either. Go back to Unit 112 and swap the blended ratio for one of the other two real options, same unit, same master bill:
Unit 112 — Same Inputs, Three Possible Formulas
Square Footage Only600 / 18,000 sqft$113.33
Occupant Count Only1 / 60 occupants$56.67
Blendedour example, 50/50$85.00
Same unit, same master bill, three genuinely different numbers. Which formula a property picks is a real decision, not a technicality, the same way choosing flat over tiered was a real decision for Submetering.
What This Complexity Demands From a System
Everything above is really one question: what does a pricing engine actually need to be able to do? A pricing engine, generically, is the part of a billing system responsible for turning usage, and everything else a bill depends on, into the actual charges a customer owes. Not invoicing. Not collecting payment. Just the calculation itself, done correctly, for every account, every cycle. Five requirements make that possible. Each one is already proven necessary by an example already on this page.
Add components on demand
Start with the least glamorous requirement. The system cannot assume it already knows every piece a bill will ever need. The Pricing Ecosystem made this point: that list — usage, rate, charges, tax, discount, total — was left open on purpose. A business needs to define a new charge, tax, or fee the day it needs one, without waiting for someone to ship a feature for it.
Let a component hold logic, not just a value
A component that already exists cannot be locked into one shape either. It needs to hold real logic, not just a stored value — and that logic is often conditional: different formulas for different situations. Rate proves this. In the examples above, the same slot held one flat number for the submetered residential unit, and a three-condition rule for the commercial one — usage up to 500 kWh, the next 500, everything past that, each with its own formula. Being called “Rate” commits it to neither shape. The business makes that call each time.
Let components reference each other, and produce nothing without error
The pieces built from those numbers are not independent. A tax on one specific charge has to read that charge directly, not the whole bill — the way a real state tax or franchise fee works on a utility statement. Other pieces matter only sometimes. A late fee gets checked every cycle but usually has nothing to charge, and that should count as a normal zero, not a failure to handle. Here is the same submetered residential account on two different cycles:
Late Fee — Most Cycles
Previous Balanceunpaid$0.00
Late Fee$0.00
Late Fee — Bill Went Unpaid
Previous Balanceunpaid$86.71
Late Fee$1.30
Same account, same Late Fee component, same condition checked every cycle: is there a previous balance still unpaid past the grace period. Most cycles the answer is no, and the component correctly produces zero. On the one cycle where the answer is yes, the exact same component produces a real charge, with no special handling for either case.
Vary logic by customer type
Pricing does not only respond to usage. It also responds to who the customer is. The submetered examples above already show this. Residential and Commercial are not different services. They are the same service, billed differently, because the customer is different. That difference can live in one of two places. It can sit inside a single component, as a condition. There is only one Rate component. Its rule has a condition — is this account residential or commercial — and that condition decides which formula’s output the component uses. This is the same mechanic as a tiered rate: one component, one rule, a condition decides the output. Or the difference can sit across two separate plans. Each plan has its own Rate, but they share everything else — the same Usage tracking, the same Tax logic, the same Late Fee behavior. They only diverge where they actually need to. This second option is where reuse stops being optional. Without a way to share the parts that are genuinely identical, adding a second customer type to one service means duplicating the whole plan just to change one component.
RUBS makes a related point even more directly. Every unit runs the exact same ratio formula. There is no branching, no condition to check, no residential-versus-commercial to decide between. What varies is the input: this unit’s own square footage, this unit’s own occupant count, fed in as data specific to that one customer. The formula does not just apply differently depending on who the customer is. It depends on customer-specific numbers just to run at all.
Share select logic across separate plans
Say a business decides against putting customer type inside one component’s condition. Residential and commercial diverge in enough places that two separate plans are just easier to manage. That is a fair choice. But it cannot cost you duplicated logic where the two plans are genuinely identical. If both plans owe the exact same tax, calculated the exact same way, that logic needs to live in one place. A pricing module can hold just that one piece. Both plans point at it, instead of each writing its own copy. Change the tax rule once, in that one module, and both plans pick up the change on their next cycle. Nobody has to hand-edit two plans, and neither plan quietly falls out of sync with the other.
None of this is exotic engineering. It is just what is actually required to model the examples on this page correctly, for as long as they need to keep being billed.
How Billspree’s Pricing Engine Helps
Every requirement above is real. Billspree’s pricing engine — the Pricing Template and Pricing Module system underneath every plan — is built to satisfy all of them, not as five unrelated features, but as one mechanism applied consistently. Here is the shape of it, then each requirement mapped to what actually does the work.
Pricing Template
Defines what components exist, and the order they calculate in
Rate→Charge→Taxreads Charge→Late Fee0 most cycles
↓
Pricing Modules — many of each kind, each filling part of the template
Rate Cards
Residential
Commercial
⋯
Charges Modules
Standard
Promo
⋯
Tax Modules
Region A
Region B
⋯
↓
Plan
Picks one Rate Card, one Charges Module, and one Tax Module — any combination, and the link is live: change a shared module once and every plan on it reprices
Many of each module, mixed and matched. Ten rate cards over one shared tax module make ten plans — not thirty copies.
Adding new components
In Billspree, a business defines its own bill structure on a Pricing Template. A Template holds up to 50 Values and Components, named and ordered however the business needs. Nothing is fixed in advance. A new charge, a new tax, or a new fee is just a new entry on the Template — not a support ticket.
Defining output logic
Whatever gets added does not have to commit to being a plain number or a formula up front. Every component on a Pricing Template carries a Calculation Type. It is either Manual, a value entered directly, or Calculated, governed by a rule: Conditions and a Billing Formula. This is the exact mechanic behind Rate holding one flat number for the residential plan and a three-tier formula for the commercial plan. Same kind of component, different Calculation Type, chosen per plan.
Components referencing each other, and resolving to nothing when they should
Once those numbers exist, a rule in one component can reference any earlier component, by its Order. A tax can read straight off a specific charge instead of the whole bill. Billspree calls this mechanic Component Chaining. A Calculated component with no matching rule, or nothing to trigger it, does not error. It resolves to zero and moves on. This is exactly what lets a late fee sit dormant most cycles, without anyone writing a special case for it.
Varying logic by customer type
Customer-driven variation has two legitimate homes here, matching the two options from before. It can live inside one component’s Conditions, checking a Subscription Property like customer type, and picking a formula accordingly. Or it can live across two separate Pricing Modules, built on the same Template — one for Residential, one for Commercial — each with its own Rate. Plan A and Plan B, from the examples above, are exactly this: two Pricing Modules, each with Plan marked so a customer can actually subscribe to them.
RUBS needs the same underlying mechanism for a different reason. Its ratio formula reads Subscription Properties too, but not to pick between formulas. Square footage and occupant count are customer-specific numbers the formula needs just to compute, not a condition deciding which formula runs.
Sharing select logic across separate plans
Sometimes two modules need to share something exactly, instead of duplicating it. That is what a Pricing Module built purely to be inherited from is for. A Tax Module holds just the tax rules. A Rate Card holds just the rate values. Neither is a complete plan on its own, and nobody subscribes to either one directly. Each exists only to be pointed at. Point both the Residential and Commercial modules at the same Tax Module. Update it once, and both modules pick up the change live, the next time each one bills. The two plans do not quietly drift apart because one got edited and the other didn’t.