Table of Contents
- Which Stripe events actually need you
- Step 1 — Create a channel per urgency level
- Step 2 — Add the endpoints in Stripe
- Step 3 — Template the payload into something readable
- Step 4 — Test it without waiting for a real payment
- What this setup does not give you
- Frequently asked questions
- Can Stripe call my phone directly?
- Will a dispute alert actually wake me up?
- Can my co-founder get the same alerts?
- What about test mode?
- Wrap-up
- Related
Stripe emails you about everything and nothing. A successful charge, a failed subscription renewal and a chargeback all arrive as the same kind of message in the same inbox, and by the time you read them you have already lost the difference between them.
The fix is not more notifications. It is giving each Stripe event the urgency it actually deserves: a quiet push when someone pays, a time-sensitive alert when a renewal fails, and a phone call when a dispute lands with a response deadline attached.
Which Stripe events actually need you
Not every event is worth a notification, and the ones that are worth it are not equally urgent.
| Stripe event | Why it matters | Urgency |
|---|---|---|
payment_intent.succeeded | Someone paid. Good to know, never urgent. | Normal |
invoice.payment_failed | A renewal failed. You have a retry window before the subscription lapses. | Time-sensitive |
charge.dispute.created | A chargeback. Stripe gives you a response deadline set by the card network, and missing it loses the case by default. | Calling |
payment_intent.payment_failed | A one-off checkout failed. Useful in volume, noisy one at a time. | Normal, or skip |
The dispute is the one that justifies a phone call. Everything else can wait until you pick up your phone; a dispute you notice a week late is money you were never going to keep.
Step 1 — Create a channel per urgency level
Create three channels in Echobell, because urgency is a per-channel setting:
- Stripe · Revenue — normal notifications, for successful payments
- Stripe · Payment failed — time-sensitive
- Stripe · Dispute — calling
Copy each channel's webhook URL from its settings. You will point Stripe at all three.
Turn on POST Only for each of them while you are there. Stripe always posts, and it stops link previews and address-bar autocompletion from firing your channel by accident.
Step 2 — Add the endpoints in Stripe
In the Stripe Dashboard, go to Developers → Webhooks → Add endpoint, paste the channel URL, and select only the events that channel should handle.
Add one endpoint per channel rather than one endpoint for everything. Stripe lets you pick events per endpoint, which means the routing happens on Stripe's side and your channels stay simple.
If you prefer a single endpoint, point it at one channel and filter with a condition instead:
type == "charge.dispute.created"
Conditions are written without the {{ }} wrappers that templates use.
Step 3 — Template the payload into something readable
Stripe posts a JSON body shaped like this:
{
"type": "charge.dispute.created",
"data": {
"object": {
"amount": 4900,
"currency": "usd",
"reason": "fraudulent",
"status": "warning_needs_response"
}
}
}
So the channel templates reach into data.object:
Title
Dispute: {{data.object.reason}}
Body
{{data.object.amount}} {{data.object.currency}} disputed
Status: {{data.object.status}}
One gotcha that bites everyone: Stripe amounts are in the smallest currency unit. 4900 is $49.00, not $4,900. Echobell templates substitute the value as-is, so either divide it before you send it, or write the currency after it and read it as cents. If the number matters at a glance, put the division in whatever sits between Stripe and Echobell — a Worker, a Zap, your own endpoint.
For the revenue channel, the same idea with fewer words:
Title
+{{data.object.amount}} {{data.object.currency}}
Body
{{data.object.description}}
Step 4 — Test it without waiting for a real payment
The Stripe CLI can fire real event payloads at your endpoint:
stripe trigger payment_intent.succeeded
stripe trigger charge.dispute.created
Do this before you rely on it. It is also the fastest way to see what your template renders when a field you assumed would be there is null.
What this setup does not give you
Two limits worth knowing before you put this in front of your revenue.
Echobell does not verify Stripe's signature. Stripe signs every webhook with a Stripe-Signature header, and verifying it requires the endpoint secret. Echobell's webhook endpoint does not do that check, so the channel URL is the only thing protecting the channel. Treat it as a secret, keep POST Only enabled, and do not paste it into a public repository or a screenshot.
You can add a weak sanity check with a condition:
header["stripe-signature"] != ""
That confirms something is sending a Stripe-shaped request. It does not confirm it was Stripe. If a forged notification would cause real harm — as opposed to a moment of confusion — put your own endpoint in front, verify the signature there, and have it call Echobell.
This is an alerting path, not a ledger. Stripe retries failed webhook deliveries, but notifications are not a record of what happened. Reconcile against Stripe, not against your notification history.
Frequently asked questions
Can Stripe call my phone directly?
No. Stripe sends email, and webhooks. A phone call means routing a webhook to something that can place one.
Will a dispute alert actually wake me up?
If the channel is set to Calling, yes — it arrives as an incoming call and rings through Focus and Do Not Disturb. See bypassing iOS Focus Mode for critical alerts.
Can my co-founder get the same alerts?
Yes. Share the channel and each subscriber picks their own notification type. You can take the calls while someone else gets a quiet push for the same event.
What about test mode?
Stripe test-mode events go to endpoints registered in test mode. Register your channel URL in both if you want to see test traffic, or in test mode only until you trust the setup.
Wrap-up
Three channels, three endpoints, one template each. The point is not that you get notified about Stripe — you already were. It is that a chargeback stops looking exactly like a receipt.
Download Echobell for iPhone or get it on Google Play, then run stripe trigger charge.dispute.created and let your phone ring once on purpose.