Displaying tax as a line item only on the checkout page — and omitting it from the cart summary, order confirmation page, and confirmation email — violates both FTC Mail, Internet, or Telephone Order Merchandise rules and EU Consumer Rights Directive 2011/83/EU Article 6, which require clear pre-payment disclosure of total costs. When the tax amount is absent from the confirmation email, customers have no documentation of what they were charged for taxes, which becomes a dispute point during returns or accounting reconciliation. A static Tax: $0.00 placeholder is worse than omission — it actively misleads the customer about their actual tax liability.
High because omitting tax from order summaries and confirmation emails violates FTC and EU consumer disclosure rules and leaves customers without the documentation required for expense reporting or dispute resolution.
Add a dynamically computed tax line to the order confirmation component in components/OrderConfirmation.tsx:
// components/OrderConfirmation.tsx
export function OrderConfirmation({ order }: { order: Order }) {
return (
<div className="order-summary">
<div className="flex justify-between">
<span>Subtotal</span>
<span>${(order.subtotal / 100).toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span>Shipping</span>
<span>${(order.shipping / 100).toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span>Tax{order.tax_jurisdiction ? ` (${order.tax_jurisdiction})` : ''}</span>
<span>${(order.tax / 100).toFixed(2)}</span>
</div>
<div className="border-t pt-2 flex justify-between font-bold">
<span>Total</span>
<span>${(order.total / 100).toFixed(2)}</span>
</div>
</div>
)
}
Mirror the same four line items (subtotal, shipping, tax, total) in the order confirmation email template. Never render a static $0.00 for tax — pull the value from the stored order record.
ID: ecommerce-shipping-tax.tax-computation.tax-breakdown-display
Severity: high
What to look for: Enumerate all order summary display locations: (1) cart summary, (2) checkout page, (3) order confirmation page, (4) confirmation email template. For each location, count the number of financial line items shown: subtotal, discount, shipping, tax, total. Report: X of 4 locations show a separate tax line item.
Pass criteria: At least 3 of 4 order summary locations display tax as a separate, clearly labeled line item (e.g., "Tax: $X.XX" or "Sales Tax (CA): $X.XX"). The tax amount must be dynamically calculated, not a static placeholder. Report even on pass: list which locations show the tax breakdown.
Fail criteria: Fewer than 3 of 4 locations display a separate tax line item, or tax is hidden/rolled into the total without breakdown, or tax line shows a static "$0.00" placeholder.
Skip (N/A) when: The business does not collect sales tax (no tax calculation logic found anywhere in the codebase).
Detail on fail: "1 of 4 order summary locations shows tax (checkout page only). Cart summary, confirmation page, and email template omit the tax line item." or "All locations show 'Tax: $0.00' as a static value — not dynamically calculated."
Remediation: Add tax breakdown to order confirmation in components/OrderConfirmation.tsx:
// components/OrderConfirmation.tsx
export function OrderConfirmation({ order }) {
return (
<div className="order-summary">
<div className="flex justify-between">
<span>Subtotal</span>
<span>${(order.subtotal / 100).toFixed(2)}</span>
</div>
<div className="flex justify-between">
<span>Shipping</span>
<span>${(order.shipping / 100).toFixed(2)}</span>
</div>
<div className="flex justify-between font-semibold">
<span>Tax ({order.tax_jurisdiction})</span>
<span>${(order.tax / 100).toFixed(2)}</span>
</div>
<div className="border-t pt-2 flex justify-between font-bold">
<span>Total</span>
<span>${(order.total / 100).toFixed(2)}</span>
</div>
</div>
)
}