Add a Terms Checkbox on Shopify (Cart vs Checkout)

Quick answer: To add a terms and conditions checkbox on Shopify, put it on the cart (drawer or cart page) unless you are Plus and can add a checkout UI extension next to Pay. Shopify will not let Basic/Grow/Advanced stores "add a checkbox to the checkout page" on payment steps. A drawer tick is the workaround for slide-cart themes. It is not legally required for every store. EU digital-goods waivers often need consent at purchase, not only in a cart they abandoned. Never pre-tick. Express buttons can skip a drawer-only box. This is not legal advice.
They tap Checkout. Nothing happens. A line appears: "I agree to the Terms and Returns policy." Unticked. They tick it. Checkout opens.
That is the whole feature. Ranking apps sell the same box on the cart page. Almost none explain when the box is useless, when it is dangerous, and when Plus checkout is the real seat.
Last checked August 20, 2026. We ship this as a cart-drawer block in Oxify. We are not your counsel.
Key Takeaways
- Not universal law. Many stores rely on a linked policy at checkout. A forced tick is a choice, not a default Shopify rule.
- Non-Plus: you usually cannot add a custom checkbox on payment steps. Cart drawer or cart page is the workaround.
- Plus: Checkout UI extensions can put the box next to Pay. That is closer to "purchase" consent.
- Never pre-tick. Pre-ticked terms are how consent arguments start.
- Express / Shop Pay can skip a drawer-only box. Preview those buttons.
Do You Actually Need the Checkbox?
Search intent here is mixed: "Shopify wants me to add terms," "EU lawyer said tick the box," and "how do I stop checkout until they agree."
Split the job:
| Job | Usually enough | Often not enough |
|---|---|---|
| Show policies exist | Footer + checkout policy links Shopify already prints | Hiding policies behind a tiny link with no name |
| Prove they saw a specific version | Checkbox + store timestamp and policy URL/version on the order | A box with no log |
| EU digital goods, waive 14-day withdrawal | Consent at purchase, clear "you lose the right" text, often checkout | A cart-drawer tick they can complete then abandon |
| Age / restricted goods | Follow your market's age-gate rules (often stricter than a terms box) | One generic "I agree" |
If a lawyer in your market said you need a recorded tick, put the box as close to Pay as your plan allows. If they said "link the policies," do not add friction for SEO.
Why the Cart Drawer Became the Default Seat
Shopify Checkout Extensibility lets you add blocks on information, shipping, and payment steps — Plus only, per Shopify's checkout UI extension docs. Last checked August 20, 2026.

