Recover failed Paddle payments

Paddle handles billing, tax and the merchant-of-record relationship. Their failure notifications carry the next retry date, which makes them a good input for a recovery layer that schedules customer messages around Paddle's own retry attempts instead of on top of them.

The Paddle events recovery depends on

transaction.payment_failed
A Paddle transaction failed — open a recovery case.
transaction.completed
Payment collected. Close the case and attribute the recovery.
subscription.canceled
Paddle ended the subscription after its dunning window.

Verifying Paddle webhooks

Scheme
HMAC-SHA256 over `${timestamp}:${rawBody}`
Signature location
Paddle-Signature

The header carries a timestamp and one or more h1 digests. Recompute the digest with your notification secret and compare timing-safely.

import { createHmac, timingSafeEqual } from "crypto";

const header = req.headers["paddle-signature"] as string; // ts=...;h1=...
const parts = Object.fromEntries(header.split(";").map((p) => p.split("=")));
const digest = createHmac("sha256", process.env.PADDLE_NOTIFICATION_SECRET!)
  .update(`${parts.ts}:${rawBody}`)
  .digest("hex");

if (!timingSafeEqual(Buffer.from(digest), Buffer.from(parts.h1))) {
  return new Response("Invalid signature", { status: 401 });
}

const event = JSON.parse(rawBody);
if (event.event_type === "transaction.payment_failed") {
  await rrlabs.enqueueRecovery({ provider: "paddle", externalId: event.data.id });
}

Decline playbook for Paddle

Recovery actions per Paddle failure signal
Failure signalRecovery action
Paddle schedules another retryDo not add a competing retry. Send a reminder message timed just before Paddle's next attempt.
Card requires an updateSend the Paddle update-payment-method link across email and, if unopened, WhatsApp.
Final Paddle retry approachingEscalate to the highest-response channel available before the subscription is cancelled.

What happens after a payment fails

  1. T+0s

    Payment failed

    Provider webhook received and verified

  2. T+2s

    AI analysis

    Decline reason classified, amount at risk scored

  3. T+5s

    Dynamic email

    Copy generated for that decline code and customer

  4. Day 2

    Smart retry

    Retry scheduled only when the decline code is retryable

  5. Day 2

    WhatsApp push

    Second channel used when the email went unanswered

  6. On success

    Recovered

    Counted only when the provider confirms the charge

Timings describe the configured workflow, not a guaranteed outcome. Every step is skipped when the decline reason makes it counter-productive.

Frequently asked questions

How does RRLabs intercept Paddle subscription payment failures?
Paddle posts a signed notification to an RRLabs endpoint. After signature verification, the failure is recorded and a recovery case opens with Paddle's own next-retry date taken into account.
Does RRLabs interfere with Paddle's dunning?
No. Paddle keeps retrying on its schedule. RRLabs adds the customer communication layer around it.

Connect Paddle with read-only credentials

RRLabs reads failure events and orchestrates recovery. It never holds card data and never becomes the merchant of record.

Get early access