Three-way match July 31, 2026 13 min read

Three-way match: software, and the document problem underneath it

Three-way matching compares a purchase order, a goods-received note and a supplier invoice before anything is paid. The concept is simple and the practice is not, because in most businesses those three documents live in three different formats and one of them is a PDF nobody has read. This page covers how the match actually works, where it breaks, what tolerance really means — and the part we do: turning all three documents into data you can compare.

FlowParse
flowparse.io

What a three-way match is for

The purpose is narrow and important: do not pay for something you did not order, did not receive, or were charged the wrong price for. The purchase order says what was agreed. The goods-received note says what arrived. The invoice says what you are being asked to pay. If the three agree, payment is safe.

It is the oldest control in accounts payable because it catches the three things that actually cost money: overbilling, phantom deliveries and duplicate invoices. None of those require anyone to be dishonest — most are ordinary mistakes that nobody would ever notice from the invoice alone.

The reason it is hard has nothing to do with the concept. It is that the three documents rarely exist in the same place, in the same format, at the same time.

Two-way, three-way and when each applies

A two-way match compares the invoice against the purchase order only: was this ordered, at this price? It suits services, subscriptions and anything with no physical delivery, and it is the pragmatic default for small businesses.

A three-way match adds the receipt: did it actually arrive, and how much of it? That step is what catches short deliveries billed in full, and it is essential for anything physical.

Some organisations run a four-way match, adding an inspection or quality record. That belongs to manufacturing and regulated supply chains rather than to a typical business, and adding it without the operational discipline behind it just creates a queue.

Three documents, three sources, three formats

The purchase order comes from your side — a system, a spreadsheet or an email attachment. The goods-received note comes from whoever accepted the delivery, often signed on paper and photographed. The invoice comes from the supplier in whatever format they choose, which in practice is a PDF.

The matching problem is therefore a data problem first. You cannot compare three documents that are, respectively, a database row, a photograph and a PDF — someone has to make them comparable, and that someone is usually a person with a spreadsheet.

This is where extraction earns its place: purchase orders, delivery notes and invoices all become tables with the same shape, so the comparison is arithmetic rather than reading.

FlowParse
flowparse.io

The fields the match actually turns on

Matching at header level — supplier and total — catches almost nothing. The errors that cost money live in the lines, and a line match needs a specific, small set of fields from each document.

FieldPurchase orderGoods receivedInvoice
SupplierOrdered fromDelivered byBilling entity — often differs
ReferencePO numberPO number on the notePO number quoted, or missing
ItemYour code or descriptionWhat was acceptedSupplier's own code
QuantityOrderedReceivedBilled
Unit priceAgreedn/aCharged
Line totalOrdered valuen/aBilled value
DateOrder dateDelivery dateInvoice date and period

Where the match breaks in real life

Partial deliveries are the commonest by far. Sixty units ordered, forty delivered, sixty invoiced — or forty delivered and forty invoiced against a PO that still shows sixty open. Neither is wrong exactly; both need a human decision.

Unit-of-measure mismatches come next: ordered in boxes, delivered in units, invoiced in pallets. The numbers disagree by a factor nobody notices until someone multiplies.

Then price variance — a price agreed in April and invoiced in July — and item codes that differ between your catalogue and the supplier's. And, quietly, invoices with no PO number at all, which cannot be matched by machine and become the manual queue.

What each exception usually means

Sorting exceptions by type rather than by supplier is what makes them fast to clear: each type has a standard question and a standard owner.

ExceptionUsually meansWho resolves it
Quantity billed > receivedShort delivery, or receipt not enteredWarehouse or receiver
Quantity received > billedPartial invoice; more to comeAP — hold the PO open
Price higher than POPrice change or wrong contractBuyer
No PO referencedOrdered outside processBuyer and the requester
Supplier name differsTrading name vs legal entityAP — vendor master
Duplicate invoice numberRe-sent invoice, or a genuine duplicateAP — check before paying
Line count differsConsolidated billingAP with the buyer

What a tolerance is really for

Every matching setup has tolerances — a small percentage or absolute variance accepted without review. Their purpose is not laziness; it is to keep humans focused on differences that matter rather than on rounding and freight.

The mistake is setting them by feel. A tolerance wide enough to swallow a systematic overcharge defeats the control, and one so narrow that a third of invoices stop is a control nobody will run for long.

The honest method is empirical: look at your actual variance distribution for a month, set the threshold where the noise ends, and review it. That requires having the variances as data — which is, again, the extraction problem.

How small teams actually do this

Most businesses running three-way matching have no matching software at all. They have a spreadsheet, an inbox and somebody diligent, and the process works until volume or staff turnover breaks it.

