# Pre-selected add-ons clearly labeled with cost and easy to deselect

- **Pattern:** `ab-001490` (`ftc-consumer-protection.dark-patterns.pre-checked-upsells-labeled`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001490
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001490)

## Why it matters

Pre-checked paid add-ons where the cost is only visible in the order total — not adjacent to the checkbox — are identified in the FTC's Dark Patterns Report as a manipulative checkout pattern. The Negative Option Rule also applies when a pre-checked add-on carries a recurring charge. Pre-checked marketing opt-ins at checkout additionally violate GDPR consent requirements for EU users and the CAN-SPAM Act's opt-in standards. These patterns collectively drive consumer complaints, chargebacks, and regulator attention across multiple frameworks.

## Severity rationale

Low because discovering a pre-checked add-on requires active user attention during checkout rather than post-purchase, reducing immediate harm — but the pattern is explicitly called out in the FTC Dark Patterns Report and compounds with Negative Option Rule exposure for recurring charges.

## Remediation

Label all pre-selected add-ons with their cost immediately adjacent to the checkbox, and default marketing opt-ins to unchecked.

```tsx
function AddOnOption({
  label, price, interval, defaultChecked = false, onChange
}: AddOnProps) {
  const [selected, setSelected] = useState(defaultChecked)

  return (
    <label className="flex items-start gap-3 cursor-pointer">
      <input
        type="checkbox"
        checked={selected}
        onChange={e => { setSelected(e.target.checked); onChange?.(e.target.checked) }}
        className="mt-1"
      />
      <div>
        <span className="font-medium">{label}</span>
        {/* Cost must appear adjacent to the checkbox — not only in the order total */}
        <span className="text-sm text-gray-600 ml-2">+${price}/{interval}</span>
        {defaultChecked && (
          <span className="text-xs text-amber-600 ml-2">
            (pre-selected — uncheck to remove)
          </span>
        )}
      </div>
    </label>
  )
}
```

For annual billing as default: show 'Billed as $288/year' prominently next to the option — not just the per-month equivalent. Marketing opt-ins must default to unchecked in all checkout flows.

## Detection

- **ID:** `pre-checked-upsells-labeled`
- **Severity:** `low`
- **What to look for:** Count all relevant instances and enumerate each. Examine checkout forms and multi-step purchase flows for pre-selected checkboxes or toggles that add cost. Look for: (1) add-on products or services that are checked by default and add to the purchase total; (2) optional insurance, warranty, or protection plans that are selected by default; (3) plan upgrades that are pre-selected with a note that the user must "downgrade" to a cheaper tier; (4) annual billing selected by default when monthly is also available (acceptable if clearly labeled, problematic if the default's annual cost is not immediately visible). Also look for "opt-out" consent for marketing subscriptions pre-checked in checkout forms — this is both a dark pattern and a GDPR violation for EU users.
- **Pass criteria:** Add-ons that increase the purchase price are either not pre-selected, or are clearly labeled with their cost immediately adjacent to the checkbox/toggle. At least 1 implementation must be verified. Deselecting them is trivially easy (one click). Marketing email opt-ins are not pre-checked. Annual billing as default is acceptable if the annual total is prominently shown alongside the checkbox.
- **Fail criteria:** Optional paid add-ons are pre-checked with no visible cost label adjacent to the checkbox. The cost increase from a pre-selected add-on is only visible in the order total, not next to the checkbox. Marketing opt-in is pre-checked at checkout.
- **Skip (N/A) when:** The application has no checkout flow, no add-ons, and no optional paid features.
- **Detail on fail:** Example: `"Checkout form pre-checks 'Priority Support' add-on (+$10/month) with no cost shown next to the checkbox. Cost is only visible in the order total."` or `"Annual billing plan pre-selected by default; the $288/year charge is not shown until the final confirmation step."` or `"Marketing newsletter opt-in checkbox is pre-checked at checkout."`
- **Remediation:** Label all pre-selected items with their cost and make deselection obvious:

  ```tsx
  // Pre-selected add-on — with clear cost label
  function AddOnOption({
    label,
    price,
    interval,
    defaultChecked = false,
    onChange,
  }: AddOnProps) {
    const [selected, setSelected] = useState(defaultChecked)

    return (
      <label className="flex items-start gap-3 cursor-pointer">
        <input
          type="checkbox"
          checked={selected}
          onChange={e => {
            setSelected(e.target.checked)
            onChange?.(e.target.checked)
          }}
          className="mt-1"
        />
        <div>
          <span className="font-medium">{label}</span>
          {/* Cost must be immediately adjacent to the checkbox */}
          <span className="text-sm text-gray-600 ml-2">
            +${price}/{interval}
          </span>
          {defaultChecked && (
            <span className="text-xs text-amber-600 ml-2">
              (included by default — uncheck to remove)
            </span>
          )}
        </div>
      </label>
    )
  }
  ```

  If annual billing is the default, show the annual total prominently: "Billed as $288/year" — not just the monthly equivalent. Marketing opt-ins should always default to unchecked in the checkout flow.

---

## External references

- external ftc-dark-patterns-report — https://www.ftc.gov/reports/bringing-dark-patterns-light
- external ftc-negative-option-rule — https://www.ftc.gov/legal-library/browse/rules/negative-option-rule

Taxons: regulatory-conformance, user-experience

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