Stripe Payments vs Balance Transactions: Why Counts Differ

Stripe's Payments count, your synced event count, and your QuickBooks record count are three different numbers. Why all three can be correct at once.

Acodei Content Team · 8/9/2026 · 16 min read

Open Stripe, filter Payments to last month, and read the count at the top: 412.

Open your sync tool or your QuickBooks Stripe clearing account for the same month and count what landed there. It is not 412. Depending on how you count, it is somewhere between 430 and 900, and the natural conclusion is that something is duplicating.

Almost nothing ever is. You are looking at three different numbers that count three different things, and in a healthy month all three are correct at the same time. Knowing which is which takes about five minutes and saves the afternoon you were about to spend hunting for duplicates that do not exist.

Reconciling Stripe by hand every month? Acodei posts charges, fees, refunds, payouts, and disputes into QuickBooks Online automatically, with the accounts and the direction already right. Start a free trial.

The three numbers

Number one is Stripe's Payments count. It counts customer charges. One customer, one successful payment, one row.

Number two is Stripe's balance transaction count. A balance transaction is created for every movement of money into or out of your Stripe balance. Stripe's balance transaction types reference describes them as "our recommended starting point for reporting on your account's balance activity," created "for every type of transaction that comes into, or flows out of, your Stripe account's balance." Charges are only one kind of movement. Payouts, refunds, disputes, product fees, top-ups, and reserve holds are all movements too, and each gets its own row.

Number three is your accounting event count, which is whatever your sync tool decides your books need to see. This is usually the largest of the three, and the reason is the single most useful thing in this article.

The gap between one and two is Stripe telling you about money that moved for reasons other than a sale. The gap between two and three is your books needing a level of detail that Stripe's own data model deliberately compresses.

What Stripe's Payments view is actually counting

The Payments list is a customer-facing view. It answers "who paid me and did it go through," which is the question it should answer, and it is the wrong number to reconcile against because it is missing every event that is not a customer paying you.

It also splits along a line that has nothing to do with accounting. Stripe uses type=charge for card charges and type=payment for charges made with other payment methods. Same commercial event, two type names, purely because of how the money arrived. Refunds split the same way, into refund and payment_refund.

So before you have even left the sales side, the type field has given you four names for two ideas. Hold that thought, because Stripe has a fix for it.

Where the fee hides, and why it matters more than anything else here

Here is the thing almost everyone gets wrong, including people who have been reconciling Stripe for years.

The processing fee on a card charge is not a separate balance transaction. It is a field on the charge's own balance transaction. Every balance transaction object carries amount (the gross), fee ("fees paid for this transaction"), and net, and Stripe spells out the arithmetic: you calculate net impact "by amount - fee". There is a fee_details array underneath it breaking the fee into components, each with a type of application_fee, payment_method_passthrough_fee, stripe_fee, tax, or withheld_tax.

One charge. One balance transaction. Gross, fee, and net all on the same row.

That is an elegant model for a payments company and a poor fit for a general ledger. QuickBooks does not have a "net" concept for a sale. Revenue is revenue, the processing fee is an expense, and they belong in different accounts on your profit and loss. A $100 sale with a $3.20 fee is one row in Stripe and at minimum two facts in your books.

This is where the count gap comes from. Any tool that gives QuickBooks a usable fee expense has to pull that fee out and treat it as its own thing. So 412 charges can legitimately become 824 accounting events before a single payout, refund, or dispute is counted, and nothing has been duplicated. The same dollars are simply represented twice, once as gross revenue and once as a fee, which is exactly what double-entry bookkeeping requires.

If you take one thing from this article: a count that is roughly double your payment count is the expected shape of a healthy Stripe month, not a symptom.

Note what this also means in the other direction. The stripe_fee balance transaction type is not your processing fees. Stripe reserves it for "fees for Stripe software and services (for example, for Radar, Connect, Billing, and Identity)," which are billed periodically rather than per charge. If you are hunting for your 2.9% and 30 cents as its own row in the balance report, you will not find it there. It is inside the charge. We wrote about the periodic ones separately in Stripe Radar and Billing fees in QuickBooks Online.

