Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.shoppex.io/llms.txt

Use this file to discover all available pages before exploring further.

You’re building a custom storefront — your own Next.js / Nuxt / React app, your own design, your own product browsing flow. You want Shoppex to handle the cart, the checkout, and the payment, without writing any of that yourself. This tutorial covers the @shoppexio/storefront SDK. By the end you’ll have a working cart and a real checkout that redirects to checkout.shoppex.io for the actual payment.

What @shoppexio/storefront does

The SDK is a thin browser-side client around Shoppex’s public storefront API. It handles:
  • Fetching products, categories, and variants from your shop.
  • Local cart state with addToCart / updateCartItem / removeFromCart.
  • Server-side cart pricing via quoteCart (taxes, discounts, totals).
  • Creating a checkout: POST to Shoppex, get back a redirect URL.
What it explicitly does not do:
  • Render any checkout UI. The actual payment happens on checkout.shoppex.io.
  • Use API keys. The SDK runs on public browser origins and is auth-less by design — Shoppex’s storefront endpoints are CORS-public and identified by the shop slug, not a key.

What you’ll need

  • A Shoppex shop. Your shop slug (the part before .shoppex.io).
  • A frontend project — anything that runs JavaScript. We’ll use Next.js for this tutorial, but the SDK works in Vite, Remix, Nuxt, plain HTML, etc.

Step 1 — Install the SDK

npm install @shoppexio/storefront
# or
bun add @shoppexio/storefront

Step 2 — Initialize

In any client-side module (use "use client" if you’re in a Next.js App Router project):
import { shoppex } from '@shoppexio/storefront';

shoppex.init('your-shop-slug');
That’s it. The SDK is now wired to your shop. If you need to point at a non-production environment, pass an options object:
shoppex.init({
  storeId: 'your-shop-slug',
  apiUrl: 'https://api.shoppex.io',          // default
  checkoutUrl: 'https://checkout.shoppex.io', // default
});

Step 3 — Fetch and render products

const products = await shoppex.getProducts();

products.forEach((p) => {
  console.log(p.title, p.price, p.id);
});
Render however you like. Each product has the fields you’d expect: id, title, description, price, currency, images, variants. For a single product detail page:
const product = await shoppex.getProduct(productId);

Step 4 — Add to cart

await shoppex.addToCart(productId, variantId, quantity);

const cart = shoppex.getCart();
// { items: [{ productId, variantId, quantity, price, ... }], total: ... }
Cart state lives in the browser (localStorage). On every change, you can re-render your cart UI. To get an authoritative total with taxes, coupons applied:
const quote = await shoppex.quoteCart({ coupon: 'BF25' });
// { subtotal, discount, tax, total, lineItems: [...] }
quoteCart calls Shoppex’s server — use it on the cart/checkout page where the buyer needs to see real totals, not on every cart modification.

Step 5 — Checkout

When the buyer is ready to pay:
const result = await shoppex.checkout({
  email: buyerEmail,         // optional but recommended for prefill
  coupon: 'BF25',            // optional
  affiliateCode: 'partner-x', // optional
  locale: 'en',              // optional
});

if (result.success) {
  window.location.href = result.redirectUrl;
}
Under the hood the SDK:
  1. POSTs your current cart to https://api.shoppex.io/v1/storefront/invoices/from-cart.
  2. Receives an invoice ID and a checkout URL of the form https://checkout.shoppex.io/invoice/{invoiceId}.
  3. Returns it to you.
You redirect the buyer there. They complete the payment on Shoppex’s hosted checkout. If you’d rather build the URL without redirecting (e.g. open in a new tab):
const url = await shoppex.buildCheckoutUrl({ email: buyerEmail });
window.open(url, '_blank');

Step 6 — Post-payment

Shoppex hosts the success and failure pages. The buyer doesn’t come back to your app by default after paying — they’re on checkout.shoppex.io looking at their order. To bring them back, you have two options:
  • Storefront-level setting — on yourshop.shoppex.io, configure a custom post-checkout redirect URL in your shop settings.
  • Per-checkout — pass success_url / cancel_url via the more advanced Developer API checkout session endpoint (see below).
For fulfillment notifications, set up a webhook (see Webhook handler in a Cloudflare Worker).

Starter project

Shoppex publishes apps/storefront-starter/ — a working Next.js 16.2 example wired with the SDK. It’s the fastest way to see the end-to-end flow in real code. Open the shoppex.config.ts, point it at your shop slug via NEXT_PUBLIC_SHOPPEX_SHOP_SLUG, and run bun dev.

What about the Developer API checkout endpoint?

The Storefront SDK uses Shoppex’s storefront API — auth-less, browser-safe, CORS-public. For server-to-server scenarios where you want Shoppex to act on a typed invoice spec, use the Developer API instead:
  • POST /dev/v1/payments — create an invoice directly.
  • POST /dev/v1/checkout/sessions — Stripe-style alias that returns { id, url }.
Both require an API key (Authorization: Bearer shx_...), and both redirect the buyer to checkout.shoppex.io/invoice/{id} for the actual payment. See the API Reference for the request/response shapes. The choice between SDK and Developer API:
  • SDK — you’re building a frontend on the buyer’s side. No server-side code. Public.
  • Developer API — you’re acting from your own backend, possibly invoicing buyers without them ever seeing a storefront (e.g. a Discord bot collecting payments, an internal admin tool generating one-off invoices).

Common pitfalls

  • No tree-shaking the SDK. It’s deliberately one client object (shoppex) so all modules share state. Don’t try to import { getCart } independently — call via the initialized client.
  • CORS errors during local dev. If you see Access-Control-Allow-Origin errors, you’re probably hitting localhost:3000 against a shop slug that doesn’t exist. Verify the slug.
  • Cart desync across tabs. The cart lives in localStorage. If a buyer has two tabs open, changes in one don’t auto-propagate to the other until they refresh.

Reference: Storefront SDK

Full method reference and types.