The FTC's updated Negative Option Rule (2024) — commonly called the Click-to-Cancel rule — explicitly requires that cancellation be 'at least as easy' as the original enrollment. A checkout that takes 2 minutes online but requires a support ticket to cancel is a per-subscriber violation. Cancellation flows with three or more confirmation screens, mandatory 'tell us why' forms, or retention specialist gatekeeping each constitute prohibited friction. Beyond FTC exposure, high-friction cancellation increases chargebacks and negative reviews from frustrated users who feel trapped.
Medium because cancellation friction must be evaluated against enrollment complexity to constitute a violation — a subscription with a complex setup might support a more involved cancellation — but online-signup products with support-ticket cancellation clearly fail the FTC's symmetry requirement.
Implement self-service cancellation completable in the account settings UI with a single confirmation step.
function CancelSubscriptionSection() {
const [confirming, setConfirming] = useState(false)
const [cancelled, setCancelled] = useState(false)
async function handleCancel() {
await fetch('/api/subscription/cancel', { method: 'POST' })
setCancelled(true)
}
if (cancelled) {
return (
<p>Subscription cancelled. Access continues until the end of
your current billing period.
</p>
)
}
return (
<div>
{!confirming ? (
<button onClick={() => setConfirming(true)}>
Cancel subscription
</button>
) : (
<div>
<p>You'll retain access until your billing period ends.
Resubscribe anytime.
</p>
{/* One counter-offer step is acceptable; more screens are not */}
<button onClick={handleCancel}>Yes, cancel</button>
<button onClick={() => setConfirming(false)}>Keep subscription</button>
</div>
)}
</div>
)
}
If a retention offer (discount, pause) is shown as one interstitial screen before the final cancel button, that is compliant. Multiple successive retention screens with no direct 'cancel now' path are not.
ID: ftc-consumer-protection.dark-patterns.cancellation-easy
Severity: medium
What to look for: Count all relevant instances and enumerate each. Map the cancellation path. Start from the user's account settings page. Count: how many clicks does it take to complete cancellation? Does the path require: (1) navigating to a non-obvious settings section; (2) calling a phone number or submitting a support ticket (when sign-up was online); (3) waiting for a response before cancellation takes effect; (4) chatting with a retention specialist who must "process" the cancellation; (5) re-entering payment information. Compare this to the signup flow: how many steps did signup take? The FTC's Negative Option Rule explicitly prohibits making cancellation substantially more difficult than enrollment. Also check for cancellation interstitials — additional screens designed to delay or prevent cancellation (counter-offers, "are you sure?" cascades with multiple confirmation steps beyond one).
Pass criteria: Cancellation can be completed entirely through the account settings UI without contacting support, in no more steps than the original signup. A single confirmation dialog (one "are you sure?" prompt) is acceptable. The cancellation takes effect immediately or at the end of the current billing period (user's choice), without delay.
Fail criteria: Cancellation requires opening a support ticket or calling a phone number when signup was entirely online. Cancellation flow has three or more confirmation screens beyond the initial request. Cancellation does not take effect immediately and requires processing time without a clear reason. Users are taken through multiple retention offers with no direct "cancel now" option on each screen.
Skip (N/A) when: The application has no subscriptions or paid recurring services — it is one-time payment or entirely free.
Detail on fail: Example: "Cancellation requires submitting a support ticket. Signup is completed online in under 2 minutes. This asymmetry is an FTC violation under the Negative Option Rule." or "Cancellation flow has 4 confirmation screens and a mandatory 'tell us why you're leaving' form before the final cancel button." or "'Cancel Subscription' button in settings opens an Intercom chat that requires speaking with a retention agent."
Remediation: Implement direct self-service cancellation:
// Self-service cancellation — one confirmation, then done
function CancelSubscriptionSection() {
const [confirming, setConfirming] = useState(false)
const [cancelled, setCancelled] = useState(false)
async function handleCancel() {
await fetch('/api/subscription/cancel', { method: 'POST' })
setCancelled(true)
}
if (cancelled) {
return (
<p>Your subscription has been cancelled. You have access until
the end of your current billing period.
</p>
)
}
return (
<div>
{!confirming ? (
<button
onClick={() => setConfirming(true)}
variant="destructive"
>
Cancel subscription
</button>
) : (
<div>
<p>Are you sure? You'll lose access at the end of your
billing period. This cannot be undone from this screen
— you can resubscribe anytime.
</p>
{/* One counter-offer is acceptable; multiple screens are not */}
<button onClick={handleCancel}>
Yes, cancel my subscription
</button>
<button onClick={() => setConfirming(false)}>
Keep my subscription
</button>
</div>
)}
</div>
)
}
The counter-offer step (showing a discount or pause option before final cancellation) is acceptable as a single screen. The user must have a clear path to complete cancellation from that screen without additional friction.