Documentation
How RescueDunning works
Current availability: early access
The free 90-day audit reads Stripe invoice history without a subscription. Stripe grants read and write access, but an audit-only connection does not charge customers or activate recovery. The recovery workflow is in early access. New optional add-ons require separate setup and opt-in.
Pay now and pause/skip/downgrade offers are EARLY ACCESS. Disabled by default. Real Stripe test-mode validation is pending. Keep disabled for customers until that validation is complete.
Feature setup is separate from live provider availability. Synthetic checks do not demonstrate real payment or message delivery, additional recovery or profit. Keep your existing Stripe recovery settings until you have reviewed the intended workflow.
1. Connect Stripe and choose your setup
Connect your Stripe account via OAuth. Stripe grants read and write access. The free audit is separate from paid recovery onboarding; it does not import customers or start recovery messages. The basic email workflow does not require a merchant webhook. Optional in-app prompts and activity observation require the authenticated product integration below.
For in-app billing actions, your server must resolve the customer from its own database and sign billing-admin permission from current organization membership. A browser-supplied Stripe ID or role is never sufficient. Missing or false permission shows a generic contact-administrator message without invoice details or action links. Existing integrations must add this role field. See the server-session example.
2. We listen for failed payments
There's no merchant webhook to add. With a recovery-authorized connection, Stripe sends us invoice.payment_failed, invoice.payment_succeeded, and subscription update/cancel events for it through Stripe Connect. A verified eligible failure opens a recovery case — one case per failed invoice (duplicate deliveries are deduplicated).
Recovery emails require an entitled account, recovery authorization, a qualifying failure and current contact eligibility, plus configured delivery and scheduling. An audit-only connection does not meet these activation requirements.
3. The Day 1 / 3 / 7 email sequence
An eligible case queues up to three emails with your logo and brand color, subject to current contact permission, suppression and experiment assignment:
- Day 1: “Action needed: your payment failed” with a branded card-update link (open the link, enter a new card, submit).
- Day 3: a friendly reminder while the subscription stays active.
- Day 7: a final reminder about the outstanding payment.
Every link carries an unguessable token to your branded card-update portal. After a verified card update is recorded, the case moves to card updated and the remaining emails are canceled — but nothing is counted as recovered yet. Only when Stripe confirms the payment (the invoice.payment_succeeded webhook) does the case close as recovered and the invoice outcome appear on your dashboard. A payment with no dunning case behind it is never counted as recovered revenue. Invoice payment, verified new cash, refunds, fees and profit are different measures.
4. Pre-dunning: reminders before card expiry
The nightly scanner refreshes Stripe card data for connected merchants with recovery access, unless the merchant has disabled pre-dunning, then queues branded reminders in 30-, 14- and 7-day windows. A late import gets only the most urgent current window; missed windows are not backfilled. Future scans can queue newly reached windows. A failed Stripe refresh skips that scan. Check the outbox for delivery evidence; a reminder does not guarantee delivery or a successful future payment.
5. Watch the dashboard
Revenue at risk, recovered revenue this month, recovery rate, tracked MRR, the full email outbox, and cards that are about to expire. The Recovery evidence page shows the eligible recorded invoice cohort, a 30-day outcome window including unresolved invoices, delivery evidence and linked refunds. Observed payments can come from Stripe retries or other actions; incremental lift and profit are unproven. Historical data and refund coverage can be incomplete.
Review recovery exceptions
Open the Recovery work queue to inspect customers with card-saved-but-unpaid invoices, RescueDunning delivery problems, an ended reminder window or missing and stale Stripe checks. Each customer groups their unresolved invoices; currencies stay separate. Refresh reads the current invoice balance, status and retry schedule from Stripe. A schedule does not prove a charge ran; a missing schedule does not prove retries are exhausted. Failed refreshes retain the last successful timestamp.
Open the exact invoice in Stripe to investigate authentication or collection settings. Mark the customer reviewed, or snooze for one or seven days. New material evidence, including a check becoming stale after 24 hours, returns the customer to review. These actions do not send, charge, alter Stripe settings or stop reminders. Payment evidence clears the collection action for that invoice; a card save does not. Delivery history remains in the case and outbox. Stripe-native email delivery is not tracked here.
Pay now after a verified card save
EARLY ACCESS. Disabled by default. Real Stripe test-mode validation is pending. Keep disabled for customers until that validation is complete.
After validation, Pay now requires a separate merchant opt-in in Payment and retention. Its intended flow shows an eligible customer the checked current invoice balance and saved method after a verified card save in the same recent browser session, then requests explicit authorization for an immediate invoice payment. Card save alone does not charge. A payment preview or redirect does not settle a recovery case.
Identity, currency, allocations and current payment defaults must match the invoice. Unsupported or processing states do not proceed. Authentication for an already verified same-card payment continues on its hosted invoice. An uncertain payment waits for read-only status checks instead of another charge; signed provider payment evidence is handled separately.
Observed product activity
Opt in to observation, provide the required user notice and instrument meaningful authenticated product actions. Logins are a separate signal. The report covers a trailing seven-day UTC window and shows instrumentation gaps and unknown balances, with currencies kept separate. No observation is not proof of inactivity, and product use is not purchase intent.
The feature stores last-use and last-login timestamps plus hashed event IDs for deduplication. It does not store URLs, IPs, device data or arbitrary properties. Expired observations are excluded immediately; physical deletion depends on scheduled maintenance. Opt-out prevents earlier observations from reappearing after re-enable. See the activity and prompt integration guide.
Messages that match the payment context
Enable decline-aware messages separately in Personal outreach settings. Current bound invoice evidence selects insufficient-funds, expired-card, authentication or generic wording. An insufficient-funds message still offers a customer action or another method. Authentication uses a verified secure hosted invoice link when available. Sensitive bank and fraud classifications stay generic.
Retry wording requires a current verified next-attempt schedule. A missing, stale or failed refresh does not create a promised date, and a schedule does not guarantee that a charge will run or succeed. The existing contact holds, suppressions and native-message review still apply.
Holdout evaluation and its limits
Opt in before eligible failures occur. Customers are assigned prospectively, remain in the same arm across invoices, and have one index invoice with a fixed 30-day outcome horizon. Measured Rescue interventions are withheld from controls; the baseline Stripe policy stays unchanged. Settings are frozen during an active experiment. Stop the experiment before changing them.
The report distinguishes mature and pending customers, uncertainty intervals and insufficient data. Small samples can remain inconclusive. Sample imbalance, contamination, configuration changes or early stopping can invalidate causal interpretation. A recorded paid invoice is not proof of new cash or profit; the value calculator uses your own margin and cost assumptions.
Pooling is a separate choice. It requires separate consent before the shared experiment and a separately enabled service, which starts disabled. The fixed privacy-qualified cohort requires ten eligible merchant accounts and at least 100 mature customers per arm per merchant. Only a coarse aggregate with uncertainty is exposed, with no merchant cells or customer records. Revocation withdraws the whole snapshot. It describes its participants under stated assumptions, not your business's expected return.
Escalating in-app prompts
Enable the banner and prompt policy separately, after integrating the signed server session and exact website origins. Configure grace, modal and softwall stages using the server-recorded failure age. Only authorized billing administrators receive invoice details or payment actions. Missing or ambiguous billing fails open.
The softwall is advisory. It offers Continue immediately, supports keyboard dismissal and does not enforce host-product permissions. Billing, support, cancellation, data export and account recovery remain available. Configure your custom protected paths and mark sensitive single-page screens explicitly. A prompt impression is not product use or payment evidence.
Pause, skip or downgrade offers
EARLY ACCESS. Disabled by default. Real Stripe test-mode validation is pending. Keep disabled for customers until that validation is complete.
After validation, configure each offer separately in Payment and retention. Each eligible customer sees a current preview and must explicitly consent. The initial supported shape is one fixed monthly licensed item, quantity one, with no trial or cancellation, tax, discount, credit balance, existing schedule or pending change. Annual, metered, multi-item and multi-seat subscriptions do not proceed.
Pause collection supports 1–90 days and voids invoices generated during the stated window. Skip uses a pause ending one day after the verified next renewal, so it can void more than one invoice generated in that window. Existing overdue invoices remain collectible and may retry. No refund or debt forgiveness is implied. A lower compatible monthly price can be scheduled at renewal only after provider preview and exact schedule verification. No plan change occurs without customer consent. Unknown outcomes require review and are not automatically rolled back.
Personal notes for big accounts
Opt in and choose a threshold for unpaid invoice balance in your chosen currency, not lifetime customer value. Current invoice and account checks select eligible cases. Contact pauses, work ownership, native-contact review and experiment assignment still apply. A measured control customer receives no personal outreach draft.
The result is a plain-text draft for you to review and copy into your own inbox. There is no inbox integration or automatic personal send. Draft availability is an intervention; it does not prove you sent it, that a customer read it or that it caused a payment. The copy does not invent a sender identity, discount or retry promise.
A weekly email or Slack digest
Set up a destination in Weekly digest, verify it and opt in as the owner. Email and Slack destinations have separate setup requirements. Dispatch also requires the delivery service to be enabled; saving an opt-in alone does not confirm delivery. Removing or disabling a destination stops future sends.
Digests cover completed UTC weeks with per-merchant deduplication and bounded dispatch. An uncertain attempt needs provider evidence instead of an automatic resend. Provider acceptance, confirmed delivery or posting, and human reading are separate outcomes. Digest audit records expire after 90 days through scheduled maintenance; this is not deletion of all account data.
Before enabling recovery
Confirm that your Stripe account is compatible with this Connect integration. Keep your native retry policy. Review overlapping failed-payment reminders and keep payment-authentication notices available. RescueDunning does not automatically check or change these settings.
A successful card update changes the relevant subscription/invoice default and stops remaining reminders; saving a card alone does not initiate collection. Early-access Pay now stays disabled pending real Stripe test-mode validation and requires a separate authorization when enabled. Check Stripe for exhausted retries, a manually collected invoice or additional authentication. Non-card-only invoices and legacy invoice-specific sources are not supported by the card portal. Signed Stripe success events and the queue reconciler resume persisted card updates if the browser closes; external card replacements are checked against current Stripe defaults when a known failure baseline exists. Payments count separately only after a payment-success event. The value calculator uses your margin and cost inputs; the $57 additional-profit target after the $19 fee is a planning goal, not a guarantee.
Sending email
RescueDunning sends through its own verified domain via Resend, with your logo and brand color in the email body and replies routed to your account email. Using the default sender does not require your own mail-provider account. Every email is logged in your dashboard outbox, so you can inspect provider acceptance and explicit delivery confirmations. These do not prove a person read the message. Custom sender domains require ownership checks and DNS verification.
Running a paid newsletter?
For compatible Stripe Billing memberships, use your publication's branding on reminders and the card-update portal. A failed renewal does not establish whether a reader wants to leave. Review eligible optional payment and retention choices before enabling them. See the newsletter workflow →
FAQ
Will this double-email customers Stripe already retries?
Overlapping reminders are possible. Review your native and RescueDunning message settings before enabling recovery, keep your native retry policy and keep payment-authentication notices available. Pre-expiry scanning is on for eligible recovery accounts unless you disable pre-dunning. RescueDunning does not automatically inspect or change your Stripe settings. Remaining reminders stop after a verified update is recorded; an in-flight email cannot be recalled.
What if a customer cancels mid-sequence?
When Stripe reports the subscription canceled, the case is marked lost and the remaining emails are canceled automatically.
Do you store card numbers?
Never. Customers type their card into Stripe's secure card fields on your branded update page, and the details go straight to Stripe. We only keep card brand, last four digits and expiry.
Can I customize the email copy?
Templates use your logo and colors. Decline-aware wording is a separate opt-in based on current invoice evidence; this release does not include a freeform template editor. Personal notes are drafts for manual review and copying.
What does it cost?
Starter is a flat $19/month for up to 500 tracked Stripe customers; Pro is $49 for up to 2,500; Scale is $99 with unlimited tracking. Annual prices are $190/$490/$990. No recovery commission; payment-provider fees still apply. Limits include free, canceled and inactive imported records across your connected accounts. Multiple subscriptions for one customer use one slot. Eligible new accounts have a 14-day trial. Optional features need separate setup and eligibility checks.
Authenticated in-app recovery banner
Install this inside your product for signed-in customers. The banner opens an existing Stripe-hosted overdue invoice or authentication page; it is separate from the email card-update portal and does not promise to update the renewal payment default. It distinguishes authentication, payment-method issues, pending retries and uncertain status. Saving a card or returning from Stripe never counts as payment. It disappears only when its cases are settled, closed, no longer actionable, or the customer signs out.
In Installation and health, copy your existing server credentials and configure exact website origins. The banner starts disabled. Never put the signing secret in HTML, browser code, logs or source control. Keep test and live accounts separate.
If an older account is missing credentials, its owner can explicitly authorize creating only the missing values in Installation. Existing keys and allowed origins are preserved; the banner stays disabled until you save its configuration. Reconnecting does not rotate or repair credentials.
<script defer src="https://rescuedunning.group/snippets/banner.js" data-site-key="rd_site_YOUR_PUBLIC_KEY" data-session-url="/api/billing/recovery-session"></script>
Your same-origin session endpoint must use your normal secure session cookie. Load the Stripe customer ID from your own server database for that authenticated user and selected billing organization. Never read it from query parameters, request bodies, email addresses or client state. Return 401 on logout. Do not allow cross-origin access to this endpoint.
// Merchant backend example: adapt requireSession and yourDatabase to your app.
import { createHmac } from "node:crypto";
export async function GET(request) {
const session = await requireSession(request); // validate secure server session
if (!session) return new Response(null, { status: 401 });
const billing = await yourDatabase.billingForAuthorizedUser(session.userId);
// billing is server-owned and must belong to this authorized organization.
if (!billing?.stripeCustomerId) return new Response(null, { status: 401 });
const now = Math.floor(Date.now() / 1000);
const secret = Buffer.from(process.env.RD_SNIPPET_SECRET, "base64url");
const body = Buffer.from(JSON.stringify({
v: 2, site: process.env.RD_SITE_KEY,
customer: billing.stripeCustomerId,
account: process.env.RD_STRIPE_ACCOUNT,
livemode: process.env.RD_STRIPE_MODE === "live",
// Derive from server-owned organization membership; never client input.
billingAuthority: billing.permissions.includes("manage_billing"),
audience: "https://app.example.com", // fixed, configured origin
// Opaque per-login nonce, never a raw session cookie or customer email.
session: createHmac("sha256", secret).update(session.internalId).digest("base64url"),
issued: now, expires: now + 90
})).toString("base64url");
const signature = createHmac("sha256", secret).update(body).digest("base64url");
return Response.json({ token: "rdb2_" + body + "." + signature }, {
headers: { "Cache-Control": "no-store, private", "Vary": "Cookie" }
});
}Only server-authorized billing administrators should receive billingAuthority: true. Missing or false values show a generic contact-administrator prompt without invoice amounts or payment links. Existing integrations must add this server-side permission check before billing actions become available. Never infer billing authority merely from membership in an organization.
Call window.RescueDunning?.clear() immediately on logout or before switching the active customer/organization. After your server session changes, call window.RescueDunning?.refresh(). The snippet also rechecks on page return, focus and visibility changes, and while the page is visible. It keeps no tokens or billing records in browser storage. Issued tokens expire within five minutes; your endpoint should use 90 seconds as shown.
Allow this script origin in your content security policy and its API origin in connect-src. Payment buttons request a fresh, account-bound invoice check before navigating to the existing Stripe-hosted invoice page. RescueDunning does not automatically charge, restart retries or change payment defaults through this banner. A link request is only an assisted-workflow observation.
Legacy email-based tokens, URL tokens and the manual data-update-url option are retired. Missing or failed checks show unavailable status rather than pretending the invoice is resolved. Verify your integration with isolated fixtures first; local tests do not prove real Stripe delivery or additional profit.