By Theo Brandt ยท Updated
Stripe Email Integration: Connect Billing Events to Email
Which Stripe events deserve an email, how each tool receives them, and the rules that keep a billing message from reaching the wrong person.
For most small SaaS teams, Loops is the best pick for connecting Stripe to email. Its Connect to Stripe step replaces hand-built webhooks, and its Growing Audience plan is listed at $99 a month, with an Early Stage plan that is free for up to 4,000 sends in any rolling 30 days. That free tier stops working once billing mail grows past that send limit, so the $99 plan is the realistic starting price for an active billing program. Check the subscriber count before you commit, because Loops prices by subscribers.
Billing email is a messaging problem with a data problem attached. The messages themselves are simple: a card-update request, a renewal notice, a receipt. The hard parts are which Stripe event should start each message, how the email tool finds the right person, and what stops a message once the customer has already acted. The tools below differ mainly in how much of that plumbing they handle for you.
Prices on this page were checked on 7 October 2026 against each vendor's pricing page, and each price links to its source. Event names and delivery behavior come from Stripe's subscription webhooks guide and its webhooks documentation.
How the four tools compare
The table summarizes who each tool suits, what it costs to start, and the limit that matters most for billing email. Prices are list prices for the named plan and billing view; they do not include taxes or any usage that the pricing page lists separately.
| Tool | Best for | Starting price (plan, billing) | Key limitation |
|---|---|---|---|
| Loops | Small SaaS teams that want Stripe events connected without writing webhook code | Early Stage: free for up to 4,000 sends in a rolling 30 days. Growing Audience: $99/month | Only events that contain an email address are processed, and contacts are matched by email |
| Customer.io | Teams that need billing events and product behavior in the same workflows | Essentials: $100/month, billed monthly. Profile-based readouts start at $145/month for 10,000 profiles | No one-click Stripe connector in its documentation; you build the webhook mapping yourself |
| Userlist | Account-based SaaS where messages go to users and companies, plus in-app messages | Basic: $149/month for up to 10,000 users, billed monthly | The Stripe listing is short, so the synced fields and events need confirming before you build on them |
Four ways Stripe data reaches an email tool
Every setup uses one of four routes, and the route decides how much engineering time you spend and how many events you can use. A vendor connector is the fastest route and the most limited, because the vendor decides which events it understands. A webhook pointed straight at the email tool gives you more events, but the tool needs a reliable way to match the Stripe customer to a contact. A relay on your own server, which receives Stripe's webhooks and calls the email tool's API, handles any event and any matching rule, and it also makes you responsible for signature checks, retries and deduplication.
The fourth route is manual: you push properties and events into the email tool yourself. Userlist's developer guidance, for example, recommends naming properties such as trial_expires_at for dates you push in from your own system. That works for a small set of dates, but it drifts quickly if the Stripe data changes and nobody updates the push code.
For most teams the deciding question is who owns the failure. If an engineer can maintain a relay, it is the most flexible option. If nobody wants to maintain code, choose the connector and accept its event list. If billing and product events must share one workflow, a webhook trigger in the email tool is usually the middle path.
Which Stripe events to email on
Stripe publishes dozens of subscription and invoice events, but a billing email program needs about eight. Each one should come with a stop rule, so the customer never receives a message that contradicts what just happened. The list below is the set most SaaS teams start with.
- customer.subscription.trial_will_end fires ahead of a trial ending. It is the natural trigger for a charge notice or a prompt to add a card. Skip it if the subscription is already active.
- invoice.upcoming fires a few days before renewal, with the timing set in the Dashboard. Use it for a renewal reminder that shows the amount and date. It does not fire for invoices collected by sending an invoice, so do not expect it there.
- invoice.payment_failed marks a failed payment. Send a card-update email with a direct link. Stop the sequence on invoice.paid.
- invoice.paid confirms payment. Send a receipt or a short "payment received" note, and cancel any queued recovery emails for that invoice.
- customer.subscription.updated fires on renewals, plan changes, coupons and discounts. It is noisy, so compare the old and new plan and ignore plain renewals before sending an upgrade or downgrade confirmation.
- customer.subscription.paused covers a trial that ends without a payment method, when the subscription is set to pause. Send a come-back message with a link to the billing portal, and stop it on resume.
- customer.subscription.deleted marks the end of a subscription. Send a cancellation confirmation followed by a feedback request, and suppress upgrade promotions.
- charge.refunded and charge.dispute.created usually need no customer email. Remove the person from promotions, and alert a human instead of starting a sequence.
Two of these need extra care. The first is customer.subscription.updated. Because routine renewals trigger it, a workflow keyed on it needs a filter on what changed. Loops' integration guidance does not list it among its supported events, and it suggests sending that signal from your own backend through the events API when you need it. The second is the trial without a card. Stripe documents a missing_payment_method setting that cancels, pauses or invoices when a trial ends, and the trial_will_end email is the natural place to link the customer to the billing portal. The trial conversion email guide builds the full sequence around that message.
Webhook rules that protect your customers
Stripe's webhook documentation sets out behavior that billing emails have to respect. Each rule below maps to a specific failure that a customer would see.
- Verify the signature. Stripe signs each event in the
Stripe-Signatureheader, and verification needs the raw request body. A framework that parses the body first breaks the check. An endpoint that skips the check lets anyone trigger "payment failed" emails to your customers. - Answer fast, work later. Return a 2xx response before any complex logic, and process events through an asynchronous queue. A burst of renewals at the start of the month can overwhelm a handler that does everything synchronously.
- Expect duplicates. Stripe says an endpoint may receive the same event more than once, so log processed event IDs. A duplicate that reaches the email step becomes two failed-payment notices.
- Expect disorder. Stripe does not guarantee delivery in the order the events were generated. Re-read the subscription state before every billing email rather than trusting the order of arrival.
- Know the retry window. Stripe retries failed deliveries for up to three days in live mode, using exponential backoff. An outage on your side delays emails rather than losing them, and a late event can still arrive after the customer has acted.
Tool by tool
Loops: the lowest-effort connector
Loops is the strongest fit for a small team that wants Stripe events in a workflow quickly. Its Stripe integration page describes installing the Loops app and clicking Connect to Stripe, so you do not create webhook endpoints yourself. Its listed events include customer.subscription.created, paused, resumed, trial_will_end and deleted, along with invoice.paid, invoice.payment_failed and invoice.upcoming. You choose a Stripe event as the trigger for a workflow, and the rest of the email setup works like any other Loops workflow.
Its limits are specific. Only events that contain an email address are processed, and contacts are matched by email. If a customer changed the email address in Stripe and not in your product, the billing message can miss the person or reach an old inbox, so check that the two systems agree before launch. Loops also lists customer.subscription.updated outside its supported set, so plan-change messages need a backend event.
The pricing is contact-based. The free Early Stage plan includes up to 4,000 sends in any rolling 30 days to the 1,000 newest contacts, with a Loops footer and a limit of 10 emails per second. The Growing Audience plan is $99 a month and includes unlimited sends to subscribers, transactional sends to users outside your audience, and all features. Loops is a good choice when the email list is modest and the team wants a short route from Stripe to the inbox. Review the Loops pricing page before you commit, because the free plan's send ceiling is reached quickly once renewal and dunning mail is added.
Customer.io: billing events inside a larger workflow
Customer.io has no one-click Stripe connector in its documentation. Its guide to syncing customers from Stripe has you create a webhook-triggered automation, paste its URL into a Stripe endpoint, send customer.created, and create or update the person while storing the Stripe customer ID. Later Stripe events such as invoice.payment_failed then identify the person by that stored ID.
This takes longer to set up, and it is the right shape when billing events must combine with product events. A customer who fails a payment and has not logged in for two weeks needs a different message from one who is still active, and Customer.io can branch on both in the same journey. The cost of that flexibility is the mapping work: someone has to store the Stripe customer ID on the profile and keep it consistent with the product's user records.
The price is by profiles. Essentials is $100 a month, billed monthly. Its readouts at larger profile counts are $145 a month at 10,000 profiles, $235 at 20,000, $325 at 30,000, $415 at 40,000, and $505 or more at 50,000 profiles and above. Premium is listed at $1,000 a month with custom profile volume and elevated AI Agent limits. Check the Customer.io pricing page for the current readouts before you size a plan, since the profile tier, not the email count, drives the bill.
Userlist: account-based messaging
Userlist lists Stripe under billing on its integration page. That listing is brief, so ask support which fields and events arrive before you design a sequence around them. Userlist's real strength is its model of users and companies: segments can target a whole account, and in-app messages can reach the same people as email. For a B2B product where a billing problem belongs to an account rather than to a single login, that model is a better match than a per-person sequence.
Userlist's pricing is tiered. Basic is $149 a month for up to 10,000 users, and it includes marketing and lifecycle email, in-app messages and segments for users and companies. Professional is $349 a month at the same user count and adds A/B split testing, conversion goals and advanced workflow features. Enterprise is priced on custom message limits. Read the Userlist pricing page to confirm which tier includes the workflow features your billing program needs, because some advanced steps sit on the higher plan.
What it costs at 5,000, 10,000 and 25,000 customers
The pricing bases differ, so a comparison needs one common assumption. This table assumes each customer receives about four billing or lifecycle emails a month: 20,000 sends at 5,000 customers, 40,000 at 10,000, and 100,000 at 25,000. Where a vendor prices by contacts, profiles or users rather than sends, the table uses the number of customers as the unit.
| Tool | 5,000 customers (20,000 sends) | 10,000 customers (40,000 sends) | 25,000 customers (100,000 sends) |
|---|---|---|---|
| Loops | $99/month, Growing Audience plan | $99/month, Growing Audience plan | Pricing on request. The pricing summary does not state the contact ceiling for this size |
| Customer.io | $100/month, Essentials base, billed monthly | $145/month, Essentials 10k profiles, billed monthly | $325/month, Essentials 30k profiles, billed monthly |
| Userlist | $149/month, Basic, up to 10,000 users | $149/month, Basic, up to 10,000 users | Pricing on request. Basic is listed only up to 10,000 users |
Monthly totals change with behavior. Contact-priced and profile-priced plans do not change with sends, which helps if you plan to add product tips, onboarding series or win-back mail on top of billing messages. Teams whose volume is mostly billing notices should compare subscriber, profile and user limits against their own counts.
The table also does not show every cost. Stripe's own processing fees, Paddle's transaction pricing and any SMS or add-on charges sit outside these figures. For broader comparisons of Stripe-focused tools, see the Stripe-focused platform list, and for dunning-specific options, the dunning platforms list.
How to choose
The right tool depends on three questions: which events must trigger mail, whether those events have to combine with product behavior, and whether someone can maintain a webhook. The table below turns those answers into a pick, with the reason in each row.
| If you need | Pick | Because |
|---|---|---|
| Stripe connected in an afternoon, with no webhook code | Loops | Connect to Stripe is a built-in step, and its supported events cover the core billing messages |
| Billing events and product behavior in one journey | Customer.io | Its webhook trigger accepts forwarded events, and the stored Stripe customer ID links them to the same profile |
| Messages to accounts, with users grouped under companies | Userlist | Segments target users and companies, and in-app messages reach the same people as email |
| A low-volume pilot before paying anything | Loops Early Stage | Its free tier lets you prove the pipeline with up to 4,000 sends in 30 days |
Two cautions apply to every row. First, a connector reduces engineering effort but does not remove the need to test. Second, the email tool should never be the only source of truth for whether a customer has paid. The billing system holds that state, and every message should check it before sending.
Setup and migration checklist
Use the checklist below whichever tool you pick. Each step has a clear finish line, so you can tell when it is done without asking anyone.
| Step | What to do | Done when |
|---|---|---|
| 1. Inventory the messages | List every billing email you send today, and the Stripe event behind each one | Each message maps to exactly one event and one stop rule |
| 2. Choose the route | Pick a connector, a webhook into the tool, or a relay on your own server | The decision and its owner are written down |
| 3. Map identities | Store the Stripe customer ID on each user or profile, and confirm the email addresses match | A test customer resolves to the same person in both systems |
| 4. Harden the endpoint | Verify signatures on the raw body, return a 2xx quickly, and log processed event IDs | A replayed test event sends no second email |
| 5. Add the stop rules | Re-read the subscription state before each billing send, and cancel queued recovery mail on invoice.paid | Delivering invoice.paid before invoice.payment_failed suppresses the notice |
If you are migrating from a tool that already sends billing mail, run both systems in parallel for one billing cycle. Send the new messages only to an internal test list while the old tool keeps sending to customers, then compare what each system would have sent. Switch off the old sequence only after the two match for every event family you use.
Setup order: start small and prove the pipe
Start with a single event family and run it end to end before adding more. A sound first pilot is invoice.payment_failed to a card-update email, with invoice.paid as the stop. Test it with Stripe's test cards in a sandbox, deliver the same event twice to confirm the duplicate is dropped, and deliver invoice.paid before invoice.payment_failed to confirm the email is suppressed. Once those checks pass, add trial_will_end, then cancellations, then plan-change messages, which need the most filtering.
Keep the order of work in mind too. Recovery mail is the most valuable message and the easiest to get wrong, because a customer who has just paid must never receive a "payment failed" note. Starting there forces the team to build the stop rules early, and those rules then protect every later sequence.
Who sends what: Stripe's own emails
Stripe can send some customer mail itself. Its trials documentation describes reminder emails for collecting payment details, which you configure in the Dashboard's free trial messaging settings, and for failed payments it points to Smart Retries and its other revenue recovery features. Decide for each message whether Stripe or your email tool sends it. Both sending the same reminder reads as a bug, and it erodes trust in the rest of the program.
A workable split is Stripe for receipts and invoices, which customers expect to come from the billing system, and the email tool for anything carrying your product's branding, guidance or segment logic. Document the split in the same place as the event inventory, so a future team member can see at a glance which system owns each message.
Verdict
Pick Loops if you want a connector that works in an afternoon and your billing emails fit its supported event list, and budget the $99 Growing Audience plan once the free tier stops covering your sends. Pick Customer.io if billing events must combine with product behavior and someone can own the webhook mapping. Consider Userlist if accounts and roles matter more than the individual user. Whatever you choose, keep retry logic in the billing system and keep the email tool to messaging.
Frequently asked questions
Which Stripe events should trigger emails?
Five cover most SaaS billing programs: customer.subscription.trial_will_end for the pre-charge notice, invoice.upcoming for renewal reminders, invoice.payment_failed for card-update mail, invoice.paid to stop recovery messages, and customer.subscription.deleted for cancellation follow-up. Loops lists most of these among its supported Stripe events, and Customer.io can trigger on any event you forward to its webhook trigger.
Does the email tool retry failed payments?
No. Retry timing stays in Stripe, where Smart Retries and the subscription settings in the Dashboard decide when another charge is attempted. The email tool sends the message that asks the customer to fix the card, so check which system owns the retry schedule before you build the email sequence.
Do I need a native Stripe connector, or are webhooks enough?
Webhooks are enough if someone on the team can own the plumbing: verify the Stripe-Signature header, store event IDs to drop duplicates, and map Stripe customer IDs to your users. A native connector, such as Loops' Connect to Stripe, removes most of that work but supports only the events the vendor has chosen to expose. Customer.io sits in between, with a webhook trigger that you configure yourself.
What if Stripe sends events out of order?
Stripe does not guarantee that events arrive in the order they were generated, so an email workflow must re-check state before it sends. Look up the subscription status, or read it from your own database, immediately before each billing email. A trial-ending notice that arrives after the customer has already converted should be dropped, not delivered.
Which tool is cheapest at 5,000 customers?
Among the tools covered here, Loops has the lowest listed monthly price at that size: its Growing Audience plan is $99 a month. Customer.io Essentials starts at $100 a month, and Userlist Basic is $149 a month for up to 10,000 users. Those plans depend on contacts, profiles or users, so compare the unit each vendor counts with your billing volume.
Should Stripe or my email tool send the receipts and renewal notices?
Pick one sender for each message. Stripe can send invoices and some trial and recovery reminders from its own settings, and a second send of the same notice from your email tool looks like a bug to the customer. A common split is Stripe for receipts and invoices, and the email tool for anything carrying your branding, product guidance or a segment rule.
How do I test the pipeline before going live?
Use Stripe's test mode and test cards to trigger each event, deliver the same event twice to confirm the duplicate is dropped, and send invoice.paid before invoice.payment_failed to confirm the recovery email is suppressed. Only after those three checks pass should you enable the remaining event families one at a time.