customer.subscription.trial_will_end: The Stripe Webhook That Saves Your Trial Conversions
Stripe fires trial_will_end 3 days before a trial converts. Use it to catch dead cards before the highest-risk charge in SaaS fails.

The 30-second answer
customer.subscription.trial_will_end is a Stripe webhook event that fires exactly three days before a subscription's trial ends. It's Stripe handing you a warning shot: this subscription is about to attempt its first real charge. Use those three days to check the card on file and email the customer a heads-up — because the trial-to-paid transition is the single riskiest charge in your entire customer lifecycle.
Most founders wire up the famous events — payment_failed, subscription.deleted — and ignore this one. That's backwards. The famous events tell you a payment already broke. trial_will_end tells you one is about to, while you can still do something cheap about it.
Why the first post-trial charge is so fragile
Think about what a card on file has been through by the time a trial ends. The customer typed it in 14 or 30 days ago, in a hurry, during signup. Since then it has never been charged. Nobody validated it against a real debit. Meanwhile, life happened:
- •Expiry rollover. A card saved on the 28th with an expiry of 08/26 can be dead by the time a 30-day trial converts in September.
- •The balance moved. Trial signups cluster around moments of curiosity, not moments of budget. Three weeks later the account looks different.
- •The 'burner card' problem. Some trial users deliberately sign up with a card they know won't survive a charge — a privacy card with a $1 limit, an old card they meant to swap. The trial_will_end email is often what converts them into real customers, because it forces the decision.
- •Forgot entirely. A chunk of your trial users do not remember signing up. Their first clue is a mysterious charge — which is how you get disputes and chargebacks instead of revenue.
Every one of those is a failed first charge waiting to happen. And a failed first charge is worse than a normal one: this customer has zero payment history with you, zero habit, and now their first real interaction with your billing is a decline.
What to actually do with the event
The event payload gives you the subscription object, which includes the customer ID and the trial_end timestamp. Three days of runway. Here's the playbook:
- •Step 1 — check the payment method. Pull the customer's default payment method via the Stripe API. No card on file? That's an immediate email: 'Your trial ends Friday and there's no card on your account — add one here to keep access.' This one check catches the most avoidable failure in the whole flow.
- •Step 2 — send the heads-up email. Plain text, from a human address, with three facts: the trial ends on [date], the card ending in [last4] will be charged [amount], and here's a link if you'd rather use a different card or cancel. No marketing fluff.
- •Step 3 — get ready for payment_failed. If the charge fails anyway, your dunning flow kicks in — but now the customer isn't confused about why. The heads-up email recontextualizes the failed charge from 'surprise bill' to 'the thing they told me about.'
That middle email does more work than it looks. The customer who gets told 'you'll be charged $29 on Friday' and does nothing is an informed, consenting subscriber. The customer who gets silently charged is a dispute risk. Same charge, wildly different relationship.
The heads-up email that actually works
Since this email does so much work, let me be concrete about what goes in it. Subject line: something plain like 'Your [product] trial ends Friday.' Body: three short paragraphs. One: the fact — trial ends [date], card ending [last4] gets charged [amount]. Two: the options — keep going (do nothing), swap the card ([link]), or cancel ([link]). Three: one line of humanity — 'reply to this email if anything's unclear, I read every response.'
Notice what's absent: no countdown timers, no 'DON'T LOSE ACCESS' urgency theater, no feature list trying to re-sell them. The trial itself did the selling. This email's job is to remove surprise, because surprise is what turns a routine first charge into a dispute, a refund request, or a rage-cancel. Customers who feel informed pay. Customers who feel ambushed charge back.
One more detail worth stealing: include the amount. Always. Hiding the number doesn't protect conversion — it guarantees the surprised version of this customer finds out from their bank statement instead of from you, and the bank statement version comes with a 'dispute this charge' button. I've seen founders test hiding the amount to protect conversion. It never survives contact with the dispute queue.
When the first charge fails anyway
Some first charges fail no matter how good your heads-up game is. The play: your standard dunning sequence kicks in, but the trial context changes the framing. This customer just finished a trial — they were mid-decision. Your recovery emails should acknowledge that: 'Your trial just ended and the first payment didn't go through — here's the quick fix, and you're one click from being fully up and running.' It's a continuation of the onboarding story, not a collections notice. Trial-conversion failures recover noticeably better than veteran-subscriber failures when the emails respect that context — the intent to pay was there yesterday. Don't waste it with a robot email.
The no-card-on-file trial problem
If your trial doesn't collect a card upfront, this event matters even more. Without a payment method, the subscription will roll past trial_end into either an unpaid state or an automatic cancel, depending on your settings. Either way, the trial ends with a whimper. trial_will_end is your three-day window to ask for the card while the customer still has momentum — while they remember why they signed up and (hopefully) have been getting value all trial.
Timing that ask matters. Asking for a card on day 1 of a no-card trial gets ignored — they just started. Asking on the last day is desperate. Day 'three before the end' is the sweet spot Stripe chose for a reason: enough time to act, close enough to feel real.
Wiring it up (the short version)
In your webhook handler, add customer.subscription.trial_will_end to your listened events. When it arrives, read subscription.customer and subscription.trial_end from the payload, then kick off your checks: fetch the customer's default payment method, send the email, log that you handled the event. If you're already handling other subscription events, this is maybe an afternoon of work. The Stripe docs cover the event shape; my subscription webhooks post covers where this one fits among the events that actually matter.
"Everyone obsesses over recovering failed payments. trial_will_end is how you prevent the most predictable failure you'll ever have — the one Stripe literally announces three days early."
One honest caveat: this webhook is a trigger, not a system. You still need the emails, the card-update page, and a plan for when the charge fails anyway. That's the whole pre-dunning and dunning stack — and yes, it's the thing I built StayPaid to do without the afternoon of webhook plumbing: trial-ending emails, payment-failure recovery, all sent from your own address like a human wrote them. But whether you use a tool or a weekend of code, stop ignoring this event. It's the cheapest conversion save in SaaS.
FAQ
When does customer.subscription.trial_will_end fire?
Three days before a subscription's trial period ends. It fires once per trial, giving you a built-in warning window before the first real charge attempts.
What should I do when trial_will_end fires?
Two things: verify the customer has a valid payment method on file, and send a heads-up email that the trial is ending with the exact date and amount of the first charge. Both prevent failed-payment surprises.
Why do first charges after a free trial fail so often?
The card was saved 14-30 days earlier and never validated against a real charge. Expiry rollovers, insufficient funds, and cards the customer forgot they used all surface at the trial-to-paid transition.
Does trial_will_end fire if the customer never entered a card?
The event fires based on the subscription's trial configuration, not on payment method status. If your trial doesn't collect a card upfront, the webhook is your reminder that there's nothing to charge when the trial ends.
Keep reading
Robert
Founder at StayPaid
Want to recover failed payments like a founder?
Start Free — First 3 recoveries