Stripe Historical Import to QuickBooks: How It Works

A historical import is two processes, not one. Stripe counts your history by category, then Acodei runs it through the same sync jobs as live traffic on a...

Acodei Content Team · 9/10/2026 · 12 min read

You buy a historical import for 14 months of Stripe activity. You get an email with an estimate. You approve it. Then you open QuickBooks and nothing is there. An hour later, sales receipts are appearing but the payout deposits are not. By the next morning everything has landed.

Nothing went wrong in that sequence. Every part of it is the design, and the design is worth understanding before you buy, because it tells you what to check and when to worry.

A historical import is not one process. It is two, running in two different systems, and they answer two different questions. The first asks how much history exists. The second actually moves it. Almost everything that surprises people about a backfill comes from confusing the two.

If you are deciding whether to backfill, and where to set the cutoff date, that is a separate question with its own answer: read the historical Stripe import playbook for cutoffs, double-counting and verification. This post is about what the machine does once you say go.

If you would rather see the shape of your own history than read about the mechanism, start a free trial and request an estimate. Requesting a count writes nothing to QuickBooks, for reasons the next section explains.

Stage one asks Stripe how many, not which ones

The first thing that happens is not an import. It is a count.

When a pull is requested for a Stripe account and a date range, Acodei asks Stripe for a report. Specifically it requests the balance_change_from_activity.summary.1 report type, and it asks for the count column.

That choice is the whole story of stage one. Stripe publishes two shapes of balance report. The itemized types return one row per balance transaction, which is what you would use to actually read your history. The summary types return one row per reporting category, and per Stripe's Balance report reference the count column on that summary is "the number of transactions associated with the reporting_category".

So the sizing stage never reads your transactions. It asks Stripe to tally them by category and hand back the totals. A 41,000 transaction year comes back as a short table of counts, not 41,000 rows.

Two consequences follow, and both are practical:

The estimate is fast and cheap regardless of your volume. Counting a million balance transactions is the same shape of request as counting a thousand. This is why you get a quote on a multi-year backfill without anyone scheduling a data migration to produce it.

No QuickBooks records exist yet. The sizing stage creates no transaction rows at all. If you are watching QuickBooks during this phase, you are watching the wrong window. There is nothing to see because nothing has been extracted.

Acodei also reuses an existing report for the same account and date range if one is already there, rather than asking Stripe to build the same report twice. And because Stripe builds reports asynchronously, Acodei polls each pending report and writes the total back once Stripe reports it as succeeded. Reports still pending are skipped and picked up on the next poll. If your estimate takes a few minutes, that is Stripe generating a report, not a queue backing up.

Alongside the summary total, a separate set of counting calls produces the per-month counts stored against the pull record. That is what lets an estimate be broken down by month instead of arriving as one opaque number.

The estimate email waits on purpose

When counting finishes, Acodei sends an estimate ready email. The sweep that sends it runs every minute, but it applies a configurable delay, ten minutes by default.

That delay is deliberate and it exists for a specific reason: so that a user connecting several Stripe accounts gets one email rather than one per account. If you connect four accounts in a row and expect four notifications, you will get one, and it will cover all four.

Worth knowing because the alternative reading is that three of your accounts failed.

Daily summary accounts are priced differently

Pricing and credit consumption are computed from those counts, and daily summary accounts are priced differently from real time accounts.

The reason is structural rather than commercial. A real time account gets a QuickBooks record per charge. A daily summary account gets one aggregated receipt per day, so the same 41,000 Stripe transactions produce a very different number of QuickBooks records depending on which mode the account runs in. The count of Stripe rows is not the count of work.

Which mode you are in, and what each writes, is covered in daily summary versus real time Stripe sync.

Historical imports consume historical data credits according to your plan. That is a commercial question rather than a mechanical one, so check current pricing rather than assuming a backfill is bundled with a subscription.

Stage two runs your history through the ordinary pipeline

Once a pull is approved, extraction and sync happen. Two commands do this work, walking Stripe balance transaction data for the purchased range and creating transaction rows: a main path, and a newer path that runs hourly when a configuration flag enables it.

Here is the part that matters for your books. Those rows then dispatch through the standard sync jobs, the same sales receipt and payout jobs that handle live webhook traffic, on a dedicated queue named l11-historicalpull.

Same jobs. Different queue.

The dedicated queue is an operational choice: a 40,000 transaction backfill does not get to sit in front of today's live charges. But because the jobs themselves are the ordinary ones, all of your mapping, fee, tax and holding account rules apply to historical records exactly as they apply to live ones.

That is a stronger guarantee than it sounds. It means a historical sales receipt is not a lesser record. Your product mapping resolves the same way. Your Stripe fee product is used the same way. Your tax codes attach the same way. The record lands in the same holding account. A year of imported history is indistinguishable in QuickBooks from a year you synced in real time, which is exactly what you want when your accountant reads across the boundary.

It also means the failure modes are the ordinary ones. If your Stripe fee product is unmapped or was deleted in QuickBooks, a historical import will surface that the same way live sync does, and the fix is the same fix.

One detail carries more weight than its size. Both import commands set the daily summary marker while creating rows. That marker is what routes a record to the right job, so daily summary history and Financial Account history go to the daily jobs rather than to per charge jobs. Your history is built in your account's own sync mode, not converted into some generic shape and then translated.

Why a big import lands in pieces

This is the part the playbooks skip, and it is the single most common reason someone thinks a backfill has stalled.

If your holding account is a regular asset clearing account, each payout posts as one transfer for the net amount, and it does not depend on anything else having synced first. Imports under that setup tend to appear steadily.

