Back to blog

Product thinking

One Bill, Fifty Bikes: One Subscription, One Bill (Until It Wasn't)

·4 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 — The real question was never B2C vs B2B. It was simpler: does one subscription get its own bill, or do many subscriptions share one bill? That has nothing to do with who the customer is — think of how AWS bills you for many services on one invoice, and that does not make you a business. We only had to solve this because one client's fleet buyers asked for it. The billing account is what answers the question.

The assumption that worked

Billspree started as a billing app we built for a large utility. While building it, we saw the same problem elsewhere: utilities and other recurring-service businesses needed something that off-the-shelf tools did not cover well. So we turned that work into a product.

The first requirement was simple: one bill for one meter on one consumer. We designed around B2C and one main rule — one bill per subscription. (The utility only had consumers and meters. A meter is too narrow for a general product, so we used subscription as the billable unit instead. That was the right call.) This matched how most utility and rental billing works.

In Billspree, a customer can have one or more subscriptions, and each subscription gets its own bill. Two subscriptions means two bills. That worked fine for utilities: one meter, one bill; two meters, two bills.

Then a customer showed up that this model could not handle.

A fleet that needed one bill

This customer sells EV bikes and bills riders for the power those bikes use. Riders swap empty batteries for charged ones, and also pay per kilometer for battery use. So each bike has two usage types to bill: swaps and kilometers. Billing is monthly, in arrears — at month-end, each bike gets a bill for what it used.

They use Billspree for their customers too: both B2C and B2B. Here we mean that in a narrow sense — how they bill individuals versus fleet buyers — not every difference between consumer and enterprise software (we are not talking about CPQ, contract negotiation, or other B2B-only workflows).

B2C worked. Each bike was a subscription under a rider. One bike, one bill. Two bikes, two bills.

B2B did not. Fleet buyers needed one bill for all fifty bikes. In Billspree, those bikes were fifty subscriptions under one customer — so we generated fifty bills. That was the problem.

When batches weren't enough

We needed a quick fix. The fastest option: put the bikes in a batch, assign that batch to the B2B customer, and bill the batch. We already used batches in bill runs to group subscriptions. We extended that so a customer could own a batch and get one bill for the whole group. That was our first way to bill multiple subscriptions on one invoice.

But it broke accounts receivable. Before this, every subscription had its own AR account — bills and arrears lived there. With batches, B2B AR moved to the batch, and the subscriptions under it had none. Some subscriptions had accounts, some did not. Some batches had accounts, some did not. Same objects, different rules depending on customer type. It produced the right bills, but the data model was inconsistent.

We could generate correct bills, but the AR split and the stretched use of batches were not something we wanted long term. It did make one thing clear: this is the same pattern as AWS or DigitalOcean — many services, one bill, each service as a line item.

At that point it was easy to reach for a neat summary: if we can bill many subscriptions on one invoice, then B2C is just B2B with N = 1. That slogan sounds right. But it is not — it still makes B2C and B2B the frame, and that frame was never the real one. It is where we nearly stopped thinking.

We needed a proper model that could:

  • Let a customer get more than one bill
  • Put more than one subscription on a single bill
  • Keep AR clean underneath

The billing account

We did not jump from the batch workaround to the right design. We spent a while trying to force our existing objects to cover this.

We tried subscription hierarchies: one parent subscription for the B2B customer, child subscriptions under it, bill the parent. We tried subscription groups: a new grouping that could hold receivables and act like a subscription, because subscriptions already had accounts. Both looked fine on a whiteboard. Both fell apart in practice.

The common failure: we kept putting the bill and the receivable on something that was still “subscription-shaped.” The thing that receives a bill is not a subscription, and it is not a group of subscriptions pretending to be one. It needed its own concept.

That concept is the billing account.

How it works: a customer can have one or more billing accounts. Subscriptions attach to a billing account, not directly to the customer. The billing account gets the bill — not the subscription, not the customer. Subscriptions under that account show up as line items on that bill. AR also sits on the billing account: each one has its own balance and transaction history, so collections and reconciliation stay consistent.

For the EV company, the fleet became: one customer, one billing account, fifty subscriptions — one monthly bill, fifty line items, one receivable. Batches stayed for bill runs only. They no longer stood in for the customer's bill.

With that, B2C vs B2B stopped being two separate problems — for billing, at least.

Neither one was the general case

A B2C customer is a customer with one billing account and one subscription. One bill.

A B2B customer is a customer with one billing account and fifty subscriptions (one bill), or several billing accounts — for example one per site — each with its own bill.

Same model. Same bill run. Same AR. The only difference between one rider and a fifty-bike fleet is how many subscriptions sit under a billing account.

So is B2C a special case of B2B? That question assumes B2C and B2B were ever the real split. They were not. The real question is how many subscriptions sit under one bill, and that has nothing to do with whether the customer is a person or a company. A single customer can want many subscriptions on one bill too — think of how AWS bills one developer for many services on one invoice. That does not make the developer a business account. Our client needed this on the B2B side, because that is where their fleet buyers asked for it. If a single rider had asked for the same thing, we would have built the same billing account for them.

Neither B2C nor B2B was ever the split that mattered. The billing account is. One customer, one or more billing accounts, each holding however many subscriptions belong on one bill.

We did not set out to design for both. We set out to bill an EV bike fleet — and that forced the right model.

More detail in the billing account docs. If you are dealing with a similar billing problem, get in touch.