Package Exports
- @commercengine/js
- @commercengine/js/cdn
- @commercengine/js/package.json
Readme
@commercengine/js
Embed Commerce Engine checkout in any website.
Installation
CDN (Recommended)
<script src="https://js.commercengine.com/v1.js" async></script>npm
npm install @commercengine/jsQuick Start
<script src="https://js.commercengine.com/v1.js" async></script>
<script>
window.Commercengine.onLoad = async () => {
const checkout = await Commercengine.init({
storeId: "store_xxx",
apiKey: "ak_xxx",
});
document.getElementById("cart-btn").onclick = () => checkout.openCart();
};
</script>Configuration
CheckoutConfig
interface CheckoutConfig {
// === Credentials (required) ===
storeId: string; // Your Commerce Engine Store ID
apiKey: string; // Your Commerce Engine API Key
// === Development ===
url?: string; // Direct checkout URL (local dev only)
// If provided, storeId/apiKey are optional
// === Theme ===
theme?: "light" | "dark" | "system"; // Default: "system"
// === Appearance ===
appearance?: {
zIndex?: number; // Overlay z-index. Default: 99999
};
// === Authentication ===
authMode?: "managed" | "provided"; // Default: "managed"
accessToken?: string; // Initial access token (if user logged in)
refreshToken?: string; // Initial refresh token
// === Quick Buy (add item on init) ===
quickBuy?: {
productId: string; // Product ID (required)
variantId: string | null; // Variant ID (required, null for non-variant)
quantity?: number; // Default: 1
};
sessionMode?: "continue-existing" | "force-new"; // Default: "continue-existing"
autoDetectQuickBuy?: boolean; // Auto-detect from parent URL. Default: false
// === Callbacks ===
onReady?: () => void;
onOpen?: () => void;
onClose?: () => void;
onComplete?: (order: OrderData) => void;
onCartUpdate?: (cart: CartData) => void;
onAuthChange?: (auth: AuthChangeData) => void;
}Example: Full Configuration
const checkout = await Commercengine.init({
storeId: "store_xxx",
apiKey: "ak_xxx",
theme: "dark",
appearance: {
zIndex: 100000,
},
accessToken: userSession?.accessToken,
refreshToken: userSession?.refreshToken,
onReady: () => {
console.log("Checkout loaded");
},
onComplete: (order) => {
window.location.href = `/thank-you?order=${order.orderNumber}`;
},
onCartUpdate: (cart) => {
updateCartBadge(cart.count);
},
onAuthChange: ({ type, accessToken }) => {
if (type === "login") {
// User logged in via checkout - sync to your auth system
saveUserSession(accessToken);
} else if (type === "logout") {
clearUserSession();
}
},
});Methods
openCart()
Open the cart drawer.
checkout.openCart();openCheckout()
Open checkout directly, bypassing cart. Use for "Buy Now" flows.
checkout.openCheckout();close()
Close the checkout overlay.
checkout.close();updateTokens(accessToken, refreshToken?)
Sync authentication state from parent site. Call when user logs in/out on your site.
// When user logs in on your site
checkout.updateTokens(session.accessToken, session.refreshToken);
// When user logs out
checkout.updateTokens("", "");addToCart(productId, variantId, quantity?)
Add an item to cart and open the cart drawer. This is the canonical implementation of "quick buy" functionality.
// Add a product (non-variant)
checkout.addToCart("prod_123", null, 1);
// Add a product variant
checkout.addToCart("prod_123", "var_456", 2);
// Quantity defaults to 1
checkout.addToCart("prod_123", "var_456");Parameters:
productId(string, required) - Product IDvariantId(string | null, required) - Variant ID, ornullfor non-variant productsquantity(number, optional) - Quantity to add, defaults to 1
Behavior:
- Adds item to cart and automatically opens the cart drawer
- If item already in cart: adds to existing quantity
- If item not in cart: adds new item
- If no cart exists: creates cart with the item
getCart()
Get current cart state.
const cart = checkout.getCart();
console.log(cart.count, cart.total, cart.currency);destroy()
Remove checkout iframe and cleanup event listeners.
checkout.destroy();Properties
| Property | Type | Description |
|---|---|---|
ready |
boolean |
Whether checkout is initialized and ready |
open |
boolean |
Whether checkout overlay is currently visible |
Events
Subscribe via callbacks (in config) or the event emitter.
Event Types
| Event | Callback | Data | Description |
|---|---|---|---|
ready |
onReady |
- | Checkout iframe loaded |
open |
onOpen |
- | Drawer opened |
close |
onClose |
- | All drawers closed |
complete |
onComplete |
OrderData |
Order placed successfully |
cart:updated |
onCartUpdate |
CartData |
Cart state changed |
auth:change |
onAuthChange |
AuthChangeData |
Auth state changed |
Event Data Types
interface OrderData {
id: string; // Order ID
orderNumber: string; // Human-readable order number
}
interface CartData {
count: number; // Number of items
total: number; // Subtotal amount
currency: string; // Currency code (e.g., "USD", "INR")
}
interface AuthChangeData {
type: "login" | "logout" | "refresh";
accessToken?: string; // New token (on login/refresh)
refreshToken?: string; // New refresh token
}Event Emitter API
// Subscribe
checkout.on("cart:updated", (cart) => {
console.log("Cart:", cart.count, cart.total);
});
// Subscribe once
checkout.once("complete", (order) => {
console.log("Order:", order.orderNumber);
});
// Unsubscribe
const handler = (cart) => console.log(cart);
checkout.on("cart:updated", handler);
checkout.off("cart:updated", handler);Authentication Flow
Scenario 1: User Not Logged In
User will be prompted to login within checkout (WhatsApp, Phone, or Email OTP).
const checkout = await Commercengine.init({
storeId: "store_xxx",
apiKey: "ak_xxx",
onAuthChange: ({ type, accessToken, refreshToken }) => {
if (type === "login") {
// Save tokens to your auth system
saveSession({ accessToken, refreshToken });
}
},
});Scenario 2: User Already Logged In
Pass tokens to skip login screen.
const checkout = await Commercengine.init({
storeId: "store_xxx",
apiKey: "ak_xxx",
accessToken: currentSession.accessToken,
refreshToken: currentSession.refreshToken,
});Scenario 3: Sync Auth Changes
When user logs in/out on your site, sync to checkout.
// User logs in on your site
myAuth.onLogin((session) => {
checkout.updateTokens(session.accessToken, session.refreshToken);
});
// User logs out on your site
myAuth.onLogout(() => {
checkout.updateTokens("", "");
});TypeScript
All types are exported:
import {
Commercengine,
Checkout,
type CheckoutConfig,
type CheckoutEventType,
type CartData,
type OrderData,
type AuthChangeData,
} from "@commercengine/js";URL Parameters (Advanced)
For direct iframe integration without the SDK, checkout accepts these URL parameters:
| Parameter | Description | Example |
|---|---|---|
store_id |
Store ID | store_xxx |
api_key |
API Key | ak_xxx |
mode |
Deployment mode | iframe |
parent_origin |
Parent origin for postMessage | https://brand.com |
theme |
Theme preference | light, dark |
token |
Access token | JWT string |
refresh_token |
Refresh token | JWT string |
auth_mode |
Auth management | provided, managed |
product_id |
Quick buy product | Product ID |
variant_id |
Quick buy variant | Variant ID |
qty |
Quick buy quantity | 1 |
session_mode |
Session behavior | continue-existing, force-new |
Auth Modes
managed(default): Checkout manages token lifecycle with auto-refreshprovided: Parent manages tokens. Checkout uses in-memory only, syncs changes via events
Session Modes
continue-existing(default): Add quick-buy item to existing cartforce-new: Delete existing cart and start fresh with only the quick-buy item
Note: When quick buy params are provided (via config or auto-detected), the cart drawer automatically opens once checkout is ready.
Auto-Detect Quick Buy
For ad-driven traffic, enable autoDetectQuickBuy to automatically parse quick buy params from the parent page URL:
// Ad link: https://brand.com?product_id=prod_123&variant_id=var_456&qty=2
const checkout = await Commercengine.init({
storeId: "store_xxx",
apiKey: "ak_xxx",
autoDetectQuickBuy: true, // Reads product_id, variant_id, qty from parent URL
});This allows embedded checkout to handle ad clicks natively without custom URL parsing.
URL Cleanup: When quick buy params are detected, they are automatically removed from the browser URL (using replaceState) to prevent duplicate adds on page refresh.