@commercengine/js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +367 -0
- package/dist/index.cjs +514 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +341 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +341 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +518 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +510 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# @commercengine/js
|
|
2
|
+
|
|
3
|
+
Embed Commerce Engine checkout in any website.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### CDN (Recommended)
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<script src="https://js.commercengine.com/v1.js" async></script>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### npm
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @commercengine/js
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<script src="https://js.commercengine.com/v1.js" async></script>
|
|
23
|
+
<script>
|
|
24
|
+
window.Commercengine.onLoad = async () => {
|
|
25
|
+
const checkout = await Commercengine.init({
|
|
26
|
+
storeId: "store_xxx",
|
|
27
|
+
apiKey: "ak_xxx",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
document.getElementById("cart-btn").onclick = () => checkout.openCart();
|
|
31
|
+
};
|
|
32
|
+
</script>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
### CheckoutConfig
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
interface CheckoutConfig {
|
|
41
|
+
// === Credentials (required) ===
|
|
42
|
+
storeId: string; // Your Commerce Engine Store ID
|
|
43
|
+
apiKey: string; // Your Commerce Engine API Key
|
|
44
|
+
|
|
45
|
+
// === Development ===
|
|
46
|
+
url?: string; // Direct checkout URL (local dev only)
|
|
47
|
+
// If provided, storeId/apiKey are optional
|
|
48
|
+
|
|
49
|
+
// === Theme ===
|
|
50
|
+
theme?: "light" | "dark" | "system"; // Default: "system"
|
|
51
|
+
|
|
52
|
+
// === Appearance ===
|
|
53
|
+
appearance?: {
|
|
54
|
+
zIndex?: number; // Overlay z-index. Default: 99999
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// === Authentication ===
|
|
58
|
+
authMode?: "managed" | "provided"; // Default: "managed"
|
|
59
|
+
accessToken?: string; // Initial access token (if user logged in)
|
|
60
|
+
refreshToken?: string; // Initial refresh token
|
|
61
|
+
|
|
62
|
+
// === Quick Buy (add item on init) ===
|
|
63
|
+
quickBuy?: {
|
|
64
|
+
productId: string; // Product ID (required)
|
|
65
|
+
variantId: string | null; // Variant ID (required, null for non-variant)
|
|
66
|
+
quantity?: number; // Default: 1
|
|
67
|
+
};
|
|
68
|
+
sessionMode?: "continue-existing" | "force-new"; // Default: "continue-existing"
|
|
69
|
+
autoDetectQuickBuy?: boolean; // Auto-detect from parent URL. Default: false
|
|
70
|
+
|
|
71
|
+
// === Callbacks ===
|
|
72
|
+
onReady?: () => void;
|
|
73
|
+
onOpen?: () => void;
|
|
74
|
+
onClose?: () => void;
|
|
75
|
+
onComplete?: (order: OrderData) => void;
|
|
76
|
+
onCartUpdate?: (cart: CartData) => void;
|
|
77
|
+
onAuthChange?: (auth: AuthChangeData) => void;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Example: Full Configuration
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const checkout = await Commercengine.init({
|
|
85
|
+
storeId: "store_xxx",
|
|
86
|
+
apiKey: "ak_xxx",
|
|
87
|
+
theme: "dark",
|
|
88
|
+
appearance: {
|
|
89
|
+
zIndex: 100000,
|
|
90
|
+
},
|
|
91
|
+
accessToken: userSession?.accessToken,
|
|
92
|
+
refreshToken: userSession?.refreshToken,
|
|
93
|
+
onReady: () => {
|
|
94
|
+
console.log("Checkout loaded");
|
|
95
|
+
},
|
|
96
|
+
onComplete: (order) => {
|
|
97
|
+
window.location.href = `/thank-you?order=${order.orderNumber}`;
|
|
98
|
+
},
|
|
99
|
+
onCartUpdate: (cart) => {
|
|
100
|
+
updateCartBadge(cart.count);
|
|
101
|
+
},
|
|
102
|
+
onAuthChange: ({ type, accessToken }) => {
|
|
103
|
+
if (type === "login") {
|
|
104
|
+
// User logged in via checkout - sync to your auth system
|
|
105
|
+
saveUserSession(accessToken);
|
|
106
|
+
} else if (type === "logout") {
|
|
107
|
+
clearUserSession();
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Methods
|
|
114
|
+
|
|
115
|
+
### `openCart()`
|
|
116
|
+
|
|
117
|
+
Open the cart drawer.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
checkout.openCart();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `openCheckout()`
|
|
124
|
+
|
|
125
|
+
Open checkout directly, bypassing cart. Use for "Buy Now" flows.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
checkout.openCheckout();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `close()`
|
|
132
|
+
|
|
133
|
+
Close the checkout overlay.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
checkout.close();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `updateTokens(accessToken, refreshToken?)`
|
|
140
|
+
|
|
141
|
+
Sync authentication state from parent site. Call when user logs in/out on your site.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// When user logs in on your site
|
|
145
|
+
checkout.updateTokens(session.accessToken, session.refreshToken);
|
|
146
|
+
|
|
147
|
+
// When user logs out
|
|
148
|
+
checkout.updateTokens("", "");
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `addToCart(productId, variantId, quantity?)`
|
|
152
|
+
|
|
153
|
+
Add an item to cart and open the cart drawer. This is the canonical implementation of "quick buy" functionality.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// Add a product (non-variant)
|
|
157
|
+
checkout.addToCart("prod_123", null, 1);
|
|
158
|
+
|
|
159
|
+
// Add a product variant
|
|
160
|
+
checkout.addToCart("prod_123", "var_456", 2);
|
|
161
|
+
|
|
162
|
+
// Quantity defaults to 1
|
|
163
|
+
checkout.addToCart("prod_123", "var_456");
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Parameters:**
|
|
167
|
+
- `productId` (string, required) - Product ID
|
|
168
|
+
- `variantId` (string | null, required) - Variant ID, or `null` for non-variant products
|
|
169
|
+
- `quantity` (number, optional) - Quantity to add, defaults to 1
|
|
170
|
+
|
|
171
|
+
**Behavior:**
|
|
172
|
+
- Adds item to cart and automatically opens the cart drawer
|
|
173
|
+
- If item already in cart: adds to existing quantity
|
|
174
|
+
- If item not in cart: adds new item
|
|
175
|
+
- If no cart exists: creates cart with the item
|
|
176
|
+
|
|
177
|
+
### `getCart()`
|
|
178
|
+
|
|
179
|
+
Get current cart state.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const cart = checkout.getCart();
|
|
183
|
+
console.log(cart.count, cart.total, cart.currency);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### `destroy()`
|
|
187
|
+
|
|
188
|
+
Remove checkout iframe and cleanup event listeners.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
checkout.destroy();
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Properties
|
|
195
|
+
|
|
196
|
+
| Property | Type | Description |
|
|
197
|
+
|----------|------|-------------|
|
|
198
|
+
| `ready` | `boolean` | Whether checkout is initialized and ready |
|
|
199
|
+
| `open` | `boolean` | Whether checkout overlay is currently visible |
|
|
200
|
+
|
|
201
|
+
## Events
|
|
202
|
+
|
|
203
|
+
Subscribe via callbacks (in config) or the event emitter.
|
|
204
|
+
|
|
205
|
+
### Event Types
|
|
206
|
+
|
|
207
|
+
| Event | Callback | Data | Description |
|
|
208
|
+
|-------|----------|------|-------------|
|
|
209
|
+
| `ready` | `onReady` | - | Checkout iframe loaded |
|
|
210
|
+
| `open` | `onOpen` | - | Drawer opened |
|
|
211
|
+
| `close` | `onClose` | - | All drawers closed |
|
|
212
|
+
| `complete` | `onComplete` | `OrderData` | Order placed successfully |
|
|
213
|
+
| `cart:updated` | `onCartUpdate` | `CartData` | Cart state changed |
|
|
214
|
+
| `auth:change` | `onAuthChange` | `AuthChangeData` | Auth state changed |
|
|
215
|
+
|
|
216
|
+
### Event Data Types
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
interface OrderData {
|
|
220
|
+
id: string; // Order ID
|
|
221
|
+
orderNumber: string; // Human-readable order number
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
interface CartData {
|
|
225
|
+
count: number; // Number of items
|
|
226
|
+
total: number; // Subtotal amount
|
|
227
|
+
currency: string; // Currency code (e.g., "USD", "INR")
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface AuthChangeData {
|
|
231
|
+
type: "login" | "logout" | "refresh";
|
|
232
|
+
accessToken?: string; // New token (on login/refresh)
|
|
233
|
+
refreshToken?: string; // New refresh token
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Event Emitter API
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Subscribe
|
|
241
|
+
checkout.on("cart:updated", (cart) => {
|
|
242
|
+
console.log("Cart:", cart.count, cart.total);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
// Subscribe once
|
|
246
|
+
checkout.once("complete", (order) => {
|
|
247
|
+
console.log("Order:", order.orderNumber);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Unsubscribe
|
|
251
|
+
const handler = (cart) => console.log(cart);
|
|
252
|
+
checkout.on("cart:updated", handler);
|
|
253
|
+
checkout.off("cart:updated", handler);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Authentication Flow
|
|
257
|
+
|
|
258
|
+
### Scenario 1: User Not Logged In
|
|
259
|
+
|
|
260
|
+
User will be prompted to login within checkout (WhatsApp, Phone, or Email OTP).
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
const checkout = await Commercengine.init({
|
|
264
|
+
storeId: "store_xxx",
|
|
265
|
+
apiKey: "ak_xxx",
|
|
266
|
+
onAuthChange: ({ type, accessToken, refreshToken }) => {
|
|
267
|
+
if (type === "login") {
|
|
268
|
+
// Save tokens to your auth system
|
|
269
|
+
saveSession({ accessToken, refreshToken });
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Scenario 2: User Already Logged In
|
|
276
|
+
|
|
277
|
+
Pass tokens to skip login screen.
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const checkout = await Commercengine.init({
|
|
281
|
+
storeId: "store_xxx",
|
|
282
|
+
apiKey: "ak_xxx",
|
|
283
|
+
accessToken: currentSession.accessToken,
|
|
284
|
+
refreshToken: currentSession.refreshToken,
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Scenario 3: Sync Auth Changes
|
|
289
|
+
|
|
290
|
+
When user logs in/out on your site, sync to checkout.
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// User logs in on your site
|
|
294
|
+
myAuth.onLogin((session) => {
|
|
295
|
+
checkout.updateTokens(session.accessToken, session.refreshToken);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// User logs out on your site
|
|
299
|
+
myAuth.onLogout(() => {
|
|
300
|
+
checkout.updateTokens("", "");
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## TypeScript
|
|
305
|
+
|
|
306
|
+
All types are exported:
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import {
|
|
310
|
+
Commercengine,
|
|
311
|
+
Checkout,
|
|
312
|
+
type CheckoutConfig,
|
|
313
|
+
type CheckoutEventType,
|
|
314
|
+
type CartData,
|
|
315
|
+
type OrderData,
|
|
316
|
+
type AuthChangeData,
|
|
317
|
+
} from "@commercengine/js";
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## URL Parameters (Advanced)
|
|
321
|
+
|
|
322
|
+
For direct iframe integration without the SDK, checkout accepts these URL parameters:
|
|
323
|
+
|
|
324
|
+
| Parameter | Description | Example |
|
|
325
|
+
|-----------|-------------|---------|
|
|
326
|
+
| `store_id` | Store ID | `store_xxx` |
|
|
327
|
+
| `api_key` | API Key | `ak_xxx` |
|
|
328
|
+
| `mode` | Deployment mode | `iframe` |
|
|
329
|
+
| `parent_origin` | Parent origin for postMessage | `https://brand.com` |
|
|
330
|
+
| `theme` | Theme preference | `light`, `dark` |
|
|
331
|
+
| `token` | Access token | JWT string |
|
|
332
|
+
| `refresh_token` | Refresh token | JWT string |
|
|
333
|
+
| `auth_mode` | Auth management | `provided`, `managed` |
|
|
334
|
+
| `product_id` | Quick buy product | Product ID |
|
|
335
|
+
| `variant_id` | Quick buy variant | Variant ID |
|
|
336
|
+
| `qty` | Quick buy quantity | `1` |
|
|
337
|
+
| `session_mode` | Session behavior | `continue-existing`, `force-new` |
|
|
338
|
+
|
|
339
|
+
### Auth Modes
|
|
340
|
+
|
|
341
|
+
- **`managed`** (default): Checkout manages token lifecycle with auto-refresh
|
|
342
|
+
- **`provided`**: Parent manages tokens. Checkout uses in-memory only, syncs changes via events
|
|
343
|
+
|
|
344
|
+
### Session Modes
|
|
345
|
+
|
|
346
|
+
- **`continue-existing`** (default): Add quick-buy item to existing cart
|
|
347
|
+
- **`force-new`**: Delete existing cart and start fresh with only the quick-buy item
|
|
348
|
+
|
|
349
|
+
**Note:** When quick buy params are provided (via config or auto-detected), the cart drawer automatically opens once checkout is ready.
|
|
350
|
+
|
|
351
|
+
### Auto-Detect Quick Buy
|
|
352
|
+
|
|
353
|
+
For ad-driven traffic, enable `autoDetectQuickBuy` to automatically parse quick buy params from the parent page URL:
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// Ad link: https://brand.com?product_id=prod_123&variant_id=var_456&qty=2
|
|
357
|
+
|
|
358
|
+
const checkout = await Commercengine.init({
|
|
359
|
+
storeId: "store_xxx",
|
|
360
|
+
apiKey: "ak_xxx",
|
|
361
|
+
autoDetectQuickBuy: true, // Reads product_id, variant_id, qty from parent URL
|
|
362
|
+
});
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
This allows embedded checkout to handle ad clicks natively without custom URL parsing.
|
|
366
|
+
|
|
367
|
+
**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.
|