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

  1. Create a plan with a stripeProductId pointing to a Stripe Product, and a price tier with a stripePriceId pointing to the corresponding Stripe Price.
  2. Stripe sends customer.subscription.created, customer.subscription.updated, and customer.subscription.deleted webhook events to POST /api/webhooks/stripe.
  3. Auth Service validates the webhook signature using STRIPE_WEBHOOK_SECRET, resolves the internal plan from the Stripe Price or Product ID, and updates the userSubscriptions.isActive flag 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

EventAction
customer.subscription.createdSets isActive = true for the matching user subscription
customer.subscription.updatedUpdates isActive based on status (active or trialingtrue, all others → false)
customer.subscription.deletedSets isActive = false

Unhandled events

All other event types return 200 OK with { "received": true } and are not processed.

Stripe Dashboard setup

  1. Go to Developers → Webhooks → Add endpoint.
  2. Set the endpoint URL to https://auth.example.com/api/webhooks/stripe.
  3. Select the events: customer.subscription.created, customer.subscription.updated, customer.subscription.deleted.
  4. 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 }
  }
}
Copyright © 2026