Stripe Automatic Collection and Your QuickBooks A/R

An open Stripe invoice tells you a customer owes you money, not whether Stripe is chasing it. That fact lives in auto_advance, and it never reaches...

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

An open Stripe invoice tells you that a customer owes you money. It does not tell you whether Stripe is doing anything to collect it.

Those are two separate facts, stored in two separate fields, and only one of them ever reaches QuickBooks. The receivable syncs. The question of whether anything is chasing it does not. So an invoice that Stripe has quietly stopped working on can sit in your accounts receivable looking a lot like one raised this morning.

Start a free trial and watch each Stripe invoice event land in QuickBooks as it happens.

Two fields, and only one of them means "someone is working on this"

The field people reach for first is collection_method. Stripe documents it as "Either charge_automatically, or send_invoice. When charging automatically, Stripe will attempt to pay this invoice using the default source attached to the customer. When sending an invoice, Stripe will email this invoice to the customer with payment instructions."

That field answers a question about mechanism. It says how payment is supposed to arrive: pulled from a card on file, or paid by a human who received an email.

The field that answers whether anything is happening at all is auto_advance. Stripe defines it as controlling "whether Stripe performs automatic collection of the invoice", and adds the consequence: "If false, the invoice's state doesn't automatically advance without an explicit action."

Read those two definitions side by side and the distinction gets sharp. collection_method is a preference about route. auto_advance is a switch on the engine. An invoice can be set to charge a card automatically and still have nothing scheduled to charge it, because those are different fields and only one of them is a switch.

Stripe scopes the switch to the states where it could still matter: "An invoice must be in a draft or open state to update automatic advancement. Invoices that are paid, void, or uncollectible always have automatic advancement turned off." Once an invoice reaches a terminal state, the field stops carrying information. It is only meaningful on the invoices you actually care about, which is the ones still outstanding. If the status vocabulary itself is the unfamiliar part, our Stripe invoice status entry covers what each one means.

One piece of Stripe's interface causes real confusion here, and it is worth naming. The Dashboard does not always call this setting the same thing. Stripe documents the control as Turn on/off automatic reminders, then notes that "Invoices set to charge a payment method on file automatically display Turn on/off automatic collection, which changes the auto_advance property on the invoice." Same field, two labels, depending on the invoice you happen to be looking at. If two people on your team describe this setting differently, they may both be right about what their screen said.

Defaults differ by origin too. "Automatic invoice advancement is on by default for any invoice created in the Dashboard." Invoices created through the API are the ones where somebody had to decide, and Stripe's guidance in its automatic advancement documentation is explicit: "For invoices created using the API, set the auto_advance property on the invoice to true."

The collection clock starts with your webhook endpoints, not with the invoice

This is the part that surprises people, and it is the most consequential thing on this page.

When automatic collection is on, Stripe does not finalize and charge immediately. It waits for your systems first. In Stripe's words: "When you enable automatic collection, Stripe automatically finalizes, and begins automatic collection of the invoice. We wait 1 hour after receiving a successful response to the invoice.created event from all listening webhooks before attempting payment. If we don't receive a successful response within 72 hours, we attempt to finalize and send the invoice."

Note what the hour is measured from. Not from invoice creation. From a successful response, from every listening endpoint. The clock does not start until your webhook consumers have acknowledged the event.

And when they do not acknowledge it, Stripe holds off on the customer: "In live mode, if your webhook endpoint doesn't respond properly, Stripe continues retrying the webhook notification for up to 3 days with an exponential back off. In a sandbox, we retry three times over a few hours. During that time, we won't attempt to charge the customer unless we receive a successful response. We also send you an email to notify you that the webhook is failing."

Then Stripe's status transitions documentation says the part that turns this from an engineering footnote into an accounting one: "This behavior applies to all webhook endpoints defined on your account, including cases where a Connect application or other third-party service is having trouble handling incoming webhooks."

So the schedule on which your customers get charged is downstream of the health of every webhook consumer on your Stripe account, including ones you did not write. That is documented Stripe behaviour, not a theory about it.

