Stripe Invoice Doesn't Match QuickBooks? Causes and Fixes

Stripe and QuickBooks invoice totals diverge for seven specific reasons - applied customer balance, inclusive-tax rounding, multicurrency, fees,...

Acodei Content Team · 7/31/2026 · 18 min read

Stripe says the invoice was $1,206.25. QuickBooks says $1,356.25. Nothing is broken, nobody fat-fingered anything, and both numbers are correct.

That is the frustrating part of an invoice mismatch: the two systems are usually not disagreeing about money at all. They are answering two different questions. Stripe is telling you what it charged the card. QuickBooks is telling you what the customer owed. A $150 credit sits between them.

This post covers what actually causes Stripe and QuickBooks invoice totals to diverge, how to tell a real error from an accounting difference that is supposed to be there, and what a sync tool should be checking before it writes anything into your books. If you want the totals to stop drifting in the first place, Acodei checks what it writes into QuickBooks against the Stripe original — the four specific checks, and their scope, are in the next section.

First, stop comparing the wrong two numbers

A Stripe invoice is not one number. It is at least six, and most "mismatches" are a comparison between two fields that were never meant to be equal. Straight from Stripe's invoice object reference:

FieldWhat it actually means
subtotalTotal of subscriptions, invoice items and prorations before any invoice-level discount or exclusive tax. Item-level discounts are already applied.
totalThe subtotal after discounts and taxes.
amount_dueThe final amount due at this time. Account credit and a positive starting_balance are both taken into account. This is the amount Stripe generates the charge for.
amount_paidWhat was actually paid, in the currency's smallest unit.
amount_remainingamount_due minus amount_paid.
starting_balanceThe customer balance before the invoice was finalized.

The two fields people compare by reflex are total and whatever QuickBooks shows in A/R. Those two are supposed to be different the moment a customer has a credit balance, a discount, or an out-of-band payment. Before you chase a sync bug, pull the invoice in the Stripe dashboard and write down subtotal, total, amount_due and amount_paid. In most escalations, the "missing" money is sitting in the gap between total and amount_due, and it has a name: applied balance.

One more field worth knowing: amounts come back in the currency's minor unit. 1000 is $10.00 USD. For zero-decimal currencies like JPY, 10 is ¥10 — no division by 100. Anything that assumes two decimals everywhere will be off by a factor of 100 on a yen invoice. Acodei does not support zero-decimal currencies.

The four checks that should run before anything is written

Most integrations treat "sync" as a one-way write: read the Stripe invoice, create the QuickBooks invoice, mark it done. The write succeeding is not the same as the write being correct. QuickBooks will happily accept an invoice with the wrong total.

Acodei validates after writing, and the checks are specific:

  1. Invoice numbers are compared to prevent duplicate invoices from being created in QuickBooks.
  2. The final QuickBooks invoice is compared against the Stripe invoice amount — exactly. This check applies when tax is enabled.
  3. When a payment is recorded, the payment amount is checked against what should have been applied to the QuickBooks invoice.
  4. When a payment is recorded, the payment linkage is checked — that it attached to the correct QuickBooks invoice, not merely to the right customer.

Checks 3 and 4 only run when a payment is being recorded, and check 2 is scoped to tax-enabled accounts. That scoping matters more than a marketing page would admit, so it is worth being plain about it: an untaxed invoice does not get the exact-amount comparison. What it does get is the invoice-number check and, at payment time, the amount and linkage checks.

When a check fails, the job does not quietly move on. The transaction records the error and surfaces in the Data Feed — the ledger in the Acodei dashboard showing every synced and errored transaction. A failed invoice is visible as a failed invoice, which is the entire point. A silent partial write is worse than a loud failure, because you find the silent one in March while reconciling January.

Seven reasons the totals legitimately drift

1. Applied balance — the $150 in the opening example

Stripe lets a customer carry a balance from past overpayments or manual adjustments in the dashboard, and applies it to reduce amount_due on the next invoice. Here is the invoice from the top of this post:

LineAmount
Pro plan$1,000.00
Onboarding$250.00
Subtotal$1,250.00
Sales tax (8.5%, exclusive)$106.25
Total$1,356.25
Applied customer balance−$150.00
Amount due (and charged)$1,206.25

By default, Acodei includes the applied balance as a line item on the QuickBooks invoice, so the invoice totals $1,206.25 and matches the amount Stripe actually charged. Cash and A/R agree, and the invoice closes cleanly when the payment lands.

There is also an admin setting — Skip "Applied Balance" as line item on Invoice — that does the opposite: Acodei ignores the applied balance and creates the invoice at the full gross amount, subtotal + tax, so QuickBooks A/R reflects the full value of the sale. Under that setting our example posts at $1,356.25 while Stripe charged $1,206.25, a $150.00 difference that is expected rather than broken.

