Integration guide
Recovering failed Lemon Squeezy payments
Lemon Squeezy is a strong checkout for SaaS and digital products, and it retries failed subscription payments on its own schedule. The gap is the same one every merchant of record leaves open: one email cadence for every failure, no channel choice, and no attempt-level attribution when the payment finally clears.
Quick answer
Lemon Squeezy recovery uses the subscription_payment_failed webhook to start reason-aware follow-up, while Lemon Squeezy continues to own the checkout, invoice and tax handling.
Events that matter
- subscription_payment_failed
- A renewal payment was declined.
- subscription_past_due
- The subscription entered the grace window.
- subscription_payment_success
- Payment recovered — stop outreach.
- subscription_expired
- The grace window closed; the customer churned.
Setting it up
- 1
Add the webhook
Create a webhook in Lemon Squeezy settings pointing at your RRLabs endpoint and select the subscription payment events.
- 2
Verify the HMAC
Every payload carries an X-Signature header verified against the signing secret before processing.
- 3
Link to the customer portal
Follow-ups link to the Lemon Squeezy customer portal so card updates happen inside their hosted flow.
- 4
Close the loop
subscription_payment_success resolves the attempt and stops queued messages.
Consume Lemon Squeezy subscription webhooks
// Lemon Squeezy → Settings → Webhooks
// Verify the X-Signature HMAC against your signing secret before parsing.
const event = JSON.parse(rawBody);
const name = event.meta?.event_name;
const attrs = event.data?.attributes ?? {};
if (name === "subscription_payment_failed") {
await rrlabs.enqueueRecovery({
provider: "lemonsqueezy",
externalId: String(event.data.id),
customerEmail: attrs.user_email,
amountCents: Number(attrs.total ?? 0),
currency: attrs.currency,
});
}
if (name === "subscription_payment_success") {
await rrlabs.closeRecovery({ provider: "lemonsqueezy", externalId: String(event.data.id) });
}Manual recovery vs. automated recovery
| Capability | Lemon Squeezy alone | With RRLabs |
|---|---|---|
| Retry schedule | Fixed platform dunning cadence | Outreach timed to the failure reason and customer timezone |
| Channels | Email, WhatsApp and SMS where consented | |
| Copy | Platform templates | Your brand voice with reason-specific drafts |
| Reporting | Revenue recovered in aggregate | Per-attempt attribution across channels |
| Source of truth | Lemon Squeezy | Lemon Squeezy — checkout, tax and invoices stay there |
Frequently asked questions
Does RRLabs take payments on Lemon Squeezy's behalf?
No. Lemon Squeezy stays the merchant of record and processes every charge; RRLabs only reads events and sends follow-ups.
Can I reach customers on WhatsApp?
Only with a stored consent record. Lemon Squeezy checkouts collect email by default, so phone-based channels need an explicit opt-in.
What happens when a subscription expires?
subscription_expired ends the recovery sequence and marks the outcome as churned rather than recovered.