The pragmatic version: extract the invoices as they arrive into one register, keep the POs in the same shape, and match by PO number and line where possible. Anything without a PO reference goes to a queue that a buyer clears weekly rather than an AP clerk chasing daily.

That is not a platform, and for a few hundred invoices a month it does not need to be. What it needs is that the three documents are data rather than paper — which is the part that can be automated cheaply.

FlowParse
flowparse.io

Doing it in a spreadsheet, properly

1

One register per document type

POs, receipts and invoices as three tables with the same key fields.

2

Normalise the keys

PO number and supplier name cleaned to a consistent form before matching.

3

Match on PO + line

Header-only matching hides exactly the errors you are looking for.

4

Flag, do not delete

Unmatched rows stay visible; deleting them is how a control quietly stops working.

5

Sort exceptions by type

Each type has one question and one owner.

6

Keep the source reference

Every row traceable to the document it came from.

The part FlowParse does

Extraction, and only extraction. Purchase orders, invoices with their line items, delivery notes, remittance advice and supplier statements all become structured tables with the same field names, from any supplier's layout, with no template to configure.

Scanned and photographed documents — which is what a signed delivery note usually is — go through OCR first, with low-confidence values flagged in an editable preview rather than silently guessed.

What comes out is three comparable datasets. What you do with them, and which exceptions you accept, stays yours.

When you genuinely need matching software

Be honest about the threshold, because buying too early is a common and expensive mistake, and buying too late is worse.

You need a real AP or ERP matching module when purchase orders are raised in a system rather than by email, when receipts are entered by warehouse staff at the point of delivery, when approval routing has rules that differ by value or department, and when volume makes a weekly spreadsheet pass genuinely impossible.

Below that, the software is not the constraint — the process is. A team without a reliable goods-receipt step cannot three-way match no matter what it buys, because the second document does not exist.

The invoices with no purchase order

Every AP function has a share of invoices that reference no PO, because someone ordered directly. These cannot be matched by any software, and they are usually where the leakage is.

The fix is procedural, not technical: decide which spend categories require a PO, make it easy to raise one, and route no-PO invoices to the person who ordered rather than absorbing them into AP. Measuring the share is the first step — and that needs the invoices as data.

Extraction gives you the measurement almost free: a register of invoices with a PO-reference column, and a count of how many are blank each month.

What the control actually catches

Genuine invoice fraud does happen — fabricated suppliers, altered bank details, invoices for goods never ordered — and the three-way match is the structural defence against the last of those.

But the vast majority of what it catches is ordinary error: a price that changed, a delivery short by two units, an invoice sent twice by a supplier chasing payment. Those are the ones that recur, and cumulatively they cost far more than the dramatic cases.

Bank-detail changes are a different control entirely and worth naming: verify them by a known channel, never from the email that requested the change. No matching process protects against paying the right invoice into the wrong account.

Matching and duplicate payments

A matching process reduces duplicate payments but does not eliminate them, because a duplicate can arrive with a different invoice number, a different date, or through a different route entirely — one copy emailed to AP and one to the person who ordered.

The complementary check is on the payment side rather than the invoice side: look for repeated amounts to the same payee within a short window. That is a data exercise on your bank statements, and it is covered on duplicate payment detection.

Running both is what a proper control looks like: one check before payment and one after, because neither catches everything the other does.

A worked example: one month, 180 invoices

A distributor receives about 180 supplier invoices a month against roughly 140 purchase orders. Delivery notes are paper, signed at the door and scanned in batches.

Extraction turns all three into registers in an afternoon: invoices and POs by line, delivery notes with quantities and PO references. Matching on PO plus line clears 118 invoices with no human involvement.

Of the remaining 62, thirty-one are partial deliveries where more is still to come, eleven are price variances from a contract that was renegotiated, nine reference no PO at all, seven are unit-of-measure mismatches, and four are the same invoice arriving twice — two of which had already been paid.

The four duplicates are the entire business case, and they were invisible in the invoice stack. The rest is a queue with owners rather than a mystery.

The numbers worth tracking

Three metrics tell you whether the control is working: the share of invoices matched without human involvement, the share arriving with no PO reference, and the number of exceptions still open after a week.

The first tells you about data quality, the second about buying discipline, and the third about ownership. Almost every AP improvement project is really an attempt to move one of those three, and knowing which one saves buying the wrong tool.

All three come out of the registers you already built to do the matching — no separate reporting project required.

If you already have an ERP

If purchase orders and receipts already live in an ERP, the matching logic is there and you do not need another engine. What is often still missing is the invoice side: supplier PDFs arriving by email that someone keys in.

