Checkout & payments
Terms & Conditions Checkbox
Generated from docs/plan/core/terms-conditions-checkbox/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
Merchants need customers to accept terms before checkout. This core feature adds a mandatory checkbox and prevents order placement if unchecked.
The problem
Without terms acceptance, I have no legal protection against disputes. Customers must accept my terms of service and return policy before I process their order.
What it does
- Checkbox in checkout form: ‘I agree to the Terms & Conditions’
- Link to full terms (theme-defined URL or inline modal)
- Validation: order is rejected if checkbox is unchecked
- Record: store on Order that customer accepted terms (and timestamp, for legal proof)
- Customizable text: merchant can change the checkbox label via theme settings
- Multiple checkboxes: allow merchant to add privacy policy, newsletter consent, etc. (per theme)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Legal template generation — merchants are responsible for their own legal terms. AstroBaaS does not provide template terms.
- Versioning or acceptance history — core just records that terms were accepted, not which version or when they changed.
Data model
Add to Order: terms_accepted (boolean, required; absent on orders created before this feature means accept without recording), privacy_accepted (boolean, optional; for GDPR consent). Both are frozen at checkout; retroactive changes are not possible.
API
- POST /api/orders — checkout. Request includes
terms_accepted: true(or false). If false, order is rejected with code ‘checkout.terms_not_accepted’. Response returnsterms_acceptedin the confirmation.
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Checkout form has checkbox; no admin interface needed.
The seam — why this is core
Core owns the Order.terms_accepted field and validation at checkout. Theme owns the checkbox HTML, label text, and link to terms.
Core owns the interface + honest checkbox; checkout compliance is infrastructure, not a per-country obligation or credential.
Dependencies
- shopping-cart → payment-status-tracking
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Unchecked: POST /api/orders with terms_accepted=false → 400 error, code ‘checkout.terms_not_accepted’
- Checked: POST /api/orders with terms_accepted=true → 201, order created, terms_accepted=true stored
- Order detail view shows ‘Customer accepted terms’ or similar confirmation
- Merchant can customize checkbox label in theme settings (e.g., ‘I agree to the Store Terms’)
Risks
Acceptance without reading: customer checks the box without reading. This is unavoidable and a limitation of legal UX; provide a link to the terms, not just a box. Recording acceptance time: if Order.created_at is the only timestamp, and merchant changes terms later, there’s ambiguity about which version the customer accepted. Solution: store the terms_accepted_at timestamp and optionally a hash of the terms version at that moment (advanced; out of scope for core). Retroactive enforcement: if a customer disputes and says ‘I never saw the terms’, having recorded acceptance is helpful but not foolproof; a lawyer’s advice is needed.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included (via apps); Magento: included |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.