Both behaviors are defensible; they answer different questions. What you cannot do is run the second setting and then reconcile as though the first were in force. If you are unsure which one your account uses, the Data Feed shows what was actually written for a given invoice — check there before adjusting anything by hand.

2. Inclusive tax and the rounding cent

Stripe's tax behavior is either exclusive (tax added on top of the listed price) or inclusive (the listed price already contains the tax). Inclusive pricing is the norm for B2C outside the US, and it is arithmetically awkward.

Take a €99.99 line at 20% VAT, inclusive. The net is €99.99 ÷ 1.2 = €83.325. There is no such thing as a third of a cent, so something has to give:

  • Round the net to €83.33 and recompute tax at 20% and you get €16.67 — a €100.00 total, a cent above the price you advertised.
  • Hold the gross at €99.99 and derive the tax as €99.99 − €83.33 = €16.66, and the tax line is no longer exactly 20% of the net.

Every inclusive-tax system picks one of these and lives with it. Acodei handles inclusive tax through a manual tax calculation in the backend so the QuickBooks totals align with Stripe's final tax figures, and choosing "Inclusive" in the dashboard turns that on automatically. It is still worth knowing the honest limitation: partial and daily-summary scenarios can sometimes produce rounding differences of a cent or two. On a twelve-line invoice those cents can add up to a visible discrepancy, and it is a rounding artifact rather than lost revenue.

A related trap: if a Stripe tax rate has been archived but still appears on older invoices, that txr_… ID may need to be added manually in Acodei so the rate maps. Our Stripe Tax and QuickBooks guide covers the mapping approaches in full — a single tax product mapped to a liability account for US accounts, or per-rate mapping to QuickBooks tax codes for non-US accounts, including group rates like GST + PST on one line.

3. Multicurrency — two right answers in two currencies

If the invoice is in a currency other than your QuickBooks home currency, "the total" is genuinely two numbers. QuickBooks Online's multicurrency feature must be ON for any non-home-currency invoice to sync at all — and once enabled in QuickBooks, it cannot be switched off.

With Invoice Multicurrency active, a $1,000 CAD Stripe invoice posts to QuickBooks as $1,000 CAD, and the payment carries an exchange rate — say 0.8 — so QuickBooks records $800 USD in the home currency. Both numbers are correct. A reconciliation that compares the CAD invoice against the USD home-currency figure will find a 20% "error" that does not exist.

Two structural details cause most of the confusion here:

  • Per-currency customer records. When a Stripe transaction's currency does not match the QuickBooks customer's assigned currency, Acodei creates a second record in the format Acme - CAD. This is QuickBooks' own design — currency is a property of the customer — and QuickBooks' API restrictions mean these cannot be automatically cleaned up. Seeing Acme and Acme - CAD side by side is expected behavior, not duplication.
  • Undeposited Funds makes it harder. If the holding account is Undeposited Funds, Acodei may delete and resync the invoice in the final recognized currency, rebuilding it so it is neither under- nor over-paid, and applies the exchange rate to each line item individually — tax, shipping, coupons — specifically to stop rounding drift and make the total match the Stripe payment. This is why Invoice Multicurrency is not permitted on Undeposited Funds holding accounts, and why the recommendation for multi-currency users is to pair Invoice Sync with a non-UF asset holding account to reduce resync churn.

One limitation worth stating plainly: Stripe does not provide an invoice-level exchange rate at invoice.created, so the rate comes from QuickBooks' ExchangeRate API or from Stripe later, at payment time. Note also that both Multicurrency Support and Invoice Multicurrency are enabled by the Acodei team on request rather than being self-serve toggles. There is more detail in our Stripe multicurrency guide.

4. Fees — the most common false alarm

This one accounts for a large share of "the totals don't match" tickets, and it is not a mismatch at all.

Stripe fees are never added to invoices. Putting them there would mismatch the totals — the invoice is what the customer owes, and your customer does not owe Stripe's processing fee. Fees are handled separately, through sales receipts, deposits, or expenses depending on your fee-management configuration. With a non-UF holding account and Invoice Sync on, fees as an expense is the only option; with Undeposited Funds, fees can appear as an expense or on the bank deposit.

So a $1,000 invoice does not become $971 in QuickBooks because Stripe took $29. The invoice stays $1,000, and the $29 lands as a separate expense. If you are trying to reconcile the payout rather than the invoice, that is a different exercise entirely — start with our guide to reconciling Stripe fees in QuickBooks, which is the canonical walkthrough for the fee side.

5. Invoice numbers with an -AC1 suffix

If you have ever created invoices by hand in QuickBooks, you have hit "duplicate document number." Acodei's invoice-number suffix setting appends -AC1, -AC2 and so on to synced invoices so they cannot collide with numbers you assign yourself. It is on by default and it is the reason a Stripe invoice numbered INV-2041 may appear in QuickBooks as INV-2041-AC1.

