Integration Guide
Get PaymentRescue up and running in under 2 minutes. No code changes required.
How It Works
┌─────────────┐ invoice.payment_failed ┌──────────────────┐
│ │ ──────────────────────────────> │ │
│ Stripe │ │ PaymentRescue │
│ │ <───────────────────────────── │ │
└─────────────┘ billing_portal.session └────────┬─────────┘
│ │
│ payment_intent.succeeded │ Dunning Emails
│ │ (3-step sequence)
▼ ▼
┌─────────────┐ ┌──────────────────┐
│ Customer │ <────────────────────────────── │ Email Inbox │
│ pays with │ "Update Payment" link │ (Resend API) │
│ new card │ └──────────────────┘
└─────────────┘
│
│ Webhook: payment succeeded
▼
┌─────────────────────────────────────────────────────────────────┐
│ PaymentRescue marks invoice as RECOVERED, stops email sequence │
└─────────────────────────────────────────────────────────────────┘
Step-by-Step Setup
Create an Account
Sign up for PaymentRescue with your email. No credit card required for the 14-day trial.
Connect Stripe
Click "Connect Stripe" in the dashboard. You'll be redirected to Stripe's OAuth flow where you authorize PaymentRescue to access your account.
Stripe Sends Webhook Events
Once connected, Stripe automatically sends us invoice.payment_failed events. Here's what the webhook payload looks like:
// Stripe webhook event: invoice.payment_failed
{
"id": "evt_1234567890",
"type": "invoice.payment_failed",
"data": {
"object": {
"id": "in_1234567890",
"customer": "cus_ABC123",
"amount_due": 9900,
"currency": "usd",
"attempt_count": 1,
"next_payment_attempt": 1711324800,
"customer_email": "customer@example.com",
"customer_name": "Jane Smith"
}
}
}PaymentRescue Processes the Event
We store the failed payment, create a secure payment update link via Stripe, and queue the first dunning email.
// Internal flow (simplified)
async function handleFailedPayment(event) {
// 1. Store the failed invoice
await db.failedPayments.create({
invoiceId: event.data.object.id,
customerId: event.data.object.customer,
amount: event.data.object.amount_due,
email: event.data.object.customer_email,
});
// 2. Create Stripe billing portal session
const session = await stripe.billingPortal.sessions
.create({
customer: event.data.object.customer,
return_url: "https://yourapp.com/billing",
});
// 3. Queue first dunning email
await emailQueue.add("send-dunning", {
step: 1,
to: event.data.object.customer_email,
updateUrl: session.url,
amount: event.data.object.amount_due,
});
}Dunning Sequence Runs Automatically
The 3-step email sequence fires on days 0, 3, and 7. Each email includes a one-click payment update link. If the customer pays at any step, the sequence stops automatically.
// Dunning schedule
const DUNNING_SEQUENCE = [
{ step: 1, delay: "0 days", tone: "friendly" },
{ step: 2, delay: "3 days", tone: "urgent" },
{ step: 3, delay: "7 days", tone: "final" },
];
// Email is automatically skipped if:
// - Payment was recovered
// - Customer updated payment method
// - Invoice was voided or marked uncollectibleMonitor Results in Dashboard
Track recovery rates, email performance, and revenue saved in real-time. Export data to CSV for reporting.
Stripe Events We Listen To
PaymentRescue automatically processes these Stripe webhook events:
| Event | Action |
|---|---|
| invoice.payment_failed | Start dunning sequence, create recovery link |
| invoice.payment_succeeded | Mark as recovered, stop email sequence |
| customer.subscription.deleted | Mark as churned, log final status |
| payment_method.attached | Trigger immediate retry of failed invoice |
| invoice.voided | Cancel dunning sequence |
Technical FAQ
Ready to get started?
Set up in 2 minutes. 14-day free trial. No credit card required.