Checkout
Use the framework-generated checkout and understand its actual requirements.
The framework already generates these routes:
/checkout/redirects to/cart./checkout/:checkoutIdrenders the purchase flow./thank-yourenders the confirmation.
Do not create pages/checkout.* or pages/thank-you.tsx; those routes are
reserved.
Requirements
Checkout always calls useAuth and useCart, even when the store allows guest
checkout. Your layout must mount both providers:
import { AuthProvider, CartProvider, defineLayout } from "@ecomiq/storefront";
import { authClient } from "./lib/auth-client";
export default defineLayout(({ children, settings }) => (
<AuthProvider client={authClient}>
<CartProvider
storeId={settings.store.id}
currencyCode={settings.store.currency}
>
{children}
</CartProvider>
</AuthProvider>
));You also need:
lib/auth-client.tswithcreateStorefrontAuthClient.- The
pages/api/$.tsproxy. - The
pages/api/auth.$.tshandler.
The accounts guide includes those files.
Send the shopper to checkout
import { Link, useCart } from "@ecomiq/storefront";
export function CheckoutButton() {
const { cart } = useCart();
if (!cart) return null;
return (
<Link to="/checkout/$checkoutId" params={{ checkoutId: cart.id }}>
Continue to checkout
</Link>
);
}Checkout reads settings.store.checkoutSettings.general.allowGuestCheckout.
If guest checkout is disabled and no session exists, it redirects to
/login?redirect=/checkout/{id}. You must create the /login and /register
pages.
Low-level API
For an alternative flow, serverApi exposes the real operations. Each receives
one object that includes cartId:
await serverApi.patchCartBuyer({
cartId,
email: "andrea@example.com",
firstName: "Andrea",
lastName: "Ramos",
phone: "+1 555 0100",
});
const shipping = await serverApi.getShippingOptions({
cartId,
postalCode: "10001",
});
const rate = shipping.groups[0]?.rates[0];
if (rate) {
await serverApi.putCartShippingMethod({
cartId,
rateId: rate.rateId,
shippingMethodId: rate.shippingMethodId,
});
}
const result = await serverApi.checkoutCart({
cartId,
paymentMethodCode: "bank_transfer",
externalRef: crypto.randomUUID(),
});getCartCheckout, patchCartAddresses, uploadPaymentReceipt,
addCartPromotionCode, and removeCartPromotionCode are also available.
Stripe and Mercado Pago
The included UI opens a redirect URL when returned by the API and supports
manual receipts. It does not yet mount an embedded Stripe or Mercado Pago UI
when the provider returns only a clientSecret. Test the selected payment
method end to end before publishing.