Storefront overview
Country-aware catalog, cart, checkout, confirmation, and account routes in Openfront E-commerce.
The built-in storefront lives under app/(storefront)/[countryCode]. Screens are in features/storefront/screens, UI in features/storefront/modules, and GraphQL calls in features/storefront/lib/data.
Country routing
proxy.ts hands storefront requests to features/storefront/middleware.ts. It loads regions and their countries, then picks a country code from the URL, the Vercel geo header, NEXT_PUBLIC_DEFAULT_REGION (default us), or the first region. Requests without a country code are redirected, so / becomes /us. While the database has no users, every page redirects to /dashboard/init.
Routes
Route under /[countryCode] | Screen | Customer journey |
|---|---|---|
/ | HomePage | Home page with store title and description |
/store | StorePage | All products, sortable by price through getProductsSortedByPrice |
/categories/[...category] | CategoryPage | Category listing |
/collections/[handle] | CollectionPage | Collection listing |
/products/[handle] | ProductPage | Product detail with options and regional price. Only published products are readable. |
/cart | CartPage | Cart lines, quantities and discount codes |
/checkout | CheckoutPage | Address, shipping method, payment, review |
/order/confirmed/[id] | OrderConfirmedPage | Confirmation. Guests use the order secretKey. |
/account (login slot) | LoginPage | Sign in and register |
/account (dashboard slot) | AccountDashboardPage | Overview |
/account/profile, /account/addresses | AccountProfilePage, AccountAddressesPage | Profile, password and saved addresses |
/account/orders, /account/orders/details/[id] | AccountOrdersPage, AccountOrderDetailsPage | Order history and detail |
/account/invoicing | AccountInvoicingPage | Business account request form, account balance, unpaid items, invoice creation and payment, customer token |
/account/invoices | AccountInvoicesPage | Paid invoices |
/account/checkout-link | inline pages | Legacy checkout link. See limitations. |
Cart identity
createActiveCart returns a signed cart proof. The storefront stores it in the _openfront_cart_id cookie (httpOnly) and sends it as the x-openfront-cart-proof header. Cart operations call assertCartAccess: a guest must present a valid proof, and a signed-in customer must own the cart. Staff with canManageOrders can read any cart. A checkout link may carry ?cart_proof=. The middleware turns it into the cookie and sends the shopper to the address step. A bare cart ID is never accepted.
Checkout workflow
createActiveCart(regionId)creates a cart in the region for the current country.- Add and change lines (
updateActiveCart,updateActiveCartLineItem) and apply discount codes (addDiscountToActiveCart,removeDiscountFromActiveCart). - Set email and addresses with
updateActiveCart. Changing them clears the payment collection. - List options with
activeCartShippingOptionsand choose one withaddActiveCartShippingMethod. - List providers with
activeCartPaymentProviders(regionId). Then callcreateActiveCartPaymentSessionsandinitiatePaymentSession. Only installed providers that are configured in the environment and linked to the cart's region can start a session. - Call
completeActiveCart(cartId, paymentSessionId). The server reserves stock and discount usage, checks the provider status, captures if needed, checks amount and currency against the cart, and creates the order with line snapshots. Each step is recorded so a retry resumes instead of charging twice. - Without a
paymentSessionId, a signed-in customer with an active business account checks out on account credit. The order is added to the account if it fits the credit limit and uses the account currency.
Limitations
- The Manual provider (
pp_system_default, shown as Cash on Delivery) is refused bycompleteActiveCart. The storefront still shows a "Place order" button for it, and that order fails. - Gift cards cannot be applied.
updateActiveCartrejectsgiftCards, even though the cart UI has gift-card display code. - The account checkout-link pages read a bare
cartIdand try to set the cart's user. Cart access rules reject a cart ID without a proof for anyone who does not own the cart, andupdateActiveCartdrops user changes. Treat that route as not working. The MCPgetCheckoutLinktool builds the same kind of URL. - Customers cannot start returns or claims from the storefront. Staff create them in the dashboard.
getMyPrivacyData,updatePrivacyPreferencesandrequestPrivacyActionexist in the API, but no storefront page calls them.
Custom storefronts
You can change the built-in storefront or build another client. Use the same cart proof header and the named cart, checkout and account operations. Do not expose provider credentials or call generic list mutations from the browser.