CANCEL FLOWSLEMON SQUEEZY

How to reduce churn on Lemon Squeezy

How Lemon Squeezy handles subscription states, failed payment retries, dunning, pause and cancel, and how to add a cancel flow and win-back on top.

Published 5 min read

Lemon Squeezy already does a fair amount to keep subscriptions alive: it retries failed payments, sends recovery emails, and gives customers a portal where they can pause instead of cancelling. This guide explains what it does natively, which subscription states and webhooks to watch, and where a cancel flow and win-back fit on top.

It sticks to Lemon Squeezy’s own documentation: subscriptions, the subscription object, recovery and dunning, managing subscriptions with the API, customer portal, webhook event types, discounts and refunds and chargebacks (all accessed November 2026).

Lemon Squeezy is the merchant of record

Lemon Squeezy sells to your customers as merchant of record. It processes payments, refunds and chargebacks. Its docs say that for a dispute it typically refunds on your behalf and deducts the amount (minus its platform fee) plus a $15 dispute fee from your next payout, and that it provides information to the payment provider to make the case. Too many chargebacks can lead it to suspend a store. For churn work, this means you change subscriptions through Lemon Squeezy’s API and portal, and you do not run payments yourself.

The subscription states

The subscription object has seven statuses. Knowing which ones still grant access is the base of everything else.

Status Meaning Access
on_trial On a trial, waiting for the first payment Yes
active Active and valid Yes
paused Payment collection paused, subscription still live Optional, your choice
past_due A renewal failed and Lemon Squeezy is retrying Yes
unpaid All retries failed; dunning rules decide what happens next See below
cancelled Future payments cancelled, still valid until the period ends (grace period) Yes
expired Ended, after cancellation or after dunning No

Lemon Squeezy’s guidance is to allow access for on_trial, active, cancelled, past_due and optionally paused. Its dunning page says that once the final retry fails, the subscription becomes unpaid and the customer loses access.

What Lemon Squeezy does on failed payments

Lemon Squeezy has built-in recovery, described on its recovery and dunning page:

  • Retries. After a failed renewal, the subscription moves to past_due and Lemon Squeezy retries the payment four times over two weeks. A successful retry returns it to active. If all four fail, it becomes unpaid.
  • Emails during retries. Each failed attempt sends the customer an email asking them to update their billing information.
  • Dunning after retries. If you turn dunning on, Lemon Squeezy sends a series of dunning emails over a period you configure, and your dunning rules decide when the subscription becomes expired. You can edit the default emails, subject lines and schedule. If dunning is off, the status stays unpaid.
  • Expiring card notices. Lemon Squeezy can email customers before a saved payment method expires.
  • PayPal is different. For PayPal subscriptions, the PayPal page says retries happen every 5 days, up to twice per billing cycle, and the subscription is suspended after two failed billing cycles.

The same card update link is sent with each retry and dunning email. Lemon Squeezy notes that these update URLs expire after 24 hours, so if you send your own messages, fetch a fresh URL from the API each time rather than storing one.

This is a solid native baseline. The parts you control are the dunning schedule and email copy; the retry timing itself is set by Lemon Squeezy.

Pause and cancel through the API

The subscription management guide covers both.

Pause. Send PATCH /v1/subscriptions/:id with a pause object. Two modes exist:

  • void: for periods when you cannot provide the service;
  • free: the customer keeps using the product for free during the pause.

Both stop payment collection. An optional resumes_at date unpauses automatically. Setting pause to null resumes collection on the original schedule.

Cancel. DELETE /v1/subscriptions/:id cancels an active subscription. It moves to cancelled and stays valid until the next renewal date, shown in ends_at, then expires. During that grace period you can resume it by updating the subscription with cancelled set to false.

The customer portal

Lemon Squeezy’s hosted customer portal lets customers switch between subscription products, pause and unpause, cancel and resume, and update billing details. You choose which features appear in the portal settings. Each subscription object also carries a customer_portal URL, a pre-signed link valid for 24 hours, which you can open from your app.

If you let customers cancel straight from the portal, they skip any retention step you build. Decide on purpose: either send “Cancel” in your app to your own flow first, or rely on the portal’s pause option as your only offer.

Discounts

Lemon Squeezy discounts have three durations (discount object): once, repeating for a set number of months, or forever. For yearly plans the repeating count is still in months, so two yearly payments means 24. The discount documentation describes codes redeemed at checkout; it does not describe applying a discount to a subscription that already exists. Check with Lemon Squeezy before promising a “50% off your next 3 months” offer to a current subscriber. Pause and a move to a cheaper product through the portal are the offers its docs clearly support.

Webhooks to listen to

From the event types page:

Event Use it for
subscription_updated Catch-all for the latest subscription data; Lemon Squeezy recommends it
subscription_payment_failed A renewal failed; retries start
subscription_cancelled Cancelled by the customer or you; grace period begins
subscription_expired Access should end
subscription_paused / subscription_unpaused Pause started or ended

You can simulate events such as subscription_cancelled and subscription_expired in test mode.

Adding a cancel flow

  1. Route “Cancel” in your app to your flow. Show a short list of reasons plus “Other”.
  2. Offer one thing that fits the reason. “Not using it now”: a pause in void mode with resumes_at set. “Too expensive”: a cheaper product. “Missing a feature”: a reply from a person.
  3. Keep “Cancel now” visible on every step. One click should finish the cancellation without accepting an offer.
  4. Apply the outcome with the API. Pause with PATCH and a pause object; cancel with DELETE, which keeps access until ends_at.
  5. Confirm the end date from the subscription returned by the API.
  6. Offer “keep my subscription” during the grace period, which sets cancelled to false.

Win-back

Once a subscription has expired, it is over. Keep the reason you collected, and contact the customer later with something that answers it. Use the subscription_expired event as the start of the timer, and send them to a new checkout.

Doing this with NoChurn

NoChurn reads your Lemon Squeezy subscriptions and webhooks. It adds a cancel flow with reasons, offers (such as a pause or a plan change) and a one-click cancel that is always visible, hosted or headless through the API, plus win-back emails at day 30, 60 and 90 based on the cancel reason and a churn score from 0 to 100. Lemon Squeezy stays the merchant of record: payments, payment recovery, refunds and disputes stay with it. Failed payments show up in NoChurn’s customer timeline and churn score, and disputes appear read only. NoChurn is free under $300 MRR. See NoChurn + Lemon Squeezy.

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