Handle Stripe webhook events

POST https://app.speybooks.com/api/v1/stripe-webhook/stripe

Receive and process Stripe webhook events. The processing flow is:

  1. Extract Stripe-Signature header — reject 400 if missing
  2. Verify signature against STRIPE_WEBHOOK_SECRET using the raw (unparsed) request body
  3. Insert event into webhook_events as pending
  4. Dispatch to the appropriate handler by event type
  5. Update event status to processed or failed
  6. Return { received: true } regardless of processing outcome

This endpoint must receive the raw request body (not parsed JSON) for signature verification. It is registered before Fastify's JSON content-type parser.

Error responses:

  • 400 { error: "Missing signature" } — no Stripe-Signature header or STRIPE_WEBHOOK_SECRET not configured
  • 400 { error: "Webhook Error: ..." } — signature verification failed (wrong secret, tampered payload, or replay attack)

Monitoring: Failed events can be queried from webhook_events where status = 'failed'. The error_details column contains the handler error message. The Stripe dashboard's webhook event log can be cross-referenced using the event_id column.

Response

200 Webhook received and processed. Always returns 200 to prevent Stripe retries, even if processing fails internally.
Show response fields
received boolean
Always true when the webhook is acknowledged.

Error codes

400 Missing Stripe signature header or webhook signature verification failed.