The Invoice That Almost Matched

October 20th, 2026 | by Lane Nelson


Part 6 of 10 – three-way match

Three-way match, where it is the almost-match, not the mismatch, that costs you.

It is 4:15 on a Thursday, and Colleen has an invoice that almost matches.

Colleen runs accounts payable at Spiese Fluid Power – one of the couple of people who do, anyway. The invoice on her screen is from a good supplier, a casting house Spiese has bought from for years. The purchase order says 200 pieces at $12.40. The goods receipt says 200 pieces came in. The invoice says 200 pieces at $12.40, plus a line she does not recognize: "surcharge, material, $186.00." Not on the PO. Not on the receipt. Just there, at the bottom, in a font the supplier's accounting system picked and Spiese's never will.

So now Colleen has a decision that is smaller than it looks and bigger than it should be. She can pay it and move on – it is a good supplier, it is under two hundred dollars, the odds it is legitimate are high. She can hold it and email the buyer, who will email the supplier, and in nine or ten days someone will explain that steel moved and the surcharge was in an email nobody forwarded to AP. Or she can do what she actually does at 4:15 on a Thursday with forty more of these behind it: pay the 200 pieces, short-pay the surcharge, write a note, and hope.

The invoice almost matched. That is the whole problem with this job. The ones that don't match at all are easy – you stop, you chase, everyone agrees something is wrong. It is the ones that almost match that cost money, because "almost" is exactly the zone where a busy human rounds toward "close enough" and pays.

What it costs today

Start with the volume. Spiese runs about 184 orders a business day on the sell side; on the buy side, the supplier invoices that come back against purchase orders and receipts run about 100 a business day – 25,000 a year, worked by a two-person AP desk. That desk already runs at about 85.5% utilization (13.3 of the 15.6 productive hours it has in a day), so there is almost no slack to absorb a hard invoice – the pressure to round toward "close enough" is, quite literally, built into the schedule.

Most of those match cleanly. The PO price, the received quantity, and the invoiced amount line up inside tolerance, and they should sail through with no human touching them at all. The trouble is the rest. Call it 28% that do not match cleanly on the first pass – a price off by a few cents, a unit of measure that reads "case" on the invoice and "each" on the PO, a partial shipment invoiced in full, a freight or surcharge line that was never on the order, a receipt that has not been keyed yet so the invoice arrives against nothing. That 28% is a reasoned figure, not a measured one – and it is the single most important number in this whole post, so it is the first thing to measure in your own shop.

Twenty-eight percent of 100 is about 28 exceptions a day. Each one, worked properly – open the invoice, find the PO, pull the receipt, compare three documents that were never designed to be compared, decide whether the difference is inside tolerance, and either release it or start a chase – costs on the order of 14 minutes, a stopwatch number that varies wildly with how bad the document is.

Twenty-eight exceptions at 14 minutes is about six and a half hours a day of clearing – most of one clerk's day, spent not on judgment but on document reconciliation. Annualize it across 250 business days at the AP-clerk loaded rate from the profile, $34.67/hr, and you get on the order of $57,000 a year of clerk time spent turning almost-matches into decisions. Two of those inputs – the invoice volume and the rate – come straight from the operating profile; the mismatch rate and the minutes are the ones to pin down, with a stopwatch and a month of history.

And, exactly as in the earlier posts, the visible cost is not the one that hurts. The six and a half hours a day is the number you can see. The number you cannot see splits two ways, and both are worse.

On one side, the invoices that get paid when they should not have: the surcharge that was never authorized, the second copy of an invoice already paid last month, the full quantity billed on a partial receipt, the price that crept up from the quote. Each is small. In aggregate, across a year, overpayment and duplicate payment at a shop this size is not a rounding error.

On the other side, the good invoices held too long. Spiese has suppliers offering early-pay terms – some share of spend carries a 2%-if-you-pay-in-ten-days discount. How much of your spend is discount-eligible, and the dollars on the table, is not something a model estimates – it is a number your AP ledger already holds, worth pulling before you size this. Every invoice that sits in Colleen's "hope" pile past day ten is a discount thrown away, and worse, a supplier learning that Spiese pays slowly and pricing that in next quarter. The money lost to missed discounts and the goodwill lost to slow payment do not show up on any report either. They show up in the next negotiation.

Where the boundary sits

This one sits almost perfectly on the line the series keeps drawing.

The purchase order is a record. The goods receipt is a record. The match tolerance, the GL coding, the payment terms, the posting, the payment run – all record, all arithmetic the ERP already does and should keep doing untouched. None of that is a language problem, and none of it should go anywhere near a model.

The invoice is the odd one out. It arrives as a PDF, an email body, a scan, a supplier-portal export – unstructured, differently shaped by every vendor, written in a language the ERP does not speak. Reading that document, pulling out what it is actually claiming, and reasoning about how its claim lines up against two clean records inside a defined tolerance – that is a reading-and-matching problem. It is exactly what a system of inference is good at, and exactly what a clerk cannot do at twenty-eight documents a day without rounding toward "close enough."

The AI reads and matches. The ERP holds the numbers. The human approves the exceptions – and nothing gets paid without the record's say-so.

What the AI does – and what it must never do

Does: takes the incoming invoice in whatever shape it arrived and turns it into structured lines – supplier, PO reference, item, quantity, unit, price, tax, freight, any extra charges. Then it matches those lines against the purchase order and the goods receipt the ERP already holds. Where everything lines up inside tolerance, it says so and hands back a clean three-way match ready for a human to release. Where it does not, it does the work Colleen does by hand: it names the discrepancy precisely – "invoiced 200, received 150, this is a partial shipment billed in full," or "unit of measure mismatch: invoice reads case, PO reads each," or "unauthorized line: $186 material surcharge with no PO backing" – and routes it as an exception with that reasoning attached. It drafts; it never decides.

