bitwarden/server
Billing & subscriptions
Active contributors: billing team.
Purpose
Bitwarden monetises through plans (Free, Premium, Families, TeamsStarter, Teams, Enterprise, Custom) for personal and organization tiers, plus Provider tiers, Secrets Manager seats, additional storage, and add-on products. The billing surface covers everything from "show the right Stripe checkout" to "renew this subscription, prorate the change, generate this invoice, send this dunning email". The off-prem licensing flow for self-hosted enterprise customers also lives here.
Where the code lives
| Concern | Path |
|---|---|
| Domain logic | src/Core/Billing/ |
| Webhook receiver | src/Billing/ (see apps/billing) |
| Self-service API | src/Api/Billing/Controllers/, src/Api/AdminConsole/Public/Controllers/... |
| Admin tools | src/Admin/Billing/, src/Admin/Tools/, src/Admin/Views/Tools/ |
| Plan definitions | src/Core/Utilities/StaticStore.cs (autofill team's CODEOWNERS pin) |
| Schema | src/Sql/dbo/Tables/Transaction.sql, TaxRate.sql, OrganizationSponsorship.sql, Subscription.sql (where used), Stripe-mirrored data |
Key abstractions
| Type | Path | Description |
|---|---|---|
PlanType, Plan, StaticStore |
src/Core/Utilities/StaticStore.cs |
Static plan definitions: seat counts, storage, features, Stripe price IDs. |
IPaymentService / StripePaymentService |
src/Core/Services/{IPaymentService.cs, Implementations/StripePaymentService.cs} |
The big payment gateway abstraction (purchase, change-plan, cancel, prorate, refund, store payment method). |
ISubscriberService |
src/Core/Billing/Services/ISubscriberService.cs |
Subscriber-aware operations on the Stripe customer / subscription pair. |
IProviderBillingService / ProviderBillingService |
src/Core/Billing/Providers/ |
MSP-tier billing (per-month per-org). |
OrganizationBillingService |
src/Core/Billing/Organizations/ |
Organization-scoped billing flows. |
IPriceIncreaseScheduler |
src/Core/Billing/Subscriptions/ |
The 2026 effort to use Stripe subscription schedules to defer price increases. |
BillingException |
src/Core/Billing/BillingException.cs |
Domain exception for billing-specific failures. |
ILicensingService |
src/Core/Services/ILicensingService.cs |
Issues signed OrganizationLicense files for self-hosted enterprise customers. |
OrganizationSponsorship |
src/Core/Entities/OrganizationSponsorship.cs |
Families-for-Enterprise — an enterprise org sponsors a free Families plan for an employee. |
How it works
sequenceDiagram
participant User as User (Web Vault)
participant ApiHost as Api
participant Stripe
participant BillingHost as Billing
participant DB
User->>ApiHost: POST /organizations (create) → choose plan
ApiHost->>Stripe: Customer + Subscription (StripePaymentService)
Stripe-->>ApiHost: subscription.id, status=active
ApiHost->>DB: Insert Organization with PlanType
ApiHost-->>User: 200 ok
Stripe-->>BillingHost: invoice.created webhook
BillingHost->>DB: Insert Transaction
BillingHost->>ApiHost: cache invalidate (org ability)The Api host handles the outbound side of every billing operation (the user clicks Subscribe). The Billing host handles the inbound side (Stripe sends a webhook). State of record is the database; Stripe is the source of truth for the subscription itself.
Self-host licensing
Enterprise self-hosted customers don't pay through Stripe inside their instance. They pay Bitwarden's cloud, which then issues a signed OrganizationLicense JSON file. The customer uploads it via the Admin Console, the self-host validates it against licensing.cer (committed to src/Core/), and the org is enabled.
Licensing flow:
- Customer purchases via cloud → cloud
Adminregenerates license viaILicensingService. - Customer downloads the
.jsonlicense. - Customer uploads to self-host Admin Console.
- Self-host validates via
OrganizationLicenseValidator; org plan / seat counts are populated.
ILicensingService runs every day via Quartz to refresh the license against the cloud control plane.
Plans
StaticStore.Plans enumerates every plan, including:
- Free / FamiliesAnnually / TeamsStarter / TeamsAnnually / TeamsMonthly / EnterpriseAnnually / EnterpriseMonthly.
- Per-plan: Stripe price IDs (production + non-production), seat / storage limits, optional add-on price IDs (Secrets Manager seats, additional storage GB, additional service-account seats).
The autofill team owns this file (the cipher-domain types are constructed from it).
Recent investments
- Schedule-aware price migration (PR #7305, 2026-03-26): subscription schedule used to defer price increases.
- Cancel / Reinstate path migration (PR #7331, 2026-03-31).
- Save Cancellation Details for Scheduled Subscriptions (PR #7535).
- Org Integrations 4xx error consistency (PR #7458).
Integration points
- Webhook receiver — see apps/billing.
- Mail — receipts, dunning emails, license-expiring warnings.
- Audit events — billing-related events log under the org id.
- Application cache — plan / seat changes invalidate via the Service Bus topic.
Entry points for modification
- New plan → extend
StaticStore.Plans(and the corresponding Stripe products), update thePlanTypeenum, ensure the per-plan seat / storage allowances flow throughOrganizationService. - New webhook handler →
src/Billing/Services/StripeEventService.cs(or PayPal / BitPay / Apple equivalents). - Subscription schedule rules →
IPriceIncreaseSchedulerinsrc/Core/Billing/Subscriptions/. - Add a recurring billing job →
src/Billing/Jobs/and register inJobsHostedService.
For Provider billing in particular see src/Core/Billing/Providers/Services/ProviderBillingService.cs and the matching ~2,300-line test file in bitwarden_license/test/Commercial.Core.Test/Billing/Providers/Services/.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.