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.

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., utils/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
  },
})