On Basic / Grow / Advanced you cannot drop a custom "I agree" widget on the payment step. Apps that rank for this keyword (RT Terms and Conditions Box and similar) therefore hook the cart page and write a note into order additional details.
A cart drawer is the same idea for stores that never show /cart. Most mobile shoppers never visit the cart page. If the box only lives on /cart, the drawer checkout button bypasses it.
That is the gap: cart-page apps miss drawer-first stores. Drawer checkboxes miss Shop Pay from the product page. Plus checkout blocks miss nothing except wallets that skip your block — preview those.
Cart Page vs Cart Drawer vs Checkout: Pick One Seat
| Placement | Plan needed | Catches | Misses |
|---|---|---|---|
Cart page (/cart) | Any | Desktop shoppers who visit the cart page | Drawer-first themes, Buy Now buttons, express wallets |
| Cart drawer | Any | Everyone who checks out from the slide-out — most mobile traffic | Buy Now on the product page, Shop Pay from anywhere but the drawer |
| Checkout step | Plus + Checkout Extensibility | Every path, including wallets that render your block | Wallets that skip the step your block sits on — preview each |
One more thing before you pick: checkout.liquid is dead. Shopify deprecated it and turned it off for information/shipping/payment in 2024, and August 26, 2026 is the hard cutoff for the remaining legacy checkout customizations on non-Plus plans — anything still on the old stack gets auto-upgraded and stripped. Old tutorials that say "paste this into checkout.liquid" no longer apply to anyone. Checkout customization now means Checkout UI extensions. Non-Plus stores can run app extensions on the Thank-you and Order-status pages, but blocks on information, shipping, and payment steps — where a required terms tick would live — are still Plus-only.
No-App Version: I-Agree Checkbox in Dawn Without an App
Most "shopify agree to terms checkbox without app" tutorials give you roughly this, added to sections/main-cart-footer.liquid above the checkout button:
<div class="cart__terms">
<input type="checkbox" id="agree-terms" required>
<label for="agree-terms">
I agree to the <a href="/policies/terms-of-service">Terms</a>
and <a href="/policies/refund-policy">Returns policy</a>.
</label>
</div>
<script>
document.querySelector('#checkout').addEventListener('click', function (e) {
if (!document.querySelector('#agree-terms').checked) {
e.preventDefault();
alert('Please agree to the Terms and Returns policy first.');
}
});
</script>
It works — on the cart page. Three problems the 1,200-word tutorials do not mention:
- It never reaches the drawer.
main-cart-footer.liquidrenders/cart. Dawn's slide-out iscart-drawer.liquid/cart-drawer.js— a different template with its own checkout button. Drawer-first stores that paste the cart-page snippet have a checkbox nobody ever sees. - Buy Now skips it. Dynamic checkout buttons on the product page go straight to checkout. If the checkbox must be unskippable, disable dynamic checkout buttons in the theme editor (product section → uncheck "Show dynamic checkout buttons") — and accept the conversion cost, or move the box to Plus checkout.
- An
alert()proves nothing. No record lands on the order. See the next section.
Horizon changes the map. Shopify's 2025-era Horizon theme family does not have main-cart-footer.liquid at all. The cart is built from web components (<cart-items-component> and friends) and block files under blocks/, each with its own scoped CSS and JavaScript. The Dawn snippet above has nowhere to paste. On Horizon your realistic options are a custom block a developer writes, or an app that injects into the drawer. Check which theme family you are on before you follow any 2023 tutorial: Dawn-style sections and Horizon-style blocks are different codebases.
Record the Consent, or the Box Is Theater
A checkbox that blocks a button is UX. A checkbox that writes evidence is a dispute exhibit. Chargeback teams and "the customer says they never agreed" tickets want: this person ticked this box at this time against this policy version.
The mechanism on cart surfaces is cart attributes. Post them with the tick and they land on the order under Additional details:
fetch('/cart/update.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
attributes: {
'Terms accepted': 'Yes',
'Terms accepted at': new Date().toISOString(),
'Terms version': '2026-08-20'
}
})
});
Run that when the box is ticked, before checkout fires. /cart/update.js is the documented AJAX Cart API endpoint for attributes; it merges the keys into the live cart and they carry through checkout onto the order. Two caveats: attributes belong to the cart, so they vanish if the cart is emptied or expires — they are consent for this purchase, not the account. And if the shopper unticks the box, post the attribute again with an empty string to clear it, or you will log consent that was withdrawn.
Whatever app you use, place a test order and open the order in admin: if you cannot see the timestamp and policy version under Additional details, you bought theater.
The 3-Bucket Test (What to Ask Counsel)
Before you turn the feature on, put your store in one bucket. We use this on Oxify onboarding. It is a scoping tool, not a statute.
- Link-only. Physical goods, no special waivers. Shopify policy links at checkout. No extra box. Lowest friction.
- Recorded tick. You need a timestamp, policy version, and IP or customer id on the order. Cart drawer or cart page checkbox that writes order attributes / additional details. Still preview express pay.
- Purchase-tied waiver. Digital goods, subscriptions, or a withdrawal waiver. Counsel often wants the text next to the pay button, not only in a drawer they left. Plus checkout extension or a specialist compliance app. A drawer tick alone can be the wrong artifact.
If you are in bucket 3, do not celebrate a cart checkbox as "GDPR done."
How to Add It Without Blocking Honest Buyers
- Link the named policies in the label: Terms, Returns, Privacy — not "policies."
- Leave the box unchecked.
- Block the drawer Checkout button until it is ticked. Show a one-line error, not a silent fail.
- Save to the order: checkbox true, timestamp, policy URL or version string. If the app cannot write that, the box is theater.
- Preview Shop Pay, Apple Pay, and Google Pay from the drawer and from the product page. If those skip the box, tell counsel. Either move the box to Plus checkout, add a cart-page backup, or accept the gap in writing.
- Check the box stays ticked when the cart updates. Drawers re-render on quantity change; a checkbox that resets to unticked after "+1" trains people to rage-tap. Persist the state (session storage or a cart attribute) across re-renders.
- Translate the label per market. A Spanish storefront with an English "I agree" is a worse consent record than none — put the label in your locale files or the app's per-language fields. See translating the cart drawer.
- Test on a real phone, not just responsive mode. The tap target should be the whole label row, not the 16px square.
- After two weeks, compare checkout conversion on mobile vs desktop. If mobile drops and desktop does not, the box is fighting thumbs. Shorten the label. Do not shrink the tap target.
In Oxify the terms checkbox lives in the cart drawer next to Checkout. Pair it with drawer customization so the legal line is readable, not 9px gray.

