CheckboxDocs

How to make Stripe Checkout auto-renewal compliant

What Stripe Checkout shows by default for a subscription, what ROSCA and state automatic-renewal laws additionally require, and the exact Checkout Session parameters, page changes, emails and portal settings that close each gap.

Stripe Checkout is the fastest way to sell a subscription, but its default subscription page was not designed around automatic-renewal law. This guide maps each legal requirement to what Stripe shows and to the change that closes the gap. Every requirement is from Checkbox's legal catalog, with its citation.

What Stripe shows by default

For a mode: "subscription" session, Stripe's hosted page shows the product, the recurring price and interval in the order summary, a trial line when there is a trial, and a short authorization statement near the button. It does not, by default:

  • state that the subscription continues until cancelled and how to cancel;
  • ask for consent to the renewal terms with a checkbox the customer must tick;
  • make the terms conspicuous — Stripe's custom text is small and grey and you cannot restyle it.

The gaps and the fixes

RequirementCitation (examples)Stripe defaultFix
Disclose that it renews until cancelled, the price, frequency, term, trial terms and how to cancel, before billing information15 U.S.C. § 8403(1); Cal. Bus. & Prof. Code § 17602(a)(1); N.Y. Gen. Bus. Law § 527-a(1)(a)Price and interval onlycustom_text.submit.message with the full disclosure
Affirmative (express) consent to the renewal terms before charging15 U.S.C. § 8403(2); Cal. Bus. & Prof. Code § 17602(a)(2), (a)(4); N.Y. Gen. Bus. Law § 527-a(1)(b)Noneconsent_collection.terms_of_service: "required" and custom_text.terms_of_service_acceptance.message stating the terms
Clear and conspicuous, in visual proximity to the consentCal. Bus. & Prof. Code § 17601(c), § 17602(a)(1)Small grey textAlso show the set-off disclosure on your own page before the redirect
Acknowledgment the consumer can keep, with terms and how to cancelCal. Bus. & Prof. Code § 17602(a)(3); N.Y. Gen. Bus. Law § 527-a(1)(c)Stripe's receipt (no renewal terms or cancellation instructions)Send an acknowledgment from your checkout.session.completed handler
Trial-ending and renewal notices inside each state's windowCal. Bus. & Prof. Code § 17602(b); N.Y. Gen. Bus. Law § 527-a(1)(f), (h)Optional trial reminder 7 days beforeSend them on the dates from checkNoticeSchedule
Simple online cancellation15 U.S.C. § 8403(3); Cal. Bus. & Prof. Code § 17602(d); N.Y. Gen. Bus. Law § 527-a(1)(d)Customer portal, if enabledEnable cancellation in the portal and link it from the account page

The Checkout Session params

Checkbox generates the wording from your real terms and verifies it with the rules engine. Ask for it with your own params (here a 14-day trial at $19.99 a month):

Shell
cat > session.json <<'EOF'
{
  "mode": "subscription",
  "line_items": [{ "price_data": { "currency": "usd", "unit_amount": 1999, "recurring": { "interval": "month" }, "product_data": { "name": "Joybox Pro" } }, "quantity": 1 }],
  "subscription_data": { "trial_period_days": 14 },
  "success_url": "https://joybox.example/welcome"
}
EOF
checkbox check stripe-session --file session.json --merchant-name Joybox \
  --cancel-url https://joybox.example/account/cancel --offline

The correction adds:

correction.patch (abridged)
[
  { "op": "add", "path": "/consent_collection", "value": { "terms_of_service": "required" } },
  {
    "op": "add",
    "path": "/custom_text",
    "value": {
      "submit": { "message": "Your free trial lasts 14 days, then $19.99 every month. Cancel before the trial ends and you won't be charged. Your Joybox subscription automatically renews every month at $19.99 (plus applicable taxes) until you cancel. You can cancel anytime online at https://joybox.example/account/cancel; …" },
      "terms_of_service_acceptance": { "message": "I agree that after my 14-day free trial, my Joybox subscription renews automatically every month at $19.99 (plus applicable taxes) until I cancel, and I understand I can cancel anytime online at https://joybox.example/account/cancel." }
    }
  }
]

consent_collection.terms_of_service requires a Terms of Service URL in your Stripe settings (Dashboard → Settings → Public details).

Why one check stays "needs review"

Even with the params above, Checkbox reports signup.disclosure.conspicuous as needs_review on any Stripe-hosted page: whether text is clear and conspicuous depends on its size, contrast and setting-off, and Stripe renders custom text in its own small grey style. California defines "clear and conspicuous" as larger type, contrasting type, font or color, or text set off by symbols — legible is not enough (Cal. Bus. & Prof. Code § 17601(c)). The robust fix is to show the same disclosure on your own page, next to the button that starts checkout, set off in a box at body size or larger. Checkbox Elements renders exactly that.

After checkout

  • Acknowledgment: Stripe's receipt does not restate the renewal terms or how to cancel. Send your own from the checkout.session.completed webhook; check the template with checkEmail (kind: "acknowledgment").
  • Reminders: get the dates for your plan from checkNoticeSchedule.
  • Cancellation: enable cancellation in the customer portal or use the hosted cancellation page.
  • Prove it end to end: a test subscription runs the whole lifecycle in Stripe test mode with a test clock.

Do it with your coding agent

Prompt
Make our Stripe Checkout subscription flow compliant with automatic-renewal laws using Checkbox
(https://checkbox.site/docs/learn/stripe-checkout-auto-renewal-compliance.md). Preflight the exact params we pass to
stripe.checkout.sessions.create with `checkbox check stripe-session --json`, apply correction.patch, add the
disclosure on our pricing page with <checkbox-disclosure>, and send an acknowledgment email from our
checkout.session.completed handler. Re-check until everything passes or only needs_review items remain.

Checkbox is compliance software, not a law firm; nothing in these docs is legal advice (details). For AI agents: every page is available as Markdown at the same URL plus .md; the index is /llms.txt.