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.
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_dueand Lemon Squeezy retries the payment four times over two weeks. A successful retry returns it toactive. If all four fail, it becomesunpaid. - 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 staysunpaid. - 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
- Route “Cancel” in your app to your flow. Show a short list of reasons plus “Other”.
- Offer one thing that fits the reason. “Not using it now”: a pause in
voidmode withresumes_atset. “Too expensive”: a cheaper product. “Missing a feature”: a reply from a person. - Keep “Cancel now” visible on every step. One click should finish the cancellation without accepting an offer.
- Apply the outcome with the API. Pause with
PATCHand apauseobject; cancel withDELETE, which keeps access untilends_at. - Confirm the end date from the subscription returned by the API.
- Offer “keep my subscription” during the grace period, which sets
cancelledto 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.