Automating Failed Subscription Recovery for Lemon Squeezy Stores

By Palash Sarker, Founder & Software Architect, Revenue Recovery Labs6 min read Verified by RRLabs

Where Lemon Squeezy leaves recovery on the table

Lemon Squeezy is a merchant of record built for digital products, and it does the hard parts well: global tax, checkout, licence keys, affiliate payouts. Its dunning, however, is deliberately simple — a small number of retry attempts paired with a templated email from the store, on a fixed cadence, in one language, on one channel.

For a store doing $30k MRR, a 7% monthly failure rate is roughly $2,100 of at-risk revenue every cycle. Simple dunning typically recovers a portion of it; a decline-aware, multi-channel sequence routinely recovers a substantially larger share of the same pool without touching acquisition spend.

The point is not that the platform is deficient. It is that recovery is a specialised conversation problem, and a billing platform optimises for collecting money rather than for persuading a distracted human to spend two minutes updating a card.

The webhook contract

Lemon Squeezy sends webhooks with an `X-Signature` header containing an HMAC-SHA256 of the raw request body, keyed on the signing secret you set when creating the webhook. Verification rules are identical to every other provider: hash the raw bytes, compare in constant time, reject before persisting.

The events that matter are `subscription_payment_failed` for the failure itself, `subscription_payment_success` for the confirmation of recovery, `subscription_updated` for state transitions into and out of past-due, and `subscription_expired` for the terminal loss.

Each payload carries the store, the customer, the order and subscription identifiers, the amount in cents, the currency, and the card brand and last four digits — enough to write a message that names the exact card without ever storing a credential.

Idempotency and ordering on a busy store

Webhook deliveries are retried and can arrive out of order, which matters when a customer's card recovers between your queueing a message and your sending it. Nothing damages trust faster than a 'your payment failed' WhatsApp arriving twenty minutes after the receipt.

Guard with two rules. Deduplicate on the provider event identifier with a unique constraint so replays are no-ops. And re-check subscription state immediately before dispatch: if the subscription is active again, cancel the queued touch and log it as a self-recovery rather than a send.

Return 200 fast and do the work asynchronously. A handler that waits on copy generation or an outbound API will eventually time out and trigger a retry storm that your deduplication then has to absorb.

Routing the four codes that matter

Lemon Squeezy surfaces a normalised failure reason. Map it into the standard buckets and give each its own timing and channel.

Short balance: retry at roughly 48 hours, message on email plus WhatsApp, state the retry date plainly. Recovery in the 55-70% range is typical because the underlying condition is temporary.

Expired or replaced card: no useful retry exists. Send the customer-portal update link immediately, lead with the card brand and last four so the customer knows which card to replace, and expect the highest recovery of any code at 70-85%.

Issuer decline with no reason: retry at about 36 hours and ask for a different card in the first message. Recovery here is the weakest of the four, commonly 30-45%, so do not spend your whole cadence on it.

Authentication required: send within minutes on WhatsApp with nothing in the message but the confirmation link, and retry at 24 hours before the challenge goes stale.

Using the hosted customer portal correctly

Lemon Squeezy provides signed customer-portal URLs where a subscriber can update their payment method. Always deep-link to that page rather than building any form of your own — it keeps card handling entirely inside the platform and your integration entirely outside PCI scope.

Generate the portal link at send time, not at ingestion time, because signed URLs expire. A dead link in a dunning message is a recovery you have thrown away, and it is the most common preventable bug in this entire pipeline.

Put the link in the first third of the message on both channels. On WhatsApp, a single call-to-action button outperforms a paragraph containing a URL, and Meta's utility template rules encourage exactly that shape.

Template approval and message design on WhatsApp

Sending on WhatsApp Cloud API requires Meta-approved utility templates before the first send. Write them as transactional notices with variable slots for product name, amount, card last four and retry date. Approval typically takes hours, not days, when the template avoids promotional language.

Keep one template per decline bucket. A single generic template forces vague copy, and vague copy is why most dunning underperforms. The expired-card template should not mention retry dates; the insufficient-funds template should not mention updating a card as the primary action.

Because Meta bills conversations to your own WhatsApp Business account, the marginal cost per touch is visible and predictable, and it is trivially covered by a single recovered subscription in almost any price band.

Failed payment ingestion pipelineDark-mode SVG pipeline diagram by Palash Sarker (Founder & Software Architect, RRLabs) showing webhook ingestion, HMAC-SHA256 signature verification, AI decline scoring and adaptive smart retry.INGESTION ARCHITECTURE01Webhook ingestionprovider event02HMAC-SHA256 verifytiming-safe03AI decline scoringrecoverability04Adaptive smart retrycode-derived windowNo card data enters the pipeline — the recovery layer stays out of PCI scope.
Failed payment ingestion architecture: webhook ingestion, HMAC-SHA256 signature verification, AI decline scoring and adaptive smart retry.

