Recover failed Stripe payments with Supabase context and personalized retry emails

When a Stripe payment fails, pull the customer's history from Supabase, log the failure, alert revenue ops in Slack, and send a retry email matched to the customer's tier.

Agentic Task
StripeSupabaseSlack BotResendFinanceCustomer SupportOperationsNotifications & AlertsEmail AutomationData Sync
PromptCreate

Build an agent workflow that turns every failed Stripe payment into a fully contextualized, personalized recovery action across Stripe, Supabase, Slack, and Resend.

Trigger: a Stripe webhook. The workflow should fire whenever Stripe emits charge.failed or invoice.payment_failed. The incoming webhook payload contains the charge or invoice object — use it as the entry point.

When the webhook fires, the agent should:

1) Hydrate the Stripe context. Call Stripe Retrieve Charge with the charge id from the webhook (or Retrieve Invoice if it's an invoice.payment_failed event, then pull the customer id from the invoice). Then call Stripe Retrieve Customer to get the full customer object. Capture the failure reason, amount (remember Stripe amounts are in the smallest currency unit), currency, and customer email.

2) Pull internal customer history from Supabase. Use Supabase Get Row on the customers table filtered by the Stripe customer id (or email) to retrieve plan tier, account owner, and lifetime value. Then use Supabase Get Many Rows on the subscriptions table filtered by that customer to read subscription history: how long they've been a customer, current plan, MRR, prior renewal events, and any prior payment failures. If the customer is not found in Supabase, fall back gracefully to the Stripe data and note the gap in the alert.

3) Log the failure to Supabase. Use Supabase Create Row on a payment_failures table with at minimum: stripe_customer_id, stripe_charge_id (or invoice id), failure_reason, amount, currency, customer_email, account_tier, and a timestamp. This becomes the durable record of what happened.

4) Decide a recommendation. Based on the customer's history, the agent should pick one of: "automatic retry" (low-value or newly failed account, likely transient), "downgrade or pause" (recurring failures on a higher plan that may warrant offering a cheaper tier), or "churn risk — escalate" (high-LTV or long-tenured customer whose card has now failed). Write the recommendation as a single short line.

5) Post a Slack alert. Use the Slack Bot Send a Message operation to post in #revenue-ops. Include: customer name and email, plan tier and MRR, lifetime value, failure reason and amount, time since the customer joined, count of any prior failures, and the one-line recommendation. Keep it scannable — a short header line, a few bullet-style fields, and the recommendation at the bottom.

6) Send a personalized retry email through Resend. Use Resend Send Email to message the customer. The tone and content must be matched to their history, not a generic dunning template:

• Trial or low-tenure customer → friendly, low-pressure nudge with a clear retry link and a quick reassurance that it's usually a card issue.

• Established paying customer (mid LTV, several months tenure) → warmer, more direct ask, acknowledge their history, give them the retry path and an offer to chat.

• High-LTV or long-tenure customer → account-manager style, mention their tenure or specific plan, offer a direct line to the account owner, and treat the retry as a courtesy rather than a demand.

The email should have a real subject line, a clear update-your-card call to action, and a sign-off that matches the recommended tone. Send it from a verified Resend domain (do not hardcode a domain — let the user configure it).

Constraints: do not send a retry email if the failure_reason indicates fraud or a disputed charge — only alert Slack in that case. If the same customer has had more than two failures in the last 14 days (visible from the payment_failures table), skip the email and explicitly flag the Slack alert as "churn risk — escalate" instead. The agent should pick the recommendation and the email tone — not run a fixed template.