The events you did not expect

Beyond fees, a handful of Stripe behaviors generate rows that surprise people. All of these are documented Stripe behavior, and each one produces balance transactions that no customer ever triggered.

Partial captures produce a refund that is not a refund. If you authorize and capture separately and capture less than you authorized, Stripe says "you see two balance transactions: one for the full amount of the authorization, and another reversing the uncaptured portion." That second row has type=refund, "just as if you had refunded a portion of a sale at some later time." Nobody was refunded. If your business authorizes high and captures low as a matter of course, your refund count is structurally inflated and your refund rate looks worse than it is.

Delayed payment methods can fail after they succeed. ACH, direct debit, and other delayed notification methods "remain in a pending state until they either succeed or fail." You get a pending payment row when the payment is created, and if it later fails, "another Balance transaction of type payment_failure_refund appears." Two rows, one attempted sale, and the second one lands days after the first.

A reserve creates two rows minimum, and sometimes four. When Stripe holds funds in reserve, "two balance transactions are created: one to debit the funds from your balance, and a second to credit the funds back to your balance at the end of the reserve period." On top of that, reserve_hold and reserve_release are described as additional balance transactions, counterparts representing the credit to and debit from the reserve balance itself. Net effect on your books over time is zero. Effect on your event count is not zero, and if the hold and the release straddle a month end, one month looks worse and the next looks better. More on the mechanics in our Stripe reserve glossary entry.

Failed and canceled payouts add rows for money that never left. payout_cancel and payout_failure are created when a payout "is cancelled" or "fails" and "the funds are returned to your Stripe balance." So one attempted payout can produce two balance transactions and zero bank deposits. We covered what your books should show in when a Stripe payout fails.

Disputes arrive as adjustments, not as their own object type. Stripe uses type=adjustment for "additions or deductions from your Stripe balance that are made outside of the normal charge/refund flow," and lists disputes, dispute reversals, and refund failures as the common reasons. The description field "describes the purpose of each adjustment," which is the only way to tell them apart at the type level. A single disputed charge that you later win produces two adjustment rows, one out and one back.

Stripe occasionally hands you money nobody paid you. payment_unreconciled is "created when a customer has unreconciled funds within Stripe for more than ninety days," transferring them to your balance. Small, rare, and genuinely income. We wrote that one up in Stripe unreconciled payments in QuickBooks.

Connect adds a whole category. Platforms see application_fee and application_fee_refund for fees earned and returned, transfer and its cancel, failure, and refund variants for money moved to connected accounts, and reserve_transaction when Stripe reserves part of the platform balance against a connected account going negative. If a connected account stays negative for 180 days, Stripe documents a connect_collection_transfer that "transfers a portion of your balance, to zero out that account's balance."

Stop reading type and start reading reporting_category

This is Stripe's own advice and it is stated plainly on the balance transaction object: "To classify transactions for accounting purposes, use the reporting_category field instead of the type field."

reporting_category exists precisely because type is a payments-engineering field and accountants kept misreading it. It fixes three things at once.

It consolidates the splits that are not accounting distinctions:

Balance transaction typesReporting category
charge, paymentcharge
refund, payment_refundrefund
payout_cancel, payout_failurepayout_reversal
transfer, recipient_transfertransfer
transfer_cancel, transfer_failuretransfer_reversal

It breaks apart the one type that was doing too much. Stripe says reporting_category "separates balance transactions with type=adjustment into several different categories, including disputes, dispute reversals, and failed refunds," which turns an undifferentiated pile into things you can actually map to accounts.

And it renames the confusing ones: application_fee becomes platform_earning, stripe_fee becomes fee, reserve_transaction becomes connect_reserved_funds, and reserved_funds becomes risk_reserved_funds. It also gives partial captures their own category, partial_capture_reversal, so you can count them "against the initial sale amount, rather than as a separate refund."

