Overview
Get started with web billing in TurboStarter.
For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
The @workspace/billing and @workspace/billing-web packages are used to manage all the billing-related logic and features for your web SaaS application.
Inside, we're making an abstraction layer that allows us to use different billing providers without breaking our code nor changing the internal API calls.

Providers
TurboStarter implements multiple providers for managing billing:
Stripe
The most popular and customizable billing provider.
Lemon Squeezy
A Stripe-owned Merchant of Record (MoR) platform for modern subscription billing.
Polar
Built for developers, Polar offers flexible, SaaS-focused billing solutions.
Dodo Payments
Streamlined recurring and usage-based billing for SaaS companies.
All configuration and setup is built-in with a unified API, so you can switch between providers by simply changing the exports and even introduce your own provider without breaking any billing-related logic.
Depending on the service you use, you will need to set the environment variables accordingly. By default - the billing package uses Stripe. Alternatively, you can use Lemon Squeezy, Polar or Dodo Payments. We may introduce more providers in the future.
Configuration
The shared billing configuration is maintained in the @workspace/billing package, while provider-specific checkout, portal, webhook, and usage logic lives in @workspace/billing-web.
To better understand all billing features and customization options provided by TurboStarter, explore the following dedicated guides:
Configuration
Learn how to structure billing settings for your app, plan details and features.
Subscriptions
Set up and manage recurring billing cycles, trial periods, and upgrade/downgrade logic.
One-time
Handle single, non-recurring payments, such as purchases or one-off charges.
Credits
Implement a system for pre-paid credits, allowing users to consume features based on available balance.
Metered usage
Track and invoice customers based on actual usage, ideal for pay-as-you-go models.
Per-seat
Charge customers based on user count, perfect for teams or organizations with varying members.
Webhooks
Handle webhooks from your billing provider and manage payment statuses.
B2C vs B2B
TurboStarter supports B2B billing by treating either a user or an organization as the billing reference.
In practice, this means:
- a personal account can be the customer for self-serve B2C billing
- an organization can be the customer for B2B team billing
- checkout, billing portal access, summaries, and usage queries all work against the selected
referenceId
When a user starts checkout on behalf of an organization, the kit creates or reuses a provider customer linked to that organization reference. Billing data is then stored and queried through that organization rather than the individual user.
This works especially well for SaaS products where:
- teams share one workspace
- the organization pays the invoice
- owners and admins manage upgrades and billing settings
- usage, seats, or credits belong to the organization
B2B billing is not limited to per-seat pricing
Organization billing works for flat subscriptions, one-time purchases, metered billing, credits-based systems, and per-seat pricing. Per-seat is just one pricing model that builds on the same organization billing foundation.
Organization billing is also permission-aware. In the current setup, billing actions performed for an organization are checked against organization billing permissions, so members can view billing while admins and owners can manage it according to their role.
Fetching customer status
After your user completes checkout, you'll often want to fetch their current billing summary (subscription status, orders, current plan) to:
- gate features in your UI
- show “Current plan” / “Manage subscription” states
- keep the app in sync after upgrades/downgrades
You can do this via the billing summary endpoint (/api/billing/summary) using the web API client.
Server-side
import { handle } from "@workspace/api/utils";
import { getActivePlan } from "@workspace/billing";
import { api } from "~/lib/api/server";
export default async function BillingStatus() {
const summary = await handle(api.billing.summary.$get)();
const plan = getActivePlan(summary);
return <p>Current plan: {plan}</p>;
}Client-side
"use client";
import { useQuery } from "@tanstack/react-query";
import { handle } from "@workspace/api/utils";
import { getActivePlan } from "@workspace/billing";
import { api } from "~/lib/api/client";
export function BillingStatus() {
const summary = useQuery({
queryKey: ["billing", "summary"],
queryFn: () => handle(api.billing.summary.$get)(),
});
if (!summary.data) {
return null;
}
const plan = getActivePlan(summary.data);
return <p>Current plan: {plan}</p>;
}In summary, TurboStarter offers a flexible and unified billing framework, allowing you to mix and match billing models and providers as needed. Each section above provides focused documentation to help you configure the approach that best suits your SaaS application's needs.
How is this guide?
Last updated on