Skip to content
Guides

Checkout

Use the framework-generated checkout and understand its actual requirements.

Last updated:

The framework already generates these routes:

  • /checkout/ redirects to /cart.
  • /checkout/:checkoutId renders the purchase flow.
  • /thank-you renders the confirmation.

Do not create pages/checkout.* or pages/thank-you.tsx; those routes are reserved.

Requirements

Checkout uses useCart (and the customer session when applicable). Your layout must mount CartProvider:

layout.tsx
import { CartProvider, defineLayout } from "@ecomiq/storefront";

export default defineLayout(({ children, settings }) => (
  <CartProvider
    storeId={settings.store.id}
    currencyCode={settings.store.currency}
  >
    {children}
  </CartProvider>
));

You do not need AuthProvider or lib/auth* files: the framework already handles customer authentication.

Send the shopper to checkout

pages/checkout.tsx
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:

lib/checkout.ts
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.

On this page