Leave Localhost logoLeave LocalhostDocs
Billing

Removing Billing

If your product does not need billing, you can disable it with a single env var or remove the billing system entirely. Billing is opt-in and ships disabled — with BILLING_PROVIDER unset, the system reports all organizations as "unconfigured" and no checkout flows or webhook routes exist.

If your product does not need billing, you can disable it with a single environment variable or remove the billing system entirely. Billing is opt-in and ships disabled: with BILLING_PROVIDER unset, the system reports all organizations as "unconfigured", no checkout flows are available, and no payment-provider webhook route is registered.

Do nothing. With BILLING_PROVIDER unset, the app will:

  • Show all plans as unavailable for checkout
  • Report billing status as "unconfigured"
  • Skip the plan badge in the sidebar
  • Allow all organization features that don't require capabilities
  • Register no billing webhook route

Every provider's code is compiled into the deployment, but none is active. This is the safest approach because it requires no code changes.

Turning billing back off

If a provider is active and you only want to turn billing back off (without deleting the billing core), unset BILLING_PROVIDER (or set it to empty) in each deployment and redeploy. No source changes are needed — the registry stays in place and simply resolves to "disabled".

Check active subscriptions first

Disabling a provider while a live subscription still needs it breaks that subscription's checkout, cancellation, and webhook processing. Before switching BILLING_PROVIDER away from a provider, run the count query against each deployment (production especially) and confirm it returns 0:

# production
bunx convex run --prod billing:countActiveSubscriptionsForProvider '{"provider":"stripe"}'
# dev (default target)
bunx convex run billing:countActiveSubscriptionsForProvider '{"provider":"stripe"}'
# any other: add --deployment <name>

A non-zero count means subscriptions are still active/trialing/past_due/ incomplete/unpaid for that provider — cancel, migrate, or sunset them at the provider before disabling it.

Option 2: Remove Billing Code

To remove the billing system entirely:

1. Remove Billing Backend Files

Delete the following from packages/backend/convex/:

  • billing.ts
  • billing.test.ts
  • billing/ (entire directory, including the stripe/, polar/, and lemonSqueezy/ provider subtrees)

2. Remove Billing Schema Tables

In schema.ts, remove:

  • billing_customers
  • billing_subscriptions
  • billing_grants
  • billing_event_sources

3. Remove Billing Webhooks and the Stripe Component

In http.ts, remove the getConfiguredBillingProvider() / getBillingProviderIntegration(...).registerWebhookRoutes(http) block and its imports. In convex.config.ts, remove app.use(stripe) and its import if no other Stripe functionality is needed.

4. Remove Provider Dependencies

In packages/backend/package.json, remove @convex-dev/stripe, @polar-sh/sdk, and buffer if nothing else uses them, then run bun install.

5. Remove Billing Permissions

In permissions/appPermissions.ts, remove:

  • billing.read
  • billing.manage

In auth/organizationAccess.ts, remove billing from the access control statements and role definitions.

6. Remove Billing Capabilities

In permissions/capabilities.ts, remove:

  • billing.portal
  • Any other billing-related capabilities

7. Remove Frontend Billing UI

In apps/app, remove billing-related components:

  • Plan display in the sidebar
  • Checkout flow
  • Customer portal redirect
  • Plan badge in the user menu

8. Remove Environment Variables

Remove all billing-related variables from:

  • env.ts (backend validation)
  • .env.example
  • Your deployment configuration

9. Clean Up Imports

Run bun run typecheck to find and fix any broken imports.

Next Reads

On this page