Supercommerce API Docs
Vendor API

Tax (Flat Provider) Module — Vendor surface

Vendor self-service for the flat tax provider — the set of inclusive tax rows (type + rate) that apply uniformly to every line on the vendor's orders. Tax computation is…

Vendor self-service for the flat tax provider — the set of inclusive tax rows (type + rate) that apply uniformly to every line on the vendor's orders. Tax computation is tax-inclusive: line unitPrice is the displayed price and the breakdown is the back-computed split. The whole flat provider is a plugin behind a neutral TAX_PORT; other providers (e.g. region-aware) would expose their own per-vendor surface.

Source: api-modules/tax-flat/src/controllers/vendor-tax-config.controller.ts.


Conventions

Authentication

Both endpoints require a Better-Auth bearer session with an active vendor.

Authorization: Bearer <session-token>

The active vendor is resolved via resolveActiveVendorId(session). Sessions missing an active vendor are rejected with 403 Forbidden. There is no platform RBAC permission — vendor users are not platform staff.

Tenant scoping

Every read and write scopes to the active vendor's id. Config is persisted via VendorSettingsService (audit row per changed key); the controller is the focused UI over the generic vendor.admin.tax settings group.

Response envelope

{
  "data": <payload>,
  "message": "Success",
  "statusCode": 200,
  "metadata": { /* optional */ }
}

Error envelope

statusCodeerrorCode examples
400BAD_REQUEST, VALIDATION_ERROR
401UNAUTHORIZED
403FORBIDDEN (no active vendor)
500INTERNAL_SERVER_ERROR

Domain types

TaxConfigLine

type TaxConfigLine = {
  type: string;                            // e.g. "CGST", "SGST", "VAT"1..50 chars trimmed
  rate: number;                            // 0..100 (percent)
};

FlatTaxConfigResponse

type FlatTaxConfigResponse = {
  taxes: TaxConfigLine[];                  // empty array = no tax applied
};

Tax config

Base path: /vendor/tax/config.

GET /vendor/tax/config — Current tax rows

Returns the rows shown in the Tax Details panel of the vendor settings UI.

Response 200FlatTaxConfigResponse.

{
  "data": {
    "taxes": [
      { "type": "CGST", "rate": 9 },
      { "type": "SGST", "rate": 9 }
    ]
  },
  "message": "Success",
  "statusCode": 200
}

Empty array (taxes: []) means the vendor has no taxes configured — orders include no tax breakdown.

Errors

StatusCodeWhen
403FORBIDDENNo active vendor on session

PATCH /vendor/tax/config — Replace tax rows

Replaces the whole list. Two distinct semantics:

BodyEffect
{} (omit taxes)List untouched; no-op
{ "taxes": [] }Explicitly clears the list — no tax applied to future orders
{ "taxes": [...] }Replaces the list with the new rows

Body

{
  "taxes": [
    { "type": "CGST", "rate": 9 },
    { "type": "SGST", "rate": 9 }
  ]
}
FieldTypeConstraints
taxesTaxConfigLine[]?Whole-list replace. Send [] to clear; omit to leave untouched
taxes[].typestringTrimmed; 1..50 chars
taxes[].ratenumber>= 0 and <= 100

The body is .strict() so unknown top-level keys are rejected at the zod layer.

Response 200 — updated FlatTaxConfigResponse.

Side effects — per-key audit rows via VendorSettingsService. The config lives in the vendor admin.tax settings group (one key per row).

Errors

StatusCodeWhen
400VALIDATION_ERRORBody fails zod (rate out of range, empty type, unknown top-level key)
403FORBIDDENNo active vendor on session

  • tax (core) — defines taxConfigLineSchema and the neutral TAX_PORT interface. The flat provider is one binding; other providers can expose their own per-vendor surface.
  • settingsvendor.admin.tax.* keys are the underlying store. The generic /vendor/settings/admin/tax endpoints can read the same rows; this controller is the focused PATCH surface.
  • order — line taxBreakdown and netAmount are computed using this config at place-order. See order.md for the order-line shape.

On this page