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.
Option 1: Leave It Disabled (Recommended)
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.tsbilling.test.tsbilling/(entire directory, including thestripe/,polar/, andlemonSqueezy/provider subtrees)
2. Remove Billing Schema Tables
In schema.ts, remove:
billing_customersbilling_subscriptionsbilling_grantsbilling_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.readbilling.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
- Billing Overview — billing system overview.