That is a formatting difference, not a mismatch — but there is a real limitation attached to it. Automated suffixing does not protect against invoices being manually renamed in QuickBooks after the fact. Rename a synced invoice and you have broken the link that the duplicate check relies on. This is also the honest scope of duplicate protection generally: it tracks what Acodei itself has synced. It is not scanning your hand-keyed QuickBooks records looking for near-matches. If you are cleaning up duplicates that predate the integration, our duplicate transactions guide covers that job.

6. Zero-dollar and negative invoices

Two edges that surprise people at month end:

  • A pure $0 invoice is not synced. If every line item is zero, it is ignored. But an invoice whose amount_due is 0 while carrying at least one line item greater than zero — a fully credited invoice, for instance — can sync as a regular invoice when the admin Enable $0 Invoices setting is on. It is off by default.
  • A negative invoice total, where credits exceed charges, converts to a Credit Memo, or splits into a memo plus a $0 invoice, depending on amount_paid. Note that the separate "Handle Negative Invoices" admin feature is not released, so this is the behavior to expect today.

Credit notes are their own topic: credit_note.created produces a QuickBooks Credit Memo, linked to the invoice where possible and otherwise posted to the customer. We covered the full mechanics — including what a credit note does to a paid versus an open invoice — in Stripe credit notes in QuickBooks.

7. Failed ACH payments

ACH is slow and optimistic, and the accounting has to handle a payment that looked fine and then wasn't. The current behavior: a new ACH payment in a pending state has payments created against the invoice as though they had succeeded. If it succeeds, nothing changes. If it fails, the payment is deleted, and a pending sale record plus a reversal of that sale record are written to the daily balance summary for the day of the failure.

If you are looking at a period that contained a failed ACH charge, you will see that pair of entries. They are the correction, not a double-count.

What to do when the numbers really are wrong

Sometimes it is a genuine error. The instinct — open QuickBooks, fix the invoice by hand — is the wrong move, and it is worth understanding why.

Acodei stores the mapping between the Stripe object and the QuickBooks record it created. Editing that record directly in QuickBooks changes the books without telling the integration, so the stored mapping now points at something that no longer matches Stripe. The next event on that invoice — a payment, a credit note, a void — is processed against your assumption of the record, not the record you edited into place.

The supported path is resync from the Data Feed. A resync deletes the QuickBooks side and re-runs the transaction through its job, producing the invoice and payment again from the Stripe source of truth. Even in the awkward case where the parent invoice cannot be deleted because it is already linked to a deposit, the child transactions are still dispatched.

A practical order of operations when an invoice looks wrong:

  1. Pull the Stripe invoice and record subtotal, total, amount_due, amount_paid and starting_balance.
  2. Identify which question QuickBooks is answering. If the delta equals the applied balance, see reason 1. If it equals Stripe's fee, see reason 4. If it is a cent or two, see reason 2. If it is a clean percentage, see reason 3.
  3. Check the Data Feed for that transaction. An error there tells you the write was caught, not missed.
  4. Resync from the Data Feed rather than editing QuickBooks.
  5. Confirm QuickBooks' automation settings. Payments and credit memos rely on QuickBooks' automatically apply credits setting being on to settle against invoices; with it off, payments can sit unapplied and every invoice will look unpaid.
  6. Escalate with the invoice ID, not a screenshot of a total.

Two configuration notes that prevent recurring problems: avoid marking invoices "paid outside Stripe" unless you genuinely need to — the setting generates a QuickBooks payment and can route it to Undeposited Funds regardless of your normal holding account — and if a customer is refunded at the payment level rather than through a credit note, the line-level tax breakdown may not be available, which can leave the refunded tax indeterminate and produce a real discrepancy. Refunding via credit note keeps the tax correct.

Where invoice sync fits

Invoice Sync is a one-way mirror: Stripe to QuickBooks, never the reverse. A finalized Stripe invoice creates a QuickBooks Invoice reproducing every line item and tax line your mapping settings allow. A paid invoice creates a Payment or Credit Memo and applies it to the invoice already there. Voided invoices are voided or converted to a credit memo, with any attached credit notes deleted first. An invoice marked uncollectible behaves like a void, and if it is later paid, it is reopened, the void transactions are deleted, and the new payment is processed.

It is a paid-plan feature, enabled per company under Account Mapping ▸ Premium Features, and it runs alongside customer sync, product mapping, tax and multicurrency rather than replacing them. Each invoice line uses the product returned by Multiple Product Mapping when that is enabled, and the default product otherwise.

If you are choosing between per-transaction invoices and an aggregated daily record, that decision changes what "matching" even looks like — our daily summary versus real-time sync comparison walks through both. And if your books are already out of shape from a period of manual entry, the cleanup and rebuild playbook is the better starting point than chasing individual invoices.