Undeposited Funds works differently. There, a payout is not a simple transfer. It is an itemized deposit that sweeps the individual payments into the bank, so payouts can only build their deposits after the underlying historical charges have synced. Acodei enforces this with a missing transaction guard on the payout job.

So a large import settles in dependency order rather than instantly. Charges first, then the payouts that consume them. During that window you will see sales receipts in QuickBooks with payouts still outstanding, and the gap is not a lost record. It is a payout refusing to post a deposit that would be missing lines.

That is the behaviour you want. The alternative is a deposit that posts with holes in it and a clearing account that never reconciles.

Two things follow. First, do not run your verification checks mid import. A clearing account that does not zero out while charges are still landing tells you nothing. Wait for the import to finish, then reconcile.

That caution is sharper than it looks on Undeposited Funds, because the reconciliation method there is different in kind. On a non-UF clearing account you can compare the QuickBooks balance to the Stripe balance directly, and Acodei runs a daily tracker built for exactly that comparison, scoped to non-UF connections only. Under Undeposited Funds the supported method is narrower: match each payout deposit against the bank feed, then reconcile the bank account. Acodei does not support balance reconciling the Undeposited Funds account itself, because sales sit in UF until a payout sweeps them and some items are only added at deposit time, so a point in time balance comparison is not meaningful there even outside an import.

Second, if you are on Undeposited Funds and you see payouts pending for a while, that status is structural rather than an error, and what each Acodei data feed status means explains how to read the feed while it works through.

Imported records show up in the Data Feed like any other record, and can be resynced like any other record. If a mapping was wrong for the whole historical window, you are not stuck with it.

What to actually do with this

The sequence, with the right expectation attached to each step:

  1. Request the pull for an account and date range. Nothing enters QuickBooks. A Stripe report gets requested and polled.
  2. Wait for the estimate email. Up to about ten minutes after counting completes, and one email covers every account you connected, not one per account.
  3. Check the per month counts against your own expectation. This is the cheapest moment to catch a wrong date range, because nothing has been written yet.
  4. Approve, and let it run. Records arrive on a dedicated queue behind live traffic, through the same jobs as live sync.
  5. Expect dependency order on Undeposited Funds. Charges land before the payouts that sweep them.
  6. Reconcile after it finishes, not during. Then run the clearing account and bank feed checks from the payout reconciliation guide.

And one thing to do before any of it: if the period you are importing into holds wrong data rather than merely missing data, fix that first. Importing on top of duplicates compounds them, and cleaning up Stripe transactions in QuickBooks is the order of operations for that.

FAQ

How does Acodei estimate the size of a historical Stripe import? It asks Stripe for a balance_change_from_activity.summary.1 report and reads the count column, which Stripe defines as the number of transactions in each reporting category. That is a tally by category rather than a row level export, so the estimate does not require reading your transaction history. A separate set of counting calls produces the per month breakdown stored against the pull record.

Why has nothing appeared in QuickBooks after I requested a historical pull? Because the sizing stage creates no records. Requesting a pull produces a Stripe report and a count so you can be quoted. Extraction and sync are a second stage that runs after the pull is approved. If you are watching QuickBooks during the estimate phase, there is genuinely nothing to see yet.

Why did I only get one estimate email for several Stripe accounts? That is intentional. The email sweep runs every minute but applies a configurable delay, ten minutes by default, specifically so a user connecting multiple accounts receives one email instead of one per account.

Do historical records behave differently from live synced ones in QuickBooks? No. Historical transactions dispatch through the same sync jobs as live webhook traffic, just on a dedicated l11-historicalpull queue, so mapping, fee, tax and holding account rules apply identically. The dedicated queue keeps a large backfill from delaying today's live charges. The records themselves are the same shape.

Why are my historical payouts still pending while charges are already in QuickBooks? Under Undeposited Funds a payout is an itemized deposit that sweeps the underlying payments, so it cannot be built until those charges have synced. A missing transaction guard on the payout job enforces that, which means a large import settles in dependency order. Charges first, then payouts. On a regular asset clearing account each payout is a single net transfer and does not wait on anything.

Does a daily summary account cost the same to backfill as a real time account? No. Pricing and credit consumption are computed from the transaction counts, and daily summary accounts are priced differently from real time ones. The same Stripe volume produces a very different number of QuickBooks records in the two modes, because daily summary aggregates a day into one receipt while real time writes a record per charge.

Can I fix a bad mapping after a historical import has run? Yes. Imported records appear in the Data Feed and can be resynced like any other record, so a mapping that was wrong across the whole historical window is not permanent.

When should I run my reconciliation checks? After the import finishes, not while it is running. On Undeposited Funds especially, a clearing account will not zero out while charges are still landing ahead of their payouts, so a mid import check reports a discrepancy that is not real.

The short version

Sizing and importing are two systems answering two questions. Sizing asks Stripe for a count and writes nothing. Importing runs your history through the same jobs as your live sync, on its own queue, in your account's own mode, and under Undeposited Funds it lands in dependency order because a payout will not post a deposit with missing lines.

Read that sequence once and the surprising parts stop being surprising. The estimate arriving before any records exist is the design. The single email for four accounts is the design. The payouts trailing the charges is the design, and it is the reason the clearing account reconciles at the end instead of quietly not reconciling forever.

Acodei imports Stripe history through the same pipeline it uses for live sync, so a backfilled year reads in QuickBooks the way a synced year does. Start a free trial to size your own history against your own data, or read the full Stripe to QuickBooks sync guide for how live sync works once the backfill is done.

Share

Automate your Stripe to QuickBooks sync

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

How Acodei handles this in your stack

Stripe QuickBooks Integration

See how Acodei syncs Stripe payments, fees, refunds, invoices, and payouts into QuickBooks Online automatically.

Or go straight to a capability

Get more operational finance guides like this one

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