How to tell customers about a failed payment in Intercom
How to use Intercom to tell customers about a failed subscription payment: Stripe app data, event-triggered messages, banners and support replies.
When a renewal fails, the customer usually does not know. They find out when access stops, or when a dunning email lands in a promotions tab. If you already use Intercom to talk to customers inside your product, it can carry the failed payment message to the place where the customer actually is: the app.
This guide shows what Intercom can do with payment failure data, how to set up an in-app message, and how to handle the support conversations that follow. It relies on Intercom’s help center for the Stripe app, event-triggered messages, banners and macros, and on the Data Events API reference (all accessed November 2026).
Intercom does not retry payments
Start with what Intercom is not. It does not charge cards, retry payments or update payment methods. Those stay with your billing system: on Stripe, retries come from Smart Retries or your own schedule, and the card update happens on a Stripe-hosted page or in your app. Intercom’s role is communication: telling the customer, at the right moment, with a link that fixes the problem. For the billing side, see how to recover failed payments on Stripe.
Getting payment failure data into Intercom
Option 1: the Stripe app
Intercom’s Stripe app imports Stripe customer data as attributes on Intercom users. Among the documented attributes:
| Attribute | What it holds |
|---|---|
stripe_delinquent |
Stripe’s delinquency status (true or false) |
stripe_subscription_status |
The subscription status |
stripe_card_expires_at |
When the saved card expires |
stripe_card_brand |
The card brand |
The app also sends events to Intercom, including charge_failed, charged, invoice_created and deleted_subscription. Constraints from the same article: only live mode data syncs (test mode is not supported), the app needs a paid Stripe account, and it is available on Intercom’s Essential, Advanced and Expert plans. By default, an Intercom user is only created from a Stripe customer when the Stripe customer has both an email and a user ID in its metadata.
Option 2: send your own event
If you are not on Stripe, or want more control, send an event yourself when your billing system reports a failure. The Data Events API takes a POST to /events with an event_name, a created_at Unix timestamp, a user identifier (user_id or email) and optional metadata. Nested JSON is not supported in metadata, and the API documentation limits the number of tracked metadata keys per event, so keep it flat and small: for example, an amount, an invoice ID and the URL of the card update page.
A custom event lets you name it clearly (payment_failed) and carry the update link with it, which the Stripe app’s events do not do for you.
Choosing the message type
Banners: visible until the problem is fixed
A banner sits at the top of the page. If you hide the dismiss button, Intercom keeps showing it until the user no longer matches the audience rules or completes the configured action. That fits a payment failure well: target users where stripe_delinquent is true (or your own attribute), and the banner disappears by itself once the payment goes through and the attribute flips back.
Limits from Intercom’s documentation:
- Banners support dynamic audiences only.
- They are only delivered when the user is seen online in the Messenger.
- They do not run natively in iOS or Android apps.
- If several banners overlap, they show in the order they were set live, and a non-dismissible banner placed first blocks later ones.
Event-triggered chats or posts: once per failure
To send a message each time a failure happens, use an event-triggered message. Intercom documents several conditions:
- It requires the Proactive Support Plus add-on.
- The message must use a dynamic audience, and you can add only one event-based rule.
- Events that happened before the message went live do not trigger it.
- If the event arrives outside the message’s schedule, the message is not sent for that event; it is not held until the schedule opens.
- Event metadata cannot be used in messages inside a Series. Intercom suggests building the message standalone first, then copying it into the Series.
Email: still needed
In-app messages only reach customers who log in. A customer who has stopped using the product needs an email, and that is often the one who matters most. Keep a dunning email sequence running from your billing system or a dedicated tool. Ready-made examples are in dunning email templates.
Writing the message
The in-app message should be short and specific:
Your last payment didn’t go through. Update your payment method to keep your [plan name] plan active. [Update payment method]
Rules worth following:
- One action. A single button to the card update page. Do not send customers to a general settings page.
- No blame, no reason. Do not show the decline reason. For some codes, such as lost or stolen cards, Stripe tells you to present the decline as generic; see Stripe decline codes explained.
- Say what happens next, honestly: when you will try again, or when access will change. Do not invent a deadline you will not enforce.
- Show it to the right person. In B2B products, the person who sees the banner may not be the one who pays. Target admins or billing contacts if you have that attribute.
Handling the replies
Failed payment messages create conversations: “I updated my card, why is it still failing?”, “Can I pay by bank transfer?”, “Just cancel it.” Prepare macros for each. Macro actions can add tags and assign to a team, so tag these conversations payment-failed to measure volume.
Before replying, check the Stripe app panel, which shows the customer’s subscriptions and three most recent payments beside the conversation. A few common situations:
| Customer says | Check | Answer |
|---|---|---|
| “I updated my card” | Did a new payment method attach, and was the invoice retried? | If not retried yet, explain when; or retry from your billing system |
| “My bank says it’s fine” | The decline code | For generic declines, suggest another card or calling the bank again |
| “Just cancel” | Whether they mean it | Cancel if they confirm; a failed payment is not a reason to make cancelling harder |
| “I was charged twice” | Payment history | Explain or refund promptly; this is how disputes start |
Common mistakes
- Using the banner as the only channel. Customers who do not log in never see it.
- Leaving the banner up after recovery. Use an attribute that flips back automatically, not a manual list.
- Testing with Stripe test mode. The Stripe app ignores test data, so test with a custom event on a test user instead.
- Messaging during a retry that is about to succeed. If your billing system retries within hours for some declines, a delay before the first message can avoid needless alarm.
Doing this with NoChurn
NoChurn handles the billing side that Intercom does not: smart retries timed to the decline reason and to likely paydays, AI-written recovery emails that you review, and a hosted card update page you can link to from an Intercom banner or macro. Its Intercom connector is read-only, so it does not send Intercom messages for you; your banners and macros stay in Intercom. It reads conversations, matched to customers by email (doubtful matches are suggested, never merged automatically), and uses them in the churn score. See NoChurn + Intercom.