1. Scaffold with the CLI
2. Configure public values
[locationId] route.
3. Create separate browser and server clients
Browser code supplies a tab-scoped cartsessionStore and getAuthToken. Server Components create a client with the same explicit baseUrl and perform anonymous published reads only.
4. Follow the capability lifecycle
- Load published merchant, location, and menu data anonymously.
- Start an ordering session with a generated idempotency key.
- Store the returned cart capability in versioned
sessionStorage, scoped by canonical API environment, merchant, and location. - Let the SDK attach the capability,
If-Match, and idempotency headers. - On
CART_CONFLICT, reload the cart before asking the shopper to retry. - Clear the capability after claim, deletion, expiry, or terminal checkout handling.
5. Checkout
includeCustomerContext only when a signed-in shopper still has a guest
capability and the selected provider needs customer association. Omit it for
guest checkout; a claimed cart uses customer authentication automatically.
Render Square Web Payments or Stripe Elements based on payment.provider, then poll checkout.getOrderResult. Treat
payment_pending and order_pending as nonterminal; render success only for
completed; render an actionable failure for failed.
6. Customer and receipt access
Login and OTP requests must includemerchantSlug. Customer resources use the returned JWT, stored by API environment and merchant. Receipt links use a purpose-limited fragment capability: remove the fragment immediately, keep the token in tab-scoped storage keyed by API environment, merchant, and receipt ID, and pass it through receipts.get.
7. Deploy
- Configure the exact storefront origin in the API CORS allowlist.
- Keep provider and private integration credentials on the API service.
- Run tests, lint, type checking, a production build, and a static-bundle secret scan.
- Verify a real published catalog read and a sandbox ordering flow before promoting production.