# Cart displays accurate item count and subtotal

- **Pattern:** `ab-001096` (`ecommerce-cart-ux.cart-management.cart-totals`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001096
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001096)

## Why it matters

A cart that displays the wrong item count or a subtotal that double-counts tax erodes purchase confidence at the exact moment it matters most. ISO 25010:2011 functional correctness requires that computed outputs match specifications — a subtotal inflated by tax inclusion makes the cart total contradict the checkout total, producing customer support tickets, chargebacks, and cart abandonment. CWE-20 (Improper Input Validation) also applies when reduction logic operates on unvalidated price data that can produce negative or overflow subtotals.

## Severity rationale

Low because incorrect totals are visible to users before payment and do not expose sensitive data, but they erode trust and cause measurable abandonment.

## Remediation

Fix the total calculation in `src/components/CartSummary.tsx` to derive count from quantity sums and subtotal from line item products only — never include tax in the reduce:

```tsx
// src/components/CartSummary.tsx
const itemCount = items.reduce((sum, item) => sum + item.quantity, 0)
const subtotal = items.reduce((sum, item) => sum + (item.price * item.quantity), 0)
```

If totals are displayed in more than one location (header badge, drawer, cart page), drive all of them from a single shared selector or context value so a quantity update in one location propagates everywhere without a page reload.

## Detection

- **ID:** `cart-totals`
- **Severity:** `low`
- **What to look for:** Count all locations where cart totals are displayed (cart page, cart sidebar/drawer, header badge, checkout summary). For each location, verify: (a) item count equals the sum of all line item quantities, (b) subtotal equals the sum of (unit price x quantity) for each item. Quote the calculation code — e.g., `items.reduce((sum, item) => sum + item.quantity, 0)` in `src/components/CartSummary.tsx`. Check that totals update reactively when items change without requiring a page reload.
- **Pass criteria:** Cart displays correct count (sum of quantities) and correct subtotal (sum of line item totals) in at least 1 location. Totals update in real-time as items are added, removed, or updated. No more than 0 display locations should show stale or incorrect totals. Report the count: "X total-display locations found, all X show accurate values."
- **Fail criteria:** Displayed count or subtotal does not match actual items (e.g., shows 3 items but cart has 5, or subtotal double-counts tax).
- **Skip (N/A) when:** Cart UI does not display a count or subtotal anywhere (no header badge, no cart summary component).
- **Detail on fail:** Example: `"Cart shows '3 items' but contains 5 items. Subtotal calculation in src/components/CartSummary.tsx line 8 includes tax in the reduce, double-counting. 1 of 2 display locations shows incorrect totals."`
- **Cross-reference:** For the pre-payment order summary accuracy, see the pre-payment-review check in the Checkout Flow category.
- **Remediation:** Fix total calculations in your cart summary, typically at `src/components/CartSummary.tsx`:

  ```tsx
  // src/components/CartSummary.tsx
  function CartSummary({ items }) {
    const itemCount = items.reduce((sum, item) => sum + item.quantity, 0)
    const subtotal = items.reduce((sum, item) => sum + (item.price * item.quantity), 0)

    return (
      <div>
        <p>Items: {itemCount}</p>
        <p>Subtotal: ${(subtotal / 100).toFixed(2)}</p>
      </div>
    )
  }
  ```

## External references

- cwe CWE-20
- iso-25010 functional-suitability.functional-correctness

Taxons: data-integrity, user-experience

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