Stripe Webhook

A Stripe webhook is an HTTPS POST Stripe sends your server when something happens in your account. Learn how delivery, retries, ordering, and failures work.

Updated October 1, 2026

A Stripe webhook is an HTTPS request Stripe sends to your server when something happens in your Stripe account, such as a payment, refund, dispute, or cancellation. Your server doesn't have to keep asking the API whether a payment went through. Stripe pushes each change to you as a JSON event.

In general, a webhook is any message one system sends to another as an HTTP request when something happens. The receiver owns the URL and decides what to do with the message.

How Stripe webhooks work

  1. You register a webhook endpoint, which is a public HTTPS URL plus the event types you want. You do this in the Webhooks tab of Workbench or with the API. One Stripe account can register up to 16 endpoints.
  2. When a matching event happens, Stripe sends a POST with the Event object as the JSON body. The resource sits under data.object, for example the PaymentIntent inside a payment_intent.succeeded event.
  3. Your server checks the Stripe-Signature header with webhook signature verification and returns a 2xx status before doing any slow work.
  4. If the request fails or times out, Stripe retries. In live mode it keeps trying for up to three days with exponential backoff. In a sandbox it retries three times over a few hours.

Two delivery rules surprise most teams. Stripe doesn't guarantee order, so creating a subscription can produce customer.subscription.created, invoice.created, and invoice.paid in any sequence. And the same event can arrive more than once. Stripe's advice is to log the event IDs you've processed and skip repeats. Don't rely on the created timestamp, which is only precise to the second.

Stripe webhook events worth listening to

Many events that cost you money happen long after checkout, with no API call on your side to catch them.

  • invoice.payment_failed fires when a renewal fails overnight. Nobody knows unless something is listening.
  • charge.dispute.created fires when a cardholder files a chargeback. Stripe debits the disputed amount and a dispute fee from your balance, and your response deadline starts running.
  • customer.subscription.deleted fires when a subscription ends, which is MRR you just lost.
  • payment_intent.succeeded and invoice.paid fire when money arrives, which is when you grant access or ship the order.

Stripe recommends listening only to the event types your integration needs. Subscribing to everything adds load on your server without adding anything useful. What Stripe events should a founder monitor has a starting set.

Webhooks affect your billing

For subscription invoices with automatic collection, Stripe waits for a successful response to invoice.created before it finalizes the invoice. If it never gets one, finalization is delayed by up to 72 hours, and Stripe emails you that the webhook is failing. A broken endpoint can push back your own revenue collection by days.

When Stripe webhook delivery fails

  • Engineering finds the cause. Each endpoint's Event deliveries tab in Workbench shows the HTTP status of every attempt. A 3xx counts as a failure because Stripe doesn't follow redirects. A 4xx usually means a wrong URL, method, or access rule. A timeout means the handler does too much before responding.
  • Engineering replays what was missed. The Dashboard's Resend button works for up to 15 days after an event was created, and stripe events resend in the Stripe CLI works for up to 30 days. After that, you rebuild state from the API.
  • Founders and finance check the gap. Any failed payment or dispute that arrived during an outage needs a manual look in the Dashboard, because whatever normally reacts to it didn't run.

Stripe webhooks vs Slack incoming webhooks

The names are similar and the direction is opposite. A Stripe webhook is Stripe calling your server. A Slack incoming webhook is a URL Slack gives you so your code can post a message into a channel. Sending Stripe events to Slack yourself means running both, with code in between that verifies the signature, picks out the fields, and formats the message.

Stripe webhooks and ChargeBell

If you want Stripe activity in Slack and don't need automation, you don't need your own endpoint. ChargeBell connects to Stripe through a read-only OAuth connection and receives events on its side. There's no URL to host, no signing secret to store, and no retry queue to watch. It dedupes on the Stripe event ID, so a redelivered event still produces one alert.

Each event becomes a plain-English Slack message with the amount, the customer, what you keep after fees, and the MRR change where it applies. You route alert types to different channels, for example successful payments to #wins and failures and disputes to the people who act on them. The Free plan includes 50 real-time alerts a month with every feature, and Pro removes the cap for $24 a month. See the Stripe Slack integration for setup, or ChargeBell vs custom webhooks for the build-or-buy trade-off.

Get alerted in Slack

Stripe events: payment_intent.succeeded, payment_intent.payment_failed, charge.dispute.created, invoice.paid, customer.subscription.deleted

ChargeBell posts Stripe events to the Slack channel you pick, written in plain English.

Related terms