Alt description missing in image
Beta: Plugins coming soon!
@payments/driverresolversstartPortalSession
Alt description missing in image

startPortalSession()

import { startPortalSession } from '@payments/driver'

Creates a customer portal session URL for managing subscriptions, payment methods, and billing details. The function delegates to your active payment driver implementation which handles provider-specific portal creation.

The driver automatically uses the payment provider you’ve selected in appConfig.ts.

const { portalUrl } = await startPortalSession({
    user,
    returnUrl: `${baseURL}/settings/billing`,
})
 
// redirect(portalUrl)

Implementation details

Each payment driver implementation handles the provider-specific portal creation:

packages/@payments-driver/index.ts
export const startPortalSession = paymentsDriver['startPortalSession']

Where paymentsDriver is the active payment provider implementation, and startPortalSession typically:

  • Ensures a customer exists for the user (via ensureCustomer() internally)
  • Creates a hosted customer portal session using the provider’s API
  • Returns the portal URL so you can redirect to it

The driver entrypoint forwards calls to the active implementation from @app/registries/drivers/payments.drivers.generated.ts.

StartPortalSessionInput

The underlying driver implementations will follow 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

The underlying driver implementations will follow 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 after the user makes changes in the portal (e.g. updating payment methods, canceling subscriptions, etc.).

For implementation-specific details, see your provider’s docs (e.g. Stripe’s implementation).