# Shipping costs are taxed appropriately per jurisdiction

- **Pattern:** `ab-001232` (`ecommerce-shipping-tax.regional-compliance.shipping-tax-per-jurisdiction`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001232
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001232)

## Why it matters

Charging sales tax on shipping in Texas (which does not tax separately-stated shipping charges) overcharges every Texas customer on every order. Exempting shipping tax in New York (which does tax it) under-collects on every New York order. US state shipping taxability rules differ by jurisdiction and cannot be flattened to a single global policy. EU VAT Directive 2006/112/EC treats shipping as part of the taxable supply for EU transactions, requiring a third distinct rule. A store with no jurisdiction-specific shipping tax configuration and no documentation of its shipping tax policy is applying an undocumented guess to every order.

## Severity rationale

Low because jurisdiction-specific shipping tax errors affect a narrower subset of orders, but systematic over- or under-collection still compounds into audit exposure as volume scales.

## Remediation

Document and enforce jurisdiction-aware shipping tax in `lib/tax.ts` with a named configuration map:

```ts
// lib/tax.ts
// US state shipping taxability — source: multistate tax commission, 2024.
// When in doubt, use a tax service API (TaxJar/Avalara) to avoid maintaining this manually.
const SHIPPING_TAX_RULES: Record<string, boolean> = {
  'US-NY': true,  // NY taxes shipping when delivered by vendor
  'US-IL': true,
  'US-PA': true,
  'US-TX': false, // TX exempts separately-stated shipping
  'US-CA': false,
  'EU':    true,  // VAT applies to shipping in EU
}

function isShippingTaxable(address: Address): boolean {
  const key = address.country === 'US'
    ? `US-${address.state}`
    : address.country === 'EU' ? 'EU' : null
  return key ? (SHIPPING_TAX_RULES[key] ?? false) : false
}
```

Reference `isShippingTaxable` inside `buildTaxableSubtotal` rather than hardcoding a global include/exclude assumption.

## Detection

- **ID:** `shipping-tax-per-jurisdiction`
- **Severity:** `low`
- **What to look for:** Enumerate all jurisdiction-specific shipping tax configurations. Count the number of jurisdictions with explicit shipping-taxable or shipping-exempt designations. Verify the configuration matches known rules (e.g., NY taxes shipping, TX does not).
- **Pass criteria:** At least 3 jurisdictions have explicit shipping tax designations (taxable or exempt) configured in a lookup table, config object, or tax service integration. The configuration is documented with a code comment explaining the source of the jurisdiction rules.
- **Fail criteria:** No jurisdiction-specific shipping tax configuration exists (shipping is either always taxed or never taxed globally), or documentation of the shipping tax policy is missing.
- **Skip (N/A) when:** Tax service (TaxJar, Avalara, Stripe Tax) handles shipping tax calculation automatically with no in-house override.
- **Detail on fail:** `"0 jurisdiction-specific shipping tax designations. Shipping excluded from tax for all states with no documentation of policy."` or `"Shipping always taxed globally but only 12 US states actually tax shipping."`
- **Remediation:** Document and enforce jurisdiction-aware shipping tax in `lib/tax.ts`:

  ```ts
  // Map jurisdiction code to whether shipping is taxable
  const JURISDICTION_SHIPPING_TAX = {
    'US-NY': true,
    'US-TX': false,
    'EU': true, // VAT applies to shipping
    'CA': true  // GST applies
  }
  ```

## External references

- external us-state-shipping-taxability-rules — https://www.taxjar.com/resources/sales-tax/taxability/shipping
- external eu-vat-directive-2006-112-ec — https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32006L0112

Taxons: regulatory-conformance, data-integrity

HTML version: https://auditbuffet.com/patterns/ab-001232
