Billing
For the complete documentation index, see llms.txt. Prefer markdown by appending .md to documentation URLs or sending Accept: text/markdown.

Webhooks

Stripe webhook synchronization in Edge Kit, with subscription state, signed events, local testing, delivery diagnostics, and custom billing workflows.

A webhook is a server-to-server notification from Stripe to your application. It keeps billing state current when a subscription changes, including changes made after the customer has closed your app or through Stripe's customer portal.

Edge Kit connects these events through Better Auth's Stripe integration. The integration verifies incoming events and updates the subscription records your app uses for billing settings and paid access.

Subscription state

Three parts of the billing system have different responsibilities:

PartResponsibility
StripePayments, recurring prices, invoices, and the provider's subscription state
Application databaseSubscription records associated with customer accounts
Application policyFeatures and allowances available for a customer's current plan

A successful payment and an updated application view are separate events. The webhook synchronizes provider changes; the interface then reads the resulting subscription state. Grant paid access from that server-side state rather than a browser-supplied success flag.

The kit grants the corresponding tier for active subscriptions and trials. Cancellation scheduled for the end of a period can retain access until the subscription ends. Subscriptions explains that policy.

Endpoint and events

The existing webhook endpoint is:

https://app.example.com/api/auth/stripe/webhook

Replace the origin with your deployed auth origin. The endpoint belongs to the existing auth integration, so you do not need a second handler to synchronize the included subscriptions.

The subscription setup lists the required Stripe events and signing-secret configuration. Keep the endpoint subscribed to checkout completion and subscription creation, updates, and deletion.

STRIPE_WEBHOOK_SECRET verifies that an incoming notification belongs to your configured Stripe endpoint. It is separate from STRIPE_SECRET_KEY, which authorizes outgoing API requests to Stripe. Each environment needs its own matching configuration.

Local testing

Use Stripe test mode with the local application. The Stripe CLI forwards provider events to your development server:

stripe listen --forward-to localhost:3000/api/auth/stripe/webhook

Set the listener's signing secret in your local environment and restart the app. A secret from a dashboard endpoint does not verify events forwarded by a different CLI listener.

Synthetic events are useful for handler diagnostics, but an application checkout also verifies account association, price configuration, and the customer-facing result.

Delivery diagnostics

Stripe's endpoint delivery history shows whether an event reached the app and how the endpoint responded. Start there when Stripe shows a subscription that the app does not yet reflect.

ResultInvestigation
No delivery attemptEndpoint mode, selected events, and destination URL
Signature rejectionSigning secret for this exact endpoint or CLI listener
Server errorWorker logs, database migrations, and provider configuration
Successful delivery, unexpected accessCustomer association, subscription status, and the configured plan catalog
Correct server state, stale interfaceThe relevant billing query and route refresh

Use a fresh event or retry the failed delivery after correcting the underlying configuration. Repeating checkout unnecessarily can create more customer and subscription state to untangle.

Custom workflows

You can extend billing with product-specific actions, such as provisioning a resource or sending a subscription notification. Use the integration's supported lifecycle hooks and keep the existing subscription synchronization intact.

Make each additional side effect safe to retry. A stable event or operation key can identify work already completed; an email or resource should not be created twice because a delivery was repeated. Do not assume events arrive in the order your product actions occurred.

For slow work, hand off a small task to background jobs and let the handler load the current product state. Stripe's webhook guidance covers retries and ordering, while Better Auth's Stripe documentation describes extension points.

Production configuration

Live prices, API credentials, endpoint secrets, and customer portal settings must belong to the same live environment. Complete the setup on the final hostname, then verify a controlled customer journey and delivery history as part of your production checklist.

How is this guide?

Last updated on

On this page

Ship globally on the edge. In minutes.Try Edge Kit