Skip to main content
Flowglad provides flexible authentication integration that works with any auth provider. You have complete control over how you define your customers, whether you’re building a B2C app with individual users or a B2B platform with organization customers.
Using Better Auth? Check out the Flowglad Better Auth plugin for automatic customer creation and simplified integration.

Scoped Server Pattern

The scoped server pattern gives you maximum flexibility for defining customers and works seamlessly with any authentication provider. This approach uses a factory function that creates a FlowgladServer instance scoped to a specific customer. Key benefits:
  • Works with any auth provider
  • Full control over customer identity (user ID for B2C, organization ID for B2B)

Server Setup

Create a Flowglad server factory function in a shared file (e.g., lib/flowglad.ts):
import { FlowgladServer } from '@flowglad/nextjs/server'
import { auth } from '@/utils/auth'
import { headers } from 'next/headers'

export const flowglad = (customerExternalId: string) => {
  return new FlowgladServer({
    customerExternalId,
    getCustomerDetails: async (customerExternalId) => {
      const session = await auth.api.getSession({
        headers: await headers(),
      })
      if (!session?.user) {
        throw new Error('User not authenticated')
      }
      return {
        email: session.user.email || '',
        name: session.user.name || ''
      }
    },
  })
}
Important: customerExternalId is the ID from your app’s database (e.g., user.id or organization.id), not Flowglad’s customer ID.B2C apps: Pass user.id as customerExternalId
B2B apps: Pass organization.id or team.id as customerExternalId

Next Route Handler Setup

Set up your Flowglad API route at /api/flowglad/[...path] to handle requests from your frontend:
import { nextRouteHandler } from '@flowglad/nextjs/server'
import { flowglad } from '@/utils/flowglad'
import { auth } from '@/utils/auth'
import { headers } from 'next/headers'

export const { GET, POST } = nextRouteHandler({
  flowglad,
  getCustomerExternalId: async (req) => {
    const session = await auth.api.getSession({
      headers: await headers(),
    })
    const userId = session?.user?.id
    if (!userId) {
      throw new Error('User not found')
    }
    return userId
  },
})