Skip to content

Billing

NuxtBase ships with a working billing system, not just a pricing page mockup.

From the current template code, billing is:

  • organization-scoped
  • manager-controlled
  • Stripe-backed
  • webhook-synchronized
  • mirrored into local billing tables for the app UI

That means the billing chapter is about product behavior:

  • how plans are defined
  • how checkout and plan changes behave
  • how cancellation and resume work
  • how Stripe events keep the local app state in sync

Before changing plan logic or checkout UI, confirm these shipped behaviors:

  1. only owner and admin can manage billing for the active organization
  2. a fresh organization without an operable subscription is treated as free
  3. checkout starts one Stripe Checkout Session for the active organization
  4. Stripe webhooks update the local subscription state after checkout
  5. cancel and resume are period-end actions, not immediate deletion

There are four practical layers to keep in mind:

  1. static plan metadata in server/config/plans.ts
  2. billing endpoints under server/api/billing/*
  3. the dashboard billing screen in app/pages/dashboard/billing.vue
  4. Stripe webhook processing in server/api/billing/webhook.post.ts

The important design choice is that the app UI does not trust Stripe directly at render time. The product reads local billing tables and syncs them from Stripe through explicit local mutations and Stripe webhooks. Checkout itself only creates a Stripe Checkout Session and returns a URL; it does not write the local subscription record.

Billing changes are rarely isolated. If you change plan keys, pricing copy, or customer billing actions, review organizations, AI quota assumptions, support copy, and webhook handling at the same time.