Skip to content
Back to skills

Build Win Back Flow

ASecurity

Build a win-back flow for lapsed and churning subscribers using Apple StoreKit 2 win-back offers, RevenueCat campaigns, and segmented messaging. Use when the user says 'win-back', 'lapsed users', 'churn recovery', 'bring users back', 'expired trial', 'canceled subscription', 'reactivation', or 'promotional offer'.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 4, 2026
developmentgoreactrailsapibackend

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 4, 2026

npx -y skills add khadinakbarlabs/expo-mobile-app-builder --skill build-win-back-flow --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Build Win Back Flow?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Build Win Back Flow
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/khadinakbarlabs-build-win-back-flow/badge)](https://www.skillsdirectory.com/skills/khadinakbarlabs-build-win-back-flow)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: "build-win-back-flow"
description: "Build a win-back flow for lapsed and churning subscribers using Apple StoreKit 2 win-back offers, RevenueCat campaigns, and segmented messaging. Use when the user says 'win-back', 'lapsed users', 'churn recovery', 'bring users back', 'expired trial', 'canceled subscription', 'reactivation', or 'promotional offer'."
---

# Build a win-back flow

Win-back is recovering users who have lapsed — expired trials, canceled subscriptions, or gone inactive. It is one of the highest-ROI growth motions because reactivating a known user is far cheaper than acquiring a new one, and the data shows most churn is recoverable if you act on it.

## Segment first — different lapsed states need different offers

Never treat all churn the same. The message and offer must match the segment:

| Segment | Definition | Best offer |
|---|---|---|
| **Expired trial** | Started a trial, never converted | Discounted first period; surface the value they didn't see; remove friction |
| **Lapsed subscriber** | Paid, then canceled or let it expire | Win-back offer (StoreKit 2); "we miss you" + what's new since they left |
| **Inactive free user** | Was active, hasn't opened in 10+ days | Re-engagement push/email with a specific reason to return; no paywall |
| **Involuntary churn** | Payment failed | Dunning/retry — see below; this is the most recoverable of all |

## The Apple/Google win-back primitives

### Apple StoreKit 2 win-back offers (iOS 18+)

Configured in App Store Connect, target subscribers whose subscription has **expired** (lapsed, not active). RevenueCat and Superwall both expose them. The user sees the offer on the App Store product page, in App Store emails, and you can present it in-app.

- Up to a limited number of win-back offers per subscription group.
- Discounted price for a set duration (e.g., 50% off for 3 months).
- Presented via StoreKit; RevenueCat surfaces them in the offerings/entitlements API.

```tsx
// RevenueCat: detect eligibility and present a win-back offering
import Purchases from 'react-native-purchases';
const offerings = await Purchases.getOfferings();
const winback = offerings.all['winback_expired']; // offering configured for lapsed segment
```

### Apple promotional offers

Target **existing or previous** subscribers with a discounted price for a set duration. More flexible than win-back offers (you control eligibility in your backend) and can target currently-active subscribers too.

### Google Play

No equivalent first-class "win-back offer" primitive, but you can use promo codes and in-app messaging to the same effect. Subscribe to Real-Time Developer Notifications (RTDN) for `SUBSCRIPTION_CANCELED`, `SUBSCRIPTION_EXPIRED`, and `SUBSCRIPTION_ON_HOLD` to trigger flows. See `app-store-server-notifications-android`.

## Involuntary churn is the easy win

**30–50% of total churn is involuntary** (failed payments), and it's the most recoverable. On Google Play, nearly a third of cancellations are involuntary billing failures vs just 14% on Apple. ([RevenueCat State of Subscription Apps](https://www.revenuecat.com/state-of-subscription-apps))

- **Dunning emails** ("your payment failed — update your card") + **smart retries** recover an estimated **50–60%** of failed payments.
- Apple/Google handle billing retries on their side, but surface grace-period and account-on-hold states to the user in-app with a clear "update payment method" CTA.
- Subscribe to server notifications (`app-store-server-notifications`, `app-store-server-notifications-android`) to react to `BILLING_RETRY`, `GRACE_PERIOD`, `ACCOUNT_HOLD`.

## The win-back campaign structure (RevenueCat web checkout)

RevenueCat supports routing win-back offers through a **web checkout** to bypass the 15–30% store commission — present the lapsed user with a "Claim your offer" button (push, email, or in-app banner), route to a Stripe-hosted web checkout, then restore access in-app immediately on success. This works in regions/states where alternative billing is permitted; respect current Apple/Google policy and regional law before relying on it.

### Timing

- **Expired trial**: wait 1–3 days, then a single "we saved your progress" + discounted offer. Don't spam.
- **Lapsed subscriber**: at genuine expiry (when premium access actually ends, not when they hit cancel), then again at 7/30/60 days with escalating personalization.
- **Inactive free user**: 3 days silent → gentle nudge; 7 days → direct message + incentive; 14 days → escalated offer. (See `design-lifecycle-messaging`.)

## The cancel-vs-expire distinction (important)

A user who *cancels* (turns off renewal) but is still in their paid period is **not yet lapsed** — don't fire a win-back. Wait until premium access actually expires. Firing win-back at cancel-time cannibalizes the subscription they're still paying for. Use server notifications to distinguish `SUBSCRIPTION_CANCELED` (still active until period end) from `SUBSCRIPTION_EXPIRED` (lapsed).

## Messaging that converts

- **Name the specific value they're missing.** "Your 47-day streak is frozen. Come back before you lose it." Not "We miss you!"
- **Surface what's new since they left.** Features, content, improvements. Give them a reason beyond the discount.
- **Make the offer time-limited and specific.** "50% off your next 3 months — claim by Friday." Not "a discount."
- **One clear CTA.** Claim offer / update payment / come back. No menus.

## Measure

```text
winback_segment_assigned   {segment: expired_trial|lapsed|inactive|involuntary}
winback_message_sent       {channel: push|email|in_app|web}
winback_offer_presented
winback_offer_claimed
winback_reactivated        // returned to active subscription or active use
winback_revenue            // attributed revenue from the campaign
```

Track reactivation rate and attributed revenue per segment. Win-back ROI is typically far higher than new-user acquisition ROI.

## What not to do

- **Don't fire win-back at cancel-time.** Wait for genuine expiry.
- **Don't spam.** One well-timed, personalized message beats five generic ones.
- **Don't offer >50% off routinely** — trains users to cancel-for-deals. Cap routine win-back at 20–30% for 2–3 months. See `build-cancellation-flow`.
- **Don't ignore involuntary churn** — it's the biggest, cheapest recovery pool and the most neglected.

## Pair with

- `integrate-revenuecat-rn` — win-back offerings, web checkout, server notifications.
- `app-store-server-notifications` / `app-store-server-notifications-android` — the lifecycle signals that trigger win-back.
- `build-cancellation-flow` — intercept active churn *before* it becomes win-back territory.
- `design-lifecycle-messaging` — the cross-channel cadence this lives in.
- `pricing-strategy` — discount guardrails.

Files in this skill

  • SKILL.md6.7 KB
  • agents/openai.yaml188 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…