Extraction fills that gap specifically — invoice header and lines as data, exported as Excel or CSV for import, or pulled through the API into whatever ingests them.

That is a much smaller purchase than a matching platform and it removes the actual bottleneck, which is usually keying rather than logic.

FlowParse
flowparse.io

How this differs from our other matching pages

Payment matching and invoice reconciliation are about a different pair of documents: invoices against payments, after the fact. That is the money side.

Three-way matching happens before payment and involves the order and the delivery. Same discipline, different documents, different failure modes.

Bank reconciliation is a third exercise again — the ledger against the bank. Businesses that confuse these end up doing one of them twice and none of them properly.

Who this helps

Distributors and wholesalers

High line counts, partial deliveries, real quantity risk.

Manufacturers

Materials ordered, received and invoiced across long lead times.

Construction and trades

Deliveries to sites, notes signed on paper, prices that move.

Finance teams without an ERP

Doing the control in spreadsheets and needing the documents as data.

Why extraction quality decides the match

A matching process is only as good as the data under it. A quantity misread on one line produces an exception that costs someone twenty minutes and teaches the team to distrust the process.

Line-level extraction is the hard part — tables that wrap across pages, subtotals that look like lines, descriptions on two rows — and it is what line-item extraction is built for. Uncertain values are flagged rather than presented with false confidence.

On statements, the completeness check is arithmetic: opening balance plus transactions equals the printed close. See extraction accuracy for what that proves and what it does not.

How the documents are handled

Uploads run over TLS, processing happens in EU data centres, the original file is deleted immediately after extraction, extracted data is encrypted at rest, and documents are never used to train models — see security. FlowParse is hosted and cannot be self-hosted.

The order the documents arrive in, and why it matters

Textbook three-way matching assumes the purchase order comes first, then the goods, then the invoice. Real sequences are messier, and each variation produces a different exception.

An invoice arriving before the receipt is normal for services and for suppliers who bill on despatch — holding it until the receipt appears is correct, but only if someone is actually chasing the receipt. An invoice arriving before the purchase order means the order was placed informally, which is a buying-discipline problem rather than an AP one.

Goods arriving with no order at all is the awkward case: something has to be accepted, recorded and then retrospectively authorised. Deciding in advance who does that, and where the record lives, prevents the pile of unmatched receipts that most warehouses accumulate.

Handling partial deliveries without losing the thread

Partial deliveries are the single largest source of exceptions, and the way they are handled decides whether the process is workable at volume.

The principle is that a purchase-order line stays open until the ordered quantity has been received or the remainder is formally cancelled. Each delivery consumes part of the line; each invoice is matched against what has actually been received rather than against the original order.

Where this goes wrong is in spreadsheets that treat a PO line as a single row: the second delivery has nowhere to go, so somebody edits the original row and the audit trail disappears. Keeping receipts as their own rows, referencing the PO line, is what makes partials survivable.

Who owns each exception type

Matching fails as a process far more often because nobody owns an exception than because the software could not match it. Assigning ownership by type, in advance, is what keeps the queue moving.

ExceptionOwnerTarget
Short delivery billed in fullReceiver, then buyerResolve before payment
Price above the orderBuyerConfirm or dispute within a week
No purchase orderRequesterRetrospective PO or a decision
Receipt never enteredWarehouseSame day as delivery
Supplier name mismatchAPFix the vendor record, not the invoice
Possible duplicateAPCheck before the payment run

The boundary, stated plainly

FlowParse is a document-extraction engine, not an accounts-payable platform and not an ERP. It has no approval workflow, no purchase-order system, no vendor master, no payment execution and no ledger of its own. Nothing here approves, posts or pays anything.

What it does is turn the documents this work depends on — purchase orders, invoices, delivery and goods-received notes, supplier statements, remittance advice and bank statements — into structured, comparable data, with a completeness check on the statements so the numbers you compare are provably whole.

That is deliberately half the job. The other half — deciding what an exception means, approving a payment, posting a journal — belongs to your process and your people, and any tool claiming otherwise is describing something you would still have to supervise.

Where to start

Take one month of supplier invoices and the corresponding purchase orders, extract both, and match on PO number and line. The share that matches cleanly tells you whether your constraint is data or process.

If most match, your problem was keying and you have just solved it. If most do not, the exceptions will sort themselves into three or four types — and each type is a process fix rather than a software purchase.

Get all three documents into comparable data

Extract purchase orders, delivery notes and invoices — line by line, any supplier's layout — so the match is arithmetic instead of reading.

Frequently asked questions

Related