Discount Coupons for Retention in Stripe
Create retention discount coupons in Stripe using the Coupons API with percent_off or amount_off, then apply them via cancel flows or win-back emails. A 20-30% discount for 1-3 months converts best. Targeted discounts shown during cancellation save 15-25% of price-sensitive customers without permanently lowering their rate.
When a customer clicks "cancel," the window to save them is measured in seconds. A well-timed discount coupon can turn a lost customer into a retained one. Stripe has built-in coupon and promotion code support that most SaaS founders never use for retention. Instead of letting customers walk away, you can programmatically offer a personalized discount right inside your cancel flow. The data backs this up: SaaS companies that offer targeted discounts during cancellation recover 15-25% of customers who would have otherwise churned. reducing voluntary churn significantly. This guide covers how to create coupons in Stripe, apply them to subscriptions, and integrate them into a cancel flow that actually saves revenue. Check the cancel flow save rate benchmarks to see how your results compare.
When to offer discounts
Not every churning customer should get a discount. Blanket discounting trains customers to cancel whenever they want a better price. Instead, target discounts at three specific moments:
- Cancel flow offers. when a customer initiates cancellation and selects "too expensive" as their reason, a discount is the most relevant response. This is the highest-conversion moment for coupon offers.
- Win-back campaigns, for customers who already churned, a time-limited discount in a win-back email (sent 7-30 days after cancellation) can reactivate 8-12% of lost accounts.
- At-risk customers. If your data shows a customer's usage has dropped significantly or they've downgraded, a proactive discount can prevent cancellation before it happens. Learn how to detect at-risk customers using Stripe data.
The key principle: discounts should feel like a genuine gesture to a customer who's on the fence, not a default response to every cancellation attempt.
Stripe Coupon API basics
Stripe's coupon system has two layers: coupons (the discount definition) and promotion codes (shareable codes that reference a coupon). For retention flows, you'll work directly with coupons since you're applying them programmatically rather than sharing a code.
Every coupon has a discount type and a duration:
- percent_off; a percentage discount (e.g., 25% off). Best for retention offers because it scales with plan price and feels proportional.
- amount_off; a fixed dollar amount (e.g., $10 off). Better for win-back campaigns where you want a concrete number in the email subject line.
- duration: once. applies to the next invoice only. Good for a one-time "stay with us" gesture.
- duration: repeating. applies for a set number of months (configured via
duration_in_months). The sweet spot for retention: 2-3 months gives customers time to re-engage with your product. - duration: forever. permanent discount. Avoid this for retention. It destroys LTV and sets a precedent you can't undo.
Creating a coupon via the API looks like this: call stripe.coupons.create() with percent_off: 25, duration: 'repeating', and duration_in_months: 3. That gives you a 25% discount for 3 months; the most effective retention offer according to industry benchmarks.
Creating coupons via Dashboard
If you prefer a no-code approach, Stripe's Dashboard lets you create coupons manually. Navigate to Products > Coupons in your Stripe Dashboard. Click "Create coupon" and fill in the details:
- Choose percentage or fixed amount discount
- Set the duration (once, multiple months, or forever)
- Optionally add a redemption limit (useful for limiting how many customers can use it)
- Optionally set an expiry date (creates urgency)
- Give it a clear ID like
retention_25off_3moso you can reference it in code later
Dashboard-created coupons work identically to API-created ones. You can reference them by ID when applying them to subscriptions programmatically. This hybrid approach works well: create a handful of retention coupons in the Dashboard, then apply them via code in your cancel flow.
Applying coupons programmatically
To apply a coupon to an active subscription, use stripe.subscriptions.update() with the coupon parameter. Pass the coupon ID you created earlier, and Stripe applies the discount starting from the next invoice. The customer's subscription stays active, their next charge is reduced, and you've just saved a cancellation.
The flow in practice: customer clicks cancel, your UI shows a modal with the offer ("Stay and get 25% off for 3 months"), customer accepts, your backend calls stripe.subscriptions.update() with the coupon, and you redirect them back to your app with a confirmation message. The entire interaction takes under 5 seconds.
You can also apply coupons to specific subscription items if you have multi-line subscriptions, or use stripe.customers.update() with a coupon to apply it at the customer level (affects all their subscriptions). For most SaaS products with a single subscription per customer, the subscription-level approach is simplest.
Best practices for retention discounts
Getting the discount right matters more than offering one at all. Here's what works:
- Segment by cancellation reason. "too expensive" gets a discount. "Missing features" gets a roadmap update. "Not using it" gets a guided re-onboarding. Don't waste discounts on customers who have a non-price objection.
- 20-30% off for 1-3 months; this range converts best. Below 20% feels insignificant. Above 30% signals desperation and eats too much margin. 1-3 months gives customers time to re-engage without permanently lowering their rate.
- Create urgency. "This offer expires in 24 hours" or "Available only during this session" prevents customers from bookmarking the cancel page as a discount machine.
- Limit redemptions per customer. track which customers have already received a retention discount. Offering it twice signals that your pricing is negotiable. Once per customer, ever.
- Measure save rate, not just offer rate. track how many customers who accepted a discount are still active 90 days later. A discount that saves someone for one month but they cancel again afterward has a 0% true save rate. Use a cancellation survey to capture reasons and measure offer effectiveness.
Integrating into cancel flows
The highest-converting place for a discount offer is inside your cancel flow, after the customer has told you why they're leaving. A typical flow looks like this:
- Customer clicks "Cancel subscription"
- Exit survey asks why they're leaving (5-7 options)
- Based on their answer, show a personalized offer (discount for "too expensive," pause for "not using it," feature preview for "missing features")
- If they accept, apply the coupon via API and return them to your app
- If they decline, proceed with cancellation gracefully
The personalization step is critical. Showing a discount to someone who said "I switched to a competitor" is tone-deaf. Showing a 25% discount to someone who said "it's too expensive for my budget right now" is empathetic and relevant. Companies that personalize their cancel flow offers see 2-3x higher save rates compared to showing the same offer to everyone.
Building this from scratch requires a cancel flow UI, webhook handling, coupon management, and analytics. Estimated build time: 20-30 hours, plus ongoing maintenance for A/B testing different offer amounts and durations.
Next step
SaveMRR's Cancel Shield automates the entire flow described above. It shows personalized discount offers based on exit survey responses, applies Stripe coupons automatically, and tracks 90-day retention rates for each offer type. No code required beyond a JavaScript snippet. Before building your own coupon system, run SaveMRR's free Revenue Scan to see how many of your cancellations could have been saved with a targeted discount. It connects to your Stripe account in 2 minutes and shows you the exact revenue at stake.
