An accounts payable clerk at a regional distributor receives invoice 70912 from a packaging supplier on October 2. It is entered, matched to the purchase order and approved. On October 9 the same supplier sends invoice 70912 again. Same number, same purchase order, same twelve line items. The total is $124.00 lower, and the date is a week later.

Is that a duplicate? It depends on what the word is supposed to protect against. If the question is “have we seen these bytes before,” no. If the question is “will we pay for the same goods twice,” very nearly yes. Duplicate invoice detection is the second question, and the copies that cause the most trouble are the ones that do not look like copies.

This piece walks through four cases from one fictional supplier. The supplier, the buyer, the invoice numbers and the amounts are invented. None of it is accounting or tax advice.

The key that catches the copy

The usual starting point is a composite key: vendor, invoice number, amount and invoice date. If an incoming invoice matches an existing one on all four, it is the same invoice. That key is what we use by default on invoice extraction, and it does its job well. It catches the PDF that arrives once by email and once through the supplier portal, the scan of the paper copy that follows the e-invoice, and the reminder that attaches the original.

Some of that never needs to reach the key. A message delivered twice by the mail server, or an attachment forwarded by two people, is a transport duplicate: identical bytes, often the same message ID. Those are suppressed at intake, before extraction, and the intake should say it happened rather than drop the second copy silently. That layer is covered in why an inbox is not a workflow. What reaches the duplicate check is every unique document, and from there the key has to work on extracted values, not on files.

The key fails in two directions. It misses copies where one of the four values changed for a reason, and a looser version of it flags invoices that are not copies at all. Both failures cost money, the second one more slowly.

Four cases, one table

These are the four invoices from the supplier in October, read against the four-field key.

ScenarioWhat changesWhat the four-field key seesAction
Exact copy (portal after email)NothingMatch on all fourBlock; link to the original
Corrected resubmission of 70912Tax, total and invoice dateNo match: amount and date differReview, with the differing fields shown
Number written differently“INV-004417” on one, “4417” on the otherNo match: number differs as textReview, after number normalization
Monthly charge, invoice 70955Invoice number and service periodNo match; a vendor-plus-amount key would matchPass; not a duplicate

Only the first row is easy. The second and third are the ones that get paid twice, because nothing on the screen says they are related. The fourth is the one that teaches reviewers to ignore warnings, if the check is loosened to catch the second and third.

The corrected resubmission, field by field

The supplier sent the second 70912 because the first one charged sales tax at 8.25% on a delivery to a location where 7.25% applied. The supplier corrected the rate, regenerated the invoice and sent it again. Here is what an extraction returns from each.

FieldFirst 70912Second 70912Same?
VendorHarbor Packaging Co.Harbor Packaging Co.Yes
Invoice number7091270912Yes
Invoice date2026-10-022026-10-09No
Purchase orderPO 45118PO 45118Yes
Lines (12)Subtotal $12,400.00Subtotal $12,400.00Yes, line by line
Tax8.25% · $1,023.007.25% · $899.00No
Total$13,423.00$13,299.00No (−$124.00)
Printed note—“Corrected invoice — replaces invoice dated 10/02”New

Two of the four key fields changed, so the strict key says these are different invoices. A person looking at the table says they are the same sale billed twice, once wrongly. The useful signal is not any single field. It is the pattern: same vendor, same number, same purchase order and identical lines, with the differences confined to tax, total and date.

So the second check runs on a narrower key, vendor plus normalized invoice number, and when it matches an existing invoice whose amount or date differs, the result is not “duplicate” and not “new.” It is a possible duplicate, with the list of fields that differ and both values side by side. That is what the reviewer needs: not a warning, but the reason for it.

What the reviewer does next depends on a fact that is not on either invoice: whether the first one has been paid. If it has not, the first is voided and the corrected one goes through approval. If it has, the corrected invoice is not a new payable at all. The supplier owes $124.00 back, normally as a credit note, and paying the second invoice would turn a $124.00 correction into a $13,299.00 overpayment. The extraction cannot make that decision. It can make sure the decision is made before the payment run, not discovered after it.

