stripepause subscriptioncancellation flowretention offers

Stripe's Paused Subscription Status: A Real Pause API, Not a Billing Workaround

Stripe gave subscriptions an actual paused status and dedicated pause/resume endpoints, replacing the pause_collection hack most cancel flows still run on.

XY
11 August 2026 · 8 min read

If you've built a Stripe cancellation flow with a pause offer any time in the last several years, you almost certainly built it on pause_collection — an attribute you set on the subscription object that tells Stripe to stop finalizing invoices for a while. It works, and thousands of SaaS products run on it today. It's also, structurally, a workaround: the subscription's own status field never changes, so from the outside the subscription still looks active while it's quietly not billing. Stripe closed that gap this year with a dedicated pause endpoint and a real paused status on the subscription object itself. It's a small-sounding change with a genuinely different effect on how pause offers show up in your data.

Key stat
337%
Year-over-year growth in pause usage among merchants who added a "pause before cancel" option
Source: Recurly, 2026 State of Subscriptions Report

That growth number matters because it means pause isn't a niche offer anymore — it's becoming one of the highest-traffic paths through a cancellation flow at any product that offers it. A feature that gets that much real usage is worth having the underlying API model actually match what's happening, instead of leaning on a side effect.

What pause_collection actually does

pause_collection has been available on the Subscription object for years, and it's still what our own cancellation flow guide points to. You set it with a behaviorvoid, mark_uncollectible, or keep_as_draft — and an optional resumes_at timestamp. void immediately voids any invoice generated while paused. mark_uncollectible creates the invoice but flags it as uncollectible rather than attempting to charge it. keep_as_draft leaves the invoice sitting in draft status with auto_advance off, so nothing gets sent or charged until you explicitly finalize it later. All three behaviors do the same underlying thing: let billing periods keep advancing and invoices keep getting created, then intercept them before money moves.

The part that trips people up isn't the invoice handling — it's that subscription.status doesn't move. A subscription with pause_collection set is still reported as active. That's fine for Stripe's own billing logic, which knows to check the field, but it's a landmine for everything else that reads a subscription's status as a proxy for "is this customer currently paying and engaged" — your product analytics, your data warehouse sync, a CRM integration, your own MRR dashboard. Every one of those has to separately know to check for pause_collection and treat it as a different bucket, or a paused subscriber quietly counts as active and healthy until the day they either resume or actually cancel.

What the new pause endpoint changes

Stripe's changelog added a dedicated subscription pause endpoint in May 2026: POST /v1/subscriptions/:id/pause. Call it and the subscription transitions to a genuine paused status — a new value alongside active, past_due, canceled, and the rest, with a status_details field attached that records the pause. While paused, Stripe doesn't generate invoices at all, and the subscription doesn't advance to new billing periods. Nothing has to be voided or marked uncollectible after the fact, because nothing gets created in the first place.

Resuming uses a matching endpoint with its own parameters. billing_cycle_anchor controls whether resuming resets the billing cycle to right now (the default) or leaves it unchanged from before the pause. If set to now, no proration gets generated; if you need the exact proration you'd get from resuming at a specific point, proration_date lets you replicate what a preview invoice already calculated. payment_behavior controls whether Stripe attempts payment as part of the resume call itself. One real constraint: resuming through this endpoint only works for subscriptions on charge_automatically collection — the card-on-file model, not invoice-and-wait billing.

Behaviorpause_collectionNew pause endpoint
Subscription status while pausedUnchanged — still reads as activeNew paused status, distinct from active
Invoices during the pauseStill generated, then voided / marked uncollectible / kept as draftNone generated at all
Billing periodKeeps advancing in the backgroundDoesn't advance until resumed
How you resumeUnset pause_collection, or wait for resumes_atDedicated resume endpoint with proration controls
Collection method supportcharge_automatically and send_invoiceResume requires charge_automatically

Why the status field is the part that matters for churn reporting

Every metric your pause offer is supposed to improve — active subscriber count, MRR, near-term churn risk — depends on knowing who's actually paying right now versus who's sitting in a pause window. With pause_collection, that distinction lives entirely in application code you have to write and maintain: a filter in your churn query, a flag in your data warehouse model, a check before your CRM syncs a "customer health" field. Miss it in one place — a new analytics tool, a hand-rolled export, a teammate's one-off SQL query — and paused subscribers silently count as healthy, active revenue until the moment they either resume or genuinely cancel.

