
Customer Profitability Report in Xero: Why Revenue by Contact Isn't Profit by Contact
Our biggest customer. Also, it turns out, our most expensive hobby.
A wholesale distributor runs its year-end review. The top customer by revenue is a regional chain, 18% of sales, the account everyone is proud of. Then someone adds up the volume rebate, the free delivery to eleven drop points, the pallet of credit notes for damaged stock and the 90-day payment terms. The account that looked like the business's best customer barely breaks even.
Nobody discovered that in Xero. A customer profitability report, meaning revenue and the real cost of serving each customer, is something Xero doesn't produce. It will rank customers by what they spent. But it won't tell you what it costs to serve them.
That gap is the subject of this post. It's related to, but not the same as, project profitability and case or matter profitability. Those attribute cost to a unit of work. Customer profitability attributes cost to a relationship, and most of the cost that matters never touches a job at all.
Where native Xero stops
Revenue by contact exists. Cost by contact doesn't. The Income by Contact report lists what each customer spent over a period, with a top-10 chart and a drill-down to transactions. It's a good sales ranking. But there's no column for what those sales cost, and the matching Expenses by Contact view groups costs by supplier, not by the customer they were incurred for. A courier bill belongs to the courier contact, however many customers' parcels it covers.
The P&L can't be filtered by contact. Being able to run the Profit and Loss for a single customer is one of the longer-running requests on Xero's product ideas board, raised more than once. Xero's response has been that it isn't roadmapped, with the Income and Expenses by Contact reports offered as the alternative. Those two reports don't join up, so the alternative is two separate lists and a spreadsheet.
Cost of sales is recorded against the invoice, then forgotten. If you use tracked inventory, approving a sales invoice posts cost of goods sold at the item's average cost automatically. So the cost is technically linked to the customer's invoice in the ledger. No native report surfaces that link. The P&L shows one COGS line for the whole business. Untracked stock and direct costs bought on supplier bills don't have that link at all.
Cost-to-serve lives on the wrong side of the ledger. The costs that separate a good customer from a bad one are rarely the product cost. They're freight, payment processing fees, volume rebates, early-payment discounts, credit notes, write-offs, and the hours an account manager or support team spends on the account. Each one is recorded against a supplier, a bank feed, an expense account or a payroll run. Almost none of them carry the customer's name.
Tracking categories don't scale to customers. Xero allows two active tracking categories with up to 100 options each. A business with 40 customer accounts could just about give each one an option. A business with 400 can't, and the two slots are normally already spent on location, department or channel. We've written about the two-slot ceiling in detail. Customer-level reporting is one of its most common casualties.
Payment behaviour is invisible in the margin. A customer who pays in 90 days costs more to carry than one who pays in 14, and a customer who needs three chasers costs staff time. Xero shows that in the aged receivables report, but never as a cost against the customer's margin.
What hitting the wall looks like
The finance manager at a wholesale distributor. Two hundred trade customers, tracked inventory, a courier account and quarterly volume rebates paid as credit notes. Gross margin by customer is recoverable if you export invoice lines with item costs. Freight isn't, because the courier bills one consolidated invoice a week. So the monthly customer review runs on gross margin alone, and the rebate-heavy chain accounts look healthier than they are. The same problem appears in retail reporting by SKU, one level up.
The partner at an accounting practice. Fixed monthly fees per client, time recorded in a practice management tool, payroll in Xero. The question is simple: which clients cost more in staff hours than they pay? Xero holds the fee and the salary bill. The hours, and the join between them, live somewhere else. It's the core of the margin review we've written about for firms, and it's usually done once a year in a spreadsheet, if at all.
The founder of a B2B services business. Retainer clients, a few large ones on custom terms, card payments through a processor that nets its fee off every payout. The processor fee is 2–3% on some clients and zero on those who pay by bank transfer, but it lands in Xero as one bank-fee line. The founder believes the biggest client is the most valuable. Nobody can check without rebuilding a quarter of transactions by hand, the same shape of work as reconstructing management accounts every month.
None of these businesses are unusual. They're the default for any company with more than a few dozen customers and terms that vary from one account to the next.
What a working customer profitability report actually looks like
A customer profitability report you can act on has a handful of specific properties:
- Revenue net of everything that reduces it. Credit notes, rebates, settlement discounts and write-offs come off the customer's revenue, not out of a general expense account where they disappear.
- Cost of sales from the invoice itself. For tracked stock, that means reading the COGS journal each invoice produced, so the cost is exactly what the ledger recorded. Where stock isn't tracked, a stated standard cost per item is needed, and the report should say which method each line used.
- Cost-to-serve attributed by a written rule. Freight by delivery or by weight, payment fees by the payment they were deducted from, support and account management by recorded hours. Each rule is simple on its own. What matters is that it's written down and applied the same way every month.
- Contribution margin and fully loaded margin, shown separately. Contribution margin is revenue less the costs the customer directly causes. That's the number to act on, because it's what goes away if the customer leaves. A fully loaded margin after an overhead share is useful for pricing, but it depends on the allocation rule and shouldn't drive a decision on its own.
- A cumulative view, not just a league table. Sort customers by contribution and plot cumulative profit. In most businesses the curve climbs well above total profit before the loss-making accounts drag it back down. That shape shows at a glance how much margin the tail is costing.
- A tie-out to the P&L. Customer contributions plus unallocated costs equal the business's profit for the period. If they don't, somebody will spend the next board meeting explaining the gap instead of discussing the customers.
The workarounds, ranked
1. Income by Contact plus an assumed margin. Take revenue per customer and apply the business's average gross margin. It's quick and it's wrong in exactly the way that matters: it assumes every customer costs the same to serve, which is the one assumption a customer profitability report exists to test.
2. A tracking category for customer segments. Tag invoices and major costs as "Key accounts", "Trade" or "Online". It's clean, native and ties to the ledger, but it only works at segment level, and only while a slot is free. It tells you trade customers are less profitable than online ones. It can't tell you which trade customers.
3. Invoice-line exports and a spreadsheet. Export sales by item with costs, add freight and fees from their own exports, and join them all on customer name every quarter. It's the most common route and it works, up to a point. It breaks when a customer is renamed, when someone reorders the columns, or when the person who built the lookup leaves.
4. Build it from the API. Xero's Journals endpoint links every journal back to its source (invoice, credit note, bill, payment), so COGS and credit notes can be attributed to the customer exactly, and cost-to-serve can be layered on by rule. It's the only route that is both exact and repeatable. It's also real engineering: pagination, rate limits, and the edge cases worth knowing before you start.
Where Cheetah fits
Customer profitability is a recurring build for us. It's usually for a distributor, a services business or an accounting practice that already suspects its largest accounts aren't its best ones and wants a number to settle it. We pull invoices, credit notes, COGS journals, bills and payments from Xero, attribute cost-to-serve using the business's own rules, and produce a per-customer contribution report that ties to the P&L and refreshes every month in Google Sheets.
If "which customers actually make us money" still means a spreadsheet that someone rebuilds once a year, Cheetah is worth a look.
The short version
Xero can tell you which customers spend the most. It can't tell you which ones make you the most, because the costs that separate them are scattered: COGS sits behind the invoice, freight on a courier's bill, fees in a bank line, rebates in credit notes and support time in payroll. None of it is missing. It just isn't joined to the customer. Joining it once, with written attribution rules and a tie-out to the P&L, turns a hunch about your best customers into something you can price, renegotiate or walk away on. For the same problem applied to units of work rather than relationships, see project profitability. For the reporting layer underneath both, see what a custom Xero report actually takes to build.
Frequently asked questions
- Can Xero show profit by customer natively?
- No. Xero can show revenue by customer through the Income by Contact report, but the Profit and Loss can't be filtered by contact, and no native report puts cost of sales and cost-to-serve against the customer that caused them. Filtering the P&L by contact is a long-standing request on Xero's product ideas board that Xero has said isn't roadmapped.
- What's the difference between the Income by Contact report and a customer profitability report?
- Income by Contact answers how much each customer spent with you. A customer profitability report answers how much each customer left you with after the cost of what they bought, the cost of serving them (freight, payment fees, rebates, credit notes, support time) and a stated share of overheads. The first is a sales ranking; the second is a margin ranking, and the two lists rarely come out in the same order.
- Can I use a tracking category for customers?
- Only for a handful of large accounts or for customer segments. Xero allows two active tracking categories with up to 100 options each, so a business with hundreds of customers can't give each one an option, and the slots are usually already used for location, department or channel.
- Should overheads be allocated to customers?
- Show both. Contribution margin, meaning revenue less the costs a customer directly causes, is the number to act on, because it's what disappears if the customer leaves. A fully loaded margin after an overhead allocation is useful for pricing, but only if the allocation rule is written down and applied the same way every month.

A finance professional turned product builder, Jarvin has built hundreds of reports by hand and knows what financial and operational reporting demands: customisability, auditability, scalability, and security. Having automated that work reliably, he's now helping advisory firms and finance teams do the same.