n8n Tutorial: Stripe Renewal Due in 30 Days → Auto Email Sequence + Slack Automation
Subscription renewals are a silent revenue killer. Not because customers churn — but because you find out too late. A customer's card expired three weeks ago, the renewal fails on day 30, and you're s
Subscription renewals are a silent revenue killer. Not because customers churn — but because you find out too late. A customer's card expired three weeks ago, the renewal fails on day 30, and you're scrambling to recover an account that should have been flagged a month earlier. If your Stripe subscription business has more than 50 active customers, this is happening to you right now.
This tutorial walks through building a fully automated renewal alert system in n8n: one that catches every subscription renewal 30 days out, sends a proactive email sequence to the customer, and drops a Slack summary to your team — all without writing a single line of backend code.
The Problem: Stripe Renewal Blind Spots
Stripe sends webhook events when a subscription renews, fails, or cancels. What it doesn't do natively is alert you 30 days before any of those things happen. That gap is where revenue leaks.
For technical founders and ops teams, the real pain shows up in three scenarios:
- Expired cards on file: The customer hasn't updated their payment method. You have 30 days to reach them before the renewal attempt fails.
- Annual plan renewals: Customers forget they're on annual billing. A renewal email 30 days out reduces dispute rates and chargebacks significantly.
- High-value accounts: A $5,000/year customer renewing next month deserves a personal heads-up from your team, not silence until the invoice lands.
The standard fix is a cron job that queries Stripe's API daily, compares subscription dates against the current date, and fires off notifications. Building and maintaining that in custom code takes hours and creates another brittle script to babysit. The n8n approach handles all of it visually, with built-in error handling and zero infrastructure to manage.
The Solution: How This n8n Workflow Operates
The workflow runs on a daily schedule. Each morning it pulls all active Stripe subscriptions, filters for any that renew within the next 30 days, and then executes two parallel actions: it triggers an email sequence to the customer and posts a structured Slack message to your team's billing or ops channel.
The architecture is straightforward:
- Schedule Trigger → fires at 08:00 UTC daily
- Stripe node → fetches all active subscriptions
- Filter node → isolates subscriptions with
current_period_endwithin 30 days - Split In Batches → processes each qualifying subscription individually
- Send Email node → delivers customer-facing renewal notice
- Slack node → posts internal team summary
- Wait node + second Email → sends a follow-up reminder 7 days before renewal
The email sequence isn't just a single blast. The workflow sends an initial notice at 30 days and a tighter reminder at 7 days, giving your team two touchpoints and customers two chances to update payment details or engage with your sales team on renewal terms.
Step-by-Step Setup in n8n
Step 1: Connect Your Stripe Account
In n8n, add a Stripe node and create a new credential using your Stripe Secret Key (find it under Stripe Dashboard → Developers → API keys). Use your live key for production, restricted key if you want to limit scope to read-only subscription access.
Configure the node: Resource → Subscription, Operation → Get All. Enable Return All to paginate through your full subscriber list. Add a filter for status = active to exclude trialing and canceled subscriptions from the check.
Step 2: Filter for 30-Day Renewals
Add an IF node after the Stripe node. The condition uses a JavaScript expression to compare the subscription's current_period_end timestamp against today's date:
{{ $json.current_period_end * 1000 - Date.now() <= 30 * 24 * 60 * 60 * 1000 && $json.current_period_end * 1000 - Date.now() > 0 }}
Stripe stores Unix timestamps in seconds, so multiply by 1000 to convert to milliseconds before comparing against Date.now(). The second condition (> 0) ensures you're not catching already-expired subscriptions.
Step 3: Retrieve Customer Details
After the filter, add another Stripe node set to Resource → Customer, Operation → Get. Pass {{ $json.customer }} as the customer ID. This fetches the customer's email, name, and any metadata you've stored — all of which you'll use to personalize the outgoing email.
Step 4: Send the Customer Email
Add a Send Email node (or Gmail/SMTP node depending on your setup). Map the fields:
- To:
{{ $json.email }} - Subject:
Your {{ $('Stripe').item.json.plan.nickname }} subscription renews in 30 days - Body: Include the renewal date formatted from
{{ new Date($('Stripe').item.json.current_period_end * 1000).toLocaleDateString() }}, the renewal amount from{{ $('Stripe').item.json.plan.amount / 100 }}, and a link to your customer portal for self-serve payment updates.
Keep the email transactional: renewal date, amount, payment method status, and a single CTA to update billing. No marketing copy.
Step 5: Post the Slack Summary
Add a Slack node in parallel with the email (use a Merge node if you want to wait for both before proceeding). Configure it to post to your #billing or #ops channel:
*Renewal Alert* — 30 days out
Customer: {{ $json.name }} ({{ $json.email }})
Plan: {{ $('Stripe').item.json.plan.nickname }}
Amount: ${{ $('Stripe').item.json.plan.amount / 100 }}
Renewal Date: {{ new Date($('Stripe').item.json.current_period_end * 1000).toLocaleDateString() }}
Stripe ID: {{ $('Stripe').item.json.id }}
Use Slack's Block Kit for cleaner formatting if your team prefers structured messages. The Slack node supports Block Kit JSON natively — wrap the above in a section block with a Markdown text field.
Step 6: Set Up the 7-Day Follow-Up
After the initial email and Slack message, add a Wait node set to resume after 23 days (30 days minus 7 = 23 days until the 7-day mark). Then add a second Send Email node with a shorter, more urgent message — "Your subscription renews in 7 days, your card on file ends in [last 4 digits]."
Note: n8n's Wait node keeps the execution paused in your database. This works well for small subscription volumes. For thousands of subscriptions, consider a dedicated workflow triggered by a second daily cron at the 7-day window instead, to avoid holding large numbers of paused executions.
Benefits Beyond the Obvious
The immediate benefit is fewer failed payments. But the operational impact runs deeper:
Reduced churn from payment failures: Involuntary churn — subscriptions that lapse because of failed payments rather than customer decision — accounts for 20-40% of total churn in most SaaS businesses. A 30-day heads-up with a payment update link addresses this directly.
Sales team enablement: High-value renewals that show up in Slack give your account managers or founders advance notice to reach out personally. A $10,000 annual renewal gets a phone call, not just an automated email, when your team sees it 30 days out.
Audit trail: Every execution in n8n logs the subscriptions processed, emails sent, and Slack messages posted. If a customer claims they never received a renewal notice, you have timestamped proof in your execution history.
Zero maintenance overhead: Unlike a cron script, this workflow runs on n8n's scheduler. No server to maintain, no script to update when Stripe's API changes (n8n's Stripe node handles that), no alerting to configure if the job fails — n8n's built-in error workflow handles failure notifications.
Common Pitfalls and How to Avoid Them
Duplicate emails on retry: If a workflow execution fails midway and retries, customers can receive duplicate renewal notices. Guard against this by adding a check against a simple log — write each processed subscription ID to a Google Sheet or Airtable base before sending the email, and filter out IDs already present. A Code node before the email step with a lookup against your log handles this cleanly.
Timezone mismatches: Stripe timestamps are UTC. If your customers are in a mix of timezones and you're formatting dates in email bodies, convert explicitly: new Date(timestamp * 1000).toLocaleDateString('en-US', { timeZone: 'America/New_York' }). Otherwise a customer in Los Angeles sees "June 19" when the actual local date is still June 18.
Trial subscriptions included: Subscriptions in trialing status have a current_period_end that marks trial expiry, not a paid renewal. If you don't filter by status = active in your Stripe node, trial customers will receive renewal notices for plans they haven't yet committed to paying. Set the status filter explicitly.
Missing customer email: Stripe allows subscriptions to exist on customers without an email address set (common with API-created customers). Add a check in your IF node: {{ $json.email !== null && $json.email !== '' }}. Route subscriptions without email to a separate Slack alert flagging the data gap rather than letting the execution fail silently.
High-volume rate limiting: The Stripe node in n8n respects Stripe's API rate limits, but if you have thousands of subscriptions, the daily "Get All" call can take time. Schedule the workflow during off-peak hours (02:00-06:00 UTC) and use n8n's Split In Batches node with a batch size of 100 and a short delay between batches to stay well within Stripe's 100 read requests per second limit.
Deployment and Monitoring
Once the workflow is live, activate it and run a manual test execution using a test subscription with a future current_period_end date set to within 30 days. Verify the email lands in the correct inbox, the Slack message posts to the right channel, and the execution log shows clean completion.
Set up an error workflow in n8n (Settings → Error Workflow) that pings your Slack #alerts channel if any execution fails. This ensures a Stripe API outage or credentials issue doesn't silently stop your renewal alerts without your team knowing.
Review the execution history weekly for the first month. Watch for patterns: subscriptions that keep appearing because the customer hasn't updated their card, high-value accounts that might warrant a personal outreach, or clusters of renewals on specific dates that could inform your billing cycle strategy.
The workflow handles the mechanical work. What it gives your team is time — 30 days of runway to act on every subscription renewal instead of reacting after the fact.
Ja construimos isso pra voce
Nao comece do zero. O Stripe Renewal Due in 30 Days → Auto Email Sequence + Slack e um workflow n8n pronto para instalar — conecta suas ferramentas em minutos, sem codigo.
Instalar por $49 →