startStripePortalSession()
Creates a Stripe Billing Portal Session for the user’s Stripe customer, returning a hosted portalUrl.
Usage - Driver
import { startPortalSession } from '@payments/driver'If you chose ‘stripe’ as the default payment driver in
@app/configofcourse.
const { portalUrl } = await startPortalSession({
user,
returnUrl: `${baseURL}/settings/billing`,
})
// redirect(portalUrl)Usage - Directly
import { startStripePortalSession } from '@payments/stripe/resolvers/startStripePortalSession.resolver'const { portalUrl } = await startStripePortalSession({
user,
returnUrl: `${baseURL}/settings/billing`,
})
// redirect(portalUrl)Implementation details
- Ensures a Stripe customer exists for the user via
ensureStripeCustomer() - Creates a billing portal session using
createCustomerPortalSession() - Returns the hosted portal URL so you can redirect to it
startStripePortalSession.resolver.ts
export const startStripePortalSession = createResolver(async ({ args, parseArgs, withDefaults }) => {
const parsedArgs = parseArgs(args)
const { user, customer } = await ensureStripeCustomer({ user: parsedArgs.user })
const portalSession = await createCustomerPortalSession(customer.customerId, parsedArgs.returnUrl)
return withDefaults({ provider: 'stripe', customer, portalUrl: portalSession.url })
})StartPortalSessionInput
Follows the driver signature StartPortalSessionInput schema:
import { StartPortalSessionInput } from '@payments/driver/driver.signature'export const StartPortalSessionInput = schema('StartPortalSessionInput', {
user: User,
returnUrl: z.string().url().describe('URL to redirect the user to after they are done in the portal'),
})StartPortalSessionOutput
Follows the driver signature StartPortalSessionOutput schema:
import { StartPortalSessionOutput } from '@payments/driver/driver.signature'export const StartPortalSessionOutput = schema('StartPortalSessionOutput', {
provider: PaymentProvidable.shape.provider,
customer: Customer,
portalUrl: z.string().url().describe('URL of the customer portal session to redirect the user to'),
})Recommendations
💡
Use a return URL that triggers a post‑portal syncPaymentData() to keep entitlements up to date.
