Backdating a Stripe Subscription: The QuickBooks Side
Stripe can start a subscription in the past. The invoice it writes is dated now, covers then, and its shape depends on a billing mode most people never...
Stripe lets you start a subscription in the past. You pass one field, backdate_start_date, and Stripe behaves as though the subscription had been running since whatever date you named. It is the field you reach for when you migrate a book of subscribers onto Stripe, or when somebody had access for six weeks before anyone got around to billing them.
It is also the field that writes invoices into months your books have already closed.
That second half rarely gets discussed, because backdating is documented as a billing problem and lands as an accounting one. The invoice Stripe creates is dated now. The service it covers happened then. And the shape of the document you receive, one line or several, is decided by a subscription setting most businesses never chose deliberately.
Start a free trial if you want your Stripe invoices reaching QuickBooks without hand-keying them. The rest of this post is what to know before you backdate anything.
What backdating actually does
Stripe's own framing, in its documentation on backdating subscriptions, is short: "You can backdate a subscription to bill customers for time that has already elapsed. This is often used when migrating to Stripe or for record keeping purposes."
Passing backdate_start_date when you create a subscription does two things. It sets the subscription's start_date to the date you named, and it creates an invoice "with charges for the time between the backdated start date and the current time."
So there is a real invoice, for real money, covering a period that has already happened. If you backdate to 1 June and it is now 31 August, you have just created a document covering June, July and August, finalized on 31 August.
Everything that follows is a consequence of that one gap between the period and the finalization date.
Two billing modes, two completely different documents
This is the part worth understanding before anything else, because it changes what your books receive for identical money.
Stripe has two billing modes, classic and flexible, and since API version 2025-04-30 the behaviour of backdating depends on which one a subscription uses. Stripe's comparison of classic and flexible billing mode is the reference for everything in this section.
Classic mode produces one line. Stripe: "Use billing_mode=classic to create a single prorated line item for the backdated period."
Flexible mode produces one line per period. Stripe: "Use billing_mode=flexible to generate one line item for each natural billing period that occurs during the backdated period, which behaves similarly to regular billing."
Stripe's own worked example makes the difference concrete. A subscription is backdated to cover two missed billing periods, March and April. Storage is billed at 10 USD per 10 GB. March used 100 GB, April used 150 GB.
| Classic | Flexible | |
|---|---|---|
| March | 100 GB = 10 x 10 USD = 100 USD, as a separate line item | |
| April | 150 GB = 15 x 10 USD = 150 USD, as a separate line item | |
| Whole range | 250 GB = 25 x 10 USD = 250 USD, as a single line item | |
| Total | 250 USD | 250 USD |
Same money. Two documents that mean different things.
The classic invoice tells you 250 USD was earned. It does not tell you when. To split that across March and April you have to go back to the usage data and work it out yourself, on a document that gives you no help at all.
The flexible invoice has already done the split, and it did it on billing-period boundaries rather than on your best guess.
If you care about which month revenue belongs to, and any business on accrual does, this is not a cosmetic difference. It is the difference between an invoice that carries the information you need and one that has thrown it away. Our post on revenue recognition for Stripe in QuickBooks covers what to do with the periods once you have them.
How classic calculates the single line
Worth knowing, because the number frequently looks wrong.
Classic mode does not simply add up the elapsed months. It prorates against an imagined interval starting from the backdated date. Stripe's example: with a monthly billing period beginning on the first of the month, setting backdate_start_date to 15 February in a non-leap year makes Stripe "calculate the proration based on an imagined month running from February 15 to March 15. Because February has 28 days, the prorated amount for the 14 days from February 15 to March 1 is exactly half the amount of a normal monthly charge."
Move the date and the fraction moves with it. Backdating to 15 January bases the calculation "on an imagined month running from January 15 to February 15", which has 31 days, "so the prorated amount for the 17 days from January 15 to February 1 is 17 divided by 31 (approximately 0.548) of a normal monthly charge."
Two backdates of similar length, two different fractions, because February is short. If you are checking a backdated invoice against what you expected to see, that is usually where the discrepancy is.
There is a hard ceiling at 250 lines
Stripe states it twice, in both the backdating guide and the billing mode comparison: "Backdating isn't supported if the resulting invoice has more than 250 line items."
Classic mode collapses everything into one line, so it never approaches this. Flexible mode generates a line per billing period, and on a usage-heavy subscription with several items it can generate several lines per period. A long backdate on a weekly subscription with a handful of metered items is not a theoretical problem.
The failure is not partial. Backdating is not supported for that invoice, so the plan you had for migrating that customer needs to change before you discover it.
Backdating without charging anyone, and the trap inside it
Migrations usually do not want to bill for the backdated period. The customer already paid, on the old system. You want the history, not the money.
Stripe supports this: "You can also backdate a subscription without charging the customer for the backdated period, which you can use if you're migrating to Stripe. To do so, pass proration_behavior: 'none' when you create the subscription. That sets the start_date to the same value as backdate_start_date, but it doesn't charge the customer for backdated time."
So far so good. No invoice, no money, nothing to record.
Here is the part that surfaces months later. What happens when that customer eventually cancels or downgrades depends on the billing mode, and the two modes disagree.
Under classic, Stripe "generates a credit proration for the remaining unused time in the backdated period, even though no invoice was created for those billing periods."
Under flexible, no credit proration is generated, "because flexible billing mode calculates credit prorations based on previously debited amounts", and there was no debit.
Sit with what that means. A customer you deliberately never charged for the backdated period cancels. On a classic subscription, Stripe issues a credit for time inside a period nobody ever paid for. On a flexible subscription, it does not. Identical customer, identical action, and one of the two files ends up with a credit memo reducing a receivable that was never raised.
If you migrated a book of subscribers with proration_behavior: 'none' on classic mode, every future cancellation in that cohort carries this. It is the single most expensive thing on this page, and it is invisible at the time you do the migration, because at the time you do the migration nothing happens at all. See Stripe proration for how credit prorations behave generally.
It is worth auditing the cohort afterwards for a related reason. A migrated subscription that never took a successful payment does not sit quietly: depending on where it landed in the subscription status lifecycle, it may still be generating invoices every cycle. A subscription that is past due keeps billing, and one that is unpaid keeps creating invoices and closing them immediately, so neither state is as dormant as it sounds. The subscription object reference documents each status value.
The actual migration recipe
If you are moving subscriptions onto Stripe and need to keep the existing billing dates, the documented approach combines two fields.
Stripe: "You can combine backdate_start_date with billing_cycle_anchor to backdate a subscription and set the billing cycle anchor to a date in the future. This creates a prorated item on the next invoice for the time between the backdated start date and the billing cycle anchor."
Their example is exactly the migration case. It is 15 October. A subscription started on 1 September and next bills on 1 November. You set backdate_start_date to 1 September and billing_cycle_anchor to 1 November. Stripe "immediately issues an invoice for the prorated amount covering the time between September 1 and November 1", sets start_date to 1 September, and issues the next invoice on 1 November.
Note what that invoice covers: 1 September through 1 November, which includes future time as well as past. It is not a backdated invoice and a normal one. It is one document spanning both, finalized in the middle of the range.
There is also a default worth knowing. In flexible mode, Stripe "automatically aligns the billing cycle anchor to the backdate_start_date when not explicitly set." So if you backdate to the 3rd of a month and say nothing about the anchor, every future invoice for that customer lands on the 3rd. On a migration of a few hundred subscribers, that is how a business that used to bill everyone on the 1st ends up billing on 300 different days.
Coupons get consumed by the past
A smaller trap, and an easy one to walk into.
Stripe: "When you apply a coupon to a backdated subscription, the coupon's duration starts counting from the backdated start date, not from the date you make the API call. This means the coupon's duration is consumed by the backdated period."
Their example: create a subscription on 1 March, backdated to 1 January, with a coupon set to repeat for 2 months. The coupon applies to January and February. By March it is spent, "and the discount is removed from the subscription item."
So the customer you meant to give two months of discount to received two months of discount on time they had already lived through, and pays full price from the first invoice they actually see. To carry a discount past the backdated period, "the coupon's duration must be longer than the backdated period."
What lands in QuickBooks
Acodei's documentation is specific about the trigger, and the trigger is the thing that matters here.
A QuickBooks Invoice is created when the Stripe invoice is finalized, reproducing every line item and the tax lines as your mapping settings allow. A Payment follows when the invoice is paid, either by a successful charge or through the setting that handles invoices marked paid outside Stripe, and it is applied to the invoice already created. Automatic application in QuickBooks needs to be on for that last step to settle cleanly.
Read that against everything above and the consequence is direct: the record is written when the invoice finalizes, and the period it covers is not what drives that. Backdate to June and finalize on 31 August, and the QuickBooks document appears on 31 August. The June service is inside it, described on the lines, and nothing in the header is derived from June.
Be precise about what is documented here, because the exact date field is where people want certainty. Acodei documents that the record is created on finalization, and it documents an off-by-default toggle called "Use Stripe Supply Date as Invoice Date", which only makes sense as a setting because the supply date is not what the invoice date follows by default. What the documentation does not do is state which date lands in the field when all three toggles are off. So check one synced invoice in your own file before you plan a migration around the answer.
That also means the line-item structure is inherited rather than chosen. Acodei reproduces the lines Stripe produced. Under classic you get one line for the whole range. Under flexible you get one per period. Your QuickBooks invoice looks the way it does because of a Stripe billing-mode setting, which is not where most people would think to look.
Two other documented behaviours are worth knowing before you run a backfill:
Invoice numbering. Acodei appends a suffix, -AC1, -AC2 and so on, to prevent duplicate-number errors when invoices are also being hand-entered in QuickBooks. It is on by default. If you are reconciling a migration batch against a spreadsheet of old invoice numbers, expect the suffix. There is more on this in our post on Stripe invoice numbers in QuickBooks.
Service and supply dates. This is the setting people go looking for, so it is worth stating exactly. Acodei documents a Service / Supply Date Logic group of three mutually exclusive toggles: "Add Invoice Date as Service Date", "Use Stripe Supply Date as Invoice Date", and "Use Stripe Supply Date as Service Date". Combinations are restricted, and all three are off by default. They are administrator-side settings rather than something you flip yourself in the dashboard.
What the documentation does not describe is any behaviour specific to backdating. Nothing detects a backdated invoice, adjusts its date because the period is old, or warns you that the period is closed. There is no such feature, and you should not plan around one existing. If a backdated invoice needs to land differently in your file, the decision is yours to make before the invoice finalizes.
One more, because it comes up on migrations: where a synced record needs rebuilding, Acodei's documented guidance is to resync from the Data Feed rather than to alter the transaction by hand in QuickBooks.
Before you backdate into a closed month
The QuickBooks side of a closed period is its own topic, and the closing date covers what the control actually does. The short version for this purpose: a closing date does not make it impossible to post into a closed month, it makes it require a password and it makes the change visible.
A workable sequence:
- Check the billing mode first. It determines the shape of every document the backdate produces, and you cannot migrate a subscription from flexible back to classic. Stripe is explicit: "You can't migrate a subscription from flexible billing mode to classic billing mode."
- Decide whether you are billing for the period at all. If not, and you are on classic, plan for the credit prorations that will appear on future cancellations.
- Count the periods. Multiply by items. If you are near 250 lines, split the backdate or accept a single-line classic invoice.
- Pick the date the invoice should carry in your books before it finalizes, not after. Once it is in QuickBooks the tidy path is a resync, not an edit.
- Reconcile the batch by amount, not by date. The finalization dates will cluster on the day you ran the migration, which tells you nothing.
- If the periods genuinely belong in closed months, the entry to make is a reclassification in QuickBooks, decided with whoever signs off on reopening a period. Backdating in Stripe does not reopen anything on your side.
If what you actually need is your existing Stripe history brought into QuickBooks, rather than new invoices for old periods, that is a different job with a different method. Our historical import playbook covers it.
Frequently asked questions
What does backdate_start_date do in Stripe?
It starts a subscription in the past. Stripe sets the subscription's start_date to the date you pass and creates an invoice with charges for the time between that date and now. It is intended for migrations and record keeping, and it is the reason a brand-new subscription can arrive with an invoice covering several months that have already happened.
Does a backdated Stripe invoice reach QuickBooks with the old date?
Not by default. Acodei creates the QuickBooks Invoice when the Stripe invoice is finalized, and the backdated period is described on the line items rather than in the invoice header. Acodei documents a Service / Supply Date Logic group of three mutually exclusive toggles governing service and supply dates, including "Use Stripe Supply Date as Invoice Date", all off by default. It does not document which date fills the field when they are all off, so confirm that on one synced invoice in your own file rather than assuming it. Nothing in the documentation describes behaviour specific to backdated invoices.
Why is my backdated Stripe invoice one line instead of several?
The subscription is in classic billing mode, which creates a single prorated line item for the whole backdated range. Flexible billing mode generates one line item for each natural billing period inside the range instead. Both produce the same total, but only the flexible version tells you which period each amount belongs to.
Can I backdate a Stripe subscription without charging the customer?
Yes. Passing proration_behavior: 'none' sets the start date back without billing for the elapsed time, and Stripe names migration as the use case. Be aware of the consequence on classic billing mode: a later update or cancellation still generates a credit proration for the unused time in the backdated period, even though no invoice was ever created for it. Flexible billing mode does not do this.
Is there a limit on how far back I can backdate?
The documented limit is not a length of time, it is a document size. Stripe states that backdating is not supported if the resulting invoice has more than 250 line items, which is the default limit. Classic mode collapses the range into one line and never reaches it. Flexible mode generates a line per billing period, so long backdates on short billing intervals or usage-heavy subscriptions are where this bites.
What happens to a coupon on a backdated subscription?
Its duration starts from the backdated start date rather than from the day you created the subscription, so the backdated period consumes it. A two-month repeating coupon on a subscription backdated two months applies entirely to the past, and the discount is removed from the subscription item before the customer sees an invoice. To carry the discount forward, the coupon's duration has to exceed the backdated period.
Does backdating change my future billing dates?
It can. In flexible billing mode, Stripe automatically aligns the billing cycle anchor to the backdated start date when you do not set one explicitly, so future invoices follow the backdated day of the month. If you need to preserve an existing billing date through a migration, set billing_cycle_anchor explicitly alongside backdate_start_date.
Will a backdated invoice mess up a closed period in QuickBooks?
Not on its own, because the QuickBooks invoice is dated when the Stripe invoice finalized rather than when the service happened. The risk is the opposite one: revenue for a closed month arrives dated in the current month and quietly lands in the wrong period. Deciding where it belongs is a bookkeeping call, and reclassifying into a closed month is subject to your closing date and whoever holds the password for it.
The point
Backdating is one field, and it looks like a scheduling convenience. What it actually does is create a document whose date and whose content describe different months, in a shape determined by a setting you may not know your subscriptions have.
Before you run one at scale, three things are worth five minutes: which billing mode the subscriptions use, whether you are charging for the backdated period, and what your credit prorations will do a year from now if you are not. The first is irreversible in one direction. The second is invisible until somebody cancels. The third is the one that shows up in an audit.
Acodei syncs the invoices Stripe produces into QuickBooks Online, reproducing the line items and the tax lines your mapping allows, and recording the payment against the invoice when it settles. What it will not do is guess which month you meant. Start a free trial.
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
Advanced Product Mapping
Map Stripe products to QuickBooks with rule-based logic on product ID, price ID, metadata, and account. Set rule priority and extend mapping to refunds and fees.
Automated Invoice Sync
Bring Stripe invoices into QuickBooks and auto-apply payments and credit memos, with numbering, invoice matching, and quantity tracking to cut double-entry.
Multi-Currency Mastery
Sync Stripe transactions across currencies with automatic exchange rate handling and currency-specific customer records. Our team enables multicurrency on request, and zero-decimal currencies such as JPY are not supported.
Class Mapping
Map Stripe products to QuickBooks classes for scalable categorization and multi-entity reporting. Class tracking requires QuickBooks Online Plus or Advanced.
Historical Data Import
Backfill historical Stripe data into QuickBooks by month range. Preview volume and cost before syncing so reporting starts from a complete baseline.
How to Connect Stripe to QuickBooks Online
Connect Stripe to QuickBooks Online in minutes. Acodei links both accounts with secure OAuth and syncs payments, fees, refunds, and payouts automatically.
Reconcile Stripe Payments in QuickBooks
Reconcile Stripe in QuickBooks Online automatically. Acodei splits out fees, matches payouts to deposits, and keeps every charge audit-ready.
Get more operational finance guides like this one
We will only send high-value product and finance content.