How to ask customers why they cancel, in Stripe
Oct 31, 2026 · Luis Miguel
I'm a robotSkip the pixels. Read the .mdTo ask customers why they cancel in Stripe, turn on "Cancellation reason" in Settings, then Billing, then Customer portal. Customers who cancel through the portal then pick a reason from a short list before the cancellation goes through, and Stripe saves their answer on the subscription, in cancellation_details.feedback, with anything they typed in cancellation_details.comment. If they cancel somewhere else, in your app for example, you can ask them yourself and save the answer in the same fields through the API.
It takes a minute to set up and costs nothing. The steps match Stripe's docs for the customer portal and the cancellation page.
How do you turn it on?
In the Dashboard, go to Settings, then Billing, then Customer portal. In the Cancellations section:
- Cancel subscription lets customers cancel from the portal at all.
- Cancellation reason shows them a short list of reasons before the cancellation goes through.
- Retention coupons offers a coupon you pick when they try to cancel. Stripe calls this deflecting cancellations. It's off by default.
You also choose whether a cancellation happens right away or at the end of the period they already paid for. I'd pick the end of the period. The customer keeps what they paid for, and you get days or weeks to talk to them before they go, which is why scheduled cancellations are worth watching. If you cancel immediately, you also choose whether to prorate what's left of the period.
If you configure the portal through the API instead, the same switches live under features.subscription_cancel: mode (at_period_end or immediately) and cancellation_reason.enabled with its options.
Which reasons can customers choose?
The customer picks one of these. The second column is what Stripe stores:
| What the customer sees | Stored as |
|---|---|
| It's too expensive | too_expensive |
| I need more features | missing_features |
| I found an alternative | switched_service |
| I no longer need it | unused |
| Customer service was less than expected | customer_service |
| Ease of use was less than expected | too_complex |
| Quality was less than expected | low_quality |
| Other reason | other |
You can choose which ones to show. With "Other reason" they can type a comment. Stripe also lets you define your own feedback options, which are stored in cancellation_details.feedback_option instead.
Show only the options that fit your product. If "customer service" doesn't apply to you, leave it out, and the answers you get are easier to act on.
Where do the answers end up?
On the subscription, in cancellation_details:
feedbackis the reason they picked, from the table above.commentis anything they typed.reasonis how the cancellation happened, not why:cancellation_requestedwhen someone canceled it,payment_failedwhen it ended after failed payments,payment_disputedafter a dispute.
You can see them on the subscription's page in the Dashboard and in the customer.subscription.updated event, or query them with Sigma.
To pull them all at once, a few lines of the API and a read-only key will do it:
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_KEY!);
for await (const s of stripe.subscriptions.list({ status: "canceled", limit: 100 })) {
const d = s.cancellation_details;
if (d?.feedback || d?.comment) console.log(s.id, d.feedback ?? "", d.comment ?? "");
}
What if customers cancel in your own app?
You can still ask them and keep the answers in the same place. Both the cancel call and the update call accept cancellation_details with a feedback (one of the values in the table) and a comment. Even after a subscription is canceled, Stripe still lets you update its cancellation_details, so a reason that arrives by email a day later can go on the right subscription.
How should you read them?
With a few dozen customers, read every one. Tallying the reasons is fine, but the typed comments are where you find something to reply to.
What each reason tends to mean:
too_expensivecan mean "not worth it for what I use" as much as "I can't afford it". Send one email asking which part they used. Sometimes a smaller plan or a pause keeps them.unusedcan mean they never got set up. Look at onboarding before you touch pricing.missing_featuresandswitched_servicetell you what you're compared against. Ask what they moved to.too_complexpoints at the first days of use. Check where those customers stopped.payment_failedinreasonisn't a decision at all. That's involuntary churn, and it needs a different fix.
When you're small, I'd look at the reasons before the rate. If ten cancellations give the same reason, you know what to work on, whatever your churn number says (churn with 20 customers).
Should you offer a coupon when they cancel?
The portal can do it: with a retention coupon set, customers who start to cancel see the offer first. It can keep customers for whom price really was the issue. It can also teach customers that clicking "cancel" gets a discount, and it does nothing for the other reasons. If you try it, look at whether the customers who took the coupon are still there a few months later, not only whether they took it.
Do reasons show up on TrustChurn?
Never on a public profile. They go to your private list, which shows everyone who left in the last 30 days with the reason and the comment they gave in the portal, and a new "too expensive" sends you an email the same hour, while there's still time to write back.
FAQ
Where do I see why a customer canceled in Stripe?
On the subscription's page in the Dashboard, and in the subscription's cancellation_details: feedback has the reason they picked and comment anything they typed. You can also query them with Sigma or list canceled subscriptions with the API.
Can I add my own cancellation reasons?
Yes. Besides choosing which of Stripe's reasons to show, you can define custom feedback options. The answer to those is stored in cancellation_details.feedback_option.
Can I offer a discount when someone tries to cancel?
Yes. In the Cancellations section of the customer portal settings, pick a retention coupon. Stripe offers it to customers before the cancellation goes through. It's off by default.
What does cancellation_details.reason mean?
It says how the subscription was canceled, not why the customer left: cancellation_requested when someone canceled it, payment_failed when it ended after failed payments, and payment_disputed after a dispute. The customer's own answer is in feedback.
Can I record a reason if I canceled the subscription myself?
Yes. The cancel and update calls accept cancellation_details with a feedback and a comment, and you can still update them after the subscription is canceled.
Keep reading
How to find scheduled cancellations in Stripe
A customer who cancels at the end of the period still looks active in Stripe. How to find them and what to do before the date.
Failed payments and expiring cards in Stripe
Retries, emails to the customer, expiring cards and what happens when every retry fails. What to turn on in Stripe.