Work snippet 18 / 30Recurring billing
Maintenance contract recurring billing in Xero, with indexation and a release schedule
How I'd approach recurring billing for a national maintenance operator with about 460 contracts, so every contract is billed once, on time and at the right price, and amounts billed in advance are held until earned.
Work snippet with example figures.
- Area
- Recurring billing
- Tools
- Xero · Contract register · Make
- Typical scope
- US$2,500–4,500
- Timeline
- About 5 weeks · 4 fixed milestones
01Context
A national maintenance operator with about 460 active service contracts across commercial buildings. Contracts are billed monthly, quarterly or annually in advance, and each renews on its own anniversary with a price review.
The systems in play
In the example the contract details sit in a mix of spreadsheets, email and a few repeating invoices in Xero. The finance lead wants every contract billed once, on time, at the right price, with the billed-in-advance amount held properly until it is earned.
| System | What it does for the business |
|---|---|
| Contract register | One record per contract and site: customer, term, price, billing frequency, index rule, PO requirement and status. An Airtable base in the example; a spreadsheet works too. |
| Xero | Invoices, customers, credit notes and the unearned revenue balance. |
| Invoice run | A scheduled flow that reads the register and creates draft invoices in Xero for review. Make in the example. |
| Finance lead | Reviews the exceptions list and approves each run. |
| Account managers | Own renewals, price reviews and customer notices. |
| Accountant | Agrees the treatment of amounts billed in advance and posts the release journal. |
02Problem
What the owner sees
- Contracts that go unbilled for a quarter before anyone notices
- Price reviews that are applied late, or never
- Customers who are billed after they have cancelled
- Revenue that is hard to explain because billed-in-advance amounts sit in sales
Recurring billing looks simple until a contract changes. A repeating template cannot know that a site was added last week, a price review took effect yesterday, or the customer is on hold. Each change is a chance to bill wrongly or not at all.
| Everyday situation | What goes wrong |
|---|---|
| Price review | The template is edited late, so months are billed at the old price |
| Site added or removed mid-term | Nobody adjusts the next invoice and no credit is raised |
| Customer on hold or in dispute | The template keeps sending invoices to a customer who should not receive them |
| PO number required | The invoice goes out without a PO and is rejected by the customer’s accounts team |
| Contract ended | The repeating invoice is never switched off |
| Billed in advance | The whole quarter or year appears as income in the month of billing |
03Approach
Four steps, in this order. Each one ends with a result that is checked.
- LookA read-only review of the contracts, the Xero repeating invoices and 12 months of invoices. Every active contract is matched to what was billed.
- Agree the rulesBilling frequency, indexation, pro-rata, holds, credits and the treatment of amounts billed in advance are written down.
- Build and connectThe register becomes the source of truth. The invoice run creates drafts in Xero from it. Repeating templates are retired.
- CheckEvery run is compared with the register before approval. A weekly list shows contracts with nothing billed and bills with no contract.
| Item | Example setting |
|---|---|
| Source of truth | The contract register. Nothing is billed that is not in it. |
| Billing date | The first day of the billing period, created as a draft on the 18th of the month before |
| Indexation | Applied on the anniversary using the index in the contract, with a stated cap and floor. The customer notice date is tracked. |
| Pro-rata | By days, on a 365-day year, for any site that starts or ends inside a billing period |
| On hold | Excluded from the run, listed on the exceptions list, and released by the account manager in writing |
| Purchase orders | Required for named customers. A draft without a PO is held, not sent. |
| Amounts billed in advance | Held in an unearned revenue account and released monthly from a schedule prepared from the register |
| Approval | The finance lead approves the run. The accountant approves the release journal. |
04What the setup includes
What the setup includes, and why each piece is there. The detail of how it is configured is agreed in the scoping call.
Show the setup, layer by layer
| Layer | What is set up and why |
|---|---|
| Contract register | Contracts, sites, price lines, index rules and status in one place, with a billing schedule generated for each contract. |
| Billing schedule | Each contract gets a dated list of invoices for the term, with the amount, the PO and the tax code for each site. |
| Xero items and accounts | One revenue item per service type, an unearned revenue account, and a naming rule for references. |
| Invoice run | A scheduled flow reads the schedule and creates draft invoices. It reads before it writes and skips any contract already billed for the period. |
| Exceptions list | Missing PO, customer on hold, unmatched contact, amount not equal to the schedule, and tax code not found. |
| Indexation and notices | A monthly list of contracts reaching their anniversary, the new price, the notice due date and a draft customer letter. |
| Unearned revenue schedule | A monthly release amount per invoice, ready for the accountant to post as a journal. |
| Retired repeating invoices | Each template is matched to a contract, then switched off after the first run is checked. |
How the data moves
- Contract in the register
- Billing schedule
- Draft invoices on the 18th
- Exceptions list
- Finance review and approval
- Invoice sent
- Monthly release schedule
05Edge cases
These are agreed with the finance lead and the account managers and tested on three past months.
| Situation | How it is handled |
|---|---|
| Indexation above the cap | The cap applies. The uncapped figure is shown in the register for the next review. |
| Customer given a price freeze | Index set to zero with an end date and a reason, visible on the schedule |
| Site added inside a period | A pro-rata line on the next invoice, calculated by days and shown on the exceptions list for approval |
| Contract ended inside a billed period | A credit note for the unexpired months, created as a draft and linked to the invoice |
| Customer on hold | Not billed. Listed every month until released or ended. |
| Different PO per site | One invoice per site where the customer requires it, with the PO in the reference |
| Customer paying by direct debit | The invoice is sent with the debit date and flagged in the register |
| Contract renewed with a new term | A new schedule starts on the day after the old one ends. The old one is closed, not edited. |
| Amount in the draft differs from the schedule | Held and shown with both figures, never sent |
| Run executed twice | Nothing is created twice because each invoice carries a unique key built from contract, site and period |
| Who changed what | Every register change carries a user and a date, and every invoice shows the schedule line it came from |
06Worked example
The tables below use eight contracts with example figures. They show the shape of the checks, not a client result.
| Contract | Billing | Value before | Index applied | Value after | Per invoice |
|---|---|---|---|---|---|
| C-1042 | Quarterly | 86,400.00 | 3.4% | 89,337.60 | 22,334.40 |
| C-1057 | Monthly | 31,200.00 | 3.4% | 32,260.80 | 2,688.40 |
| C-1063 | Quarterly | 148,000.00 | 3.0% | 152,440.00 | 38,110.00 |
| C-1078 | Annual | 18,600.00 | Price freeze | 18,600.00 | 18,600.00 |
| C-1091 | Monthly | 54,000.00 | 4.1% | 56,214.00 | 4,684.50 |
| C-1102 | Monthly | 262,800.00 | 3.4% | 271,735.20 | 22,644.60 |
| C-1115 | Quarterly | 42,000.00 | Capped at 5.0% | 44,100.00 | 11,025.00 |
| C-1120 | Annual | 96,000.00 | 3.4% | 99,264.00 | 99,264.00 |
| Total, 8 contracts | 739,000.00 | 763,951.60 |
| Month | Held at the start | Released to income | Held at the end |
|---|---|---|---|
| January | 22,334.40 | 7,444.80 | 14,889.60 |
| February | 14,889.60 | 7,444.80 | 7,444.80 |
| March | 7,444.80 | 7,444.80 | 0.00 |
| Change | Calculation | Amount |
|---|---|---|
| Site added on February 10 at 4,380.00 a year | 50 days remaining at 12.00 a day (4,380.00 ÷ 365) | 600.00 on the next invoice |
| Contract C-1042 ends on February 28 | 1 month unexpired, 22,334.40 ÷ 3 | 7,444.80 credit note |
| Group | Register expects | Drafts created | Held on the exceptions list |
|---|---|---|---|
| Monthly contracts | 198 | 192 | 6: 4 missing PO, 2 on hold |
| Quarterly contracts due this month | 57 | 57 | 0 |
| Annual contracts at anniversary | 8 | 8 | 0 |
| Total drafts due | 263 | 257 | 6, each with an owner |
| Day of the month | Step | Owner |
|---|---|---|
| 15 | Register frozen for next month’s changes | Account managers |
| 18 | Draft invoices created from the schedule | Invoice run |
| 19 to 20 | Exceptions reviewed; missing POs requested | Finance lead |
| 22 | Run approved and invoices sent | Finance lead |
| 1 | Invoice date and the first day of the period | Automatic |
| 5 | List of contracts with nothing billed | Finance lead |
07How the result is checked
The register is the control. Every run is compared with it before approval, and every month a second check looks for what should have been billed and was not.
| Check | How | Pass condition |
|---|---|---|
| Run against the register | Drafts compared to the schedule by contract, site and period | Equal in count and amount, or each difference is on the exceptions list |
| Nothing billed | Active contracts with no invoice in their expected period | Zero, or each has a named reason |
| Nothing billed twice | Unique key of contract, site and period | No duplicates in the draft list or in Xero |
| Annual value | Register value compared to the sum of the schedule | Equal for every contract |
| Unearned revenue | Xero balance compared to the balance worked out from the register | Equal, with the release journal approved by the accountant |
| Indexation | Anniversary list compared to the invoices that follow | Every new price applied from the right date |
| Retired templates | Each repeating invoice matched to a contract | None left active without a register record |
08Scope and milestones
A fixed scope agreed in writing before anything starts. Each milestone is paid when you sign off its deliverable.
| Area | Included |
|---|---|
| Audit | Read-only review of the contracts, the Xero repeating invoices and 12 months of invoices, a 45-minute call, written findings and a fixed quote |
| Billing rules | The rules in writing, signed by the finance lead and the accountant |
| Contract register | Built or cleaned from your spreadsheets, with a billing schedule per contract |
| Xero set-up | Items, accounts and naming rules, including the unearned revenue account |
| Invoice run | A scheduled flow that creates drafts, with a duplicate guard and an exceptions list |
| Indexation | Anniversary list, new prices and draft customer letters |
| Release schedule | A monthly schedule for the accountant to post |
| Handover | Written SOPs, a recorded handover video and files you own, plus 14 days of fixes after go-live |
| Not included | Tax filing and statutory returns. |
| Also outside the scope | Sending customer letters. Collections and chasing overdue invoices. Changing the contract terms. Software subscriptions (billed to you by the vendors). |
| Milestone | Deliverable | Timing | Share |
|---|---|---|---|
| M1 Audit and rules | Findings, a fixed quote and the billing rules in writing | Week 1 | 20% |
| M2 Register | Contracts loaded and checked against 12 months of billing | Weeks 2 to 3 | 30% |
| M3 Invoice run | Drafts created, exceptions list working, first run approved | Week 4 | 35% |
| M4 Handover | Indexation list, release schedule, SOPs, handover video, 14 days of fixes | Week 5 | 15% |
Typical scope for this kind of project: US$2,500–4,500
About 5 weeks across 4 fixed milestones. The Systems Audit (US$300, fixed) comes first and confirms the scope.
Describe what is going wrong between your job system and your books, and I'll say where I'd look first.
Send a short note through the form on the home page. I will reply with where I would start, and whether the US$300 Systems Audit is the right first step.