You do not need to use a Shoppex theme or a Shoppex storefront domain as the customer-facing surface. Everything here is reachable from a plain Next.js, Nuxt, SvelteKit, Astro, Remix, React Native, or native mobile app.
When to go headless
- You already have a brand site — you run a marketing site, landing pages, or an app. You want checkout, invoices, and licenses without redesigning around a theme.
- You want custom UX — your storefront is part of a larger product. Examples include a Discord bot UI, a SaaS paywall, a mobile app, or an internal admin tool. A hosted shop does not fit.
- You want API-first automation — you generate catalog entries, licenses, or orders programmatically and want the frontend to stay thin.
- You ship to native clients — you need commerce inside iOS, Android, or Electron apps where a hosted web checkout is not ideal.
What you keep, what Shoppex runs
Pick your integration shape
Dev API
Server-to-server. Bearer API keys or OAuth2. Full control over catalog, orders, customers, licenses, subscriptions, webhooks.
Storefront SDK
Browser-side reads plus hosted-checkout redirect. Good fit for SPAs and SSR storefronts.
Checkout Embed SDK
Drop-in modal checkout on any existing site with one script tag.
Headless Checkout SDK
Build your own checkout UI with a publishable key while Shoppex handles payment sessions.
Decision tree
1
Do you need to read catalog or orders from a backend?
Use the Dev API with
@shoppexio/sdk (Node, Python, PHP) or plain HTTP.2
Do you need product, cart, or page data in the browser?
Use the Storefront SDK (
@shoppexio/storefront) for public read endpoints and hosted-checkout redirect.3
Do you only need a buy button on an existing page?
Use the Checkout Embed SDK — drop one script tag, add
data-shoppex-* attributes, done.4
Do you need to build the checkout UI itself?
Use the Headless Checkout SDK (
@shoppexio/checkout-js/headless) with a dashboard-generated publishable key and allowed origins.5
Do you mix all three?
That is the normal case. Dev API for server workflows, Storefront SDK for browser reads, Embed SDK for buy buttons.
If you are unsure which to pick, start with the Next.js quickstart. It builds a custom storefront in Next.js 16 in under 15 minutes. For a working foundation instead of building from scratch, use the Storefront Starter.
Reference setups
Three shapes cover almost every headless build. Every one of them uses the same three pipes: reads through the Storefront SDK or Dev API, checkout through a hosted session or the Embed SDK, and signed webhooks back to your server.Setup A — pure SPA (React / Vue / Svelte / Astro Islands)
Best when your frontend is static or client-rendered and your only backend is your webhook receiver.
Pick this for landing pages, marketing sites, and lightweight storefronts where you do not want to run a full origin server.
Do not ship
shx_* API keys in the SPA bundle. Server-side reads need a small backend, either a worker or a Route Handler. If you need to transform data before it reaches the browser, use Setup B.
Setup B — Next.js SSR (or Nuxt / SvelteKit / Remix)
Best when you want SEO, per-request personalization, and a single deployable unit.
Pick this for any storefront where SEO matters, where you have a login, or where you serve per-customer content. The Next.js quickstart builds exactly this shape.
Server Actions and Route Handlers must be the only place you touch
SHOPPEX_API_KEY. Wrap your SDK client in import 'server-only'. Next.js 16 request APIs are async, so use await cookies(), await headers(), await params, and await searchParams. Use constant-time signature comparison (timingSafeEqual) in your webhook route.
Setup C — mobile and backend-for-frontend
Best for native iOS, Android, React Native, or Electron apps, and for any client that must not hold long-lived API keys.
The app sends its own session token to your BFF, the BFF creates the payment with the Dev API, and the app opens the hosted checkout URL in the system browser. Shoppex redirects the buyer back to your app and sends the signed webhook to your BFF, so your backend holds the final source of truth.
Use a universal link or app link as
return_url so the operating system hands control back to your app cleanly. Never bundle the shx_* key in the app binary — always route through your BFF.
Data flow per checkout stage
Server-side cart state is not required for any of these setups today. Carts live in your frontend (local state, cookie, or your own database) until you create the payment session.
Authentication
Which side holds the key depends on the setup. In Setup A it is the worker or small backend, in Setup B the Server Components and Route Handlers, and in Setup C the BFF only.
Customer OTP (
/v1/customer/auth/otp/request and /verify) works as a drop-in auth for Setup A. Setup B and C usually keep their own auth and use Shoppex for commerce only. For headless frontends, pass an optional redirect_url on /v1/customer/auth/otp/request. The URL is validated against the shop’s allowed callback hosts (<slug>.myshoppex.io or any enabled custom domain) and returned on a successful /verify response. Invalid or disallowed hosts are rejected with 400.
Package names are intentionally separate: use
@shoppexio/storefront in customer-facing browser and headless code, and use @shoppexio/sdk only in trusted backend code that talks to the Developer API.Webhooks and idempotency
Your backend receives signed events after state changes:order:created,order:paid,order:cancelled,order:disputedproduct:created,product:edited,product:stock,product:dynamicsubscription:created,subscription:renewed,subscription:cancelled,subscription:trial:started,subscription:trial:ended,subscription:upcomingquery:created,query:replied,feedback:received,affiliate:payout_requested
:product variants (for example order:paid:product) when you need full product payloads. For paid purchases that reduce stock, handle order:paid:product. Use product:stock for direct catalog stock edits. New handlers must verify the timestamped X-Shoppex-Signature-V2 header.
All three setups share the same reliability rules:
- Send
Idempotency-Keyon every mutating Dev API call. A UUID v4 is fine. Shoppex stores the response for 24 hours and replays it on retry. - Make webhook handlers idempotent. Shoppex retries on non-2xx. Use the event’s
data.uniqidandeventtuple as your deduplication key. - Acknowledge webhooks fast. Queue heavy fulfillment work and return 2xx within a few seconds.
DYNAMIC products.