In March, a UK manufacturing firm processing 240 invoices a month found that three supplier payments had cleared without a matching purchase order. Two were duplicates from the same supplier — submitted eleven days apart with different invoice numbers, each passing through a brief manual check because neither AP team member ran a search before authorising. The third was a payment for goods that had never arrived: a warehouse manager confirmed delivery on a goods receipt note in error, the note sat unchallenged, and the invoice matched it well enough to clear. The AP team had been doing three-way matching in a shared spreadsheet, updated when someone remembered to update it, and nobody checked it before the payment run. This is the default outcome when an AP process built for 80 invoices a month is still running unchanged at 240.
Three-way matching mechanics: PO, goods receipt note, and invoice reconciliation — and where the process breaks without automation
Three-way matching checks three documents against each other before any payment goes out: the purchase order (what was approved to buy), the goods receipt note or GRN (confirmation of delivery), and the supplier invoice (what the supplier is claiming to be paid). All three must agree within defined tolerances before the invoice queues for payment.
The process breaks at predictable points once volume grows.
Timing gaps. The PO is raised in the ERP on Tuesday. The warehouse logs the GRN on Thursday, two days after physical delivery. The invoice arrives by email on Friday. Manual matching requires someone to hold all three in mind at the same time — manageable at 30 invoices a month, unreliable at 120.
Reference mismatches. Suppliers do not always quote your PO number on their invoices. Without the reference, manual matching becomes a search problem: find the correct PO from a list of hundreds, confirm it covers these specific line items, then locate and check the GRN. Under time pressure before a payment run, that search gets abbreviated to a glance.
Duplicate invoices. A re-submitted invoice with a different number, a corrected date, or a slightly altered amount is nearly impossible to catch manually unless someone runs a specific duplicate check before each payment run. Almost no one does — the March incident confirmed it. An automated pipeline solves these problems: the duplicate check becomes a database query rather than a memory exercise.
Purchase order data extraction: structured fields from PO PDFs, spreadsheets, and ERP system exports
The first stage ingests PO documents from wherever they live: PDFs from Sage 200, Business Central, or Unleashed; Excel-based PO sheets maintained by a buyer; direct ERP exports or API feeds. For each PO the pipeline extracts and validates this structure before it enters the matching pool:
{
"document_type": "purchase_order",
"po_number": "PO-2024-003847",
"supplier_code": "SUP-00142",
"supplier_name": "Midlands Steel Components Ltd",
"issue_date": "2024-02-14",
"delivery_date_expected": "2024-02-28",
"currency": "GBP",
"line_items": [
{
"line_number": 1,
"description": "M8 Hex Bolts Grade 8.8 - Box 500",
"part_number": "HB-M8-500",
"quantity": 20,
"unit": "box",
"unit_price": 14.50,
"line_total": 290.00
},
{
"line_number": 2,
"description": "M10 Nyloc Nuts - Box 200",
"part_number": "NN-M10-200",
"quantity": 10,
"unit": "box",
"unit_price": 9.80,
"line_total": 98.00
}
],
"subtotal": 388.00,
"vat_rate": 0.20,
"vat_amount": 77.60,
"total_inc_vat": 465.60,
"payment_terms": "NET_30",
"extraction_confidence": 0.94,
"source": "s3://ap-documents/pos/PO-2024-003847.pdf"
}
Sage 200 exports POs in XML via its import/export utility. Business Central exposes them through OData. PDF-based POs go through a document extraction model — see our invoice data extraction pipeline for the field-level extraction approach used for similar unstructured documents.
The extraction_confidence field is not decorative. Any PO extracted below 0.85 goes to a human review step before it enters the matching pool. A single mis-extracted unit price will generate false discrepancies on every invoice matched against that PO for the rest of its life.
Invoice-to-PO matching logic: exact match, fuzzy match, and the tolerance rules finance teams actually use in practice
Once both POs and invoices are in structured form, the matching engine runs three passes in sequence, stopping at the first pass that produces a result above the confidence threshold.
| Match type | Trigger condition | Tolerance applied | Auto-approve? |
|---|---|---|---|
| Exact PO reference | Invoice contains a valid PO number | ±2% per line price | Yes, within tolerance |
| Header fuzzy match | No PO number; supplier code + total + ±14-day window | ±2% total; confidence >0.90 | Yes, if all conditions pass |
| Line-item fuzzy match | PO reference present but amounts diverge | ±5% quantity, ±3% per-line price | Yes, if invoice total within ±2% |
| Exception queue | Confidence below threshold or no candidate PO | None | No — routes to review |
The ±2% price tolerance is not arbitrary. HMRC's VAT record-keeping rules require input VAT to be reclaimed on the correct invoice amount; tolerances above 5% create tax record problems at year end. UK SMEs typically run ±1–3% on line prices and accept ±5% only on quantities, where partial deliveries make exact matching impractical.
The duplicate check runs as a pre-pass before any matching logic fires. It compares each incoming invoice against invoices received in the previous 180 days using a composite key: supplier code plus invoice total plus a normalised description hash. Two invoices from the same supplier for the same amount within 30 days trigger an automatic hold regardless of invoice numbers.
Goods receipt note validation: what to extract from delivery confirmations and how to route line-item discrepancies
The GRN is the weak link in most SME AP workflows because it originates outside the finance team. Warehouse staff confirm deliveries, sometimes accurately and sometimes not.
The pipeline extracts from GRN documents (PDFs, WMS exports, or manual entries in Sage or Unleashed):
- Delivery note number and delivery date
- Supplier reference and receiving location
- Line items received: part number, quantity, acceptance status (accepted or rejected)
- Signatory name and timestamp
The manufacturing firm in the opening scenario failed specifically here. A warehouse manager logged the GRN but the goods were never received. The pipeline would have flagged this with WMS integration: the GRN shows 20 boxes confirmed, the stock system shows zero movement — a discrepancy that fires an automatic exception. That cross-check requires your WMS to expose an API, which most modern systems do.
Without inventory integration, the minimum viable check is to flag any GRN where the confirmed quantity exceeds the PO quantity by more than 10%. Suppliers occasionally ship more than ordered and invoice for the overage; that should never auto-approve without an amended PO.
Line-item discrepancies route to the exception queue with the specific lines highlighted, the PO quantity shown alongside the GRN quantity, and a pre-filled supplier query template the AP team member can send directly from the review interface.
Exception queue design: the human review interface for discrepancies above tolerance threshold before payment runs
The exception queue is not a bin for failed matches. It is a structured review interface designed to reduce time-per-decision to under 90 seconds, not to create a second inbox that people avoid.
Each exception card displays: 1. The invoice rendered alongside its extracted key fields 2. The best-candidate PO with specific discrepant fields highlighted 3. The GRN if one exists, with quantity differences marked 4. Suggested action: approve with override, reject, request credit note, or escalate to finance manager
Approval thresholds operate at two levels. Invoices up to £1,000 with a single minor discrepancy — typically a rounding difference or a price variance under 5% — can be approved by a single AP team member. Invoices above £1,000 or with a missing GRN require sign-off from a finance manager or ops director. The threshold values are configurable per client.
The exception queue aligns to the payment run schedule. For a weekly Friday payment run, exceptions received before Wednesday noon clear review in time; those received after hold until the following run with an automatic supplier acknowledgement. See our OCR with human-in-the-loop post for the principles behind review interfaces that actually get used.
ERP and accounting integration: writing matched and approved data to Sage 200, Xero, and QuickBooks automatically
Once an invoice clears the matching and approval gates, the pipeline writes the matched record back to the accounting system without manual re-keying.
Xero's purchase order API accepts a PATCH request to update PurchaseOrder status and a POST to create the matched Bills record with the linked PO reference populated. The PO moves to BILLED status; the bill record carries the GRN reference and the matching confidence score in a custom field for audit purposes.
QuickBooks uses a comparable pattern via its PurchaseOrder and Bill entities; capture the returned bill ID and write it back to the pipeline's matched-record log for reconciliation.
Sage 200 on-premise is more involved. The REST API covers a subset of entities, so most clients use a watched XML import folder. The pipeline writes approved invoices as XML matching the Sage 200 import specification — supplier reference, invoice number, date, VAT treatment, nominal code, cost centre, and payment terms must all be present or the import rejects the record silently.
Across all three systems the pipeline writes: matched PO status, invoice record with PO and GRN cross-references, payment due date from PO terms, and an audit trail entry with approver name and timestamp — see the automated board pack reporting post for how this feeds into Xero-based management accounts.
Supplier deduplication and vendor master data as a prerequisite for accurate automated matching
The matching engine uses the supplier code as its primary identifier, not the supplier name. This matters because supplier names in UK SME systems are unreliable: "Midlands Steel Components Ltd" in Sage, "MSC Ltd" on the invoice, "MIDLANDS STEEL COMPONENTS LIMITED" in Companies House — the same legal entity, registered three ways by three different people. The typical finding when auditing a vendor master of 200-plus suppliers: 12–18% of suppliers have duplicate records under different name variants, causing false mismatches or missed matches.
The deduplication process: 1. Normalise all supplier names: strip "Ltd", "Limited", "LLP", lowercase, remove punctuation 2. Fuzzy-compare all normalised names (Levenshtein or token sort ratio); flag pairs above 0.85 3. Cross-reference Companies House registration numbers — the definitive identifier 4. Merge duplicates under one canonical supplier code; archive the aliases
This is a one-off project of two to three days for a 200-supplier vendor master and a prerequisite before deploying automated matching.
What changed in 2025–2026: native three-way matching features in Xero Advanced and QuickBooks Enterprise
Two developments over the past twelve months affect the build-vs-use-native decision for UK teams.
Xero Advanced added native two-way matching in late 2025, with three-way matching (incorporating delivery confirmations) entering general availability for UK accounts in early 2026. For businesses processing under 100 invoices a month where suppliers consistently quote PO numbers, the native feature is worth evaluating first. The limitations: no fuzzy matching for invoices without PO references, no duplicate detection pass, no multi-tier tolerance rules. Available only on the Advanced tier, which carries a higher subscription cost.
QuickBooks Enterprise 2025 extended PO tracking to include bill linkage with line-item comparison, but tolerance rules and exception routing still require custom API work, and PDF invoices by email still need a separate extraction step.
Above 150 invoices per month, or where suppliers are inconsistent with PO references, the native features fall short. A custom pipeline is the right answer.
Good / Bad / Ugly: three PO automation approaches and the bad payment each one did or did not catch
Back to March. Three payments cleared that should not have. Here is what each approach would have produced:
Good — full three-way match pipeline with duplicate detection
The duplicate check catches both re-submitted invoices before matching runs: same supplier code, same total, different invoice numbers, eleven days apart — automatic hold. The GRN validation step flags the goods-never-arrived invoice because the GRN is present but the stock movement is absent; it goes to the exception queue with the WMS discrepancy highlighted. All three bad payments caught.
Bad — two-way match only (PO and invoice, no GRN step)
Both duplicate invoices are caught by the pre-pass duplicate check. The goods-never-arrived invoice clears: the pipeline sees a valid PO, a matching invoice amount, and no GRN data to contradict the approval. Two of three bad payments caught; one goes out. This is the common intermediate state for teams who have automated invoice-to-PO matching but have not yet integrated warehouse data.
Ugly — spreadsheet-based manual matching, current state
The spreadsheet is updated when someone remembers. No duplicate check runs before the payment run. The goods-not-received payment clears because the GRN is in the system and nobody pulls the stock movement report. All three payments clear. Zero of three caught.
The ICAEW's guidance on accounts payable controls argues that automation alone is insufficient: segregation of duties and defined human review gates remain essential. That is correct — the exception queue and tiered approval thresholds here are designed to preserve those controls, not replace them.
For the extraction and retrieval patterns underpinning this pipeline, see our Invoice OCR case study and Document RAG portfolio entry.