DEV Community

Zee
Zee

Posted on

I Built an AI That Talks People Out of Cancelling Their Subscriptions

Here's the thing about churn: by the time someone clicks "Cancel Subscription", they've already decided. Your generic "Would you like 20% off?" popup is too late and too weak.

I spent the last month building SaveMyChurn — an AI-powered churn recovery tool for Stripe SaaS founders. This is how it works, what I learned building it, and why I think most cancellation flows are doing it wrong.

The problem

I was looking at my own Stripe dashboard one day and noticed something: the cancellation flow was the most ignored piece of the entire subscription experience. People pour weeks into onboarding, feature development, marketing — and then the cancel button just... ends things. No conversation. No understanding of why.

For bootstrapped SaaS founders running £5K-50K MRR, every subscription matters. Losing 5% of your customers a month isn't a statistic — it's the difference between growing and dying.

The existing tools didn't fit. Churnkey starts at $250/month — that's a significant chunk of revenue when you're small. The cheaper options are just form builders with a discount code at the end. Nobody was actually talking to the customer.

What I built

SaveMyChurn does three things:

1. Listens to Stripe in real time

When a customer hits cancel, Stripe fires a customer.subscription.deleted webhook. SaveMyChurn catches it instantly, pulls the subscription metadata, payment history, and plan details, and builds a profile of who's leaving and why.

# The webhook handler — this is where it starts
@router.post("/webhooks/stripe")
async def stripe_webhook(request: Request):
    payload = await request.body()
    event = stripe.Webhook.construct_event(
        payload, request.headers["stripe-signature"], webhook_secret
    )

    if event["type"] == "customer.subscription.deleted":
        subscription = event["data"]["object"]
        # Build subscriber profile from Stripe data
        profile = await build_subscriber_profile(subscription)
        # Generate AI retention strategy
        strategy = await generate_retention_strategy(profile)
        # Send personalised recovery email
        await send_retention_email(profile, strategy)
Enter fullscreen mode Exit fullscreen mode

2. Generates a unique retention strategy per subscriber

This is the part I'm most proud of. Instead of a static "here's 20% off" flow, an AI strategist analyses the subscriber's behaviour — how long they've been a customer, what plan they're on, their payment history, any support tickets — and creates a genuinely personalised retention offer.

Someone cancelling after 2 months gets a different approach than someone who's been around for a year. Someone on a basic plan gets a different offer than someone on enterprise. The AI adjusts tone, offer type, discount level, and follow-up timing based on the full context.

3. Follows up automatically

One email rarely saves a cancellation. SaveMyChurn runs a multi-step sequence — initial offer, follow-up with adjusted terms, final value reminder — spaced over a few days. Each step is informed by whether they opened the previous email, clicked anything, or went silent.

The tech stack

Keeping it simple and cheap:

  • FastAPI backend — async Python, handles webhooks fast
  • MongoDB for subscriber profiles and strategy storage
  • Redis for caching and rate limiting
  • LLM via API for strategy generation — the AI strategist
  • Resend for transactional emails
  • Docker on a single VPS — the whole thing runs on one machine

The LLM cost per strategy generation is under a penny. When your competitor charges $250/month, that's a ridiculous margin.

The pricing model (and why it matters)

I went with a commission model. Monthly fee + a percentage of recovered revenue. The idea is simple: if I don't save you money, I don't make money.

This was a deliberate choice. Flat-fee tools have an incentive to get you signed up and keep you paying, regardless of results. Commission pricing means I'm motivated to actually recover subscriptions, not just ship a dashboard.

For founders at the £5K-50K MRR stage, this aligns incentives in a way that $250/month flat fees don't.

What I learned

Webhook reliability is everything. If you miss a customer.subscription.deleted event, you miss the entire recovery window. I ended up implementing retry queues and idempotency keys before anything else.

AI strategy > rules engine. I initially built a simple rule-based system (if cancel reason = "price" → offer discount). It was okay. The AI strategist that replaced it generates strategies I wouldn't have thought of — bundling features differently, offering plan downgrades instead of discounts, timing follow-ups based on engagement patterns.

One email is never enough. The first recovery email has maybe a 15-20% open rate. The follow-up catches another chunk. The third one gets the people who were "going to get around to it." Multi-step sequences doubled recovery rates compared to single emails.

Where it's at

SaveMyChurn is live and in production. It works end-to-end: Stripe webhook → AI strategy → personalised email sequence → dashboard showing what was saved.

If you're a bootstrapped SaaS founder on Stripe watching subscriptions slip away, give it a look. There's a free trial — no credit card required.

Top comments (0)