Free · no signup · no row cap

Duplicate Invoice Checker — free client-side duplicate invoice checker

Drop a CSV or Excel invoice ledger, map columns, and find duplicate-payment risks. Your file never leaves your browser.

Private by design: the file never leaves your browser. There are no uploads, accounts, credits, watermarks, or usage limits.
CSV is parsed locally; simple .xlsx workbooks are also read in the browser.

Load a ledger to begin, or review the sample mapping below.

Column mapping

Auto-guesses are shown after upload. You can correct every field before running the check.

Rows scanned: 0
Exact duplicates0
Near duplicates0
Same invoice number across different suppliers0

Exported findings CSV

Exact duplicates

Near duplicates

Same invoice number across different suppliers

Parsing errors

One-line tool description

Drop your CSV or .xlsx ledger and run a privacy-first scan (no signup, no upload). The checker finds exact duplicates, near-duplicates (same supplier + same amount within a date window), and same invoice number used for different suppliers — all in your browser.

Three quick steps

  1. Drop your CSV or XLSX file (or paste). The tool auto-guesses headers; confirm the mapping for invoice number, supplier, amount, currency and date.
  2. Click "Scan" (adjust the near-duplicate window or enable optional fuzzy supplier matching). Progress is shown for large files.
  3. Review grouped results (Exact duplicates / Near duplicates / Same invoice across suppliers / Parsing errors). Export findings as CSV with original row numbers.

What the summary shows

A short top-line summary lists rows scanned and counts for each finding class (Exact duplicates, Near duplicates, Same invoice across different suppliers) so you know the scope at a glance.

How it works — rules and formulas

File handling and privacy: the file never leaves your browser — no fetch/XHR/upload is performed. No signup, no limits, no watermark.

Row identity and reporting

Original file row indexes are preserved and shown. If the file has a header row, the UI clearly indicates whether row numbers count the header (recommendation: show first data row as row 2 when header present).

String normalization (invoice ID, supplier name)

Apply Unicode NFKC normalization, trim leading/trailing whitespace, collapse consecutive internal spaces, then compare case-insensitively (toLowerCase).

Invoice-number equality (Exact duplicates)

Exact equality on normalized invoice strings by default. There is a toggle to optionally strip non-alphanumeric characters before comparing (user-controlled). Exact duplicates = same normalized invoice number appearing more than once; all rows reported with their original row numbers.

Amount parsing and equality

Strip currency symbols and grouping separators (commas, thin spaces U+2009, etc.), parse numeric value using arbitrary-precision decimal to avoid floating-point error. Compare amounts after rounding to the currency's minor unit (number of decimal places) per CLDR / ISO 4217.

Date parsing and window rule

Parse dates with ISO-aware parser; accept common formats (ISO YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY) but surface ambiguous inputs for locale selection. Compute calendar-day difference using UTC-day boundaries (convert dates to UTC 00:00 and subtract). Near-duplicate date rule = abs(dayDiff) <= windowDays (default windowDays = 7, inclusive).

Near-duplicates definition (classic double-payment detection)

Two rows A and B are near-duplicates if:

  1. Supplier match: supplier names equal after normalization (default exact); optional fuzzy-match with Jaro–Winkler >= 0.85 if enabled.
  2. Amount match: amounts equal after rounding to the currency's minor unit.
  3. Date proximity: calendar-day difference <= windowDays (default 7).
  4. Invoice numbers differ after normalization (if they’re the same, they belong to Exact duplicates).

Same invoice number across different suppliers

Report cases where the same normalized invoice number appears with two or more different normalized supplier values (these are likely data-entry mix-ups and need a different fix than exact duplicates).

Malformed rows

Rows with missing mapped columns, unparseable amounts, or invalid/ambiguous dates are listed in a "Parsing errors" section with the row number and error reason; the scanner does not crash on malformed input.

Performance and scale

To handle tens of thousands of rows without freezing, the implementation uses streaming parsing + Web Worker and shows progress. For near-duplicates, indexing by supplier+amount and sorting by date then sliding a window is recommended for O(N log N) performance per bucket.

Security & privacy note

Files are processed entirely in your browser — we never upload ledger contents to any server. That’s why no signup or account is required.

FAQs

Is my file uploaded or sent to a server?

No. Processing is performed entirely in your browser; no fetch/XHR/upload is performed and your file never leaves your machine.

What columns does the tool need?

It needs an invoice number (ID), a supplier/vendor name, an amount, a currency (recommended), and an invoice date. Column names vary across systems — the tool auto-guesses common headers but always shows the mapping so you can correct it.

How does near-duplicate detection work?

Near-duplicates are rows with the same supplier (normalized), the same amount after rounding to the currency’s minor unit, and invoice dates within the configurable window (default 7 days). Invoice numbers must be different for rows to be classified as near-duplicates.

What date formats are supported and what if my dates are ambiguous?

The scanner accepts ISO (YYYY-MM-DD) and common localized formats (MM/DD/YYYY, DD/MM/YYYY). If a date is ambiguous (e.g., 03/04/2023), the UI surfaces the ambiguity and asks you to pick the correct locale or marks the row as malformed rather than guessing.

Can I change the date window or enable fuzzy matching for suppliers?

Yes — the near-duplicate date window is adjustable (default 7 days). Fuzzy supplier matching is optional and off by default; enabling it applies a Jaro–Winkler style similarity threshold (recommended 0.85) and may increase false positives.

How do you handle currencies with no decimal places (e.g., JPY)?

Amounts are rounded to the currency’s minor units (per CLDR / ISO 4217). For example, JPY has 0 fractional digits so comparisons are integer-based after rounding.