Webhooks

Declined sends outbound webhooks when recovery events occur. Configure endpoints in the dashboard under Webhooks & SDK. Each endpoint can subscribe to specific event types or all events (*).

Outbound event types

  • recovery.started — Customer enrolled in a recovery sequence
  • recovery.completed — Payment successfully recovered
  • recovery.failed — Recovery attempt exhausted or failed
  • message.delivered — Dunning message sent
  • message.opened — Customer opened an email
  • message.clicked — Customer clicked a recovery link
  • incentive.accepted — Customer accepted a discount offer

Payload format

json
{
  "type": "recovery.completed",
  "data": {
    "recovery_attempt_id": "ra_abc123",
    "customer_id": "cus_123",
    "invoice_id": "inv_456",
    "amount_cents": 24900,
    "currency": "usd"
  },
  "created_at": "2026-06-12T14:30:00.000Z"
}

Signature verification

Each endpoint has a signing secret. Declined sends an X-Declined-Signature header (HMAC-SHA256 of the raw body). Verify signatures before processing webhook payloads.

typescript
import crypto from "crypto";

function verifySignature(payload: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

Retry policy

Failed deliveries are retried with exponential backoff. View delivery status and replay events from the dashboard Webhooks page.

Inbound provider webhooks

Payment provider webhooks (Stripe, Paddle, etc.) are configured separately under Payment Providers. Those are distinct from outbound Declined webhooks described here.