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 word undefined in 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

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