Two things stop this from being as alarming as it sounds. There is a ceiling: at 72 hours without a successful response, Stripe finalizes and sends anyway rather than waiting indefinitely. And Stripe tells you, by email, that an endpoint is failing. The documented failure mode is a delay with a notification attached, not a silent hole. Stripe also notes you can configure a longer grace period if you want one.

The invoice object carries the evidence of all this, which is useful when you are working out why something sat still. webhooks_delivered_at is documented as tracking "the time when webhooks for this invoice were successfully delivered", with the same rule restated: "Invoices are automatically paid or sent 1 hour after webhooks are delivered, or until all webhook delivery attempts have been exhausted." ending_balance repeats the timing from another angle, noting that "Invoices are finalized approximately an hour after successful webhook delivery or when payment collection is attempted for the invoice." And on drafts, automatically_finalizes_at gives you "The time when this invoice is currently scheduled to be automatically finalized", which is null when nothing is scheduled.

That last field is the cleanest single answer to "is anything going to happen to this draft". A null there on a draft invoice means no, not on a schedule.

What switching it off actually switches off

Stripe publishes a comparison of behaviour with auto_advance set to true versus false, and the list is longer than most people expect. Turning it off disables emailing invoices, retries of both email and charge, invoice reminder emails, 3D Secure reminder emails, attempting payments for auto-charge invoices, finalizing draft subscription invoices to open, and Stripe Automation. Stripe summarises it as disabling "most of the automatic collection features for Invoicing".

One row does not change. Email receipts stay available in both columns.

That asymmetry deserves a moment, because it shapes what the outside world sees. If a customer happens to pay an invoice that nobody is chasing, they still get a receipt. Nothing about the transaction looks unusual from their side. Silence from your billing system is not a signal anyone receives, which is part of why these invoices go unnoticed.

Stripe is clear that this is a legitimate configuration rather than a mistake. It lists the reasons you would want it: to "Use your own business logic to manage the lifecycle of an invoice", or to "Decide if and when to send invoice emails on a per-invoice basis". The trouble is not that the setting exists. It is that an invoice under manual management and an invoice under automatic management are indistinguishable in every downstream report.

There is one case where Stripe makes this choice for you. When you revise an invoice, the replacement comes out with automatic collection off even if the original had it on. We covered the mechanics of that swap in Stripe invoice revisions and the second QuickBooks invoice. It is one route to an uncollected invoice that nobody chose deliberately.

Emails have a second switch worth knowing about, independent of this one. Stripe says it "doesn't email invoices in the following cases: When charged automatically. When automatic collection is turned off for the invoice. When the Email finalized invoices to customers option is turned off", and warns that "If you turn off the Email finalized invoices to customers option, automatic or manual finalization doesn't send an invoice." So an invoice can be finalized, open, correctly configured for automatic collection, and still never emailed, because of an account-level setting that has nothing to do with auto_advance.

Two nulls that tell you which kind of invoice you are looking at

Two timestamp fields on the invoice object are each null in exactly the case where the other is meaningful, and the symmetry is genuinely useful.

due_date is "The date on which payment for this invoice is due", and Stripe states that "This value will be null for invoices where collection_method=charge_automatically."

next_payment_attempt is "The time at which payment will next be attempted", and it "will be null for invoices where collection_method=send_invoice."

So for any given invoice, exactly one of "when is this due" and "when will Stripe try again" is populated. An automatically charged invoice has no due date because the concept does not apply: nobody is waiting on a human. An emailed invoice has no next attempt because Stripe is not going to attempt anything.

This matters the moment anyone builds a receivables report sorted or filtered by due date. Every automatically charged invoice drops out of that report, and it drops out because the field is null by design rather than because someone forgot to fill it in. A team that bills both ways, some customers on cards and some on invoice terms, can build an aging report that quietly covers only half the book. The same field turns up in our walkthrough of which sync settings change your books, where the null due date is what drives the invoice-date decision.

The inverse is the more useful query. If you want to know what Stripe still intends to do, next_payment_attempt is the field, and it only ever speaks about the automatically charged half.

Why attempt_count is not a count of attempts