Must never do:

  • Never post a payment or approve a payable itself. It produces a match result and a drafted disposition. The human releases; the ERP posts and pays through its normal path, with the normal audit trail.

  • Never accept the invoice's number over the PO and the receipt. When the price or quantity on the invoice disagrees with the record, that is an exception for a person – never a silent override. The record wins by default, every time, and the disagreement surfaces.

  • Never invent or guess GL coding or a cost center. If the coding is not derivable from the PO, it flags the gap; it does not fill it with a plausible account.

  • Never clear a discrepancy outside defined tolerance on its own. Inside tolerance, a clean match can flow. Outside it, a human looks – full stop. The tolerance lives in the record, not in the model's judgment.

  • Never match to a receipt that does not exist. "We have not received these yet" is the single most important thing this workflow must surface, not smooth over. An invoice against no receipt is an exception in bright red, never a match the model reasoned its way into.

The catastrophic failure of this whole workflow is a confident, plausible, wrong payment that no one looked at. Every rule above exists to make sure a human looks before Spiese's money moves.

The plumbing

The good news, again, is that most of what matters already exists. The POs are in the ERP. The receipts are in the ERP. The tolerances, the terms, the GL structure, the payment run – all there, all running. Nothing here rebuilds the system of record.

What you add is a read-and-propose layer in front of it. It ingests the invoice document, extracts the lines, reads the matching PO and receipt out of the ERP through read-only services, and writes back nothing on its own – it returns a match result and a proposed disposition into an exception queue a clerk works. The clean matches it can present for one-click release; the exceptions it presents with its reasoning and the three documents side by side, so Colleen decides in seconds what used to take fourteen minutes to assemble. The write path – the release, the coding confirm, the post, the pay – stays exactly where it is today, inside the record, behind a human.

Who builds it. This read-and-match layer lives on the ERP's own POs, receipts, and tolerances and posts nothing itself – so, like anything this close to the record, it sits most naturally with whoever already runs your system of record rather than a bolt-on reaching in from outside.

Failure modes and guardrails

The confident wrong match. The model reads a scanned invoice, mis-keys a quantity or a price, and presents a clean match that is not clean. Guardrail: the match is a proposal, not a post; clean matches above a dollar threshold still get a human release; and every extracted field shows next to the source document so the clerk is confirming against the PDF, not against the model's summary of it. Extraction confidence below a threshold routes to a human automatically.

The smoothed-over missing receipt. The worst case: an invoice arrives for goods not yet received, and the layer, trying to be helpful, matches it to a nearby PO and calls it good. Guardrail: no receipt, no match – ever. Absence of a receipt is a hard exception, not a soft one, and it is the specific thing to seed the test set with.

The tolerance that drifts into a rubber stamp. Set the auto-pass tolerance too loose and the layer waves through creeping prices and stray surcharges; too tight and everything becomes an exception and you have saved nothing. Guardrail: the tolerance lives in the record where finance owns it, it is reviewed on real outcomes, and the dollars auto-passed inside tolerance are sampled and audited monthly.

The duplicate that looks new. A supplier sends the same invoice twice, or an invoice for a PO already paid, and it presents as a fresh match. Guardrail: dedupe against paid history is the record's job, not the model's – the layer must check paid status through the ERP before ever proposing a clean match, and surface any prior payment loudly.

How you'd know it worked

Not invoices processed – that number rewards speed over correctness, which is exactly the wrong incentive for the function that guards the money. Three measures.

First, clerk time reclaimed from exception clearing: how much of that most-of-a-clerk's-day comes back for actual AP work. The easy, visible win.

Second, and the one that justifies the project: money that stopped leaking. Count overpayments, duplicate payments, and pay-for-goods-not-received for the quarter before and the quarter after. And build a seeded test set – past invoices where you already know which were duplicates, which were partials billed full, which had unauthorized lines – and measure what fraction the layer catches. High recall on that set, especially on the missing-receipt cases, is the evidence that it is safe to lean on.

Third, discount capture and days-to-pay: is the good-invoice pile clearing fast enough to catch the early-pay terms that were being left on the table? A layer that only prevents overpayment but still holds good invoices too long has solved half the problem.

Monday morning

Before any software, measure the two ratios that are the whole business case. Pull a month of supplier invoices and, for a sample, have Colleen mark each: did this match cleanly, or did it need a human, and if it needed one, why? That gives you the real mismatch rate and the real reason distribution – price, quantity, unit, surcharge, missing receipt, duplicate. Then pull the discount terms actually on file and count what was captured versus available last quarter. Two afternoons of work, and between them they tell you whether this is a project or a footnote.

Then pilot narrow. One supplier segment, or one buyer's POs, run through a read-and-match view for sixty days, with no auto-pay and every exception showing its reasoning next to the document. Watch the things that matter: does exception-clearing time fall, do the leaks close, and does the discount pile clear on time?

If it does, widen it. If it doesn't, you have learned that cheaply, and you still own the asset that was always the point – a record that knows exactly what you ordered and exactly what you received, waiting for someone to read the invoice against it. The model's job is not to approve the payment. It is to make the almost-match stop costing you at 4:15 on a Thursday.

Start with what the PO and the receipt already agree on.

Spiese Fluid Power is fictional – a composite built from published industry benchmarks and anonymized operating ratios. Its full operating profile, with sources, is published separately.