In 2022, an invoice-auditing company called OpenEnvoy did something mildly rude: it analyzed a year of its customers' invoices (half a billion dollars' worth) and found nearly one in ten were duplicates. The same bill, arriving twice, on its way to being paid twice. That was $42 million flagged before it left the building, which is a lot of money to ride on the absence of an if-statement. APQC's benchmark puts typical duplicate rates well below that — the vendor sells duplicate detection, after all — but "lower" still means real money, paid twice, quietly.
Here's the part I find genuinely funny: nobody has to do anything wrong to produce numbers like that. A vendor emails the invoice, then uploads it to the portal to be safe. Someone forwards the thread, and the intake system dutifully ingests the forward. A workflow times out halfway, retries, and processes the same attachment twice. Duplicates are produced by systems — and considerate humans — working exactly as designed.
And every one sailed through, because "as designed" includes no memory. The software checked that each invoice was well-formed — right fields, a plausible amount. It never checked whether the invoice was new, because nobody told it that "new" was a requirement. A human bookkeeper gets an itchy feeling seeing the same €4,300 from the same vendor twice in one week. The software feels nothing. It wasn't built to.
This is before ordinary mistakes even enter the picture: manual invoice processing runs a roughly 3.6% data-entry error rate, per IOFM — wrong amount, wrong quantity, wrong recipient. So somewhere between a few percent and, in OpenEnvoy's worst-case sample, one in ten of what arrives shouldn't be paid as-is. The system will correctly pay all of it. Correctly is doing a lot of work in that sentence.
Make it trustworthy: what the bookkeeper knew
The fix isn't smarter software. It's giving the software three habits any good bookkeeper already has — and if you build automations, each one is small enough to add this week.
Memory. Before anything gets paid, look it up in a ledger of everything already seen — a fingerprint of vendor, invoice number, and amount in a spreadsheet or a lookup table. Seen before: stop, show a human both copies. New: record it, proceed. In Zapier that's one "Lookup Spreadsheet Row" step; in n8n, a Data Table "Get row(s)" step. Ten minutes of work, and the single highest-ROI change I know of in billing automation. (Two technical footnotes that will bite you if skipped: normalize the fingerprint first, because vendors write INV-001, INV 001, inv1 and un-normalized dedup is dedup theater; and dedupe each batch before inserting, since Sheets and Airtable have no unique constraint. What you're building is an idempotency key in a spreadsheet-shaped costume.)
Matching. A duplicate is one failure; a wrong bill is another. Keep a table of what you actually agreed to pay per vendor; the system compares, and anything outside a 2% tolerance — or from a vendor not in the table at all — goes to a human. That converts "we pay what arrives" into "we pay what we ordered," a surprisingly large upgrade for one lookup.
Suspicion. Three rules, in order of importance: changed bank details always go to a human, no exceptions — "correcting" the account number on an otherwise-real invoice is how actual invoice fraud works, and an automation that auto-applies the fix is the accomplice of the year. First invoice from a new vendor: a human looks. Amount well above that vendor's usual: flag it. The point isn't catching criminals; it's that someone looks before money moves.
Then prove the habits work, because a check you've never seen fail is a check you have no evidence works: once a quarter, feed the system a duplicate on purpose — an already-paid invoice, with the payment step pointed somewhere harmless. (If the ledger is new, backfill last month's paid invoices first, or the drill "fails" for the boring reason that the ledger has never seen the invoice.) See if anything objects. If it sails through, better to learn that today than in an audit. A fire drill: mildly annoying, and much cheaper than the fire.
The takeaway
If you build automations, the ledger lookup is your ten minutes this week. But the question underneath this piece doesn't require touching a workflow, and you can ask it of anything you rely on — the payroll run, the monthly report, the process you inherited and never questioned:
If this were wrong, how would I know?
If the honest answer is "someone would probably notice," you've just found your missing if-statement. "Paid twice" is not an error to a system that was never told "twice" exists — and most systems, and more than a few teams, are running on exactly that kind of trust.
--- The If Statement — the logic everything rides on. If someone you know pays invoices on autopilot, forward this to them.