This field reads like a simple tally and is not one. Stripe's definition in the invoice object reference is worth quoting in full, because every clause removes an assumption:

"Number of payment attempts made for this invoice, from the perspective of the payment retry schedule. Any payment attempt counts as the first attempt, and subsequently only automatic retries increment the attempt count. In other words, manual payment attempts after the first attempt do not affect the retry schedule. If a failure is returned with a non-retryable return code, the invoice can no longer be retried unless a new payment method is obtained. Retries will continue to be scheduled, and attempt_count will continue to increment, but retries will only be executed if a new payment method is obtained."

Three separate things follow. Manual attempts after the first are invisible here, so a colleague repeatedly clicking pay leaves no trace in this number. The count is a position in a schedule, not a record of activity. And after a non-retryable failure the number keeps climbing while nothing is actually being attempted, because retries stay scheduled but do not execute until a new payment method arrives.

An attempt_count of six can therefore mean six real attempts, or one real attempt followed by five scheduled non-events. The field alone cannot tell you which.

Its companion attempted carries a warning from Stripe that is unusual in an API reference: "Whether an attempt has been made to pay the invoice. An invoice is not attempted until 1 hour after the invoice.created webhook, for example, so you might not want to display that invoice as unpaid to your users."

Stripe is telling you, in the field definition, that there is a window in which an invoice is legitimately untouched and showing it as unpaid would mislead. That is the same one-hour window from the webhook section, surfacing again as a data-presentation problem.

What actually lands in QuickBooks, and what does not

Here the honest answer is mostly about what is not different, and that is the point of the post.

Acodei's Invoice Sync documentation describes a one-way integration that mirrors Stripe invoices and subsequent payments into QuickBooks Online. Its lifecycle table maps invoice.created and invoice.finalized to creating a QuickBooks Invoice, storing the Stripe ID against the QuickBooks invoice ID and handling suffix rules to avoid duplicate numbers. It maps invoice.paid or charge.succeeded to creating a Payment that auto-applies to that invoice, which requires QuickBooks Automatic Application to be on. Acodei's own best-practice guidance says to keep Automatic Application turned on so payments and credit memos settle invoices automatically.

Now line that up against everything above. The QuickBooks Invoice is created at finalization. Finalization is exactly the step that happens under either setting, whether Stripe advanced the invoice for you or a person clicked the button. So the receivable arrives in QuickBooks the same way in both worlds.

The Invoice Sync documentation covers the invoice lifecycle in terms of these Stripe events. It does not document auto_advance, collection state, or dunning status as something that reaches QuickBooks, and we are not going to tell you it does. Nothing in the documented sync carries the distinction across.

What the QuickBooks side gives you instead is an absence. The documented trigger for a Payment record is a paid invoice or a succeeded charge, so where there is no payment event there is no Payment record. An invoice nobody is collecting shows up as an open invoice with no payment applied, which is also what a perfectly healthy invoice raised yesterday looks like. The two are the same shape. Only the age of the record hints at the difference, and age alone is a weak signal, because slow-paying customers exist and are not a bug.

One related case is documented and worth knowing. invoice.marked_uncollectible is handled the same way as a void, and if the invoice is later paid, it is reopened and the payment processed. That matters because Stripe puts uncollectible among the states where automatic advancement is always off. Writing something off in Stripe is a decision about collection, and a documented reversal path exists on both sides if the money turns up after all.

How to actually find these

Nothing above requires new tooling. It requires asking Stripe the question that QuickBooks cannot answer, then reconciling.

In Stripe, the population you want is invoices with status set to open and auto_advance set to false. That is the literal definition of a receivable nobody is chasing, and it is worth saving as a query rather than rebuilding each month. For anything still in draft, check automatically_finalizes_at: a null there means it is not scheduled to become collectible on its own.

For invoices that are being collected, next_payment_attempt tells you when Stripe will next act on the automatically charged ones. Read attempt_count alongside the payment method rather than on its own, given how it behaves after a non-retryable failure.

If a batch of invoices seems to have stalled around the same time, webhooks_delivered_at is where to look, and check whether Stripe emailed you about a failing endpoint in that window.