If you are building a reconciliation query, group by reporting_category. Your categories will collapse from a few dozen to a handful, and the handful will match the way your chart of accounts already thinks.

What Acodei counts, and why it counts more

Acodei's documentation is direct about this. Acodei counts fees, adjustments, and payouts as separate events. That is documented as normal and intentional: it is what ensures QuickBooks reflects all balance changes rather than only customer charges. Adjustments specifically are counted in Acodei's transaction totals and included in its balance reconciliation.

So the answer to "why does Acodei show more transactions than Stripe shows payments" is that the two systems are answering different questions. Stripe's Payments view answers "how many customers paid me." Acodei's count answers "how many things does QuickBooks need to know about," and fees and payouts are things QuickBooks needs to know about.

Which types get imported at all is not open-ended. The set of balance transaction types Acodei syncs is controlled by an allowed-types table, where each type belongs to a display group, and new types are enabled by adding them to it. That is how advance and advance_funding (the pair behind instant payouts) and fee_credit_funding were switched on.

Where an uncommon type lands in QuickBooks is yours to decide, under Account Mapping and then Balance Transaction Mapping, a section that stays hidden until you toggle Customize. During payout and daily summary processing, each type's aggregated amount posts as a line item using the product you mapped, and any type you have not mapped prompts you to map it. That is the mechanism behind reserves, advances, fee credits, and the other uncommon types appearing in your books with sensible account names instead of being dropped.

Why your QuickBooks record count is smaller again

Here is the fourth number, and the one that trips up anyone who tries to reconcile by counting rows in QuickBooks.

Synced events do not map one to one onto QuickBooks records, and they are not supposed to. Three documented behaviors collapse them.

Fees ride on the sale rather than standing alone. In real-time sync, the Stripe fee is recorded by default as a negative line on the sales receipt itself, using your mapped Stripe fee product, netting the receipt down to what actually entered your balance. Two events, one QuickBooks document. If you have configured fees as an expense instead, the receipt stays gross and the fee becomes its own expense record, which is the same information in two documents rather than one. Our Stripe fee glossary entry covers the tradeoff.

Adjustments usually produce no new record at all. This is the one that looks most like a missing transaction and is not. Acodei imports adjustments but does not post a standalone QuickBooks entry for them. Instead it adjusts the original associated entry: for a dispute or a failed payment, the original QuickBooks record is reversed or removed rather than a new one being added. In daily summary mode the adjustment is folded into that day's deposit as a negative or positive amount. Either way, an event exists and a new record does not. See Stripe balance adjustment for the detail.

Daily summary mode aggregates by design. On a daily summary account there is no per-charge record at all. The day's charges are aggregated into a single receipt, with fees summed into one negative line on the daily deposit. Four hundred charges can become one document. That is the entire point of the mode, and it is the biggest single reason two Acodei accounts with identical Stripe volume can show wildly different QuickBooks record counts. The choice is covered in daily summary vs real-time Stripe sync.

How to check the number yourself

If you want to actually verify a month rather than trust the shape, do it in this order.

Start from balance transactions, not payments. Pull the balance transactions for the period from the API or Sigma and group them by reporting_category. This is the number your books are trying to represent, and it is the only Stripe number that is complete.

Reconcile the total, not the count. The count is a diagnostic. The number that has to be right is the money. Sum the net of every balance transaction for the period and compare it to the movement in your Stripe holding account in QuickBooks for the same period. If those agree, your count difference is a representation difference and you are done. The full walkthrough lives in our Stripe payout reconciliation guide.

Use source to trace anything that looks odd. Every balance transaction carries a source field holding the ID of the related Stripe object, so any row you cannot explain can be resolved back to the charge, refund, dispute, or payout that caused it.

Check the Data Feed before assuming something is missing. If a fee you expected is not on a sales receipt, it is very often on a daily summary entry for the date Stripe charged it, because non-transactional Stripe fees such as Radar and Billing charges are captured on the daily balance summary even on accounts syncing charges in real time.

When the gap is actually a problem

Everything above describes counts that differ for structural reasons. A count difference is worth investigating when it comes with one of these instead.

