Three-way matching is the standard financial control in procurement. It validates that you only pay for goods or services that were ordered, received, and invoiced at the right price. Any mismatch blocks the payment until someone investigates. It sounds simple, but the devil is in the implementation, especially in CAFM/CMMS environments where operations and finance use separate systems.
What three-way matching is
The match runs across three documents, all of which must agree:
- Purchase Order (PO), what we agreed to order and the price we agreed to pay
- Goods Receipt Note (GRN), what was physically received and accepted
- Supplier Invoice, what the vendor is billing us for
If all three agree on quantity and price, the invoice is approved for payment automatically. If any of them disagree, the transaction is held for review. That single control prevents most procurement fraud, billing errors, and delivery shortfalls.
Why it matters
Without three-way matching
Invoices get paid on trust. Vendors can over-bill. Deliveries can fall short without consequence. Procurement fraud becomes hard to detect. Month-end becomes a reconciliation nightmare. You're spending money you can't properly account for.
The matching logic
The match validates three dimensions:
Quantity
Invoiced qty ≤ Received qty ≤ Ordered qty
Price
Invoice unit price = PO unit price (within tolerance)
Item
Item codes align across all three documents
Common mismatch scenarios
- Invoice exceeds received quantity, vendor billing for items you never got. Most common. Block and investigate.
- GRN not recorded but invoice submitted, receiving team behind on paperwork. Usually legitimate, but shouldn't auto-pay.
- Unit price differs from PO, price increase since PO was raised, or a billing error. Route to procurement for review.
- Service invoice without service confirmation, vendor claims work was done but no one signed off. Block until confirmed.
- Partial shipments, vendor sends multiple deliveries for one PO. Each invoice matches to the cumulative GRNs.
- Over-delivery within tolerance, vendor ships 105 when you ordered 100. Acceptable within configured tolerance (usually 5-10%).
Handling tolerances
Real procurement doesn't demand exact matches. Define explicit tolerances and document them:
- Quantity tolerance: typically ±5% for consumables, 0% for serialized items
- Price tolerance: typically ±2% or a fixed currency amount, whichever is lower
- Service tolerance: often higher for services (e.g., ±10%) due to scope flex
Transactions inside tolerance auto-approve; outside tolerance, escalate for review.
In a CAFM + Business Central integration
When procurement happens in CAFM and finance runs in BC, three-way matching gets distributed across both systems:
- PO created in CAFM (for maintenance needs), synchronised to BC.
- GRN recorded in CAFM when store keeper accepts delivery, synchronised to BC.
- Invoice received by Accounts Payable in BC, matched against PO + GRN.
- If matched, payment proceeds. If not, exception routed back to procurement for resolution.
The integration has to carry enough context for BC to perform the match, especially PO references, GRN references, and item IDs that map cleanly between systems. See CAFM + Business Central Integration Guide for the integration architecture.
Control principles
- No payment without valid PO + GRN (or service confirmation).
- All exceptions logged and routed for review.
- Tolerances configured explicitly, reviewed periodically.
- Audit trail preserved for every match and every exception.
- Separate roles for goods receipt vs invoice approval (segregation of duties).
Conclusion
Three-way matching is the simplest control with the biggest payoff in procurement. It is the difference between a procurement function you can trust and one that hemorrhages money you can't explain. Implement it properly, configure tolerances sensibly, and route exceptions to people who can resolve them. The payoff shows up immediately in cleaner month-end and fewer unpleasant surprises.
Written by Muhammad Abbas
Enterprise integration specialist. See the full procurement workflow that sits on top of this control.