Invoice Processing Automation
A practical intake-to-accounting workflow with field mapping, duplicate controls, human approval, exception rules, and safe retries.
— Craig Major
Direct answer
Invoice processing automation moves a supplier invoice from an agreed intake channel to a reviewed draft in accounting. The workflow extracts fields, checks required values and totals, stops duplicates, and waits for a person before any ERP write. A lost destination response must retry with the same idempotency key so a second bill is not created.
This guide covers the invoice workflow. The broader first-document-type plan stays on Document Processing Automation. If you still need to map the surrounding process, use the Business Process Automation guide.
Invoice processing automation versus accounts payable automation
Invoice processing automation covers intake, extraction, validation, duplicate checks, review, and creation of an accounting draft. Accounts payable automation can extend further into purchase-order matching, approval policies, payment scheduling, remittance, and reconciliation.
Start with invoice processing when manual entry and exception routing cause the immediate problem. Add wider accounts-payable steps only after the intake-to-draft path is stable and measured.
Who this is for
Use this when invoices arrive in one inbox or folder, one person or team already codes them, and the destination is one accounting system. You should know what object that system creates for a supplier bill. In many products that object is a bill or pending vendor invoice, not a sales invoice.
Prerequisites:
- One invoice family for the first build, such as domestic CAD supplier PDFs
- A named reviewer who can approve a draft
- A rule for what counts as a duplicate
- A destination that can create a draft and accept a retry key or an equivalent lookup
- Fictional or approved test files before any live write
Stay out of this first workflow: payment, refunds, supplier bank-detail changes, tax advice, and multi-entity matching.
What changes when the workflow is automated
| Manual step | Automated system | Human responsibility |
|---|---|---|
| Watch an inbox or folder | Capture files from one agreed channel | Resolve unsupported sources |
| Copy fields into accounting | Extract into one documented schema | Check exceptions and source evidence |
| Notice totals that look wrong | Run required-field and arithmetic rules | Decide whether an exception may proceed |
| Remember which invoices arrived | Check source hash and vendor plus invoice number | Approve any documented override policy |
| Re-enter a request after a timeout | Retry with the same idempotency key | Confirm that only one draft exists |
The value comes from consistent handling and a visible exception queue. Measure the result with your own volume, review time, duplicate stops, and failed-run records.
Worked example
Cedar & Quay Fabrication Ltd is a fictional Toronto buyer. Ridgemont Industrial Supply Co sends invoice INV-TP-2401 dated 8 September 2026. The invoice lists safety vests, clipboards, and fastener bins. Subtotal CAD 400.00, HST CAD 52.00, total CAD 452.00. Purchase order PO-CQ-188 is present.
The extractor should return vendor, invoice number, date, currency, line items, subtotal, tax, and total. The workflow should move the invoice to pending_review. No accounting draft exists until a person chooses approve. After approval, one draft exists.
That example is one of five cases in Flowgrammer's Invoice Processing Test Pack. The same companies and amounts are used below. They are fictional. They are not customer results. ## The intake-to-accounting workflow
- Receive the file from the agreed inbox or folder. Store the original and a SHA-256 of the bytes. Record the source message or path.
- Reject unsupported or unreadable files into a visible exception queue. Do not invent missing pages.
- Extract into one invoice-output schema. Keep the printed text next to any normalised value.
- Validate required fields and arithmetic. Required for this workflow: vendor, invoice number, date, and total. Check that line amounts sum to the subtotal and that subtotal plus tax matches the printed total, within a small rounding tolerance.
- Detect duplicates before review. A matching source hash is a replay. A matching vendor plus invoice number is the same bill arriving as a new file.
- Place every non-duplicate invoice in review. If no reviewer is available, the status stays
pending_reviewand the destination is not called. - After an explicit
approve, create a draft only. Attach the source if the destination allows it. Store the destination id against the intake record. - If the destination writes and the response is lost, retry with the same idempotency key. The retry must return the existing draft.
Microsoft's vendor-invoice reference architecture follows the same shape in a different stack: intake, validation, a pending vendor invoice, and a duplicate guard so a redelivered email does not create a second ERP record. That example is XML-heavy and Dynamics-specific. Use the pattern. Do not copy its country rules or its stated service-level target.
Extraction options
Extraction is one step. It is not the workflow.
| Option | What official docs say it does | What you still owe the workflow |
|---|---|---|
Azure Document Intelligence prebuilt-invoice |
Reads invoices, utility bills, sales orders, and purchase orders and returns structured JSON, including line items. Microsoft documents support for 27 languages on the current invoice page. | Map VendorName and InvoiceId into your schema. Add math, duplicates, and a human gate. |
| AI Builder invoice processing | Extracts a published field list such as VendorName, InvoiceId, InvoiceDate, SubTotal, TotalTax, InvoiceTotal, and Items. Each listed field can carry a confidence score. Microsoft documents a 20 MB file limit and a per-environment call limit. |
Confidence is not approval. Microsoft's own example flows sometimes call a second model when a score is low. You still decide who may write a draft. |
Google Document AI Invoice Parser (INVOICE_PROCESSOR) |
A specialized processor that extracts header and line-item fields such as invoice_id, supplier_name, invoice_date, due_date, total_amount, total_tax_amount, and line-item amount, description, quantity, and unit price. |
Normalised dates and amounts still need your required-field and total checks. |
| OCR or PDF text only | Returns words and lines. It does not decide that a string is the invoice number. | You must parse, validate, and review. |
| Local labeled-text helper | Useful for fixtures and unit tests. The reviewed test pack uses this so no paid account is required. | It is not a production extractor and does not prove PDF or scan performance. |
Do not publish an accuracy rate from any of these options until you have run your own files and recorded the extractor version, date, and failures. This page has no live Azure, Google, or OpenAI run.
Field mapping
Keep one internal schema. Vendor payloads change. The validator should not.
| Internal field | Typical extractor names | Required before draft review |
|---|---|---|
| vendor | VendorName, supplier_name, SupplierName | Yes |
| invoice_no | InvoiceId, invoice_id, invoice_number | Yes |
| date | InvoiceDate, invoice_date | Yes |
| due_date | DueDate, due_date | No |
| po_number | PurchaseOrder, purchase_order | No |
| currency | CurrencyCode, currency | Yes for the test pack |
| subtotal | SubTotal, net_amount | Needed for arithmetic |
| tax | TotalTax, total_tax_amount | Needed for arithmetic |
| total | InvoiceTotal, total_amount | Yes |
| line_items[].description | Description, line_item/description | Yes when lines exist |
| line_items[].quantity | Quantity, line_item/quantity | Yes when lines exist |
| line_items[].unit_price | UnitPrice, line_item/unit_price | Yes when lines exist |
| line_items[].amount | Amount, line_item/amount | Yes when lines exist |
The reviewed pack treats money as matching when the absolute difference is at most 0.011. That tolerance is for ordinary rounding. It is not a licence to rewrite a supplier total.
Map the destination separately. A QuickBooks bill, a Xero bill, and a Dynamics pending vendor invoice are different objects. Confirm the draft object in the current vendor docs before you build.
What can run automatically, and what cannot
| Situation | Automatic action | Person required |
|---|---|---|
| File stored and hashed | Yes | No |
| Fields extracted into the schema | Yes | No, unless the extractor is unavailable |
| Required field present and totals add up | Flag ready for review | Yes, before any draft write |
| Missing invoice number | Flag missing_invoice_no |
Yes. Hold it unless a person approves an override |
| Printed total does not match subtotal plus tax | Flag conflicting_total |
Yes. Hold it unless a person approves after checking the source |
| Same bytes or same vendor plus invoice number | Status duplicate. No review. No destination. |
Only if your policy later allows a documented override. The test pack does not. |
| No reviewer in the workflow | Keep pending_review |
Yes. Zero destination attempts |
Reviewer chooses approve |
Create one draft | The approve decision itself |
| Destination writes, then the response is lost | Retry the same idempotency key | Confirm the existing draft id, not a new bill |
| Payment, refund, or supplier bank change | Never in this workflow | Entirely outside the first build |
Human gates
A person keeps these decisions:
- Approve or reject a non-duplicate invoice
- Override a missing invoice number after seeing the source
- Override a conflicting total after checking the printed invoice
- Confirm that a retry returned the same draft
The workflow must not post, pay, refund, or change a supplier record. Draft only.
Microsoft's vendor-invoice architecture states that a human reviews anomalies and exceptions. AI Builder documents confidence scores. Neither source says a high score is permission to skip approval on a first accounting write.
Failure paths and retries
| Failure | Expected status | Destination |
|---|---|---|
| No reviewer | pending_review |
Zero attempts |
| Duplicate source hash | duplicate |
Zero attempts |
| Same vendor and invoice number, different bytes | duplicate |
Zero attempts |
| Missing invoice number | Review; hold unless a person overrides | Zero attempts unless a person approves |
| Conflicting printed total | Review; hold unless a person overrides | Zero attempts unless a person approves |
| Unreadable file | Exception queue | Zero attempts |
| Reviewer rejects | rejected |
Zero attempts |
| Destination writes, response lost | Retry same key, then drafted if the draft exists |
Two attempts, one write in the test pack |
| Retry without a stable key | Unsafe | Can create a second draft |
Intuit's QuickBooks Online API docs recommend a request id on writes. If the same request id is sent again, the service returns the original response instead of creating another transaction. If you omit that key, a retry can create a duplicate. Other accounting APIs need their own documented equivalent. If the product has no request-level key, look up the vendor and invoice number before you insert.
Microsoft's vendor-invoice example uses invoice number plus a vendor identifier to stop a redelivered email from creating a second Dynamics record. That is the same job as the test pack's vendor-plus-invoice-number key.
Test cases
Run every extractor and every workflow against the same five fictional invoices. Expected fields and workflow outcomes live in the reviewed pack.
| Case | Fixture | Expected extraction | Expected workflow |
|---|---|---|---|
| Clean | INV-TP-2401, CAD 452.00 | Vendor Ridgemont Industrial Supply Co, invoice number, date, matching totals | Review, then one draft after approve |
| Duplicate | Same bytes as INV-TP-2401 | Same fields | duplicate, no review, no destination |
| Missing invoice number | Ashbridge Print Works, blank number | invoice_no is null, totals 257.64 |
missing_invoice_no, pending or rejected, no draft unless a person overrides |
| Conflicting total | INV-TP-2404 | Subtotal 210.00, tax 10.50, printed total 185.00 | conflicting_total, no draft unless a person overrides |
| Ambiguous timeout | INV-TP-2405, CAD 164.98 | Matching totals | After approve, two destination attempts and one write |
The pack's reference processor uses a simulated reviewer so the unit tests are repeatable. That is test code. It is not proof that a person approved a live invoice.
Unreadable scans and low-confidence OCR are not in this five-file set. Add them later against the same schema. Do not treat labeled text as a substitute for your own PDFs.
What to measure
Record volume, handling minutes, exception reasons, duplicate stops, reviewer decisions, destination attempts, and destination writes. Measure elapsed queue time separately from active review time.
Do not convert those counts into a savings claim on this page. The existing Automation ROI Calculator is a planning worksheet. Replace its illustration with your observed numbers. Staff minutes released are not automatically cash saved. Include extractor cost, review time, and failed-run time.
This article does not report a live production metric.
How to use the test pack
The free Invoice Processing Test Pack includes five fictional fixtures, expected JSON, schemas, a local test runner, an editable workbook, and a PDF.
Start with fixtures/01-clean-invoice.txt and expected/01-clean-invoice.json side by side. Then run python3 run_tests.py, which uses the standard library only. If you test Azure, AI Builder, Google Document AI, OCR, or n8n, map the result into the adapter-result JSON rather than changing the validator to match a vendor payload.
Implementation sequence
- Write one sentence that names intake, invoice family, reviewer, and draft object.
- Lock the internal field list and the duplicate key.
- Walk the five fictional cases on paper and write the expected status for each.
- Choose an extractor and map it into the schema. Leave paid accounts out of the first test if the labeled fixtures are enough to prove the gates.
- Build validation, the duplicate store, and the review queue. Prove that no reviewer means zero destination attempts.
- Add the destination as draft-only, with an idempotency key or a pre-insert lookup.
- Run the five cases. A clean approve may write one draft. A timeout retry may not write a second.
- Pilot with human review on every live write. Widen automation only after you have recorded your own failures.
If the intake, reviewer, or destination is still unclear, start with a Document Workflow Opportunity Audit. That is the existing AI Success Audit with a document-workflow focus.
Realistic limitations
- Extraction does not prove goods were received, the tax treatment is correct, or the supplier is genuine.
- A confidence score is a model signal. It is not a posting authority.
- The five fictional cases prove workflow gates. They do not prove OCR quality on your PDFs.
- Accounting objects and retry behaviour differ by product and company settings. Read the current API docs for the destination you will use.
- This first workflow does not pay anyone.
- App-specific pages (QuickBooks, n8n, Power Automate) still need their own instructions. This page does not replace them.
Next step
If you already know the intake channel, the reviewer, and the accounting draft object, scope an Invoice Intake-to-Accounting System through AI Automation Systems. Bring the five fictional cases and your own redacted samples.
If several document workflows are competing for attention, use the AI Success Audit first.
Sources
- Flowgrammer, "Document Processing Automation: What to Automate First", Flowgrammer, accessed 2026-09-08, /insights/document-processing-automation
- Microsoft, "Invoice processing prebuilt AI model", Microsoft Learn, accessed 2026-09-08, https://learn.microsoft.com/en-us/ai-builder/prebuilt-invoice-processing
- Microsoft, "Invoice data extraction – Document Intelligence", Microsoft Learn, accessed 2026-09-08, https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/prebuilt/invoice?view=doc-intel-4.0.0
- Microsoft, "Automate vendor invoice processing with Power Automate and AI Builder", Microsoft Learn, accessed 2026-09-08, https://learn.microsoft.com/en-us/power-platform/architecture/reference-architectures/vendor-invoice-integration
- Microsoft, "Use the invoice processing prebuilt model in Power Automate", Microsoft Learn, accessed 2026-09-08, https://learn.microsoft.com/en-us/ai-builder/flow-invoice-processing
- Google, "Processor list", Google Cloud Documentation, accessed 2026-09-08, https://cloud.google.com/document-ai/docs/processors-list
- Google, "Pretrained overview", Google Cloud Documentation, accessed 2026-09-08, https://cloud.google.com/document-ai/docs/pretrained-overview
- Intuit, "Basic ID and field definitions for the QuickBooks Online Accounting API", Intuit Developer, accessed 2026-09-08, https://developer.intuit.com/app/developer/qbo/docs/learn/learn-basic-field-definitions
- Intuit, "What is RequestId and its usage", Intuit Developer Support, accessed 2026-09-08, https://help.developer.intuit.com/s/article/What-is-RequestId-and-its-usage
- Flowgrammer Invoice Processing Test Pack v0.1.0
Frequently asked questions
What is invoice processing automation?
It is the path from a supplier invoice file to a reviewed accounting draft. Extraction, validation, and routing can be automatic. Approval of the draft stays with a person.
Is invoice processing automation the same as accounts payable automation?
Invoice processing is one part of accounts payable automation. It moves an invoice through intake, extraction, validation, duplicate checks, review, and draft creation. Accounts payable automation may also cover matching, approval policies, payment, remittance, and reconciliation.
Which fields should the workflow extract first?
Start with vendor, invoice number, date, currency, line items, subtotal, tax, and total. Add purchase order, due date, and tax registration when the destination or your matching rules need them.
When should a person review an invoice?
On a first build, review every non-duplicate invoice before any draft write. Always review a missing invoice number, a conflicting total, an unknown supplier, and a low-confidence field that would change the amount.
How do you stop duplicate invoices?
Hash the source file and also key vendor plus invoice number. If either key matches a seen invoice, stop. Do not ask a reviewer and do not call the destination. A later policy override needs its own test.
What if the accounting system writes a draft and the response is lost?
Retry with the same idempotency key, or look up the vendor and invoice number before inserting again. The test-pack timeout case expects two attempts and one write.