Say you sell a small tool to wedding photographers. You have 40-something paying customers, mostly monthly. In November one of them writes:
"Season's done for me. Can I pause until March instead of cancelling? I don't want to lose my setup."
That's a good email to get. They're not leaving, they just don't want to pay for four months of nothing. But if you've never done a pause before, you open the Stripe Dashboard and find there are now two different buttons with "pause" in the name, and they do very different things. Pick the wrong one and you either keep charging them (well, invoicing them) all winter, or you lock someone out who only wanted a payment break.
This post is the version I'd want before answering that email. What each pause actually does in Stripe, what your app has to check, and a small pause policy you can write once and reuse. With under 50 customers every pause is a person you'll talk to again in March, so it's worth getting right.
Stripe has two kinds of pause now
This changed recently, so older blog posts are out of date. For years the only "pause" was pause_collection. On 2026-09-30 Stripe's changelog added the ability to pause and resume subscriptions on demand (it was in preview earlier this year). So now:
1. Pause payment collection (pause_collection on the subscription)
- The subscription stays
active. - Invoices still get created every period, Stripe just doesn't collect them.
- The customer keeps access, because nothing about the status changed.
- Stripe's own docs describe it as a grace period, for when "a customer needs more time to pay or can't pay for one or more billing periods."
2. Pause the subscription (the newer pause endpoint, or "Pause subscription" in the Dashboard)
- The status changes to
paused. - Stripe stops generating invoices until you resume.
- It's meant to stop service too. The docs literally say to make clear that pausing "stops both service delivery and invoice generation."
- It needs the subscription to be on flexible billing mode, and a few other things (more on that below).
So the photographer who's away until March wants #2. A customer who says "money is tight this month, can I keep using it and pay later" wants #1. Most of the confusion is just using one for the other.
The easy one: pausing payment collection
You can do this from the Dashboard (open the subscription, the ⋯ menu, Pause payment collection) or with one API call:
curl https://api.stripe.com/v1/subscriptions/sub_123 \
-u "sk_live_...:" \
-d "pause_collection[behavior]=mark_uncollectible" \
-d "pause_collection[resumes_at]=1803859200" # 2027-03-01 00:00 UTC
resumes_at is optional. Leave it out and collection stays paused until you unset it yourself, which is how you end up with a customer who quietly used the product free for a year because nobody remembered.
The part people skip is behavior. It decides what happens to the invoices Stripe keeps creating while collection is paused:
| behavior | what happens to each invoice | use it when |
|---|---|---|
keep_as_draft |
stays a draft, auto_advance off |
you're deferring, they'll pay later |
mark_uncollectible |
marked uncollectible (customer balance applied first) | you're forgiving the period |
void |
voided, no record of a charge | you're forgiving and want no trail |
Two things in the docs that are easy to miss:
-
keep_as_draftmeans they still owe you. When you resume, the drafts don't collect themselves. You have to turn on automatic collection for each one (auto_advance=true), and then they get charged for the paused months too. If you told the customer "no charge while paused", don't pick this one. - Invoices from before the pause keep getting retried unless you void them. So if the customer already had a failed renewal and you pause collection to be nice, Stripe can still retry that old invoice. Look at their open invoices before you click.
Also, while collection is paused Stripe doesn't send upcoming invoice emails or webhooks for those invoices. Quiet is nice, but it also means your own "your plan renews soon" logic, if it hangs off those webhooks, goes silent for that customer.
The real pause: status becomes paused
In the Dashboard it's the ⋯ menu, Pause subscription. You choose whether it starts now or on a date, and whether it stays paused "until you resume it" or until a specific date. The date option is the one you want for the photographer: pause now, resume March 1.
What happens when you pause, per Stripe's docs:
- status changes to
paused -
current_period_endgets moved to the moment you paused - no new invoices until resume
- you get
customer.subscription.paused(pluscustomer.subscription.updated)
And the money part. By default Stripe credits the unused time, from the pause moment to the end of the period, as a pending invoice item. Stripe's example: $30/month plan, paused on day 15, you get a -$15 pending item. Resume on day 45 and the resumption invoice has the -$15 credit plus a fresh $30 period, so they pay $15 and a new cycle starts. You can change that with bill_for[unused_time_from] (now, item_current_period_start, or none), and invoicing_behavior decides if the credit sits as a pending item (default) or gets invoiced right away.
If you'd rather see the numbers before you commit, Stripe lets you preview a pause invoice, but only if invoicing_behavior is invoice. With the default it returns a 404, which is easy to read as "something's broken", so heads up.
Why the pause button might be greyed out
Stripe lists the cases where you can't pause:
- the subscription uses
send_invoiceinstead of charging automatically - it's on classic billing mode (you'd migrate it to flexible first)
- it's in a free trial set with
trial_end/trial_period_days - status is
unpaid,incomplete,incomplete_expiredorcanceled - it has a subscription schedule attached (you pause through the schedule instead)
On billing mode: per Stripe's docs, API version 2025-09-30.clover and later default new subscriptions to flexible, older versions default to classic, and Dashboard-created ones follow a setting under Settings > Billing > Subscriptions and emails. If you set things up a while ago there's a fair chance your early subscribers are classic. Migration is one way only (flexible can't go back to classic), so read Stripe's compare page before migrating everyone just to get a pause button. For one customer who wants a pause next week, pause_collection plus a note might honestly be fine.
Resuming without a surprise
The resume step has a default that I'd change. The payment_behavior options:
-
resume_on_payment_attempt(default): the resume call doesn't try to charge. If the charge on that invoice fails later, the subscription goes topast_dueand Stripe doesn't retry. -
resume_on_payment_success(Stripe calls it recommended): it tries the payment in the request, stayspauseduntil payment works, and retries.
Also, a resume request can return 200 while the subscription is still paused and the invoice is waiting to be paid. So don't flip access back on just because the API call didn't throw. Check the returned status, or wait for customer.subscription.resumed.
One small trap: if the customer has a coupon, it keeps counting down during the pause. A three month launch discount paused for three months is just gone when they come back. If you promised it, you'll need to fix that by hand.
What your app checks
This is where most of the bugs are. Stripe recommends using the subscription status to start and stop service. So:
- Collection paused → status is still
active→ your paywall lets them in. That's what you want for a grace period. - Subscription paused → status is
paused→ your paywall should let them read their stuff but not use the paid features. Your call, but decide it before the first pause, not during.
The other catch: paused isn't only from a pause request. A trial that ends without a card can also put a subscription in paused. If your app shows "Add a card to continue your trial" for every paused, your photographer gets told their trial ended. Stripe gives you status_details.paused.subscription.type to tell them apart: pause_requested, trial_end_without_payment_method, system, and with the auto pause after payment failures added in the same release, first_payment_failure and final_payment_failure.
Rough version of the access check:
function access(sub: Stripe.Subscription) {
if (sub.status === "active" || sub.status === "trialing") {
return sub.pause_collection ? "full_grace" : "full";
}
if (sub.status === "paused") {
const why = sub.status_details?.paused?.subscription?.type;
if (why === "trial_end_without_payment_method") return "add_card";
if (why === "first_payment_failure" || why === "final_payment_failure") return "fix_payment";
return "paused_readonly"; // pause_requested, system
}
return "none"; // past_due etc. handled the way you already do
}
(Check the field names against your SDK version, status_details came with the newer API versions.) I went through what every status should mean for access in how Stripe's subscription statuses map to access, and paused was the one most paywalls forget.
The customer can't do this themselves (yet)
In Stripe's Customer Portal configuration docs there are toggles for switching plans, quantities, cancelling, cancellation reasons and retention coupons. I didn't find a pause option. So under 50 customers, a pause usually starts as an email to you, and that's fine. A support email at this size is a conversation, and it's often the only time a quiet customer tells you how they use the thing.
If you do want pause as self serve, put it in your own cancel flow. Offer it only when the reason fits (seasonal, project ended, taking a break) and never as a wall in front of the cancel button. I wrote more about a cancel flow that offers pause without dark patterns, and the short version is: pause is for "not right now", cancel is for "not for me", and mixing them makes people angry later.
A pause policy you can write in ten minutes
Write this down once, in a note, before the second pause request:
-
Which pause. "Away / not using it" gets a real pause. "Can't pay right now but still using it" gets paused collection, with
mark_uncollectibleif you're forgiving andkeep_as_draftonly if you said they'd pay later. - Max length. Something like up to 3 months, with a resume date always set. "Until you resume it" is how pauses turn into forgotten accounts.
- What they see while paused. Read-only, export still works, nothing deleted. Say this in the reply.
- What the first invoice after looks like. If you keep the default credit, tell them the first charge in March will be smaller than usual, or they'll think it's a mistake.
- Coupons. Mention it if a discount will run out during the pause.
- Reminder. Put a calendar reminder a few days before the resume date and send a short "you're back on March 1, here's what you'll be charged" email. I didn't see anything in the pause docs about Stripe emailing the customer before a resume, so I'd send this one yourself.
The reply to the photographer then writes itself:
"Sure, I've paused your subscription from today until March 1. You won't be charged before then and your projects stay as they are, you can still log in and look at them. Your first charge in March will be a bit lower because of the unused days from this month. I'll email you a few days before."
That's it. No retention trick, no form.
Quick checklist
- [ ] Know which pause you're using:
pause_collection(stays active, invoices still created) or real pause (paused, no invoices) - [ ] For
pause_collection, pickbehavioron purpose, and setresumes_at - [ ] Look at open invoices before pausing, old ones keep retrying
- [ ] For real pause: flexible billing mode,
charge_automatically, no trial, no schedule - [ ] Resume with
resume_on_payment_success, confirmstatusbefore giving access back - [ ] Paywall handles
pausedand readsstatus_detailsso a paused customer doesn't see trial copy - [ ] Coupons keep running during a pause
- [ ] Reminder email before resume
Stripe's pause subscriptions docs are the source of truth for the fields above, and the pages changed recently, so check them before you build anything. And since the same release also lets Stripe pause a subscription automatically after a failed payment, it's worth deciding how that fits with your retry emails. I put together a longer playbook on recovering failed payments before they turn into churn if you're setting that up anyway.
So, a question for anyone already doing this: when a customer asks to pause, do you use pause_collection, the newer pause, or do you just cancel and re-subscribe them later? And if it's pause_collection, which behavior did you go with?
Top comments (1)
the behavior field is the part that bites people. pause collection with mark_uncollectible is fine for a real grace period, but the invoices-from-before-the-pause detail is the one that surprises: a failed renewal you paused to be nice about can still get retried, so the customer comes back in March and finds months of debt sitting there. worth putting the resumes_at date in the pause email too, so March is a promise on both sides rather than a queue you have to remember to clear.