Skip to content
BuildBase

Tax

Turn on Stripe Tax so checkouts calculate tax, collect billing addresses and tax IDs, and show tax on every invoice.

BuildBase calculates and collects tax through Stripe Tax, in your own Stripe account. With it on, every checkout asks for a billing address, lets a business enter its tax ID, and adds the tax for where the buyer is. Credit packs are taxed the same way as plans.

Stripe Tax calculates and collects. It does not register you anywhere or file anything: registrations, filing and remittance stay with you. Stripe charges its own fee for Stripe Tax on each taxed transaction; check Stripe's pricing page for the current rate.

Note

Tax on the invoice list needs @buildbase/sdk 1.0.0 or later. On 0.0.90 and earlier the invoice shows its amount as before, tax included in it.

Turning it on

  1. Activate Stripe Tax in your Stripe dashboard under Settings > Tax, and add a registration for each country or state where you collect tax. Without a registration Stripe charges no tax there.
  2. Set a default tax behaviour under Settings > Tax > Defaults: whether your prices include tax (inclusive) or have it added on top (exclusive). BuildBase publishes your prices without a tax behaviour of their own, so Stripe uses this default for every plan, seat, overage and credit pack price.
  3. Switch it on in the console under Billing > Credentials > Stripe Tax.

The switch refuses to turn on while Stripe Tax is not active in your account, and says what Stripe is still waiting for: with tax on and Stripe Tax inactive, every checkout would fail. Check Stripe setup on the same page has a Stripe Tax section that reports whether Stripe Tax is active, how many registrations you have, and whether the default tax behaviour is set.

What checkout collects

With tax on, a checkout for a plan or a credit pack:

  • requires a billing address, which Stripe Tax needs to know where the buyer is;
  • offers a tax ID field. A business enters its VAT, GST or other tax number, from Stripe's list of supported ID types. Where a valid EU VAT number makes the sale a reverse charge, the invoice shows no tax and says so;
  • saves the name, address and tax ID on the customer, so the next invoice uses them. The name the buyer types replaces the workspace name on the customer, because a tax invoice names the legal entity.

Customers change their name, billing address and tax IDs later in the billing portal (useBillingPortal), whether or not you collect tax.

Subscriptions that already exist

A subscription created before you switched tax on is not taxed until it changes. On its next plan change BuildBase turns tax on for it first, when Stripe knows where the customer is; a customer with no address stays untaxed until they have one and change plan again. The plan change itself is never refused for a missing address.

Switching tax off affects new checkouts only. Subscriptions already taxed keep being taxed; turn tax off on them in the Stripe dashboard if you need to.

Where tax shows

WhereWhat
The invoice list in workspace settings"incl. €3.78 tax" under the amount, when the invoice was taxed
invoices.list and invoices.getsubtotal, discount, tax and total beside amount_due, in the currency's smallest unit
The payment.succeeded eventsubtotal, discount and tax for every paid invoice
The credit.purchased eventsubtotal, discount and tax for a credit pack
import { formatMinorAmountIntl, useInvoices } from '@buildbase/sdk/react';

function InvoiceTotals({ workspaceId }: { workspaceId: string }) {
  const { invoices } = useInvoices(workspaceId);
  return (
    <ul>
      {invoices.map((invoice) => (
        <li key={invoice.id}>
          {invoice.number}:{' '}
          {formatMinorAmountIntl(
            invoice.total ?? invoice.amount_due,
            invoice.currency
          )}
          {invoice.tax
            ? ` (tax ${formatMinorAmountIntl(invoice.tax, invoice.currency)})`
            : ''}
        </li>
      ))}
    </ul>
  );
}

subtotal, discount, tax and total are absent on an older server, so read amount_due when they are missing.

When Stripe cannot be read

If BuildBase cannot read your tax setting when a checkout starts, the checkout is refused rather than sent out untaxed: the request answers 503 with code: 'TAX_SETTING_UNAVAILABLE' and a Retry-After header, and nothing is created or charged. The same request a few seconds later can succeed. This applies to every checkout BuildBase opens: plans, a person's own plan, credit packs and add-ons. Untaxed would not be a one-off miss: a subscription keeps the tax setting its checkout gave it for every renewal, so a customer let through once would be billed without tax from then on.

The setup check reports a key that cannot read Stripe Tax settings.

A customer marked tax-exempt in the Stripe dashboard is not taxed; BuildBase leaves that to Stripe.

Tax on what your sellers sell

Everything above is tax on your own plans and credit packs. When the people in your app sell, tax on their sales is a separate switch: Billing, Selling, Settings, Money, Tax at checkout. It is off by default, and buyers pay the price as listed. With Stripe Tax chosen, Stripe works out the tax on each checkout and adds it to what the buyer pays.

ShapeWhere Stripe Tax runsWho sets it up
MarketplaceYour Stripe account, as for your plansYou, under Settings, Tax in Stripe
StorefrontEach seller's own Stripe accountEach seller, in their Stripe account
  • When it is not ready, checkout is refused with CHECKOUT_REFUSED and the problem tax_not_ready. In the storefront shape the seller finishes Stripe Tax's settings on their account; in the marketplace shape you finish yours.
  • The order keeps tax on the order and each line, and total as charged; your fee and the seller's share are worked out on the price before tax.
  • Subscriptions, prices in parts and carts are taxed per payment, per part and per seller's share; a later part needs Stripe Tax activated on the account, or it is refused with PART_REFUSED. The details are in tax at checkout.

Which registrations to hold, and what to file, is for you and your sellers to decide with your advisers.