How to build a cancellation flow on Stripe
· Alex · 4 min read
A cancellation flow is what a customer sees between clicking “Cancel” and their subscription ending. On Stripe you have three ways to build one: turn on the cancellation page in Stripe’s customer portal, build your own on the Stripe API, or point your cancel button at a hosted flow such as Reoffer. They differ in when they ask why, what they can offer, and what they count as saved.
Last updated 30 October 2026. Stripe details are from Stripe’s documentation on the customer portal cancellation page on that date.
What Stripe’s customer portal does on cancellation
The portal is free and works in minutes. Cancelling is on by default. In the customer portal settings you can also collect a cancellation reason and set one retention coupon to deflect cancellations.
- Reasons: the customer picks from a fixed list of eight, such as “It’s too expensive”, “I need more features” and “I found an alternative”. “Other reason” takes free text. Stripe asks after the customer has cancelled, so the answer can’t change what they’re offered.
- Offer: one retention coupon, the same for everyone, whatever their reason.
- Where reasons go: the subscription details page, Stripe Sigma, and the
subscription.updatedwebhook.
That covers a lot of products. The gap is matching: someone leaving on price and someone leaving because they’re on holiday get the same coupon, and nobody is offered a pause.
Building your own cancellation flow on the Stripe API
- Send the cancel button to your own page instead of straight to the portal.
- Ask the reason first, then show one offer that fits it.
- Apply the offer through the API: a coupon for a discount or a free cycle, or
pause_collectionfor a pause. - If the customer still leaves, cancel now or set
cancel_at_period_end, and decide on proration. - Listen for the subscription webhooks and record what Stripe actually changed, not what the customer clicked.
The first version takes a weekend. The cost is the second year: API versions move, coupons behave differently on metered and multi-item subscriptions, and someone has to own it the night the flow breaks.
Discount, free cycle or pause: which offer fits which reason
| Reason given | Offer that fits | Why |
|---|---|---|
| Too expensive | Discount for a few months | Answers the actual objection |
| Not using it right now | Pause | Keeps the subscription without billing for idle months |
| Want to try it longer | One free billing cycle | Buys time to see value |
| Missing a feature, switching tools | Often no offer | A discount doesn’t add the feature |
How a hosted cancellation flow works with Stripe
Reoffer connects to your Stripe account through Stripe Connect. Your cancel button opens a Reoffer page that asks why, shows the one offer you matched to that reason, and applies it to the subscription in your Stripe account. Every offer moves through four states: shown, accepted, processing, applied. Only applied, meaning Stripe confirmed the change, counts as a save. How we measure a save rate sets out the rules.
The limits, stated up front: Reoffer works with Stripe only. It has no A/B testing and doesn’t recover failed payments. Pause is for monthly plans, a free cycle isn’t offered on annual plans, and metered or schedule-managed subscriptions get the reason question without an offer.
| Stripe customer portal | Build it yourself | Reoffer | |
|---|---|---|---|
| Asks the reason | Yes, after cancelling | However you build it | Yes, before any offer |
| Offer matched to the reason | No, one coupon for all | If you build it | Yes, one offer per reason |
| Pause offer | No | Via pause_collection | Yes, monthly plans |
| What counts as saved | Not reported | Whatever you log | Only changes Stripe confirmed |
| Cost | Included with Stripe Billing | Your engineering time | Free plan (reasons only), paid from $29/month |
Questions
Cancelling is enabled by default. In the Stripe Dashboard, open the customer portal settings, expand Cancellations, and choose whether to collect a reason and which retention coupon to offer.
Yes. The portal can ask after a customer cancels, from a fixed list of eight reasons plus free text for “Other reason”. You’ll find the answers on the subscription, in Sigma and in the subscription.updated webhook.
Not from the portal’s cancellation page. You can pause payment collection through the API with pause_collection, or use a hosted flow that offers a pause to customers whose reason fits.
The customer keeps access until the current period ends and isn’t billed again. Until then, the cancellation can still be undone by clearing cancel_at_period_end.
No. Reoffer works on top of the Stripe account you already have, through Stripe Connect. It supports Stripe only.
A cancellation stings less when you know why it happened. Start on the Free plan: no card and no Stripe permission. It records why customers leave and sends them on to your billing page.
See why your customers leave
Start on the Free plan: no card, one product, feedback only. Connect Stripe on a paid plan when you want offers applied and saves counted.