Skip to content

Webhooks

The @better-auth/stripe plugin registers a webhook endpoint at POST /api/auth/stripe/webhook and handles signature verification, event parsing, and database updates automatically.

Events Handled

Stripe EventPlugin Action
checkout.session.completedActivates the subscription
customer.subscription.createdRecords a new subscription
customer.subscription.updatedSyncs status, period dates, cancellation scheduling
customer.subscription.deletedMarks the subscription as canceled

The plugin updates the subscription table in the database – no manual event handling code is needed.

Stripe Dashboard Configuration

Register the webhook endpoint in Stripe Dashboard → Webhooks:

FieldValue
Endpoint URLhttps://<your-domain>/api/auth/stripe/webhook
Eventscheckout.session.completed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted

Copy the signing secret (whsec_...) to STRIPE_WEBHOOK_SECRET.

Local Development

Use the Stripe CLI to forward webhook events to your local dev server:

bash
stripe listen --forward-to localhost:5173/api/auth/stripe/webhook

The CLI prints a webhook signing secret (whsec_...) – copy it to your .env.local:

ini
STRIPE_WEBHOOK_SECRET=whsec_...

WARNING

The local signing secret changes each time you restart stripe listen. Update .env.local and restart the dev server if webhook verification fails.

Raw Body Handling

Stripe webhook verification requires the raw (unparsed) request body. The plugin reads the body via request.text() before Hono's body parser runs, so no special middleware configuration is needed.

Production Setup

Store the webhook secret as a Cloudflare Worker secret:

bash
wrangler secret put STRIPE_WEBHOOK_SECRET

After deploying, send a test event from the Stripe Dashboard to verify the endpoint is reachable and the signature validates correctly.