BETTER-AUTH. UI
Plugins

Billing

Add plans, subscriptions, checkout, seats, and usage to Solid/Zaidan settings without coupling the UI to one provider.

The billing plugin adds a billing tab to personal or organization settings. Every view reads a provider-neutral BillingAdapter. BAUI includes adapters for Stripe, Polar, Autumn, Creem, Dodo Payments, and Commet.

The UI covers:

  • Pricing plans with monthly, yearly, and one-time prices
  • Current subscription status and renewal or end date
  • Checkout and plan changes
  • Billing portal access
  • Cancellation and restoration
  • Seat management
  • Metered usage

Setup

Configure a Better Auth billing plugin

Configure one of Better Auth's supported billing plugins on the server and client. Apply its schema before you open the billing page.

See the provider guides for Stripe, Polar, Autumn, Creem, Dodo Payments, and Commet.

Install the UI plugin

npx shadcn@latest add https://better-auth-ui.com/r/solid/billing.json

Register the plugin

Build an adapter and hand it to the plugin.

src/components/providers.tsx
import { createStripeBillingAdapter } from "@better-auth-ui/core/plugins/billing"
import { AuthProvider } from "@/components/auth/auth-provider"
import { billingPlugin } from "@/lib/auth/billing-plugin"
import { authClient } from "@/lib/auth-client"

const billingAdapter = createStripeBillingAdapter(authClient, {
  plans,
  successUrl: "/settings/billing?checkout=success",
  cancelUrl: "/settings/billing?checkout=canceled",
  returnUrl: "/settings/billing"
}) 

export function Providers(props: { children?: JSX.Element }) {
  return (
    <AuthProvider
      authClient={authClient}
      navigate={navigate}
      plugins={[
        billingPlugin({ adapter: billingAdapter, organization: true }) 
      ]}
    >
      {props.children}
    </AuthProvider>
  )
}

user defaults to true and adds the tab to personal settings. organization defaults to false. Turn it on to add the same tab to organization settings.

Bundled adapters

AdapterCheckout and stateDirect actionsScope
StripeBetter Auth subscription APICancel, restore, seatsUser and explicit organization
PolarCheckout, subscriptions, usagePortal fallbackUser and explicit organization
AutumnAttach, customer subscriptions, balancesCancel, restore, optional license seatsUser
CreemCheckout and active subscriptionCancelUser
Dodo PaymentsCheckout session and subscription listPortal fallbackUser
CommetPortal and current subscriptionCancel, optional feature usage and seatsUser

The factories are createStripeBillingAdapter, createPolarBillingAdapter, createAutumnBillingAdapter, createCreemBillingAdapter, createDodoPaymentsBillingAdapter, and createCommetBillingAdapter. They use the same BillingPlan list and work with both React and Solid billing hooks.

User-only provider clients

Autumn, Creem, Dodo Payments, and Commet resolve the signed-in customer. Their browser APIs do not accept an explicit organization ID. Their adapters declare scopes.organization: false. billingPlugin rejects an organization billing configuration instead of reading active organization state.

The adapter's supports flags decide which controls render. A provider that cannot restore a canceled subscription does not show the restore button.

Writing your own adapter

BillingAdapter is a plain interface: list plans, read state, start checkout, open a portal, cancel, restore, and update seats. Implement it against any billing service and the views work unchanged.

Prop

Type

Runtime prerequisites

  • Server and client: a Better Auth billing plugin, or your own billing endpoints.
  • App: a BillingAdapter instance.
  • Runtime API: billing query and mutation options from Solid runtime APIs.

Copied files

  • src/lib/auth/billing-plugin.tsx
  • src/components/auth/billing/billing-settings.tsx

After install the plan cards, usage bars, and dialogs are yours to restyle. The usage bar is rendered inline with role="progressbar" rather than a Zaidan primitive, since Zaidan does not ship one.

Options

Prop

Type

Localization

Prop

Type

Last updated on

On this page