What Lemon Squeezy does natively — and where it stops
Lemon Squeezy will retry a failed charge and send a templated notice. Merchant-of-record billing means dunning email comes from the store, not you. That is enough for expired cards on engaged customers and little else.
Native dunning has no view of why the bank declined, so an insufficient-funds decline gets the same schedule as a stolen-card block. The result is retries that burn issuer goodwill without converting.
Reading the failure event safely
RRLabs subscribes to `subscription_payment_failed` with a read-only connection. The signed payload is verified with a constant-time HMAC compare, deduplicated on the provider event id, and written into a row-level-security-scoped table keyed to your workspace.
No card data is ever received or stored, so the integration adds zero PCI scope to your environment.
Routing the retry
Insufficient funds retries at 48 hours near payday. Expired card waits 72 hours behind an update link. Do-not-honor retries at 36 hours with an alternate-card prompt. Authentication required retries at 24 hours, WhatsApp first.
Each retry is paired with copy written for that specific reason, dispatched through your own sending domain and your own Meta WhatsApp number.
Measuring the lift
Run RRLabs in shadow mode for one Lemon Squeezy billing cycle: events are ingested and copy is generated, but nothing is sent. Compare projected recovery against your native baseline before cutting over.
Every generated message is logged with model, latency and recovery score, so the comparison is auditable rather than anecdotal.