Articles
Automating invoice processing: what the system actually has to do
The layers an invoice pipeline needs — intake, validation, matching, posting and an audit trail — plus the mistakes that make the first version fail.
- automation
- systems
- invoice-processing
Invoice automation is usually sold as recognition: point a scanner at a PDF and the numbers appear in the accounting system. Recognition is the easy part. What decides whether the project survives its second month is what the system does with the invoice that does not fit — the missing purchase order, the supplier who changed their template, the total that does not match the lines.
The costs being removed
Three tasks repeat on every invoice, and only the first is obvious:
- Entry. Someone reads the document and types the supplier, date, lines, tax and total into the accounting system.
- Correction. A typo, a duplicated invoice, a wrong tax code or a mismatched total has to be found and fixed, usually after the fact.
- Follow-up. Someone asks whether the invoice was received, approved, paid or disputed, because the system does not say where it stands.
Automation that only addresses entry leaves the other two untouched, which is why so many first versions are quietly abandoned: the typing got faster and the month still ended with the same reconciliation.
The five layers
A working pipeline is not one program. It is five responsibilities that fail independently.
- Trigger. Something has to notice that an invoice exists — an email attachment, an upload, a supplier portal, a scheduled poll or a manual start. Every trigger needs an idempotency key, or the same invoice arrives twice and the second copy is paid.
- Validation. Structured checks before anything clever happens: required fields present, dates plausible, totals equal the sum of the lines, currency known, supplier recognised. Validation is the layer that turns a vague failure into a specific rejection the operator can act on.
- Processing. Matching the invoice against what was ordered and received, applying tax and approval rules, and deciding whether it can proceed automatically or needs a person. This is where an agent or a rules engine earns its place — and where an unexplainable decision costs the most trust.
- Integration. Writing the result into the accounting system, the stock system or the payment run, and reading back the identifiers. Integrations are the slowest part to build and the most likely to be underestimated.
- Monitoring. A queue you can look at, an alert when a document is stuck, and an audit trail that records who or what changed a field and when. Without this layer, a silent failure looks exactly like a quiet week.
The build described here used serverless functions, PostgreSQL, Redis for the queue, and an agent reached over MCP for the judgement calls, with the rules kept outside the model so they could be changed without a redeploy.
A six-week delivery that usually holds
| Week | Deliverable |
|---|---|
| 1 | Map the workflow and measure where invoices actually wait |
| 2 | Trigger and validation layers, with a manual upload as the fallback |
| 3 | Matching and approval logic |
| 4 | Integration with the accounting system, tested on copied data |
| 5 | Staging review with the people who do the work today |
| 6 | Go live for one supplier or one document type |
| 7+ | Weekly tuning, then widen the scope |
The last row matters more than the timeline. Going live on a narrow slice gives the team a way to compare the new path with the old one, and gives you a rollback that is a setting rather than a project.
Where these systems break
Starting too big. Automating the whole cycle at once means every failure appears simultaneously and nobody can tell which layer caused it. Automate the highest-friction step, prove it, then extend.
Treating every exception as a bug. Real invoices are inconsistent. The system needs a manual override from the first day, and the override needs to be recorded — an override that leaves no trace is how incorrect payments become invisible.
No monitoring. An invoice that fails validation and disappears into a log file is worse than a manual process, because nobody is looking for it. Every failure path needs an owner and an alert.
Skipping training. The people who process invoices know the exceptions your specification missed. Budget more time than you expect for them to test the system, and expect the first version to change because of what they find.
Hardcoded rules. Tax rates, approval thresholds and supplier formats change. If a rule change requires a developer and a deployment, the system will drift out of date and the spreadsheet will come back.
Patterns worth reusing
- Event-driven triggers with idempotency keys, so a retry cannot duplicate a payment.
- A validation schema per document type, versioned, with the rejection message written for the person who has to fix the document.
- A decision record for every automated choice — which rule matched, what the model proposed, what was accepted — so a disputed invoice can be explained.
- A queue with a human-readable state, not just
pendingandfailed.
A note on the figures
An earlier version of this page carried cost, ROI and percentage tables. Their rows did not reconcile with their totals, and the percentage changes did not match the numbers beside them. Rather than recalculate them into new claims, they are omitted here. What remains — the layers, the delivery shape and the list of mistakes — is the part that transfers to another business without knowing the original deployment.
Services in this article
Start a project
Have something to build?
One short brief is enough. You get a written scope and a fixed quote before anything starts.
