Turn failed Stripe payments into Close recovery tasks
When a Stripe charge or invoice fails, open a same-day recovery task on the matching Close lead and ping your revenue channel in Slack.
Build a code workflow that turns every failed Stripe payment into a same-day recovery task on the matching Close lead, plus a Slack alert in our revenue-recovery channel.
Trigger: a Stripe webhook listening for charge.failed and invoice.payment_failed events. Verify the Stripe signature on every incoming request.
On each event, extract the customer email, the failure reason (decline code or failure message), the amount in dollars, the Stripe customer id, and the invoice id when present. For invoice.payment_failed, also capture the subscription id if it exists.
Use Stripe Retrieve Subscription to pull the current plan name and monthly recurring revenue when a subscription id is available, so we can include them in the task body. Skip this step gracefully for one-off charges with no subscription.
Use Close List Leads to find the lead whose primary contact email matches the Stripe customer's email (filter by query like email_address:"{email}"). If exactly one lead matches, use it. If zero match, treat it as unmatched and skip the Close step. If more than one match, pick the most recently updated lead and note the ambiguity in the Slack alert.
When a Close lead is found, use Close Create Task on that lead with: due date = today (in the Close org's timezone), assignee = lead owner by default (with a workflow option to override to a fixed user id), text title "Recover failed payment: ${amount} from {customer name or email}", and a body that includes the Stripe failure reason, the Stripe invoice id (or charge id), the plan and MRR if we fetched them, and a deep link to the Stripe payment in the dashboard.
Then use Slack Bot Send a Message to post in a configurable revenue-recovery channel. The message should include: the customer name and email, the dollar amount and currency, the failure reason, a link to the Stripe payment, and a link to the Close lead if matched. If no Close lead was matched, prefix the message with ":warning: Unmatched customer" so a human can triage. If multiple Close leads matched, mention that too.
Configurable inputs the workflow should expose: the Slack channel id for revenue-recovery alerts, the Close task assignee strategy (lead owner vs a fixed user id), and a toggle to include plan and MRR in the task body.
Deduplicate by Stripe invoice id (for invoice.payment_failed) and charge id (for charge.failed) so retries on the same invoice do not create duplicate Close tasks or duplicate Slack alerts. If a task already exists for that invoice or charge id, update the existing Slack alert or no-op instead of opening a second one.
Always return a 2xx to Stripe quickly so the webhook is not retried unnecessarily. Log the customer email, the event type, the matched Close lead id, the created Close task id, and the Slack message timestamp for every run.
Additional information
What does this prompt do?
- Listens for failed Stripe charges and failed subscription invoices the moment they happen.
- Finds the matching Close lead by the customer's email and opens a recovery task due today with the dollar amount and the reason the card was declined.
- Posts a structured alert in your revenue channel in Slack with links to the Close lead, the Stripe customer, and the failure details.
- If no Close lead matches the email, the Slack alert still fires and flags it as unmatched so a human can triage.
What do I need to use this?
- A Stripe account with permission to view charges, invoices, and subscriptions.
- A Close account where leads carry the customer's email as a contact.
- A Slack workspace with a channel for revenue or billing alerts.
How can I customize it?
- Choose who the recovery task is assigned to. The lead owner is the usual pick, but you can route everything to a single billing rep instead.
- Change the Slack channel and tweak the wording of the alert, including which emoji or @mention it leads with.
- Decide whether to include the customer's current plan and monthly recurring revenue from Stripe in the task body, so the rep knows how much is at risk before they reach out.
Frequently asked questions
Which Stripe events does this catch?
What happens if the customer is not in Close yet?
Can the task be assigned to the lead owner instead of one fixed person?
Does this replace Stripe Smart Retries or dunning emails?
Will it spam the channel if Stripe retries the same invoice four times?
Stop letting failed payments quietly churn.
Connect Stripe, Close, and Slack once, and Geni opens a same-day recovery task with the right context every time a payment fails.