HookGet Open dashboard

Stripe webhooks

Payment, subscription and payout events, with the timestamp tolerance Stripe specifies.

In short

  • Verification: the provider’s own HMAC signature over the raw body.
  • Deduplication: The event id in the body.
  • Once verified, the event joins your catalogue with the same retries, log and replay as anything you publish yourself.

The contract

FieldValue
Provider keystripe
Header checkedStripe-Signature: t=<unix>,v1=<hex>
SchemeHMAC-SHA256 over <timestamp>.<raw body>. The timestamp must be inside a five-minute window, which is what makes a captured request useless later.
Deduplicated onThe event id in the body
Event typeThe type field becomes stripe.payment_intent.succeeded and similar.

Setting it up

# 1. create a verified source; the secret is shown once
curl -X POST https://api.hookget.com/v1/sources \
  -H "authorization: Bearer $HOOKGET_KEY" \
  -H "content-type: application/json" \
  -d '{"provider":"stripe","name":"Production"}'

# {"id":"src_…","secret":"whsec_…","ingest_path":"/ingest/src_…"}
  1. In the Stripe dashboard, open Developers → Webhooks → Add endpoint.
  2. Paste the ingest URL. Stripe issues its own signing secret — put that value into the HookGet source as the secret.
  3. Select the event types you need.

Worth knowing. The signature covers the timestamp as well as the body, so a replayed request outside the window is refused even though the HMAC is arithmetically correct. That is the point of it.

What you get after verification

  • The event appears in your log with a namespaced type, so Stripe traffic never collides with your own.
  • It fans out to your destinations with the same retry schedule and dead-letter behaviour as any other event.
  • The source secret rotates with an overlap window, so you can update Stripe at your own pace.
  • Each inbound source is rate limited on its own, so a busy provider cannot exhaust your publish budget.

Questions

How do I verify a Stripe webhook?

HMAC-SHA256 over <timestamp>.<raw body>. The timestamp must be inside a five-minute window, which is what makes a captured request useless later. With HookGet you do not implement it: the source is created with a secret, and every request is checked against Stripe-Signature: t=<unix>,v1=<hex> before the event exists.

What happens if Stripe sends the same event twice?

Redeliveries are deduplicated on The event id in the body, namespaced per source, so a repeat becomes the same event rather than a second one.

What if verification fails?

The request is refused with 401 and nothing enters the pipeline. The rejection is logged on our side as a signal worth watching; the caller learns nothing beyond the status.