From the QuickBooks side, the useful check is a comparison of counts rather than a lookup. Open invoices in Stripe should broadly track open QuickBooks invoices with no payment applied, allowing for the cases your configuration excludes from syncing at all. A gap that grows month over month is the signal worth chasing, and it is the one an aging report will not compute for you, since the field that explains it never arrives.

The point

An invoice has two states that matter and your accounting system can only see one of them. It knows the customer owes you money. It cannot know whether Stripe intends to do anything about that, because the field carrying the answer is not part of the record that syncs.

The failure is cheap to prevent and expensive to discover late. One saved query in Stripe for open invoices with automatic collection switched off, checked on the same rhythm as your close, catches every instance: the revisions that had it turned off for them, the invoices somebody paused deliberately and forgot, and the ones waiting on an endpoint that stopped answering. None of those look like problems in QuickBooks. All of them are.

Start a free trial and see exactly which Stripe invoice events become QuickBooks records, and when.

FAQ

What does auto_advance do in Stripe?

It controls automatic collection. Stripe documents the field as controlling "whether Stripe performs automatic collection of the invoice", and states that when it is false "the invoice's state doesn't automatically advance without an explicit action". With it off, you are responsible for moving the invoice between states yourself.

Is auto_advance the same as collection_method?

No. collection_method is either charge_automatically or send_invoice, and it decides how payment is meant to arrive: charged against the default source on the customer, or emailed to the customer with payment instructions. auto_advance decides whether Stripe drives the process at all. An invoice can be set to charge automatically and still have automatic collection switched off.

Why has Stripe not charged my customer yet?

One documented reason is webhook timing. Stripe waits "1 hour after receiving a successful response to the invoice.created event from all listening webhooks before attempting payment", and while an endpoint is failing it retries "for up to 3 days with an exponential back off" and "won't attempt to charge the customer unless we receive a successful response". Stripe states this applies to every endpoint on the account, including third-party services. If no successful response arrives within 72 hours, Stripe attempts to finalize and send the invoice anyway.

What does turning off automatic collection actually stop?

Stripe's own comparison lists emailing invoices, retries of both email and charge, invoice reminder emails, 3D Secure reminder emails, attempting payments for auto-charge invoices, finalizing draft subscription invoices to open, and Stripe Automation. Email receipts are the one listed feature that remains available either way.

Why is due_date empty on my Stripe invoice?

Because it is charged automatically. Stripe documents due_date as null for invoices where collection_method=charge_automatically. The mirror-image rule applies to next_payment_attempt, which is null for invoices where collection_method=send_invoice. Exactly one of the two fields is populated on any given invoice.

Does a high attempt_count mean Stripe keeps trying?

Not necessarily. Stripe documents attempt_count as counting "from the perspective of the payment retry schedule", and notes that after a non-retryable failure "Retries will continue to be scheduled, and attempt_count will continue to increment, but retries will only be executed if a new payment method is obtained". It also excludes manual payment attempts after the first. The number can rise while nothing is being attempted.

Does QuickBooks show whether a Stripe invoice is being collected?

Not through the documented sync. Acodei's Invoice Sync documentation maps invoice.created and invoice.finalized to creating a QuickBooks Invoice, and invoice.paid or charge.succeeded to creating a Payment that auto-applies to it. It does not document auto_advance or collection state as something that reaches QuickBooks, so the QuickBooks record does not carry that distinction. Check Stripe for the answer.

What does an uncollected invoice look like in QuickBooks?

Like an ordinary open invoice. The documented trigger for a Payment record is a paid invoice or a succeeded charge, so an invoice nobody is collecting simply has no Payment applied to it. That is the same shape as a healthy invoice raised recently, which is why age alone is a weak signal and the Stripe-side query is the reliable one.

What happens if a Stripe invoice is marked uncollectible and then paid?

Acodei's documentation handles invoice.marked_uncollectible the same way as a void, and states that if the invoice is later paid it is reopened and the payment processed. On the Stripe side, uncollectible is one of the states where automatic advancement is always turned off.

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.