The money does not tie. If the sum of net across balance transactions for a period does not match the movement in your holding account, that is a real difference and the count is irrelevant. Chase the total.

A holding account balance that drifts and never comes back. Reserve holds and in-transit payouts cause temporary divergence that resolves itself. A gap that grows month over month does not resolve itself.

The same document number twice. With Duplicate Protection enabled, Acodei sets the QuickBooks document number to its own transaction id, so a webhook Stripe delivers twice collides instead of writing a second record. Worth knowing what this does and does not cover: it tracks what Acodei synced. It has no view into records you or your bookkeeper keyed in by hand, so a genuine duplicate between a hand-entered sale and a synced one is still possible and still yours to spot.

Counts that changed without volume changing. A tool-side change (a newly enabled transaction type, a switch between real-time and daily summary, a fee configuration change) moves the count without moving the money. If the count jumped and Stripe volume did not, look at what changed in the configuration rather than at Stripe.

Frequently asked questions

Why does my sync show more transactions than Stripe shows payments?

Because Stripe's Payments view counts only customer charges, while your books need every movement of the Stripe balance. Fees, payouts, refunds, disputes, and adjustments are all real events with accounting consequences, and Acodei counts fees, adjustments, and payouts as separate events so that QuickBooks reflects all balance changes rather than only sales. A count noticeably higher than your payment count is the expected shape.

Is a higher transaction count a sign of double-counting?

Usually not. The reliable test is money rather than rows: sum the net field across your Stripe balance transactions for the period and compare it to the movement in your QuickBooks Stripe holding account. If those agree, nothing is duplicated, and the extra rows are the same dollars represented as both revenue and fee, which is what double-entry requires.

Does each Stripe charge create a separate fee transaction in Stripe?

No, and this is the most common misunderstanding. The processing fee for a charge is carried on that charge's own balance transaction, in the fee and fee_details fields, with net equal to amount minus fee. The separate stripe_fee balance transaction type is reserved for Stripe's software and service fees such as Radar, Connect, Billing, and Identity, which are billed periodically.

Should I reconcile against type or reporting_category?

reporting_category. Stripe's own guidance is to "use the reporting_category field instead of the type field" to classify transactions for accounting purposes. It merges distinctions that do not matter to your books, such as charge versus payment, and splits adjustment into disputes, dispute reversals, and failed refunds, which do matter.

Why does my QuickBooks record count differ from my synced transaction count?

Because events collapse into records. Fees post as lines on sales receipts rather than as separate documents by default, adjustments reverse the original record instead of creating a new one, and daily summary mode aggregates a whole day of charges into a single receipt. All three reduce the record count without losing any information.

Why do I see refunds I never issued?

Check whether you authorize and capture separately. When the captured amount is less than the authorization, Stripe creates a second balance transaction with type=refund for the uncaptured portion. Its reporting category is partial_capture_reversal, which exists so you can count it against the original sale rather than as a refund.

Does the transaction count affect what I pay?

Acodei's plans are sized by monthly transaction volume rather than by revenue, which is the practical reason this question gets asked at all. Because a transaction count is not the same thing as a Stripe payment count, it is worth reading the tier you are on against the number your tool reports rather than against Stripe's Payments view. Current tiers are on the pricing page.

The point

Three numbers, three questions, all three correct.

Stripe's Payments count answers how many customers paid you. Stripe's balance transactions answer how many times money moved. Your synced event count answers how many facts your general ledger needs, which is more, because a ledger cannot record a sale and its fee as one number the way a payments API can. And your QuickBooks record count is smaller again, because good bookkeeping collapses related events into single documents.

The number that has to reconcile is the money. Sum the net movement in Stripe for a period, compare it to your holding account, and if it agrees, the counts were never the problem. Spend the afternoon on something else.

Stop hand-keying Stripe activity into QuickBooks. Acodei syncs charges, fees, refunds, payouts, and disputes into QuickBooks Online, with every balance movement accounted for and mapped to accounts you control. Start a free trial.

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.