The Wonderful World of Billing

Pomelo runs card programs for banks and fintechs in Latin America, and bills them for every product they use. By the time it had nearly 100 clients in five countries, nobody could say for sure what to charge each one, and $6M in bills sat unpaid.

We spent 2023 and 2024 fixing that with a tech lead, a UX lead, five developers, two designers and no product manager, and this is the map we used. The name pokes fun at the mess we found, although honestly we loved cleaning it up.

Once upon a spreadsheet

Finance read every contract PDF and typed the numbers into a spreadsheet. Invoices went out by hand, four to seven per client, and one once reached the wrong client. Payments lived in a single file called the Global Tracker.

Every deal was different: up to eleven billable concepts for cards alone, each priced its own way, under four tax regimes.

A map in the dark

Nobody could see the whole system, so we drew it. Read it left to right, from signed contract to cash in the bank. What clients see sits on top, finance's work below, and arrows show what feeds what.

The labels stay hidden for now, which is roughly how the system looked to us. They light up stage by stage.

Concept calculation

Know what to bill

Billing is price times quantity, and we had neither: prices sat in contract PDFs no system could read, and usage was supposed to come from a data lake nobody had built yet.

So we set one rule: each contract is entered once, and invoices, reminders and balances come from it.

Concept calculation

A formula for every contract

Each deal was its own formula: a cut of approved transactions, a fee per printed card, tiers, minimums, other currencies. Hard-coding them meant a deploy per contract, so we argued a lot about how to model them as data.

We landed on one record per price rule (what it bills, what it applies to, how it's priced and when), so the calculator only has to run the rules. Today I'd also version them with the contract, so every invoice line can point to the rule behind it.

Invoicing

Start where every invoice passes

Calculating invoices had to wait for other teams to digitise the contracts. So we started with the step every invoice shares: sending it from one place. Brinta handled legal invoicing in each country.

Before drawing a single screen, I wrote down the six states an invoice can be in (see the note). A ✓ marks what shipped.

Invoicing

Moving the source of truth

FinOps ran billing out of their spreadsheets and trusted them more than any database. Fair enough: those sheets got the invoices out. Getting them to trust a new source of truth was the hard part.

Billing settings, billing requests and automatic invoicing replaced their sheets, one at a time. Every month we sat with them to generate the invoices together, and sometimes we sent bills ourselves. I ordered the roadmap so each release took work off their plate before asking anything new.

Collections

Then, the money

Clients report payments and finance confirms them. The system tracks balances, chases late payers and, as a last resort, cuts service.

We ran three A/B tests here. A blunt reminder got 20% more bills paid on time. Hiding the amount in the email lifted traffic 8%, and I argued against shipping it because it worked by holding information back.

Two apps, one set of data

Clients already had a dashboard. Finance had nothing, so we built them a backoffice, and other teams soon ran their own operations on it.

Auth0 organizations kept each client inside its own data through the `org_id` claim in their token. Roles and scopes, checked at the API, set what each person could do. You're looking at the client view, and switching to Finance shows theirs.

A plan people could hold us to

Every step had a status. NOW was in progress, NEXT came after, LATER waited in the backlog and ALWAYS ON never stopped. A ✓ meant done.

Nobody at Pomelo had seen the whole flow in one picture before. The team knew what came next without asking me, and the rest of the company could see what we were doing and why.

The finale

Measurably simpler

What changed once finance swapped spreadsheets and email for one product.

  • Invoices delivered on time: 22% → 95%
  • Error rate per invoice: 6% → 2%
  • External billing teams: 4 → 0
  • Unpaid bills (USD): $6M → $3M

Next ride

The same map, with agents

Billing at Pomelo meant moving a finance team off manual pulls and email approvals. Here's how I'd read the same map today, with agents in it.

Agents take the routine steps. Anything that moves money or touches the ledger gets drafted by an agent and approved by a person. Commercial and high-stakes calls stay with people. This layer is my own proposal, since Pomelo never ran it this way.

End of the ride

Explore freely

Drag or swipe to move, pinch or ctrl + scroll to zoom, Tab to jump between steps.

Map by Gonzalo Bilune and Fede Kotek at Pomelo, 2023-24.