/webhook route is the Stripe webhook receiver. Stripe sends signed POST requests to this endpoint when subscription-related events occur. The route verifies the signature before processing the event payload.
POST /webhook
Request
Content-Type:application/json (raw text — do not pre-parse)
The signature header added by Stripe to every webhook request. Used to verify that the request originated from Stripe and has not been tampered with. The value is a comma-separated string of timestamp and HMAC signatures.
stripe.webhooks.constructEvent will invalidate the signature check.
Webhook source
Signature verification
The route usesstripe.webhooks.constructEvent to verify the request:
body— the raw request body read withrequest.text().stripeSignature— the value of thestripe-signatureheader.webhookSecret— the webhook signing secret from the Stripe dashboard (format:whsec_...).
400 response.
Handled event types
| Event type | Description |
|---|---|
invoice.paid | Fired when an invoice is successfully paid. Use this to activate or extend access for the subscriber. |
invoice.payment_failed | Fired when an invoice payment attempt fails. Use this to notify the customer or restrict access. |
customer.subscription.deleted | Fired when a subscription is cancelled or expires. Use this to revoke access and update the customer’s status. |
Responses
| Status | Condition | Body |
|---|---|---|
400 | stripe-signature header is missing, webhook secret is not configured, or signature verification fails. | null or { "error": "Webhook configuration error." } |
200 | Event received, signature verified, and event processed. | { "data": "webhook" } |
Register this endpoint in the Stripe dashboard under Developers → Webhooks. For local development, use the Stripe CLI to forward events:
stripe listen --forward-to localhost:5173/webhook.