Tax & Compliance
What it is, and what it is not
| It does | It does not |
|---|---|
| Recompute what tax should have been charged | Set the tax charged at checkout |
| Reconcile that against what Shopify collected | Override Shopify's tax settings |
| Track registrations, exemptions and rate overrides | File on your behalf without your explicit action |
| Produce statutory returns and accountant exports | Replace your accountant |
| Monitor economic-nexus thresholds | Give tax advice |
The distinction matters. Changing checkout tax requires Shopify's restricted Tax Calculation API and is deliberately out of scope. What this gives you instead is the thing most stores lack entirely: an independent second opinion on whether the tax you collected was right, computed from your own registrations and rate rules rather than from Shopify's defaults.
The nine tabs
| Tab | What it is for |
|---|---|
| Overview | Period KPIs, action centre, nexus watch and data readiness |
| Calculator | Compute a supply without persisting it — for checking a rule |
| Reconciliation | The worklist of discrepancies between computed and collected |
| Filing & close | The obligation calendar, period close and statutory exports |
| Registrations & nexus | Your tax IDs per jurisdiction, and threshold monitoring |
| Exemptions | Exemption and reverse-charge certificates |
| Rates & rules | Effective-dated rate overrides and product tax classes |
| Audit | Every mutation, with the actor |
| Settings | Provider, tolerance, FX and engine configuration |
Supported regimes
| Regime | Coverage | Notes |
|---|---|---|
| India GST | CGST + SGST for intra-state, IGST for inter-state | Place of supply from the buyer's state; GSTIN checksum validated |
| EU VAT | 27 member states | OSS and reverse charge; per-state standard and reduced rates |
| UK VAT | Standard, reduced, zero | Import VAT threshold on consignments at or below £135 |
| US sales tax | Destination-based, nexus-gated | State defaults offline; county, city and special-district rates come from the tax provider |
| Canada | GST, HST, PST and QST by province | Destination-based |
| APAC GST | Australia, Singapore, New Zealand | Single-rate GST with per-country registration thresholds |
Adding a regime is a plugin, not a rewrite. Each implements the same interface — resolve the supply, determine the rate, build the tax components, apply rounding — so the rest of the engine is unchanged.
How rates are resolved
Rates come from three layers, in order:
- Your effective-dated overrides. A rate you enter with a start date wins for supplies on or after that date.
- The tax provider. For US local rates — county, city, special district — where a static table cannot be correct.
- Statutory defaults. Baked-in rates per regime as a fallback.
This is why a rate change is normally a dated override rather than a support ticket: your override is the top layer and takes effect from the date you set.
The provider layer is metered — a TTL cache, a daily spend cap and a circuit breaker — so a provider outage degrades to the statutory default with the result flagged as approximate, rather than failing the computation.
Computation is idempotent
Each computation is keyed by a hash over its canonical inputs plus the engine version and the rate epoch. The same order, computed twice, produces the same immutable record rather than a second row.
Two consequences worth knowing:
- Redelivered webhooks are safe. Shopify redelivers on any non-2xx, and a redelivery cannot double-count.
- Descriptive fields do not affect the key. Buyer name, customer ID and email are carried on the computation for reporting but deliberately excluded from the hash — enriching an order with a name must not spawn a duplicate computation.
Money is computed in decimal throughout. Component splits assign the rounding residue to the last component, so the components always sum exactly to the total, and a violated invariant fails closed rather than being written.
Multi-currency
Every headline number is normalised to a reporting currency you pick at the top of the page, and period KPIs are computed from FX-anchored columns.
You cannot sum mixed currencies. A store selling in five currencies whose dashboard adds the raw amounts produces a number that is not wrong by a percentage — it is meaningless. Every aggregate here runs against a normalised anchor, and when a rate is unavailable the row is reported as unanchored rather than silently included at the wrong scale.
When a filing period is finalised, its FX rates are snapshotted, so regenerating a return next year reproduces the same figures.
Getting data in
| Source | When |
|---|---|
| Order webhooks | Live — orders and refunds compute as they happen |
| Historical backfill | On demand, per period, from the Filing tab |
| Refunds | Credit notes compute as negative amounts |
A period before you installed the app is structurally empty until you backfill it. The Filing tab's Import orders for this period action fetches the period's orders and runs them through the same pipeline, skipping any already computed — so it is safe to re-run and cannot double-count.
Permissions
Tax is governed by its own permission set, all at Pro and above:
| Permission | Grants |
|---|---|
tax:read:all | View dashboards, reconciliation and reports |
tax:compute:run | Run and re-run computations, backfill periods |
tax:reconcile:resolve / :assign / :approve / :suppress | The reconciliation workflow |
tax:rates:manage | Rate tables and product tax classes |
tax:registration:manage | Registrations |
tax:exemption:manage | Exemption and reverse-charge certificates |
tax:report:generate / :finalize | Generate exports; close a period |
tax:filing:manage / :review | Record filings and payments; accountant review |
tax:filing:submit / :approve / :sign | Direct e-filing — maker, checker and signatory |
tax:settings:manage | Engine configuration |
Several actions enforce separation of duties on identity, not merely on permission: the person who finalises a period cannot be the person who prepared it, and the person who approves a filing cannot be the one who staged it. Holding both permissions is not a way around it.
Plan tiers
| Capability | Free | Starter | Pro | Agency | Enterprise |
|---|---|---|---|---|---|
| Everything in Tax & Compliance | — | — | ✓ | ✓ | ✓ |
The whole engine sits at Pro. Individual capabilities are then governed by the permission set above, so a Pro store can give its bookkeeper reconciliation access without giving them the ability to close a period.
Best practices
- Enter your registrations first. The engine cannot tell you what you owe in a jurisdiction it does not know you are registered in — supplies there resolve as unregistered.
- Set the reporting currency once and leave it. Comparing periods across different reporting currencies defeats the point.
- Backfill the periods you still need to file before generating a return.
- Fix the cause, not the row. A cluster of "not charged" verdicts is usually one unmapped product tax class.
- Treat every figure as a draft until your accountant has seen it. This is a reporting aid; the filer of record is you.
See also
- Registrations & nexus — tax IDs, thresholds and the nexus watch
- Reconciliation — the discrepancy worklist and how verdicts work
- Filing & close — obligations, period close and statutory exports
- Direct GSTN e-filing — filing GSTR-1 and GSTR-3B without leaving the app
- Markets & currency — where your selling currencies are configured