POS Tax Behavior
This page documents the gateway-side tax behavior a POS integration can rely on today. It is intentionally about current runtime truth, not future product direction.
Launch behavior summary
| Topic | Current behavior |
|---|---|
| Calculation surface | Public POST /api/v1/tax/calculate is live and exposed in both SDKs |
| Scoping model | Organization defaults with location-specific overrides where configured |
| SPD support | Supported |
| Sourcing model | Destination-based only |
| Negative tax rates | Rejected |
| Non-US handling | Zero-tax result in the current manual provider path |
| Category taxonomy | Free-text categories; no canonical vocabulary enforcement |
What POS should call
POS can use the normal public calculation surface:
- TypeScript:
client.taxConfig.calculate(...) - Kotlin:
client.taxConfig.calculate(...) - HTTP:
POST /api/v1/tax/calculate
That surface is appropriate for POS-side previewing or validating totals before the sale is finalized.
Current calculation rules
1. Destination-based only
The gateway calculates tax from the destination address. There is no explicit origin-based sourcing mode in the current schema or service layer.
Integration implication:
- do not assume the gateway will derive tax from the store-of-origin
- do not treat a populated
fromAddressas a signal that origin sourcing is active
If product decides origin-based tax is required later, that will need an explicit model change rather than a silent behavior switch.
2. SPD support is live
Special-purpose district (SPD) configuration is part of the current tax model and is already covered by gateway-side tests. POS does not need a separate feature flag or fallback path for SPD jurisdictions.
3. Negative rates are not accepted
The gateway rejects negative tax rates in both schema and service validation. Use discounts, credits, or promotions for rebate-like behavior rather than attempting to encode a negative tax row.
4. Non-US addresses currently return zero tax
The current manual provider path is US-only. Non-US requests do not fail, but they resolve to zero tax instead of calling an international tax engine.
Integration implication:
- if POS is expected to compute non-US tax, the current gateway result is not authoritative
- if zero-tax fallback is unacceptable for a market, treat that as a product launch blocker rather than assuming hidden support exists
5. Categories are descriptive, not canonical
appliesToCategory is currently free text. The gateway can warn about overlap
or conflict, but it does not enforce a shared product-category taxonomy.
Integration implication:
- POS may send category strings, but should not assume a centrally validated enum exists
- cross-system consistency is a process/data-governance problem today, not a gateway validation guarantee
Not promised by current gateway behavior
The following should be treated as unresolved or explicitly out of scope until the product/runtime changes:
- origin-based sourcing rules
- authoritative non-US tax calculation
- canonical product-category validation across systems
Safe launch claims
Support, solutions, and integrators can safely describe the current tax lane like this:
- the gateway exposes a live tax-calculation endpoint
- the current path is destination-based
- SPD support is available
- negative tax rows are rejected
- non-US requests currently fall back to zero tax instead of an international engine
They should not describe the current lane as:
- origin-based tax capable
- authoritative for non-US taxation
- backed by a canonical cross-system category taxonomy
Docs-side closeout checklist
Treat the tax lane as documentation-complete for #651 only if all of the
following are true:
- launch materials describe the current path as destination-based
- non-US handling is described as zero-tax fallback, not authoritative tax
- SPD support is described as live
- any remaining origin-based or taxonomy asks are tracked as product/runtime follow-ups instead of open-ended analysis work
Related docs
- Organizations and Locations — scope model for organization defaults and location overrides.
- TypeScript SDK — client examples.
- Kotlin SDK — client examples.