Tax computation excludes shipping costs unless jurisdiction requires shipping tax
Why it matters
Approximately 12 US states tax shipping charges; the remaining 38 do not. When shipping is always included in the taxable subtotal — or always excluded with no jurisdiction check — the store either overcharges customers in non-taxing states or under-collects tax in states like New York, Illinois, and Pennsylvania (CWE-682, ISO 25010:2011 functional correctness). The EU VAT Directive 2006/112/EC treats shipping as part of the taxable supply, applying a different rule than most US states. US state shipping taxability rules are jurisdiction-specific and cannot be flattened to a global default. When no code comment documents the shipping tax policy, the decision becomes invisible and unauditble.
Severity rationale
High because shipping tax treatment errors produce systematic over- or under-collection across every order that involves a jurisdiction with non-default shipping tax rules, compounding into audit exposure.
Remediation
Implement jurisdiction-aware shipping tax in lib/tax.ts with a documented configuration object:
// lib/tax.ts
// Source: state revenue authority rulings. Last reviewed: 2024-01.
// US states that tax shipping charges as of 2024:
const STATES_TAXING_SHIPPING = new Set(['NY', 'IL', 'PA', 'WA', 'GA', 'IN', 'TX', 'KS'])
function buildTaxableSubtotal(
items: OrderItem[],
shippingCents: number,
address: Address
): number {
const productSubtotal = items
.filter(i => !i.is_tax_exempt)
.reduce((sum, i) => sum + i.price * i.quantity, 0)
const taxShipping = address.country === 'US'
? STATES_TAXING_SHIPPING.has(address.state)
: true // EU VAT applies to shipping
return productSubtotal + (taxShipping ? shippingCents : 0)
}
Replace any global taxableSubtotal = productSubtotal + shippingCents with this function and add a comment citing the source of the jurisdiction list.
Detection
-
ID:
shipping-tax-handling -
Severity:
high -
What to look for: Before evaluating, quote the tax calculation function that computes the taxable subtotal. Classify whether shipping cost is: (1) always included in the taxable subtotal, (2) always excluded, or (3) conditionally included based on jurisdiction. If conditional, enumerate all jurisdictions that tax shipping and count the total.
-
Pass criteria: Shipping tax handling is jurisdiction-aware: either shipping is excluded from the taxable subtotal by default with a configurable list of at least 3 states where it is included (e.g., NY, IL, PA), or a tax service API handles shipping tax automatically. A code comment must document the policy.
-
Fail criteria: Shipping is always included in the taxable subtotal regardless of jurisdiction, or always excluded without any jurisdiction awareness, or no documentation exists for the shipping tax policy.
-
Skip (N/A) when: Shipping is always free (no shipping cost exists in the calculation) or the business is non-US with VAT applied to the total including shipping by default.
-
Detail on fail:
"Shipping cost of $12.99 always included in taxable subtotal for all 50 states. Shipping is only taxable in ~12 states."or"Shipping excluded from tax calculation globally — no jurisdiction-specific override for NY, IL, PA." -
Cross-reference: Related to
ecommerce-shipping-tax.regional-compliance.shipping-tax-per-jurisdiction(per-jurisdiction rules) andecommerce-shipping-tax.tax-computation.jurisdiction-detection(jurisdiction must be detected first). -
Remediation: Implement jurisdiction-aware shipping tax in
lib/tax.ts:const STATES_TAXING_SHIPPING = ['NY', 'IL', 'PA'] // example jurisdictions function calculateTax(items: OrderItem[], shipping: number, address: Address): number { let taxableSubtotal = items.reduce((sum, item) => { return sum + (item.is_tax_exempt ? 0 : item.price * item.quantity) }, 0) if (STATES_TAXING_SHIPPING.includes(address.state)) { taxableSubtotal += shipping } const rate = getTaxRate(address) return Math.round(taxableSubtotal * rate) }
External references
- cwe · CWE-682 — Incorrect Calculation
- iso-25010:2011 · functional-correctness — Functional Correctness (Functional Suitability)
- external · us-state-shipping-taxability-rules — US state-by-state shipping taxability rules — approximately 12 states tax shipping charges (NY, IL, PA, etc.); others do not
- external · eu-vat-directive-2006-112-ec — EU VAT Directive 2006/112/EC — VAT applies to shipping charges as ancillary supply
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-shipping-tax·automated