How the CSV Payment Importer Matches Payments to Invoices
In this article
Bank and payment-processor exports rarely use the same column names, and they never come with an invoice ID attached. Importing one of these CSVs into Invoice Generator means turning a spreadsheet of "some deposit happened on some date from someone" into a set of payments correctly attached to the invoices they were paying off — and doing that without a human manually matching every row. Here's exactly how that matching works, and where it deliberately declines to guess.
Recognizing Columns Without a Fixed Template
The importer doesn't require your CSV to follow a specific schema. For each field it needs, it checks a short list of common header aliases and takes the first one present: an amount can come from a column named amount, credit, paid, or deposit; a payment date from payment_date, date, or posted_date; a payer name from payer, name, or client; a memo from reference, description, or memo. This is why you can generally export a CSV straight from your bank or Stripe or PayPal and import it as-is — the importer is doing the work of guessing which of your columns means what, rather than asking you to rename headers first.
Rows That Get Skipped Before Matching Even Starts
Not every row in an uploaded CSV becomes a payment record. Any row where the parsed amount isn't a valid positive number is dropped silently before the matching step runs — a blank amount cell, a non-numeric value, a zero or negative figure (a refund line, say) all fall into this category. This is a deliberate filter: the importer's job is turning deposits into recorded payments, not faithfully reproducing every row of an arbitrary bank statement, some of which will be fees, transfers, or other noise that isn't a client payment at all.
The Matching Heuristic Itself
For every row that survives the amount check, the importer builds a single lowercase search string out of that row's reference, payer name, notes, and the entire raw row data, then checks it against every invoice in the workspace two ways. First, it looks for the invoice's number appearing anywhere in that combined text — a common case when a client's bank transfer memo includes the invoice number you asked them to reference. If no invoice number match is found, it falls back to checking whether the invoice's client name appears in the combined text and the payment amount is within one cent of that invoice's total. Both signals — name and amount — have to line up for this second path to count as a match; a payer name showing up alone, with a mismatched amount, isn't treated as sufficient.
What "Unmatched" Actually Means
A row that doesn't satisfy either matching path isn't discarded — it's still inserted as a payment record, just with no invoice attached and a status of "unmatched" rather than "matched." That payment is fully visible in your payments list and can be manually reconciled to the correct invoice later, which matters because the matching heuristic is intentionally conservative: it would rather leave a payment unmatched than misattach it to the wrong invoice on a fuzzy resemblance. If your CSV has ambiguous rows — a client who pays several near-identical invoice amounts in the same month, say — expect some of them to land as unmatched and need a manual nudge.
What Happens to a Successful Match
When a row does match, the importer doesn't just tag the payment row and stop there. Inside the same database transaction, it recalculates that invoice's payment snapshot — its paid amount and status — from the full set of matched payments now on record, and it writes an audit-trail entry recording that a payment was reconciled through the CSV import, distinct from a payment entered manually one at a time. This keeps a CSV-imported bulk payment behaviorally identical, from the invoice's perspective, to a payment you'd entered by hand — the invoice's status updates the same way either path gets there.
Currency Comes From the Row, Not the Invoice
Each imported payment records whatever currency code and symbol its row specifies — falling back to USD and a dollar sign if the row doesn't include one — rather than inheriting the currency of the invoice it eventually gets matched to. In a single-currency workspace this distinction never surfaces, but if you operate across currencies, it's worth checking that your export includes a currency column, since an importer default of USD applied to a row that was actually a payment in another currency would understate or overstate what was actually paid once matched against an invoice's own currency-aware total.
Why This Design Trades Convenience for Caution
A more aggressive matcher could plausibly clear more rows automatically — fuzzy string matching, partial amount tolerances, matching on date proximity — but every one of those relaxations increases the odds of a payment landing on the wrong invoice, silently marking one client's invoice paid while leaving the actual payer's invoice untouched. The importer's current design accepts leaving more rows unmatched in exchange for near-zero odds of a wrong match slipping through unnoticed, on the reasoning that a payment sitting unmatched in your list is an easy, visible problem to fix, while a payment silently misattached to the wrong invoice is the kind of error that can go unnoticed for months.
Related Articles
Matched, Unmatched, Reconciled: How Payment Status Actually Works
Every recorded payment carries a status that determines whether it counts toward an invoice's paid amount at all — and deleting an invoice doesn't delete its payments, it unmatches them.
Why Your Reports Show Separate Totals Per Currency
There's no exchange-rate conversion anywhere in the reporting layer — here's why that's a deliberate design choice, not a missing feature.
How the Tax Summary Report Calculates What You Owe
Why the tax summary report groups by invoice date instead of payment date, and how taxable revenue is derived rather than stored.
Why Your Invoice Tax Total Is Off By a Penny
You add up the line items yourself, apply the tax rate you know is correct, and the number you land on is a cent or two different from what's printed on the invoice. Nothing was overcharged, nothing was miscalculated in any meaningful se...
1099 Contractors and Invoicing: What the IRS Actually Cares About
If you work as a 1099 independent contractor, invoicing isn't just how you get paid — it's part of the paper trail that supports your actual classification as an independent contractor rather than a misclassified employee. This isn't a p...
Sales Tax on Service Invoices: A State-by-State Starting Point
"Do I need to charge sales tax on this?" is one of those questions that sounds like it should have a simple yes or no answer and instead opens up one of the more genuinely inconsistent areas of U.S. tax law. Unlike sales tax on physical...