Guide · facts checked 5 Nov 2026
Pause a Stripe subscription from a cancel flow: pause_collection or the Pause API
Stripe has two different pauses. pause_collection stops Stripe collecting payment but leaves the subscription active and the customer with access; the Pause API sets the status to paused, stops invoices and leaves cutting off access to you through webhooks. For a cancel-flow offer such as "skip two months", the Pause API matches what the customer expects, but it cannot pause every subscription, so check first.
The two pauses side by side
pause_collection | Pause API (/pause, /resume) | |
|---|---|---|
| Subscription status | Unchanged; it does not become paused. | Becomes paused. |
| Customer access | Stripe describes the customer as keeping access to the service. | Service delivery and invoice generation stop; Stripe sends webhooks so you can switch access off. |
| Invoices while paused | You choose: keep_as_draft, mark_uncollectible or void. | Stripe pauses invoice generation until the subscription resumes. |
| Resume | Unset pause_collection (or set resumes_at up front). | POST /v1/subscriptions/{id}/resume. |
| Stripe’s own framing | Offer the service free for a while, a grace period. | Holiday or a long break, and a paused state for retention flows. |
Rule of thumb: if the customer is not going to use the product, use the Pause API. If you are deliberately giving them free time and want them to keep using it, use pause_collection.
Option 1: pause_collection
Update the subscription with a behavior and, optionally, a resume time:
curl https://api.stripe.com/v1/subscriptions/sub_123 \
-u "$STRIPE_SECRET_KEY:" \
-d "pause_collection[behavior]=keep_as_draft" \
-d "pause_collection[resumes_at]=1798761600"
The timestamp above is an example (Unix seconds). Without resumes_at, collection stays paused until you remove pause_collection. To resume early, update the subscription with an empty pause_collection:
curl https://api.stripe.com/v1/subscriptions/sub_123 \
-u "$STRIPE_SECRET_KEY:" \
-d "pause_collection"=
keep_as_draft: invoices are created as drafts withauto_advancefalse, so you can finalise and collect later. After you resume, setauto_advance=trueon each draft (list them withsubscription=<id>andstatus=draft), or they are never collected.mark_uncollectible: invoices are marked uncollectible and no payment is collected for those periods. An existing customer balance is applied first, and an invoice it covers fully becomespaid.void: invoices are voided and no charge records are created for those periods.
Stripe’s page also states that while collection is paused it sends no upcoming-invoice email and no webhook for those invoices, and that invoices created before the pause keep being retried unless you void them. If custom code of yours finalises invoices, it can conflict with keep_as_draft.
Option 2: the Pause API
Pausing is a call on its own endpoint, and it takes effect immediately. What happens to the part of the period already used is controlled by bill_for:
unused_time_from:now(default),item_current_period_startornone.outstanding_usage_through:now(default) ornone.invoicing_behavior:invoiceorpending_invoice_item(default).
The call, from Stripe’s own example:
curl https://api.stripe.com/v1/subscriptions/sub_123/pause \
-u "$STRIPE_SECRET_KEY:" \
-d "bill_for[unused_time_from][type]=now" \
-d "bill_for[outstanding_usage_through][type]=now" \
-d invoicing_behavior=pending_invoice_item
With the default pending_invoice_item, the unused time becomes a pending invoice item that credits the customer and appears as a line on the resumption invoice. It is a credit, not an immediate refund. On a 30 USD monthly plan paused on day 15, Stripe creates a −15 USD pending item.
Resuming is POST /v1/subscriptions/{id}/resume with payment_behavior, billing_cycle_anchor[type] and proration_behavior:
curl https://api.stripe.com/v1/subscriptions/sub_123/resume \
-u "$STRIPE_SECRET_KEY:" \
-d payment_behavior=resume_on_payment_success \
-d "billing_cycle_anchor[type]=now" \
-d proration_behavior=create_prorations
Stripe marks resume_on_payment_success as the recommended payment_behavior. The default, resume_on_payment_attempt, does not attempt payment on the resume request, and if payment then fails the subscription goes past_due. With resume_on_payment_success a failed payment leaves it paused. A resume request can also return 200 while the subscription is still paused, so read status and pending_update in the response instead of trusting the HTTP code.
The subscription must use charge_automatically to resume. It cannot pause a subscription whose status is unpaid, paused, incomplete, incomplete_expired or canceled.
Subscriptions the Pause API cannot pause
Check these before you show a customer a pause offer, so the button never leads to an error:
- subscriptions that collect by
send_invoicerather thancharge_automatically; - subscriptions in the classic billing mode (the Pause API needs flexible billing mode);
- subscriptions with an active subscription-level free trial set by
trial_endortrial_period_days; - subscriptions with an associated subscription schedule, or an active
billing_schedulesentry; - subscriptions already in one of the statuses listed above.
When the check fails, offer a discount or a downgrade instead, or use pause_collection if giving the customer free access for a while is what you want. Pause vs discount vs downgrade covers which reason maps to which offer.
Webhooks to handle
| Moment | Events Stripe lists | What your code does |
|---|---|---|
| Paused | customer.subscription.paused, customer.subscription.updated | Suspend access; record the offer as accepted. |
| Resumed | customer.subscription.resumed, customer.subscription.updated | Restore access. |
Stripe also lists entitlements.active_entitlement_summary.updated for both moments, which matters if you use Stripe Entitlements. Verify the webhook signature before you act on any of these; the sample in how to build a cancel flow with Stripe shows the check. Stripe’s pages name no dedicated event for setting or removing pause_collection, so with that option watch the subscription itself for changes.
Two other facts that change the offer
- Coupons keep running. If a paused subscription carries a coupon, the coupon keeps its original validity period and its clock continues while the subscription is paused (Stripe’s Pause API page). A three-month retention discount granted just before a two-month pause has about one month left when the subscription resumes, and a two-month coupon would run out during the pause.
- The portal has its own pause. Stripe can let customers pause inside the customer portal; what it allows and where it stops is in the portal cancellation settings guide.
Whichever pause you use, keep “Cancel anyway” one click away, and count a pause as a save only against a holdout: what counts as a save.
Offer a pause only when the reason fits
Run a sample cancel session: play a subscriber, give a reason such as "not using it right now", and see which offer is chosen and the Stripe change behind it.
90 seconds, no sign-up. You play the subscriber; the AI answers, and “Cancel anyway” is always one click away.