WIN-BACKSTRIPE

How to win back canceled subscribers on Stripe

How to win back canceled Stripe subscribers: what Stripe keeps after a cancellation, reading cancellation_details, timing offers and restarting billing.

Published 5 min read

A canceled subscriber is not a stranger. You know what they bought, how long they stayed, and often why they left. That makes them some of the easiest people to sell to again, if you ask at the right time with the right offer.

This guide covers what Stripe keeps after a cancellation, how to read the reason, how to plan a win-back sequence, and how to restart billing cleanly when someone comes back. Stripe details come from the cancel subscription API reference, the customer portal cancellation page, retention rules, coupons and promotion codes and using webhooks with subscriptions (all accessed November 2026).

What Stripe keeps after a cancellation

When a subscription ends, Stripe sends customer.subscription.deleted. The subscription moves to canceled and, as the cancel API reference puts it, you can no longer update it. Coming back means a new subscription.

The Customer object is a different matter. It stays, with its email, invoices and payment history. That is what makes win-back practical: you do not start from zero, and if you attach the new subscription to the same Customer, your reporting shows a returning customer rather than a new one.

Scheduled cancellations are not cancellations yet

Many cancellations are set to take effect at the end of the paid period (cancel_at_period_end). Until that date, the subscription is still active and the cancellation can be removed. This window is your cheapest win-back: a short “Your access ends on [date]” email with a one-click way to keep the plan often does more than any later campaign.

Read the reason before you write a word

Stripe stores why a subscription ended in cancellation_details on the subscription, documented in the cancel API reference:

Field What it holds
reason Why the subscription ended, for example cancellation_requested, payment_failed or payment_disputed
feedback The customer’s chosen reason: too_expensive, unused, missing_features, switched_service, too_complex, low_quality, customer_service or other
comment Free text the customer wrote, up to 5,000 characters

reason separates voluntary churn from involuntary churn. A subscription that ended with payment_failed was never a decision; the right win-back there is a card update link, not a discount. For more on that split, see involuntary churn.

feedback and comment are filled when the customer tells you. If you use Stripe’s customer portal, you can turn on a cancellation page that asks for a reason from Stripe’s list, with free text when the customer picks “Other”. If you build your own cancel flow, pass the answer to the cancel call so it lives with the subscription.

Treat comment with care. It is written by the customer and can contain personal details. Store it, read it, but do not paste it into templates.

Retention at the moment of cancellation

Stripe’s retention rules let the customer portal present an offer when a customer tries to cancel, matched on the cancellation reason. Stripe evaluates the rules in the order you define and shows the offer from the first match; if nothing matches, the customer continues to cancel. Offers can be a discount coupon or, if the switch plan option is enabled in the portal, a plan switch. Retention rules replace the older retention coupon setting in the portal configuration.

That is prevention, not win-back, but it matters for one reason: if a customer already turned down a discount while cancelling, sending the same discount a week later is unlikely to land. Record what was offered and refused.

Plan the win-back sequence

A practical sequence for most subscription products:

When Who Message
Before the period ends Scheduled cancellations Reminder of the end date, one click to keep the plan
Day 30 All voluntary churn What changed since they left, tied to their reason
Day 60 Those who did not return A specific offer, if the reason was price
Day 90 Those who did not return A last, low-pressure note, and an easy way to stop emails

Match the message to the feedback value:

  1. too_expensive: lead with a cheaper plan or a time-limited discount on return.
  2. missing_features: wait until you ship something relevant, then say what it is. No discount needed.
  3. unused or too_complex: offer help getting started, a short call or a guide, not money.
  4. switched_service: ask what the other tool does better. Some of these come back; most valuable is the answer.
  5. customer_service or low_quality: apologize specifically and say what you fixed. A discount alone reads as dismissive.

Examples of full emails are in our win-back email examples.

Keep the list clean

  • Exclude customers who disputed a charge (reason is payment_disputed).
  • Exclude anyone who asked not to be contacted, and respect marketing consent rules where you operate.
  • Stop the sequence the moment someone resubscribes.

Restarting billing when someone comes back

Use the same Customer

Create the new subscription on the existing Customer ID. If you send people to Stripe Checkout, pass the existing customer rather than letting Checkout create a new one, so payment history and reporting stay connected.

Discounts for returning customers

Stripe coupons have a duration that controls how long they apply to a subscription:

  • once: the first invoice only.
  • repeating: a set number of months, which you must specify.
  • forever: every invoice.

For win-back, once or a short repeating coupon is usually enough. A forever discount for returning customers teaches people to cancel to get a better price.

If you share a code, use a promotion code on top of the coupon. One trap: Stripe’s promotion codes can be restricted with restrictions.first_time_transaction, and Stripe counts a customer with prior payments or non-void invoices as not first-time. A returning customer will fail that check. Use a dedicated win-back code without that restriction, and limit it by expiry date or redemptions instead.

Check the payment method

The card that was on file when they left may have expired or been replaced since. Make the return path go through a page where the customer confirms or updates the card, rather than charging silently.

Measure it honestly

Track, per month of cancellation:

  • How many customers came back within 90 days, and on which plan.
  • Which feedback values return most, and which never do.
  • How many returning customers used a discount, and how long they stayed afterward.

Count a reactivation only when the new subscription is on the same Customer. Without that, your churn rate and your new customer count are both wrong. See how to calculate churn rate.

Doing this with NoChurn

NoChurn reads cancellations from Stripe, including cancellation_details and the answers from its own cancel flow, and sends win-back emails at day 30, 60 and 90 based on the cancellation reason. For subscriptions that ended on a failed payment, the better path is recovery: smart retries, recovery emails you review, and a hosted card update page. Restarting the subscription and the payment stay in Stripe. See NoChurn + Stripe.

PROMPT

Read https://www.nochurn.sh/llms.txt,
then follow https://www.nochurn.sh/docs/quickstart/
to add NoChurn to this app. Use a test key
(nc_test_…) until I say we go live.

Stop leaking revenue.

  • Free until $300 MRR
  • No card needed
  • Live in 10 minutes
  • Never a cut of what we recover