That's not a hypothetical edge case once pause volume is real. At 337% year-over-year growth in pause usage, a SaaS product with even a modest cancellation flow can have a meaningful share of its subscriber base paused at any given moment — and if your reporting doesn't explicitly know how to find them, you're operating on an active count that's wrong by exactly that amount. A native paused status doesn't fix a bad query, but it removes the need to build and maintain one in every downstream system that reads subscription status, because the field itself now tells the truth.

This also connects to something we've written about separately: subscription cyclers, the customers who cancel and quietly resubscribe rather than truly leaving. A well-implemented pause is supposed to intercept exactly that behavior before it turns into a cancel-and-return cycle that shows up as churn in one month and new business in the next. If your pause implementation itself is invisible to your own status field, you can't tell the difference between "this customer paused and is coming back on schedule" and "this customer is genuinely at risk" — which undermines the entire point of offering pause as a retention lever in the first place.

What Recurly's 2026 data shows about pause behavior
Subscribers who return after pausing75%
Consumers who'd rather pause than cancel outright38%

Source: Recurly, 2026 State of Subscriptions Report (76M+ subscribers, 2,200+ global merchants)

Three out of four subscribers who pause come back. That's a far better outcome than a cancellation, and it's the whole economic case for offering pause as a primary retention path in your cancellation flow rather than a buried secondary option. But it only pays off if your systems can tell a paused subscriber apart from an active one and a canceled one — otherwise you can't measure the 75% return rate, target win-back messaging at the remaining 25%, or answer the basic question of how many people are sitting in a pause window right now.

Should you migrate?

Stripe hasn't deprecated pause_collection, and there's no forcing function to move off it today. If your product bills through send_invoice rather than card-on-file, the new resume endpoint doesn't fully cover you anyway, so pause_collection remains the more complete option for now. But for a standard self-serve SaaS product on charge_automatically billing, building a new pause offer on the dedicated endpoint going forward means one less place where your reporting logic has to compensate for what the API doesn't tell you directly. If you're already running pause_collection in production, there's no urgency to rip it out — but it's worth auditing whether every system that reads subscription status downstream of Stripe actually accounts for paused subscribers correctly, because that's the exact bug this new status field exists to prevent.

Either way, the API-level detail is secondary to the bigger point: pause is no longer a fringe retention offer. If you're trying to figure out what a 75% pause-return rate would actually be worth against your current churn number, our retention rate calculator is a fast way to model it. And if you haven't built a pause offer into your cancellation flow at all yet, that's precisely the gap CancelFlow closes — it applies the right pause behavior to a subscriber's Stripe subscription automatically the moment they accept the offer, so you're not choosing between building this yourself or leaving pause off the table entirely.

Frequently asked questions

What is the difference between pause_collection and the new pause endpoint?+

pause_collection is an attribute you set on an existing subscription that stops Stripe from finalizing invoices — the subscription's status field doesn't change, and depending on the behavior you choose, invoices can still get created as void or draft records in the background. The new pause endpoint (POST /v1/subscriptions/:id/pause) instead transitions the subscription itself into a real paused status. No invoices get generated at all, and the billing period doesn't advance while paused. It's a different object state, not a side effect bolted onto an active one.

Do I need to migrate off pause_collection?+

Not immediately. pause_collection still works, and Stripe hasn't deprecated it. But every system downstream of the Subscription object — your data warehouse sync, your CRM, your own churn dashboard, any third-party analytics tool reading subscription.status — has to already know to treat pause_collection subscriptions as functionally paused, because the API won't tell them. The new endpoint removes that entire category of bug, since anything checking subscription.status now sees paused as its own value instead of active.

Can I use the new pause endpoint with any Stripe subscription?+

Resuming a paused subscription through the API is only available for subscriptions on charge_automatically collection — the card-on-file model most self-serve SaaS products use. If your subscription bills through send_invoice, you're working with a different set of tools entirely, similar to how Stripe's payment plans and prebilling features are also scoped to specific collection methods rather than working universally.

Does a paused subscription still count as active in Stripe reporting?+

With the new status, no — paused is its own distinct value alongside active, past_due, canceled, and the rest, so Stripe's own dashboard and reporting separate it out automatically. With the older pause_collection approach, the subscription's status is unaffected by the pause, so it still reads as active everywhere unless you've built separate logic to exclude it — which is exactly the kind of quiet double-counting that inflates an active-subscriber count and hides how many people are actually paused at any given time.

Try CancelFlow

Stop losing subscribers today

One script tag. One function call. A live cancellation flow in under 10 minutes.

Start free trial →
← All postsHome