Checkout & payments
Order Confirmation Page
Generated from docs/plan/core/order-confirmation-page/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
After checkout, customers need to see their order number and confirmation. This core feature shows a success page with order summary, estimated delivery, and next steps.
The problem
After checkout, customers wonder if the order went through. Without a confirmation page, they check email, refresh the page, or contact support. A confirmation page closes the loop and reduces support tickets.
What it does
- Display on /checkout/success (or equivalent route, theme-defined)
- Show order number, order date, total amount, and currency
- List items ordered (product name, variant, qty, unit price, line total)
- Show customer email and billing address (no full PII if guest order)
- Estimated delivery date (calculated from shipping method, if available)
- Payment status: ‘Payment received’, ‘Payment pending’, ‘Payment failed’ (based on payment_status enum)
- Next steps: ‘You will receive a tracking link via email when your order ships’
- Link to order tracking page (optional; theme-specific)
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.
- Email receipt — that’s a separate email service (already shipped in core). The page is the fallback.
- Order editing or cancellation — too late at the confirmation page; those are admin-only. Storefront can offer a support form instead.
Data model
None. Uses existing Order model; confirmation page is a read-only view.
API
- GET /api/orders?number={order_number} — public (guest-accessible with order number, requires correct email for matching or uses short-lived token from checkout response)
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
No admin interface. Theme owns the confirmation page HTML.
The seam — why this is core
Core owns Order model and the public order lookup endpoint. Theme owns the confirmation page rendering.
Core owns the interface + honest confirmation renderer; checkout UX is infrastructure, not a support commitment or credential.
Dependencies
- shopping-cart → payment-status-tracking → order placement
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.
- Checkout succeeds; customer is redirected to /checkout/success?order=OG-1042
- Confirmation page displays order number ‘OG-1042’, date, total €125.50, and 3 items
- Payment status shows ‘Payment received’ (when payment_status=‘paid’)
- Payment status shows ‘Payment pending’ (when payment_status=‘pending’)
- Guest order: email and address shown, but no customer ID or account link
- Estimated delivery calculated: order on Sep 1, standard shipping 5 days, estimated Sep 6 shown
Risks
Information leakage: if order lookup requires only order number, anyone can guess numbers and see others’ orders. Solution: order lookup requires (order_number, email_hash) or a short-lived token from the checkout response. Token expiry: if confirmation page is only shown for 1 hour after checkout, a customer returning later needs the token to be long-lived or use (order_number + email) matching.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included; 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.