Billing
Use your web billing setup to unlock extension features.
For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
Billing for the browser extension is intentionally handled through the web app, not inside the extension UI itself.
That means the usual flow is:
- a user upgrades or purchases a plan in the web app
- TurboStarter syncs that billing data through the shared billing system
- the extension reads the current billing summary and unlocks features accordingly
This keeps checkout, billing portals, invoices, and provider-specific flows in the web app, while the extension only needs to react to the user's current billing state.
Extension capabilities
The extension does not create checkout sessions or host pricing tables. Instead, it reads billing state from the shared API and uses that data to:
- show the current plan
- gate premium features
- decide whether a user or organization has access
- link users back to the web dashboard when they need to upgrade
If your app supports organizations, billing in the extension can also be organization-aware.
Fetching customer data
When your user has purchased a plan from your landing page or web app, you can easily fetch their data using the API.
To do so, just invoke the summary query on the billing router to get the summary of the user's billing data:
import { getActivePlan } from "@workspace/billing";
import { api } from "~/lib/api";
export default function CustomerScreen() {
const summary = useQuery({
queryKey: ["summary"],
queryFn: handle(api.billing.summary.$get),
});
if (summary.isLoading) {
return <p>Loading...</p>;
}
const plan = getActivePlan(summary.data);
return <p>{plan}</p>;
}You may also want to ensure that user is logged in before fetching their billing data to avoid unnecessary API calls.
import { api } from "~/lib/api";
import { authClient } from "~/lib/auth";
export const User = () => {
const session = authClient.useSession();
const summary = useQuery({
queryKey: ["summary"],
queryFn: handle(api.billing.summary.$get),
enabled: !!session.data?.user,
});
if (!session.data?.user || !summary.data) {
return null;
}
return (
<div>
<p>{session.data.user.email}</p>
<p>{summary.data.length}</p>
</div>
);
};Read more about auth in extension.
Use the right billing reference
If your extension supports both personal and organization workflows, make sure you fetch billing summary for the correct referenceId. The active organization should usually take precedence over the personal account.
How is this guide?
Last updated on