The month-end version of this

Reconciling Stripe invoices against QuickBooks at close is a short list once you know what is legitimate:

  • Compare amount_due to the QuickBooks invoice total — not total, unless you know the applied-balance setting is set to full gross.
  • Expect fees to be absent from invoices and present as expenses or on the deposit.
  • Expect -AC1 suffixes on synced invoice numbers.
  • Expect foreign-currency invoices to carry both the transaction currency and a home-currency equivalent, and per-currency customer records alongside them.
  • Treat cent-level differences on inclusive-tax invoices as rounding, and anything larger as worth investigating.
  • Clear the Data Feed's errors before you close, not after.

The full close sequence — including the payout and clearing-account side, which is where most of the remaining work lives — is in our Stripe and QuickBooks month-end close checklist and the Stripe clearing account guide.

Frequently Asked Questions

Why is my Stripe invoice total different from the QuickBooks invoice total?

Most often because the customer had a credit balance applied. Stripe's total is the invoice before account credit; amount_due is what Stripe actually charged. By default Acodei includes that applied balance as a line item so the QuickBooks invoice matches what was charged, but an admin setting posts the invoice at full gross instead. The other common causes are inclusive-tax rounding, a foreign-currency invoice being compared against its home-currency equivalent, and Stripe fees being expected on the invoice when they are never placed there.

Does Acodei check that the QuickBooks invoice matches the Stripe invoice?

Yes, and there are four specific checks. Invoice numbers are compared to prevent duplicate invoices in QuickBooks. The final QuickBooks invoice is compared against the Stripe invoice amount exactly, which applies when tax is enabled. When a payment is recorded, the payment amount is checked, and the payment's link to the correct QuickBooks invoice is checked. Failures record an error and appear in the Data Feed rather than being written silently.

Why do Stripe fees not appear on my QuickBooks invoice?

Because putting them there would mismatch the totals — the invoice is what your customer owes, and they do not owe Stripe's processing fee. Fees sync separately as an expense or on the bank deposit, depending on your holding account and fee configuration. With a non-UF holding account and Invoice Sync enabled, fees as an expense is the only option.

Why does my QuickBooks invoice number have -AC1 at the end?

That is the invoice number suffix, on by default, which prevents synced invoices from colliding with invoice numbers you create by hand in QuickBooks. It is a formatting difference, not a mismatch. Note that suffixing cannot protect against an invoice being manually renamed in QuickBooks afterwards.

Why do I have two customer records for the same customer, like Acme and Acme - CAD?

QuickBooks assigns a currency to each customer record, so a customer transacting in two currencies needs two records. When a Stripe transaction's currency does not match the existing QuickBooks customer's currency, Acodei creates CustomerName - [CurrencyCode]. This is QuickBooks' design rather than a bug, and QuickBooks' API restrictions mean the extra records cannot be removed automatically.

My invoice is off by one cent. Is something broken?

Almost certainly not. Inclusive tax cannot always be split into a net and a tax figure that are both exact at two decimal places, so a cent has to land somewhere. Acodei runs a manual inclusive-tax calculation to keep QuickBooks aligned with Stripe's final tax figures, but partial and daily-summary scenarios can still produce small rounding differences. Cent-level gaps on inclusive-tax invoices are rounding; larger gaps are worth investigating.

Should I fix a wrong invoice directly in QuickBooks?

No — resync it from the Data Feed instead. Acodei stores the link between the Stripe object and the QuickBooks record it created, so editing that record by hand leaves the integration pointing at something that no longer matches Stripe. Resyncing from the Data Feed is the documented practice, rather than manually altering transactions in QuickBooks: it deletes the QuickBooks side and rebuilds it from the Stripe source.

Does Acodei support zero-decimal currencies like JPY?

No. Zero-decimal currencies are not supported. Stripe represents amounts in a currency's minor unit — 1000 means $10.00 USD, while 10 means ¥10 JPY — so any handling that assumes two decimal places misreads a yen amount by a factor of 100. If you invoice in JPY or another zero-decimal currency, raise it with us before connecting.


Invoice totals that drift are usually a configuration question, not a data-integrity one — but you should not have to reverse-engineer which. Acodei mirrors Stripe invoices, payments and credit notes into QuickBooks Online, checks what it writes against the Stripe original, and shows every synced and errored transaction in one Data Feed you can resync from.

Start a free trial to see your own invoices reconcile, or talk to us about a multicurrency or high-volume setup.

Share

Automate your Stripe to QuickBooks sync

Save hours every month. Acodei automatically syncs your Stripe transactions, invoices, and payouts to QuickBooks Online.

Get more operational finance guides like this one

We will only send high-value product and finance content.