Rescue failed Stripe payments with a Keap recovery play

By General Input

When a Stripe payment fails, tag the customer in Keap, log the reason, open a 48 hour follow up task, and send a friendly card update email.

Integrations

  • Stripe
  • Keap
  • Slack Bot

Type

Agentic Task

Categories

  • Finance
  • Customer Support

When a payment fails in Stripe, run our full failed payment recovery play across Stripe, Keap, and Slack. Trigger this from a Stripe webhook on failed payment events, covering both a failed charge and a failed invoice payment, since recurring invoice failures are where most involuntary churn comes from.

Read the Stripe customer id, the failure reason, and the failed amount from the event payload. Call Stripe's Retrieve Customer operation with that customer id to get the billing name and email address.

Watch the units. Stripe reports amounts in minor units such as cents, while Keap stores money as decimal whole units. Convert the Stripe amount into whole currency units before you compare it against the escalation threshold or write it onto a Keap record. A Stripe amount of 24900 is 249.00.

Find the matching person in Keap using List Contacts filtered on the billing email address returned by Stripe. If more than one contact comes back, use the first exact match on that email address.

When a matching contact exists, update their record in Keap. Use Apply Tag to tag them as "Payment Failed". Use Create a Note to record the failure reason, the converted amount, the date, and the Stripe charge or invoice reference. Use Create a Task to assign the account owner a follow up with this customer, due within 48 hours of the failure, with the customer name in the title.

Then, unless one of the escalation rules below applies, draft the recovery email and send it with Keap's Send an Email operation. Sending through Keap matters here: the message lands from our normal sending identity and stays attached to the contact's record where the rest of the team can see it.

Keep the email short and non-accusatory. Assume the best, because cards expire and banks decline for routine reasons. Say plainly that the latest payment did not go through, give a clear instruction for updating the card on file, and offer help if something else is going on. Do not blame the customer, do not threaten to suspend the account in this first message, and do not paste the raw failure code if it would confuse a non-technical reader.

Escalate to a human instead of sending automatically in two cases. First, if the converted failed amount is above my threshold, which should default to 500 in account currency and be easy for me to change. Second, if no Keap contact matches the billing email at all. In either case, skip the automatic email entirely and post to Slack with Send a Message so a person handles that one personally.

The Slack post should go to our billing channel and include the customer's billing name and email, the failed amount in whole currency units, the failure reason, whether a matching Keap contact was found, and which escalation rule fired. When the contact does exist but the amount was over the threshold, still apply the tag, the note, and the follow up task in Keap, and only skip the email. When no contact exists in Keap, the Slack post is the only action.

Avoid duplicate outreach. Stripe often retries the same failing payment several times. Before sending, check whether we have already emailed this contact about the same charge or invoice. If we have, add a note to the record capturing the repeat failure instead of sending another email.

Related prompts

Explore more prompts
Let support send one-off Loops emails without an engineerA brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonCustomer lifecycle inspector for Loops, Stripe and PostHogLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client account