The printed note helps when it is there, and it should come back as its own field: a document type of “corrected invoice” and a reference to the invoice it replaces. Many suppliers do not print one. The check cannot depend on it.

Normalize the number before you compare it

Invoice numbers are typed, printed, scanned and retyped. The same supplier’s invoice can reach the ledger as “INV-004417,” “INV 4417” and “4417,” depending on whether it came from the PDF, the portal export or a clerk’s manual entry. Compared as text, those are three invoices.

A normalized number makes them one. The usual steps are to fold case, drop spaces and separators, strip a prefix that the supplier uses on every invoice, and drop leading zeros. The comparison then runs on the normalized value, and both values are kept: the raw one as printed, for the audit trail and for the reply to the supplier, and the normalized one for matching.

Normalization can go too far. A supplier that numbers invoices by year, “2025-0042” and “2026-0042,” issues two different invoices that collapse into one if the year is treated as a prefix. That is why the prefix to strip should be learned from the supplier’s own history rather than written as a global rule, and why a match on the normalized number alone, with a different amount, goes to review rather than to a block.

When the same amount is not a duplicate

The supplier also bills a monthly fee of $1,850.00 for warehouse storage. Invoice 70955 in October has the same vendor and the same amount as invoice 70603 in September, and as every month before that. A check that loosens the key to vendor plus amount, to catch resubmissions with a rewritten number, flags it every month.

The discriminator is the service period. October’s invoice covers October 1 to 31; September’s covered September. Same vendor, same amount, consecutive numbers and non-overlapping periods is the signature of a recurring charge, not a copy. An overlap in the period, or a second invoice for a period already billed, is the case worth flagging.

That only works if the service period is extracted. Many invoices print it in a line description (“Storage — October 2026”) rather than in a header field, and an extraction that returns only the invoice date leaves the duplicate check with nothing to tell September from October. The cost shows up slowly: a check that raises the same false warning every month trains reviewers to dismiss it, and the real duplicate is approved by the same click.

Where the check sits in the flow

Duplicate detection belongs at entry, before approval and before the three-way match. The match does not stop a duplicate on its own: if the purchase order and the receipt still have open quantity, a second invoice for the same goods can match as cleanly as the first did.

It is not the only line of defense. A vendor statement reconciliation catches the duplicate that was already posted, because the supplier’s own statement lists the invoice once. That is a later and more expensive place to find it, often after the payment has gone out. The same idea, a key chosen for the documents and a window to search, is what links two captures of one paper check in duplicate deposit detection. Invoices need a different key because suppliers change them on purpose.

What extraction has to return

One record per invoice, with the fields the check needs as structured values: the vendor resolved to the vendor master, the invoice number raw and normalized, invoice date, service period, purchase order, currency, subtotal, tax with its rate, total, and the lines. Two fields are easy to skip and matter here: the document type (invoice, corrected invoice, credit note) and any printed reference to an invoice it replaces.

The check then returns one of three outcomes, each with its evidence:

  • Duplicate — all four key fields match an existing invoice. The record points to the original and the invoice is held, not deleted.
  • Possible duplicate — the vendor and normalized number match, or the vendor, amount and service period match, but something differs. The record lists the differing fields with both values.
  • Distinct — no candidate, or a candidate ruled out by a different service period. The ruling is recorded, so a reviewer can see why a same-amount invoice passed.

Where review still sits

Everything above is mechanical once the fields are right. The decisions are not. Whether to void the original or request a credit note, whether a supplier’s explanation for a resubmission holds, whether two invoices with the same number from a supplier that recently changed its billing system are one sale or two: those belong to a person in accounts payable, with both documents open.

For the four invoices here, that is one held copy that needs nothing, two items for review with the differences already listed, and one monthly charge that passes with its reason recorded. The exact copy was never the problem. The corrected resubmission was, and it only gets caught if the check is built for invoices that differ.

The supplier, the buyer, the invoice numbers, the amounts and the tax rates above are invented for illustration. This article is general information about document handling, not accounting, tax or legal advice.