Guides
Stripe integration
Connect Stripe to Auth Service for automatic subscription plan synchronisation via webhooks.
Stripe integration
Auth Service supports optional Stripe billing integration. When configured, Stripe product and price IDs on subscription plans are used to reconcile plan status via webhook events.
Configuration
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_... # From Stripe Dashboard → Webhooks → signing secret
When STRIPE_SECRET_KEY is not set, Stripe features are silently disabled — all Stripe-specific fields in plan create/update requests are accepted but ignored.
How it works
- Create a plan with a
stripeProductIdpointing to a Stripe Product, and a price tier with astripePriceIdpointing to the corresponding Stripe Price. - Stripe sends
customer.subscription.created,customer.subscription.updated, andcustomer.subscription.deletedwebhook events toPOST /api/webhooks/stripe. - Auth Service validates the webhook signature using
STRIPE_WEBHOOK_SECRET, resolves the internal plan from the Stripe Price or Product ID, and updates theuserSubscriptions.isActiveflag accordingly.
Stripe webhook endpoint
POST /api/webhooks/stripe
This endpoint receives raw body bytes and verifies the Stripe-Signature header before processing. Do not add authentication middleware to this route — Stripe does not send session cookies.
Handled events
| Event | Action |
|---|---|
customer.subscription.created | Sets isActive = true for the matching user subscription |
customer.subscription.updated | Updates isActive based on status (active or trialing → true, all others → false) |
customer.subscription.deleted | Sets isActive = false |
Unhandled events
All other event types return 200 OK with { "received": true } and are not processed.
Stripe Dashboard setup
- Go to Developers → Webhooks → Add endpoint.
- Set the endpoint URL to
https://auth.example.com/api/webhooks/stripe. - Select the events:
customer.subscription.created,customer.subscription.updated,customer.subscription.deleted. - Copy the signing secret and set it as
STRIPE_WEBHOOK_SECRET.
Admin API: check if Stripe is configured
GET /api/admin/services
Returns the current state of optional integrations:
{
"stripe": true,
"providers": {
"google": { "enabled": false },
"github": { "enabled": false }
}
}