Slack notifications
Get a Slack message the moment something important happens in Stripe: a payment fails, a customer cancels, a new customer signs up, a subscription is upgraded or downgraded, or an invoice is paid outside Stripe. Each event posts to a single channel, and you control which events fire and exactly what the message says.
There are two screens involved:
- Connections — connect Slack and send a test message.
- Notifications — turn events on or off and customize each message body.
Connecting Slack #
Connect Slack on the Connections page — either with Add to Slack (OAuth) or by pasting an Incoming Webhook URL — then send a test message to verify it. See Connecting Slack for the full walkthrough.
Choosing and customizing events #
Open the Notifications page. Each of the five events has its own card with:
- An enable toggle — turn the event on or off.
- A message body editor — the text of the Slack message, written with
{{mustache}}variables. - A variable palette — click any variable to insert it at the end of the body.
- A live preview — rendered with the same engine that delivers real messages, using sample data.
Click Save on a card to apply its changes.
The emoji, title, and timestamp around each message are fixed — you only edit the body. Leaving the body empty restores the shipped default for that event (use Reset to default to clear it).
Any variable with no value renders as
-. You’ll never see the literal wordundefinedin a message — for example, a failed payment with no card brand on file shows-where the brand would go.
The five events #
| Event | Fires when | Default title |
|---|---|---|
| Failed payment | An invoice payment attempt fails | ⚠️ Failed payment |
| Churn | A subscription is canceled | 💔 Subscription canceled |
| New customer | A new Stripe customer is created | 🎉 New customer |
| Upgrade / downgrade | A subscription’s MRR goes up or down | 📈 Plan change |
| Invoice paid out-of-band | An invoice is marked paid outside Stripe | 💸 Invoice paid out-of-band |
Upgrade / downgrade fires only on a real MRR change — a same-price plan swap or a non-pricing update doesn’t notify.
Variable reference #
Every event’s body can use the common variables below, plus the event-specific
ones. Link variables render as clickable Slack links (for example View in
Stripe), and customer_email renders as a mailto: link. A variable with no
value renders as -.
Common to every event #
| Variable | Renders |
|---|---|
{{customer_name}} |
The customer’s name |
{{customer_email}} |
The customer’s email, as a mailto: link |
{{customer_country}} |
The customer’s country |
{{amount}} |
The relevant money amount |
{{currency}} |
The currency code |
{{occurred_at}} |
When the event happened |
{{stripe_url}} |
Link to the most relevant object in the Stripe Dashboard |
{{hubspot_url}} |
Link to the matched record in HubSpot, when synced |
Optional link variables #
These render only when that object is in scope for the event; otherwise -.
| Variable | Renders |
|---|---|
{{stripe_customer_url}} |
Link to the customer in Stripe |
{{stripe_subscription_url}} |
Link to the subscription in Stripe (churn, plan changes) |
{{stripe_invoice_url}} |
Link to the invoice in Stripe (failed payment, out-of-band) |
{{invoice_pdf_url}} |
Link to the invoice PDF (failed payment, out-of-band) |
{{hosted_invoice_url}} |
Link to the hosted Stripe invoice page (failed payment, out-of-band) |
Linking #
Link variables render on their own as default labeled links — for example a bare
{{stripe_url}} shows as View in Stripe, and {{invoice_pdf_url}} shows as
Download PDF. To use your own link text, write a Markdown link whose target is
a URL variable:
[label]({{url_var}})
The label can contain other variables. A few examples:
[invoice {{invoice_number}}]({{stripe_invoice_url}})→ a link reading invoice INV-0042 that opens the invoice in Stripe.[Download PDF]({{invoice_pdf_url}})→ a Download PDF link to the invoice PDF.[{{customer_name}}]({{stripe_customer_url}})→ the customer’s name, linked to their Stripe customer record.
The target must be one of the URL variables (the …_url ones above). If that
variable has no value for an event, the link gracefully falls back to just the
label text — you’ll never see a broken link.
Failed payment #
| Variable | Renders |
|---|---|
{{invoice_number}} |
The invoice number |
{{invoice_pdf_url}} |
Link to the invoice PDF |
{{hosted_invoice_url}} |
Link to the hosted Stripe invoice page |
{{failure_reason}} |
Why the payment failed |
{{attempt}} |
The payment attempt number |
{{max_attempts}} |
Not available from synced data — always renders - |
{{next_retry}} |
When Stripe will retry |
{{card_brand}} |
Not available from synced data — always renders - |
{{card_last4}} |
Not available from synced data — always renders - |
Churn #
| Variable | Renders |
|---|---|
{{mrr}} |
The canceled subscription’s MRR |
{{mrr_delta}} |
The signed MRR change |
{{plan}} |
The plan name |
{{interval}} |
The billing interval |
{{cancellation_reason}} |
Why the customer canceled |
{{churn_type}} |
Voluntary (customer canceled) or Involuntary (failed payment / dispute / retention policy) |
{{customer_lifetime}} |
How long they were a customer |
Upgrade / downgrade #
| Variable | Renders |
|---|---|
{{direction}} |
Upgrade or Downgrade |
{{mrr}} |
The new MRR |
{{mrr_delta}} |
The signed MRR change |
{{old_mrr}} |
The previous MRR |
{{new_mrr}} |
The new MRR |
{{old_plan}} |
The previous plan |
{{new_plan}} |
The new plan |
{{interval}} |
The billing interval |
{{percent_change}} |
The MRR change as a percentage |
Invoice paid out-of-band #
| Variable | Renders |
|---|---|
{{invoice_number}} |
The invoice number |
{{invoice_pdf_url}} |
Link to the invoice PDF |
{{hosted_invoice_url}} |
Link to the hosted Stripe invoice page |
{{paid_at}} |
When the invoice was marked paid |
{{due_date}} |
The invoice due date |
Related #
- Connecting Slack — connect the channel and send a test message.
- Webhooks — the inbound Stripe events that drive notifications.
- Connecting Stripe — get Stripe events flowing first.