How much of your involuntary churn is recoverable?

Compares a 40% single-channel baseline against the 63.8% RRLabs platform average.

At risk / month
$5,600
Extra recovered / month
$1,333
Annualised, less $3,000 plan
$12,994

RRLabs vs legacy dunning tools

Churn Buster, Baremetrics Recover, Stripe native dunning and Gravy compared with Revenue Recovery Labs.

Feature comparison between legacy dunning tools and Revenue Recovery Labs
FeatureLegacy toolsRevenue Recovery Labs
Recovery channelsEmail and basic SMS onlyNative Meta WhatsApp Cloud API (your number) + email
Pricing architecture$129–$629+/mo, or a percentage cut of recovered cashFlat $100 / $250 / $500 per month — you keep 100%
Retry logicFixed calendar dunning (day 1, 3, 7)Retry window derived per decline code, persisted at ingestion
Copy engineStatic templates you edit by hand4-tier cascade: cache → primary model → fallback model → deterministic templates
White-labelUnavailable or enterprise-onlyFlat +$300/mo with custom domain and no vendor watermark
Audit trailSend logs at bestTier, model, latency and recovery score on every message

Measuring what the store actually recovered

Define at-risk revenue as the sum of failed renewal amounts in a cohort window, and recovered revenue as the subset whose subscriptions returned to active within fourteen days. Report the ratio, not the raw count of recovered subscriptions, because a store's failures are rarely uniform in value.

Break the ratio down by decline bucket. If expired cards recover below 60% your update link or its placement is broken; if short-balance recoveries are low your retry timing is probably fighting the customer's pay cycle rather than following it.

Track cost per recovered dollar as a first-class metric. Flat-fee tooling should keep it under a couple of cents at any real volume, which is the argument against percentage-of-recovery pricing in one number.

A two-week rollout

Week one: create the webhook, verify signatures, store events idempotently, and run in shadow mode to establish a baseline against the platform's own dunning.

Week two: enable branded email for all four buckets, submit two WhatsApp templates for approval, then enable WhatsApp for the funds and authentication buckets only.

From there, iterate on one variable at a time — timing, then channel order, then copy — and compare cohorts across full billing cycles rather than across weeks, because renewal dates cluster and a seven-day comparison will lie to you.

Store-level deliverability

Digital-product stores frequently send from a shared or platform domain, which caps email open rates well below the 18-25% baseline. Authenticate your own sending domain with SPF, DKIM and a DMARC policy, and keep billing mail on a subdomain separate from marketing.

Warm the domain before you rely on it for dunning. A cold domain sending a burst of payment-failure notices to a broad list is the exact pattern spam filters are tuned to catch, and the resulting reputation damage takes weeks to undo.

Send billing mail as plain, narrow, text-forward HTML. Heavy templates with hero images and tracking pixels are filtered more aggressively and render worse on the mobile clients where most of these are read.

Licence keys, access and the revocation decision

Many Lemon Squeezy stores gate software licences or downloads. Deciding when a failed payment revokes a licence is a recovery decision, not just a policy one: revoke too fast and you convert a temporary shortfall into an angry cancellation, revoke too slowly and the deadline stops motivating anyone.

Five to seven days of grace, stated explicitly in the second message, is the common balance. Automate the revocation so it actually happens on the stated date — a deadline that passes without consequence teaches customers to ignore the next one.

Restore access instantly on recovery. A customer who pays and then waits an hour for their licence to reactivate writes the support ticket you were trying to avoid.

Where RRLabs fits

Revenue Recovery Labs connects to a Lemon Squeezy store through signed webhooks, classifies each failure, generates copy through a four-tier cascade with deterministic fallback, and dispatches on your own email domain and your own WhatsApp Cloud API number.

Every message is logged with the tier used, latency and recovery score, and every recovery is attributed back to the original at-risk amount so the reported rate is honest rather than flattering.

Pricing is flat — $100, $250 or $500 per month, plus $300 for white-label — with no percentage taken from anything recovered.

Frequently asked questions

Do I need write access to a Lemon Squeezy store to recover payments?
No. You need webhook delivery and read access to subscriptions plus the ability to generate customer-portal links. The platform performs every charge and holds every credential.
Will my messages conflict with Lemon Squeezy's own dunning emails?
Only if they arrive at the same moment. Offset your first branded touch a few hours ahead of the platform's next retry attempt and the two reinforce each other.
How do I avoid sending a failure notice after the payment recovered?
Re-read subscription state immediately before dispatch and cancel the queued message if it is active again. Deduplicating on the webhook event ID alone is not enough because state can change between queue and send.