What this automation does
Each PO-backed invoice is matched line by line, and only real discrepancies reach a person.
- Start from a clean invoice. The workflow receives extracted invoice data, usually from the AI invoice processing workflow, including line items, quantities, unit prices and the PO number.
- Find the PO and receipts. It looks up the PO in NetSuite, Sage Intacct, QuickBooks Online or Xero, and gathers any receiving records for it, whether from item receipts or a separate receiving log.
- Pair the lines. Lines with a known item crosswalk match by rule. For the rest, an LLM reads the invoice and PO line descriptions, vendor part numbers and quantities and proposes pairings with a reason.
- Normalize units. Code converts cases, boxes, feet and each into a common unit using an item-level conversion table, so “2 CS” and “24 EA” compare correctly.
- Apply tolerances. Code checks price and quantity differences against percent and dollar limits, confirms quantity billed does not exceed quantity received, and checks that the PO has enough open quantity left.
- Route the result. Full matches go to AP approval or straight to posting. Invoices ahead of receipt are held and re-checked when goods arrive. Real mismatches go to purchasing in Slack with the lines side by side.
When it is worth building
This is worth building when PO matching is a daily grind for your AP team, and the slow part is reading lines rather than checking math. Distributors, contractors and manufacturers with hundreds of SKUs and many vendors feel this the most.
If most invoices have one or two lines, or your vendors send EDI that already carries your item codes, a rules-based match inside your ERP is enough. If you have no POs at all, start with approvals rather than matching. And if your problem is that receipts are never recorded, fix receiving first, since no matcher can confirm goods nobody logged.
Architecture
| Layer | What we use | Why |
|---|---|---|
| Invoice input | Output of an AI extraction step with line items as structured JSON | Matching needs reliable lines, so extraction is solved upstream |
| PO and receipts | NetSuite REST web services with OAuth 2.0, Sage Intacct’s web services API (requires the Web Services subscription and an authorized sender ID), or the QuickBooks Online and Xero purchase order endpoints through n8n’s HTTP Request node, since n8n’s built-in nodes for those two do not cover purchase orders | POs and receiving data live in different places in each system |
| Receiving log (when the ERP has none) | A Postgres table fed by a receiving form or warehouse app | Gives QuickBooks and Xero users a real third leg for the match |
| Line pairing | Claude Sonnet 5.5 with both line lists and the vendor’s crosswalk | Handles mismatched part numbers and descriptions |
| Crosswalk and conversions | Postgres tables of vendor item to internal item and unit factors | Each confirmed pairing becomes a rule, so model calls shrink over time |
| Exceptions | Slack messages to the buyer who placed the PO | The buyer knows whether a price change was agreed |
How to build it
- Decide your match type per category. Three-way for inventory and materials, two-way for services and subscriptions, no match for small non-PO spend. Write this down per GL range or vendor.
- Seed the crosswalk. Export the last six months of matched invoices and PO lines and build an initial vendor-item to internal-item table. This alone handles a large share of repeat purchases.
- Build the unit table. For each item, record how vendors bill it and the conversion factor. Missing conversions should block a match, not be guessed.
- Write the pairing prompt. Give the model the unmatched invoice lines and the open PO lines with IDs, and require output as pairs of IDs with a confidence and reason. Unpaired lines must be returned as unpaired, not forced.
- Implement tolerances in code. Check per line and for the invoice total. Include freight, fuel surcharges and tax as separate, expected line types so they do not fail a match.
- Handle timing. If an invoice arrives before goods are received, hold it and re-run the match on each new receipt for that PO, with a reminder to receiving after a few days.
- Write back and close lines. On a match, link the bill to the PO where the system supports it so open quantities update. NetSuite and QuickBooks Online can link bills to PO lines through their APIs, so check the returned bill to confirm the link was saved. Xero’s API has no bill-to-PO link, so mark the PO as billed instead. Save confirmed pairings to the crosswalk.
What breaks in production
- Blanket and standing POs. One PO covers months of releases. Match against remaining value and quantity, not the original PO lines.
- Mid-PO price changes. The vendor raised prices after the PO was issued. The match fails correctly, but buyers need a fast way to accept the new price and update the PO so later invoices pass.
- One invoice, several POs. Some vendors combine shipments for several POs on one invoice. Allow line pairing across all open POs for that vendor, not just the one printed in the header.
- Bad crosswalk entries. A wrong pairing confirmed in a hurry becomes a rule and repeats. Show the crosswalk source on every rule-based match and make entries easy to retire.
- Substitutions. The vendor ships an equivalent item under a different part number. Flag substitutions explicitly instead of letting the model pair them silently.
- Tolerance creep. Small overcharges always land just inside tolerance. Report cumulative within-tolerance variance by vendor each month.
Timeline and cost
One ERP, a seeded crosswalk and three-way matching for inventory purchases typically take three to four weeks. Lumeor builds it for $7,000 to $12,000, depending on the ERP, whether a receiving log needs to be built for QuickBooks or Xero, and the number of vendors with unusual billing. Model costs drop over time as the crosswalk grows and fewer lines need pairing. If you are weighing this against an RPA bot, RPA vs AI agents lays out where each fits.
How to measure success
- Touchless match rate, overall and for your top 20 vendors
- Exceptions by cause, such as price, quantity, no receipt, unit conversion or no PO
- Overbilled dollars caught per month
- Average days an invoice is held waiting for receipt
- Share of invoice lines matched by crosswalk rule versus by the model