251
All workflows

Recover failed payments before the subscription cancels

Finds past-due Stripe subscriptions, emails each customer a link to pay with Resend, and posts the largest amounts to Slack.

Outcome

  • An email with a link to pay for every customer with a past-due subscription, or a note on why not, such as Stripe already emailing them.

  • A Slack post for each customer who owes more than your escalation amount.

  • The total amount due, by currency.

How it works

  1. S

    Find past-due subscriptions, by List subscriptions by Stripe

    List subscriptions with status past_due. Keep each subscription ID and customer ID.

  2. S

    Get the unpaid invoices, by List invoices by Stripe

    For each subscription, list its open invoices. Keep, per customer, customer_name, customer_email, and each invoice's amount_due and currency (in the currency's smallest unit), next_payment_attempt and hosted_invoice_url.

  3. Write the nudges, by Your agent

    Skip this step and the next when stripe_emails_on is yes, so no one gets two emails. Otherwise draft one short, friendly email per customer, with a subject and a plain-text body: the payment did not go through, each hosted_invoice_url to pay or update the card, and the next retry date, or that no retries are left when next_payment_attempt is empty. Show the drafts to the user.

  4. R

    Send, by Send an email by Resend

    After the user approves, send each email from sender to its customer_email, one recipient per email. Keep each email's ID.

  5. S

    Escalate the big ones, by Post a message by Slack

    Post one message per customer who owes escalate_amount or more to cs_channel, with customer_name, the amount and the next retry date.

You'll be asked for

  • The address to send from, on a domain verified in Resend

    e.g. billing@acme.example

  • Whether Stripe already emails customers about failed payments

    e.g. no; if yes, this workflow only escalates

  • The amount due that deserves a personal call, with its currency

    e.g. 1,000 USD (Stripe's 100000 in cents)

  • The Slack channel for escalations

    e.g. #customer-success

failed-payment-recovery.mdView markdown

Recover failed payments before the subscription cancels

Finds past-due Stripe subscriptions, emails each customer a link to pay with Resend, and posts the largest amounts to Slack.

Set up the tools below, then run the steps in order for the user, carrying each step's results into the next. The run is done when the user has the outcome below.

Outcome

  • An email with a link to pay for every customer with a past-due subscription, or a note on why not, such as Stripe already emailing them.
  • A Slack post for each customer who owes more than your escalation amount.
  • The total amount due, by currency.

Inputs

Ask the user for these before you start.

  • sender: the address to send from, on a domain verified in Resend, e.g. billing@acme.example
  • stripe_emails_on: whether Stripe already emails customers about failed payments, e.g. no; if yes, this workflow only escalates
  • escalate_amount: the amount due that deserves a personal call, with its currency, e.g. 1,000 USD (Stripe's 100000 in cents)
  • cs_channel: the Slack channel for escalations, e.g. #customer-success

Set up

Stripe (tool:stripe/list-subscriptions, tool:stripe/list-invoices)

Use the first option your agent supports.

MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

{ "mcpServers": { "stripe": { "url": "https://mcp.stripe.com" } } }
  • List subscriptions: call the MCP tool stripe_api_read with GET /v1/subscriptions
  • List invoices: call the MCP tool stripe_api_read with GET /v1/invoices
CLI (official)

Install the command and sign in with it, then confirm it runs.

npm install -g @stripe/cli
stripe --version
  • List subscriptions: run stripe subscriptions list
  • List invoices: run stripe invoices list

Send an email (Resend, tool:resend/send-email)

Use the first option your agent supports.

Note: Pass an Idempotency-Key header (--idempotency-key on the CLI) so a retry never sends it twice; keys expire after 24 hours.

MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

{ "mcpServers": { "resend": { "url": "https://mcp.resend.com/mcp" } } }

Call the MCP tool send-email.

CLI (official)

Install the command, then confirm it runs.

npm install -g resend-cli
resend --version

Run resend emails send.

Set $RESEND_API_KEY in your environment first (get a key: https://resend.com/api-keys).

Post a message (Slack, tool:slack/post-message)

Use the first option your agent supports.

Note: Needs the chat:write scope. Over MCP it posts as the signed-in user; the API and CLI post as the app's bot.

MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

{ "mcpServers": { "slack": { "url": "https://mcp.slack.com/mcp" } } }

Call the MCP tool slack_send_message.

CLI (official)

Install the command, then confirm it runs.

curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash
slack --version

Run slack api chat.postMessage.

Set $SLACK_BOT_TOKEN in your environment first (get a key: https://api.slack.com/apps).

Before step 1, confirm access to each service with its cheapest read-only call, like a list or a search. Never send or change anything to test access.

Steps

  1. Find past-due subscriptions with List subscriptions (Stripe). List subscriptions with status past_due. Keep each subscription ID and customer ID.
  2. Get the unpaid invoices with List invoices (Stripe). For each subscription, list its open invoices. Keep, per customer, customer_name, customer_email, and each invoice's amount_due and currency (in the currency's smallest unit), next_payment_attempt and hosted_invoice_url.
  3. Write the nudges yourself. Skip this step and the next when stripe_emails_on is yes, so no one gets two emails. Otherwise draft one short, friendly email per customer, with a subject and a plain-text body: the payment did not go through, each hosted_invoice_url to pay or update the card, and the next retry date, or that no retries are left when next_payment_attempt is empty. Show the drafts to the user.
  4. Send with Send an email (Resend). After the user approves, send each email from sender to its customer_email, one recipient per email. Keep each email's ID.
  5. Escalate the big ones with Post a message (Slack). Post one message per customer who owes escalate_amount or more to cs_channel, with customer_name, the amount and the next retry date.

Rules

  • Use only the services set up above. The read-only calls they need, like listing ids or polling for results, are fine.
  • Ask the user before anything that sends messages, costs money, or changes data, and say how many records it touches. One approval covers a batch the user has seen.
  • Never print API keys.