In Oxify the checkbox is a single Show terms and conditions toggle in Settings — off by default, which is the right default. Turn it on only after the 3-bucket test above says you need it.
Copy That Does Not Read Like a Trap
- Use: "I agree to the Terms and the Returns policy." Each phrase is a link.
- Skip: "I agree to everything including future changes and marketing." That is how people bounce. Marketing consent is a different checkbox. Do not bundle it.
Common Use Cases (Match the Label to the Risk)
- Refund / final-sale policy. "I understand sale items are final." The most common chargeback shield.
- GDPR / privacy notice. Link the privacy policy by name. Do not bundle marketing consent into the same tick.
- Age verification. "I confirm I am 18+." Note: many markets require a real age gate for restricted goods; a checkbox is the floor, not the ceiling.
- Import duties. "I understand international orders may incur customs fees I pay on delivery." Kills a whole ticket category for cross-border stores.
- Preorder / made-to-order lead times. "I accept the 4–6 week production time."
App Options and Pricing
If you want an app instead of theme code, the usual suspects, as listed on the App Store in August 2026 (verify before installing — pricing moves):
| App | Price (as listed Aug 2026) | Fit |
|---|---|---|
| Terms and Conditions Pro+ | From $0.99/mo, 7-day trial (no free tier) | Cart page + product page boxes, consent logging |
| Saio: Terms and Conditions | $5.99/mo, 5-day trial | Simple cart-page checkbox, quick setup |
| I Agree ‑ Terms and Conditions | $4.99/mo, 7-day trial | Cart-page tick with order-note record |
| Oxify | $9.99/mo (whole drawer suite) | The tick lives in the cart drawer, next to upsells and free-shipping bar |
Dedicated terms apps are cart-page tools first. If your theme is drawer-first, confirm the app injects into the drawer before you pay — most do not.
How This Compares to Ranking Terms Apps
RT Terms, EasySell-style roundups, and theme hacks explain a cart-page checkbox and order notes. Good for stores that use /cart.
They usually skip:
- Drawer-first themes (Dawn-style slide-out)
- The Plus vs non-Plus checkout split
- Express checkout skip
- EU digital-goods "purchase" vs "cart" consent
If your theme is drawer-first, a cart-page-only app is the wrong install. If counsel needs purchase-tied text, a drawer-only app is the wrong install.
Frequently Asked Questions
How do I add a terms and conditions checkbox on Shopify?
Can I add an I agree checkbox to Dawn without an app?
Does the Dawn snippet work on the Horizon theme?
How do I record customer consent on Shopify orders?
Can I add a checkbox to the Shopify checkout page?
Can I add a terms box on Shopify checkout without Plus?
Is a cart-drawer tick enough for EU digital goods?
Should the terms box be pre-checked?
What about Shop Pay and Apple Pay?
Does Oxify store the agreement on the order?
What to Do Next
Bucket 1: do nothing extra. Bucket 2: checkbox on the cart you actually use (drawer if that is where Checkout lives), named links, log on the order, express-pay preview. Bucket 3: counsel + Plus checkout or a compliance app.
Drawer-first stores can require the tick in Oxify Cart Drawer & Upsells next to the Checkout button, in the same bag as upsells. $9.99/mo, 14-day trial. Dedicated terms apps (RT Terms and similar) exist if you also need newsletter/contact-form boxes or claim express-checkout coverage Oxify does not advertise. Do not add a legal box just to look professional.