A card declines. Stripe fires the invoice.payment_failed webhook. Somewhere in your dunning stack, an email queues up to go out — maybe immediately, maybe on a 24-hour delay. And then you wait.
The problem with waiting is that the reason most cards fail isn't fraud or a canceled account. It's an expired card, an over-limit balance the customer cleared an hour later, or a bank fraud-flag the customer can resolve with one tap in their banking app. These are fixable problems — but only while the customer still remembers signing up for you, still has the value fresh, and still has the card in hand. That memory decays fast. A text at hour one catches a customer who's paying attention. A text on day three catches someone who's half-forgotten you and is annoyed to be reminded.
Full disclosure: I work for Ready, an SMS platform. So I have a horse in the "you should text these people" race. But the timing argument holds regardless of whose sending infrastructure you use.
Why the recovery curve is steepest in the first hours
There's no clean public dataset that says "SMS dunning at hour 1 recovers exactly 2x day 3," so I'll frame this as what the industry roughly observes and what the mechanics predict: recovery rates on involuntary churn decay steeply, not linearly. The first 24 hours capture the bulk of the recoverable failures because those are the soft declines — insufficient funds, temporary holds, expired-card-but-customer-has-a-new-one.
The mechanism is simple:
- A soft decline is often self-correcting. The customer's paycheck hits, the hold clears, they top up the card. If you prompt them in that window, they act.
- Attention decays. At hour one they were just using your product. At day three, they've context-switched twenty times.
- Stripe's own retry schedule races you. If a card is going to auto-recover on a retry, you want your human-prompted recovery to land before the customer decides to just let the subscription lapse.
A text that reaches someone while the problem is still top-of-mind converts. The same text three days later reads as a collections notice.
The dunning window, mapped against Stripe's retries
Here's the sequencing problem. Stripe's Smart Retries already schedule automatic re-attempts over several days. If you bolt SMS on without thinking about that cadence, you either (a) text people about a failure Stripe is about to silently fix, or (b) text them after Stripe already gave up. Both waste the message.
A cleaner sequence pairs each human touch with the retry logic instead of fighting it:
| Time since fail | Channel | Purpose | Tone |
|---|---|---|---|
| Hour 0–1 | SMS | "Heads up, your card was declined — tap to update" | Helpful, not urgent |
| Hour 2–24 | Full detail, invoice link, support link | Informational | |
| Day 2 | Stripe auto-retry | Silent re-attempt | — |
| Day 3 | SMS | "Still can't process — here's the 30-second fix" | Direct, deadline-aware |
| Day 5–7 | Email + final SMS | "Access pauses tomorrow" | Consequence-clear |
The first SMS does the heavy lifting because it hits the soft-decline window. The later touches are for the customers whose failure is stickier — a genuinely dead card, a switched bank. You're not sending more messages; you're front-loading the one that matters.
One caveat worth its own paragraph: don't fire the SMS and the email at the exact same automation step. On GHL specifically, stacking both on one action inflates your unsubscribe rate because the customer gets double-pinged and reaches for STOP. I wrote about the branch logic for that in why sending SMS and email at the same step doubles your unsub rate. Space them, or branch them by channel preference.
Quiet hours will save you from your own timing logic
Here's where "text at hour 1" collides with reality: a card fails at 2:47 a.m. If your automation fires immediately, you've just woken a paying customer to tell them about a billing hiccup. That's a fast way to earn a STOP and a churn.
Ready enforces quiet hours based on the recipient's local time — sends outside permitted hours get held and released when it's an appropriate hour to text. So your "hour 1" logic becomes "hour 1, or the next reasonable send window, whichever is later." The customer whose card failed at 2:47 a.m. gets the text at 8:05 a.m. instead of a middle-of-the-night ping. You keep the front-loaded advantage without the collateral damage.
This also matters for TCPA hygiene generally. Late-night automated messages are exactly the pattern that draws complaints, and quiet-hours enforcement is one of the cheaper ways to reduce that exposure.
The consent question everyone gets wrong
"But wait — do I even have consent to text a customer about a failed payment?"
This is where SaaS teams overthink or under-think, rarely land in the middle. The nuance:
- Transactional billing messages — "your payment failed, update your card" — sit in a different bucket than marketing. A message that's genuinely operational, tied to an account the customer actively holds, is a much lower-risk send than a promo blast.
- But you still need a valid phone number and a reasonable basis to have it. If your signup form collected a phone number with any indication it'd be used for account notifications, you're on solid ground. If you scraped it or bought it, you're not.
- STOP still applies. Even transactional senders must honor opt-out. Ready's opt-out handling propagates a STOP across campaigns automatically, so a customer who opts out of your billing texts can't get re-messaged from another flow by accident.
The line between "transactional notification" and "marketing" isn't always crisp, and consent is ultimately the sender's responsibility — no platform makes you lawsuit-proof. If you're mixing a billing text with an upsell ("update your card AND check out our new plan!"), you've dragged a transactional message across the consent wall. Keep dunning texts purely operational. There's a parallel version of this problem in healthcare, where a reminder and a promo sit on opposite sides of the same consent line — same principle, different vertical.
Templates that actually recover cards
The template does as much work as the timing. A few patterns that convert:
Hour 1 (helpful, low-friction):
Hi {name} — we couldn't process your card for {product}. Usually a quick fix: {update_link}. Reply STOP to opt out.
That's 140-ish characters — one segment at $0.02 plus the $0.0045 carrier pass-through, so $0.0245 per send on the Standard tier. Keep the update link short; a bloated URL can push you into a second segment and, worse, tripping delivery filters if it's an untrusted shortener.
Day 3 (direct, deadline-aware):
{name}, your {product} payment is still pending. To keep your account active, update your card here: {update_link}
Notice what's not in these: no guilt, no all-caps URGENT, no emoji. Emoji alone drops your segment ceiling from 160 characters to 70 and can nudge the message toward a spammier profile. For a billing text, plain GSM-7 is the right call.
The money math on getting this right
Say you run a SaaS at $49/mo with 4,000 active subscribers and a typical ~5% monthly involuntary churn — 200 failed payments a month. A well-timed dunning sequence commonly recovers a meaningful chunk of soft declines; call it a conservative lift of 15 additional recovered accounts a month that email-only would've missed.
- 15 recovered accounts × $49 = $735/mo in retained MRR.
- The SMS cost: roughly 200 failures × ~2 texts each × $0.0245 = $9.80/mo.
Even if the true recovery lift is half what I assumed, the ratio is absurdly favorable — you're spending single-digit dollars to retain hundreds in MRR that compounds every month the customer stays. And if you're texting at volume across other flows too, past 50,000 segments in a month your rate drops to $0.016/segment automatically, no plan change required. The full pricing is on the Ready product page.
The point isn't that SMS is magic. It's that dunning email already works and dunning SMS at the right hour recovers the cards email misses — the ones whose owners just needed a nudge before the memory faded.
The practical takeaway
Failed-payment recovery is a timing game more than a copy game. Front-load one clean, operational SMS into the first hour (respecting quiet hours), let Stripe's retries do the silent work, and reserve later touches for the genuinely stuck cards. Keep every dunning text purely transactional so you don't drag it across the consent wall, and honor STOP without exception.
If you want to wire this against your Stripe events, Ready's automations and quiet-hours enforcement handle the send-timing part, and you can start with 2,500 free credits, no card required. Build the hour-1 text first — it's the one that pays for the rest.