Why your Partner Center recon file never matches your invoice

One subscription throws several rows a month, and some of them are negative. If you add up the Quantity column you get the wrong number every single time.

This is the thing nobody explains properly, and it is why licence reconciliation quietly costs small MSPs real money. It is not carelessness. The file is shaped in a way that makes the obvious approach wrong.

Find your number first. It is free and takes about two minutes.

Drop in the Partner Center reconciliation CSV and an invoice export. Nothing uploads, there is no account, and the answer is either zero or it is money you have been paying every month.

Run the free check or try it on sample data

The mistake everyone makes first

You download the licence-based reconciliation file, open it, filter to a client, sum Quantity, and compare that to what you invoiced. It seems like the only sensible thing to do.

Here is one real client, one product, one month:

ChargeStartDateOfferNameChargeTypeQuantity
2026-07-01Microsoft 365 Business PremiumcycleCharge38
2026-07-14Microsoft 365 Business PremiumaddQuantity4
2026-07-22Microsoft 365 Business PremiumremoveQuantity-2
2026-07-09Microsoft 365 Business PremiumcustomerCredit-1
Sum of the Quantity column39
Seats actually live at month end40

The sum says 39. The client has 40. The difference is the customerCredit row, which is money, not seats. It represents a refund for an outage or a billing correction. Counting it as a licence is like subtracting a discount from your headcount.

The rule Group by client and product, then add only the charge types that change the quantity. Credits, term extensions and immediate cancellations are financial events. They belong in your accounting, never in your seat count.
ONE SUBSCRIPTION, ONE MONTH, FOUR ROWS cycleCharge 40 counts addQuantity +2 counts customerCredit -1 money, not a seat extendTerm 0 money, not a seat Sum the column: 41 wrong Count only seat rows: 42 right
A credit for an outage is money coming back, not a seat going away. Add it up blind and every client with a credit looks like they owe you less than they do.
Every ChargeType, and whether it moves the seat count

New commerce (NCE) subscriptions use these values. This is the vocabulary that matters:

ChargeTypeWhat happenedCounts as seats?
cycleChargeThe normal monthly or annual charge. Your baseline.Yes
newSubscription purchased mid-period.Yes
renewTerm renewed.Yes
addQuantitySeats added mid-term, prorated.Yes
removeQuantitySeats removed. Arrives negative.Yes
moveQuantitySeats shifted between offers.Yes
convertTrial converted to paid, or SKU converted.Yes
customerCreditA refund or correction. Financial only.No
extendTermTerm lengthened. No seat change.No
cancelImmediateCancelled inside the window, with a refund.No

Legacy subscriptions use human-readable strings instead: Cycle fee, Cycle instance prorate, Cancel fee, Purchase fee. An MSP mid-migration will hold both formats at once, sometimes in the same month. Any script that matches only one vocabulary silently drops the other, and dropping rows looks exactly like a client who owes you nothing.

The renames that still cost money six years later

RENAMED IN APRIL 2020. STILL PRICED BY THE OLD NAME. Office 365 Business Premium Microsoft 365 Business Standard the cheaper one Microsoft 365 Business Microsoft 365 Business Premium the expensive one
The names crossed over. An invoice line that still says "Business Premium" because that is what it always said may be billing a Standard seat at Premium money, or the reverse, and it has been doing it since 2020.

In April 2020 Microsoft renamed the Office 365 SMB plans. The trap is not that names changed. It is that one name moved to a different product:

Old name on your invoiceWhat it is today
Office 365 Business PremiumMicrosoft 365 Business Standard
Office 365 Business EssentialsMicrosoft 365 Business Basic
Office 365 BusinessMicrosoft 365 Apps for Business
Microsoft 365 BusinessMicrosoft 365 Business Premium
Read that first row twice "Office 365 Business Premium" became Business STANDARD. Meanwhile a different old plan became Business Premium. So an invoice line that still says the old name describes the cheaper product, while the word "Premium" points at the dearer one. If you priced that line by its name rather than its SKU, the rate has been wrong ever since, and it is wrong in whichever direction nobody has checked.

Microsoft's own price list styles the enterprise plans differently again: Microsoft Office 365 (Plan E3) in one export is Microsoft 365 E3 in another. Same licence, two spellings, no shared word order.

Then the second half of the problem, which is worse

Suppose you have solved the charge types and you know a client owns 40 Business Premium seats. Now you have to find that product on your own invoice. Your invoice does not say "Microsoft 365 Business Premium". It says one of these, because a human typed it:

The last one is the killer. Email & Office Bundle shares not a single word with Microsoft 365 Business Premium. No amount of string matching will ever connect them. Any tool claiming to automate this either asks you once and remembers, or it quietly reports your billed seats as unbilled, which is worse than useless, because a confident wrong answer gets sent to a client.

Why this survives in well-run shops

Nothing above requires anyone to be sloppy. It requires:

  1. A file where one subscription is several rows, some negative.
  2. Two different charge-type vocabularies depending on migration state.
  3. A rename where a product name moved to a different product.
  4. An invoice written in your own language rather than Microsoft's.
  5. A month-end where this is the twelfth thing on the list.

Each is individually manageable. Together they mean the check is genuinely hard, so it gets done once a year, or when a client queries a bill. Seats added in March get noticed in November, and the eight months in between are simply gone: you paid Microsoft for them and nobody was ever invoiced.

Common questions

Why does summing the Quantity column give the wrong seat count?

Because one subscription produces several rows per month and some are negative. A cycleCharge baseline, an addQuantity for seats added mid-term, a negative removeQuantity, and a customerCredit row that represents money rather than seats. Counting the credit as a licence reduces the total for a reason unrelated to licences.

Which Partner Center ChargeType values count as seats?

These change the quantity and should be added: cycleCharge, new, renew, addQuantity, removeQuantity, moveQuantity and convert. These do not and must be excluded: customerCredit, extendTerm and cancelImmediate. Legacy subscriptions use readable strings instead, such as Cycle fee, Cycle instance prorate and Cancel fee.

What is Office 365 Business Premium called now?

Microsoft 365 Business Standard. This is the trap: a different old plan became Business Premium, so an invoice line still carrying the old name describes the cheaper product while the word Premium points at the dearer one. Pricing that line by its name rather than its SKU has been wrong since 2020.

Why can't a tool match my invoice line automatically?

Because MSPs rename products for clients. A house name such as Email and Office Bundle shares no words at all with Microsoft 365 Business Premium, so no string matching can connect them. A tool must either ask once and remember, or it will report billed seats as unbilled.

You can stop reading and just run it

Two files, two minutes, no account, nothing uploaded. If the number comes back zero you have lost two minutes. If it does not, it has been costing you that every month.

Run the free check Want it to happen every month without you? That is €39 a month, and it is the only thing on this site you ever pay for.