Auth and config to expect: Stripe secret key, Supabase project URL and secret key (Supabase tables involved: customers, subscriptions, payment_failures, all in the public schema), Slack bot OAuth, Resend API key with a verified sending domain. The Slack channel (#revenue-ops) and the from-address for Resend should be configurable inputs.

What does this prompt do?

  • Listens for failed Stripe payments and instantly pulls the full charge, customer, and account history for that account.
  • Looks up the customer in your Supabase database to gather subscription history, lifetime value, and current plan tier.
  • Logs every failure to a payment_failures table so you have a clean record of what went wrong, when, and how much was at stake.
  • Posts a Slack alert in your revenue ops channel with the customer context and a one-line recommendation: retry, downgrade, or treat as a churn risk.
  • Drafts and sends a personalized retry email through Resend, with tone and content matched to the customer's value and history, not a generic dunning template.

What do I need to use this?

  • A Stripe account where you can add a webhook for failed charges and invoice payment failures.
  • A Supabase project with a customers table and a subscriptions table the agent can read from.
  • A payment_failures table in Supabase (or permission to create one) for logging.
  • A Slack workspace and the channel where revenue ops should be alerted.
  • A Resend account with a verified sending domain for the retry emails.

How can I customize it?

  • Change which Slack channel gets pinged, or route different tiers to different channels (for example, high-value accounts to a VIP escalation channel).
  • Adjust the tone rules the agent uses to draft the retry email, such as which language to use for trial users versus long-tenured paying customers.
  • Add extra Supabase tables to the lookup (usage data, support tickets, NPS scores) so the agent can factor more signal into its recommendation.
  • Decide which Stripe events trigger the workflow. The default covers charge failures and invoice payment failures, but you can scope it to specific products or plans.

FAQs

What happens when a payment actually fails in Stripe?
Stripe sends a webhook to the workflow within seconds. The agent fetches the full charge and customer record, checks your Supabase tables for account history, logs the failure, posts a Slack alert, and drafts a personalized retry email. The whole thing runs end to end without you touching anything.
How does the agent decide what tone to use in the retry email?
It reads the customer's history from Supabase, including how long they have been a customer, their plan tier, and their lifetime value. A new trial user gets a friendly nudge. A long-time enterprise customer gets a more attentive, account manager style message. You can adjust these rules in the prompt.
Do I need to build the payment_failures table myself?
You can create it ahead of time or let the agent set up the columns it needs on the first run. The minimum is a customer id, failure reason, amount, and timestamp. Add whatever extra context you want to track.
Will this send retry emails automatically, or just draft them?
By default it sends the email through Resend. If you would rather have it draft and wait for human approval, ask for that in the prompt and the workflow will post the draft to Slack for a one-click send.
What if the customer is not in our Supabase database yet?
The agent handles that gracefully. It falls back to whatever Stripe knows about the customer, notes in Slack that there was no internal record found, and still drafts a retry email using the Stripe data alone.

Related templates

Rank your Intercom queue by what each customer pays you

See every open conversation next to that customer's plan, monthly value and unpaid invoices, so the expensive account never sits waiting all morning.

Intercom
Stripe
App
Review desk for portal forms your team still fills in by hand

Stage a batch of filings overnight, then approve each completed form from a screenshot before anything is ever submitted.

Kernel
Google Sheets
Slack Bot
App
Client-by-client cold email pipeline review for agencies

Pick a client and a date range to see sent, replies, meetings booked and the real deal value your cold email produced, campaign by campaign.

Instantly
HubSpot
Slack Bot
App
Catch the trials quietly dying before the card gets charged

Open one desk each morning to see every account still in a trial, ranked by how much money is at stake against how little they have actually used.

Intercom
Stripe
General Input Database
App
Audit what Intercom's Fin AI actually resolved before you pay

Review every conversation Fin closed as resolved, judge which ones actually stuck, and see what the gap is worth against your bill.

Intercom
Google Sheets
Slack Bot
App
One triage console for every Jira service desk queue

Merge your IT, HR and Facilities queues into one list ranked by SLA time left, then reply, change status and escalate without ever opening Jira.

Jira Service Management
Jira
Slack Bot
App

Stop losing revenue to generic dunning emails.

Connect Stripe, Supabase, Slack, and Resend once, and every failed payment gets the context, alert, and personalized recovery email it deserves.