@commercengine/react 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 ADDED
@@ -0,0 +1,358 @@
1
+ # @commercengine/react
2
+
3
+ React hook for Commerce Engine checkout.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @commercengine/react
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```tsx
14
+ import { useCheckout } from "@commercengine/react";
15
+
16
+ function App() {
17
+ const { openCart, cartCount, isReady } = useCheckout({
18
+ storeId: "store_xxx",
19
+ apiKey: "ak_xxx",
20
+ });
21
+
22
+ return (
23
+ <button onClick={openCart} disabled={!isReady}>
24
+ Cart ({cartCount})
25
+ </button>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ## Configuration
31
+
32
+ ### UseCheckoutOptions
33
+
34
+ ```typescript
35
+ interface UseCheckoutOptions {
36
+ // === Credentials (required) ===
37
+ storeId: string; // Your Commerce Engine Store ID
38
+ apiKey: string; // Your Commerce Engine API Key
39
+
40
+ // === Development ===
41
+ url?: string; // Direct checkout URL (local dev only)
42
+
43
+ // === Theme ===
44
+ theme?: "light" | "dark" | "system"; // Default: "system"
45
+
46
+ // === Appearance ===
47
+ zIndex?: number; // Overlay z-index. Default: 99999
48
+
49
+ // === Authentication ===
50
+ authMode?: "managed" | "provided"; // Default: "managed"
51
+ accessToken?: string; // Initial access token
52
+ refreshToken?: string; // Initial refresh token
53
+
54
+ // === Quick Buy ===
55
+ quickBuy?: {
56
+ productId: string; // Product ID (required)
57
+ variantId: string | null; // Variant ID (required, null for non-variant)
58
+ quantity?: number; // Default: 1
59
+ };
60
+ sessionMode?: "continue-existing" | "force-new"; // Default: "continue-existing"
61
+ autoDetectQuickBuy?: boolean; // Auto-detect from parent URL. Default: false
62
+
63
+ // === Callbacks ===
64
+ onReady?: () => void;
65
+ onOpen?: () => void;
66
+ onClose?: () => void;
67
+ onComplete?: (order: OrderData) => void;
68
+ onCartUpdate?: (cart: CartData) => void;
69
+ onAuthChange?: (auth: AuthChangeData) => void;
70
+ }
71
+ ```
72
+
73
+ **Session Modes:**
74
+ - **`continue-existing`** (default): Add quick-buy item to existing cart
75
+ - **`force-new`**: Delete existing cart and start fresh with only the quick-buy item
76
+
77
+ **Note:** When quick buy params are provided (via config or auto-detected), the cart drawer automatically opens once checkout is ready.
78
+
79
+ ### Example: Full Configuration
80
+
81
+ ```tsx
82
+ import { useCheckout } from "@commercengine/react";
83
+
84
+ function Store() {
85
+ const {
86
+ openCart,
87
+ openCheckout,
88
+ close,
89
+ updateTokens,
90
+ isReady,
91
+ isOpen,
92
+ cartCount,
93
+ cartTotal,
94
+ cartCurrency,
95
+ } = useCheckout({
96
+ storeId: "store_xxx",
97
+ apiKey: "ak_xxx",
98
+ theme: "dark",
99
+ zIndex: 100000,
100
+ accessToken: session?.accessToken,
101
+ refreshToken: session?.refreshToken,
102
+ onReady: () => {
103
+ console.log("Checkout ready");
104
+ },
105
+ onComplete: (order) => {
106
+ router.push(`/thank-you?order=${order.orderNumber}`);
107
+ },
108
+ onCartUpdate: (cart) => {
109
+ console.log("Cart updated:", cart.count, cart.total);
110
+ },
111
+ onAuthChange: ({ type, accessToken }) => {
112
+ if (type === "login") {
113
+ // Sync to your auth system
114
+ setSession({ accessToken });
115
+ } else if (type === "logout") {
116
+ setSession(null);
117
+ }
118
+ },
119
+ });
120
+
121
+ return (
122
+ <nav>
123
+ <button onClick={openCart} disabled={!isReady}>
124
+ Cart ({cartCount}) - {cartCurrency} {cartTotal}
125
+ </button>
126
+ </nav>
127
+ );
128
+ }
129
+ ```
130
+
131
+ ## Return Value
132
+
133
+ ### UseCheckoutReturn
134
+
135
+ ```typescript
136
+ interface UseCheckoutReturn {
137
+ // === Methods ===
138
+ openCart: () => void; // Open cart drawer
139
+ openCheckout: () => void; // Open checkout directly (Buy Now)
140
+ close: () => void; // Close overlay
141
+ updateTokens: ( // Sync auth state
142
+ accessToken: string,
143
+ refreshToken?: string
144
+ ) => void;
145
+ addToCart: ( // Add item to cart and open cart drawer
146
+ productId: string,
147
+ variantId: string | null,
148
+ quantity?: number
149
+ ) => void;
150
+
151
+ // === State ===
152
+ isReady: boolean; // Checkout initialized
153
+ isOpen: boolean; // Overlay visible
154
+ cartCount: number; // Items in cart
155
+ cartTotal: number; // Cart subtotal
156
+ cartCurrency: string; // Currency code (e.g., "USD")
157
+ }
158
+ ```
159
+
160
+ ## Examples
161
+
162
+ ### Cart Button with Badge
163
+
164
+ ```tsx
165
+ function CartButton() {
166
+ const { openCart, cartCount, isReady } = useCheckout({
167
+ storeId: "store_xxx",
168
+ apiKey: "ak_xxx",
169
+ });
170
+
171
+ return (
172
+ <button onClick={openCart} disabled={!isReady}>
173
+ <ShoppingCart />
174
+ {cartCount > 0 && <span className="badge">{cartCount}</span>}
175
+ </button>
176
+ );
177
+ }
178
+ ```
179
+
180
+ ### Add to Cart
181
+
182
+ ```tsx
183
+ function ProductCard({ product }: { product: Product }) {
184
+ const { addToCart, isReady } = useCheckout({
185
+ storeId: "store_xxx",
186
+ apiKey: "ak_xxx",
187
+ });
188
+
189
+ const handleAddToCart = () => {
190
+ // variantId is required - use null for non-variant products
191
+ // Cart drawer opens automatically after adding
192
+ addToCart(product.id, product.variantId ?? null, 1);
193
+ };
194
+
195
+ return (
196
+ <div>
197
+ <h3>{product.name}</h3>
198
+ <button onClick={handleAddToCart} disabled={!isReady}>
199
+ Add to Cart
200
+ </button>
201
+ </div>
202
+ );
203
+ }
204
+ ```
205
+
206
+ ### Buy Now Button
207
+
208
+ ```tsx
209
+ function BuyNowButton({ productId, variantId }: { productId: string; variantId: string | null }) {
210
+ const { addToCart, openCheckout, isReady } = useCheckout({
211
+ storeId: "store_xxx",
212
+ apiKey: "ak_xxx",
213
+ });
214
+
215
+ const handleBuyNow = () => {
216
+ addToCart(productId, variantId, 1);
217
+ openCheckout();
218
+ };
219
+
220
+ return (
221
+ <button onClick={handleBuyNow} disabled={!isReady}>
222
+ Buy Now
223
+ </button>
224
+ );
225
+ }
226
+ ```
227
+
228
+ ### Order Completion with Redirect
229
+
230
+ ```tsx
231
+ function CheckoutButton() {
232
+ const router = useRouter();
233
+
234
+ const { openCart, isReady } = useCheckout({
235
+ storeId: "store_xxx",
236
+ apiKey: "ak_xxx",
237
+ onComplete: (order) => {
238
+ // Redirect to thank you page
239
+ router.push(`/order/${order.orderNumber}`);
240
+ },
241
+ });
242
+
243
+ return (
244
+ <button onClick={openCart} disabled={!isReady}>
245
+ Checkout
246
+ </button>
247
+ );
248
+ }
249
+ ```
250
+
251
+ ### Syncing Authentication
252
+
253
+ ```tsx
254
+ function App() {
255
+ const [session, setSession] = useState(null);
256
+
257
+ const { updateTokens, openCart } = useCheckout({
258
+ storeId: "store_xxx",
259
+ apiKey: "ak_xxx",
260
+ // Pass initial tokens
261
+ accessToken: session?.accessToken,
262
+ refreshToken: session?.refreshToken,
263
+ // Sync when user logs in via checkout
264
+ onAuthChange: ({ type, accessToken, refreshToken }) => {
265
+ if (type === "login") {
266
+ setSession({ accessToken, refreshToken });
267
+ } else if (type === "logout") {
268
+ setSession(null);
269
+ }
270
+ },
271
+ });
272
+
273
+ // Sync when user logs in on your site
274
+ const handleLogin = async (credentials) => {
275
+ const tokens = await login(credentials);
276
+ setSession(tokens);
277
+ updateTokens(tokens.accessToken, tokens.refreshToken);
278
+ };
279
+
280
+ // Sync when user logs out on your site
281
+ const handleLogout = () => {
282
+ setSession(null);
283
+ updateTokens("", "");
284
+ };
285
+
286
+ return (
287
+ <div>
288
+ {session ? (
289
+ <button onClick={handleLogout}>Logout</button>
290
+ ) : (
291
+ <button onClick={() => handleLogin({ ... })}>Login</button>
292
+ )}
293
+ <button onClick={openCart}>Cart</button>
294
+ </div>
295
+ );
296
+ }
297
+ ```
298
+
299
+ ### Mini Cart Display
300
+
301
+ ```tsx
302
+ function MiniCart() {
303
+ const { openCart, cartCount, cartTotal, cartCurrency, isReady } = useCheckout({
304
+ storeId: "store_xxx",
305
+ apiKey: "ak_xxx",
306
+ });
307
+
308
+ if (!isReady) {
309
+ return <div>Loading...</div>;
310
+ }
311
+
312
+ return (
313
+ <div className="mini-cart" onClick={openCart}>
314
+ <span>{cartCount} items</span>
315
+ <span>{cartCurrency} {cartTotal.toFixed(2)}</span>
316
+ </div>
317
+ );
318
+ }
319
+ ```
320
+
321
+ ## Hook Lifecycle
322
+
323
+ The hook:
324
+ 1. Creates checkout iframe on mount
325
+ 2. Destroys iframe on unmount
326
+ 3. Reinitializes when `url`, `storeId`, or `apiKey` change
327
+ 4. Other options (theme, callbacks, tokens) update without reinitializing
328
+
329
+ ```tsx
330
+ // This will NOT cause reinit (callbacks stored in ref)
331
+ const { openCart } = useCheckout({
332
+ storeId: "store_xxx",
333
+ apiKey: "ak_xxx",
334
+ onComplete: (order) => {
335
+ // Safe to use state/props here - always uses latest values
336
+ doSomething(currentState);
337
+ },
338
+ });
339
+ ```
340
+
341
+ ## TypeScript
342
+
343
+ Types are re-exported from `@commercengine/js`:
344
+
345
+ ```typescript
346
+ import {
347
+ useCheckout,
348
+ type UseCheckoutOptions,
349
+ type UseCheckoutReturn,
350
+ type CartData,
351
+ type OrderData,
352
+ type AuthChangeData,
353
+ } from "@commercengine/react";
354
+ ```
355
+
356
+ ## Peer Dependencies
357
+
358
+ - `react` >= 17.0.0
package/dist/index.cjs ADDED
@@ -0,0 +1,132 @@
1
+ let _commercengine_js = require("@commercengine/js");
2
+ let react = require("react");
3
+
4
+ //#region src/use-checkout.ts
5
+ /**
6
+ * useCheckout Hook
7
+ *
8
+ * React hook for Commerce Engine Checkout integration.
9
+ * Handles checkout initialization, state management, and cleanup.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useCheckout } from "@commercengine/react";
14
+ *
15
+ * function MyStore() {
16
+ * const { openCart, openCheckout, cartCount, isReady } = useCheckout({
17
+ * storeId: "store_xxx",
18
+ * apiKey: "ak_xxx",
19
+ * theme: "dark",
20
+ * onComplete: (order) => {
21
+ * console.log("Order placed:", order.orderNumber);
22
+ * window.location.href = "/thank-you";
23
+ * },
24
+ * });
25
+ *
26
+ * return (
27
+ * <button onClick={openCart} disabled={!isReady}>
28
+ * Cart ({cartCount})
29
+ * </button>
30
+ * );
31
+ * }
32
+ * ```
33
+ */
34
+ /**
35
+ * React hook for Commerce Engine Checkout
36
+ *
37
+ * @param options - Checkout configuration
38
+ * @returns Checkout state and methods
39
+ */
40
+ function useCheckout(options) {
41
+ const checkoutRef = (0, react.useRef)(null);
42
+ const [isReady, setIsReady] = (0, react.useState)(false);
43
+ const [isOpen, setIsOpen] = (0, react.useState)(false);
44
+ const [cart, setCart] = (0, react.useState)({
45
+ count: 0,
46
+ total: 0,
47
+ currency: "INR"
48
+ });
49
+ const optionsRef = (0, react.useRef)(options);
50
+ optionsRef.current = options;
51
+ const { url, storeId, apiKey } = options;
52
+ (0, react.useEffect)(() => {
53
+ if (typeof window === "undefined") return;
54
+ const opts = optionsRef.current;
55
+ const checkout = new _commercengine_js.Checkout({
56
+ url,
57
+ storeId,
58
+ apiKey,
59
+ theme: opts.theme,
60
+ authMode: opts.authMode,
61
+ accessToken: opts.accessToken,
62
+ refreshToken: opts.refreshToken,
63
+ quickBuy: opts.quickBuy,
64
+ sessionMode: opts.sessionMode,
65
+ autoDetectQuickBuy: opts.autoDetectQuickBuy,
66
+ appearance: { zIndex: opts.zIndex },
67
+ onReady: () => {
68
+ setIsReady(true);
69
+ optionsRef.current.onReady?.();
70
+ },
71
+ onOpen: () => {
72
+ setIsOpen(true);
73
+ optionsRef.current.onOpen?.();
74
+ },
75
+ onClose: () => {
76
+ setIsOpen(false);
77
+ optionsRef.current.onClose?.();
78
+ },
79
+ onComplete: (order) => {
80
+ optionsRef.current.onComplete?.(order);
81
+ },
82
+ onCartUpdate: (cartData) => {
83
+ setCart(cartData);
84
+ optionsRef.current.onCartUpdate?.(cartData);
85
+ },
86
+ onAuthChange: (auth) => {
87
+ optionsRef.current.onAuthChange?.(auth);
88
+ },
89
+ onError: (error) => {
90
+ setIsReady(true);
91
+ optionsRef.current.onError?.(error);
92
+ }
93
+ });
94
+ checkoutRef.current = checkout;
95
+ return () => {
96
+ checkout.destroy();
97
+ checkoutRef.current = null;
98
+ setIsReady(false);
99
+ setIsOpen(false);
100
+ };
101
+ }, [
102
+ url,
103
+ storeId,
104
+ apiKey
105
+ ]);
106
+ return {
107
+ openCart: (0, react.useCallback)(() => {
108
+ checkoutRef.current?.openCart();
109
+ }, []),
110
+ openCheckout: (0, react.useCallback)(() => {
111
+ checkoutRef.current?.openCheckout();
112
+ }, []),
113
+ close: (0, react.useCallback)(() => {
114
+ checkoutRef.current?.close();
115
+ }, []),
116
+ updateTokens: (0, react.useCallback)((accessToken, refreshToken) => {
117
+ checkoutRef.current?.updateTokens(accessToken, refreshToken);
118
+ }, []),
119
+ addToCart: (0, react.useCallback)((productId, variantId, quantity) => {
120
+ checkoutRef.current?.addToCart(productId, variantId, quantity);
121
+ }, []),
122
+ isReady,
123
+ isOpen,
124
+ cartCount: cart.count,
125
+ cartTotal: cart.total,
126
+ cartCurrency: cart.currency
127
+ };
128
+ }
129
+
130
+ //#endregion
131
+ exports.useCheckout = useCheckout;
132
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["Checkout"],"sources":["../src/use-checkout.ts"],"sourcesContent":["/**\n * useCheckout Hook\n *\n * React hook for Commerce Engine Checkout integration.\n * Handles checkout initialization, state management, and cleanup.\n *\n * @example\n * ```tsx\n * import { useCheckout } from \"@commercengine/react\";\n *\n * function MyStore() {\n * const { openCart, openCheckout, cartCount, isReady } = useCheckout({\n * storeId: \"store_xxx\",\n * apiKey: \"ak_xxx\",\n * theme: \"dark\",\n * onComplete: (order) => {\n * console.log(\"Order placed:\", order.orderNumber);\n * window.location.href = \"/thank-you\";\n * },\n * });\n *\n * return (\n * <button onClick={openCart} disabled={!isReady}>\n * Cart ({cartCount})\n * </button>\n * );\n * }\n * ```\n */\n\nimport {\n type AuthChangeData,\n type AuthMode,\n type CartData,\n Checkout,\n type CheckoutConfig,\n type ErrorData,\n type OrderData,\n type QuickBuyConfig,\n type SessionMode,\n} from \"@commercengine/js\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useCheckout hook\n */\nexport interface UseCheckoutOptions {\n /**\n * Your Commerce Engine Store ID\n * @example \"store_abc123\"\n */\n storeId?: string;\n\n /**\n * Your Commerce Engine API Key\n * @example \"ak_test_xyz789\"\n */\n apiKey?: string;\n\n /**\n * Checkout URL for local development\n * In production, URL is resolved from storeId/apiKey\n */\n url?: string;\n\n /**\n * Theme preference\n * @default \"system\"\n */\n theme?: \"light\" | \"dark\" | \"system\";\n\n /**\n * Z-index for the checkout overlay\n * @default 99999\n */\n zIndex?: number;\n\n /**\n * Authentication mode\n * - 'managed': Checkout manages token lifecycle (default)\n * - 'provided': Parent manages tokens, checkout uses in-memory only\n * @default \"managed\"\n */\n authMode?: AuthMode;\n\n /**\n * Initial access token (if user already logged in)\n */\n accessToken?: string;\n\n /**\n * Initial refresh token\n */\n refreshToken?: string;\n\n /**\n * Quick buy configuration for \"Buy Now\" flows\n * When provided, adds the product to cart on initialization\n */\n quickBuy?: QuickBuyConfig;\n\n /**\n * Session behavior when quick buy is used\n * @default \"continue-existing\"\n */\n sessionMode?: SessionMode;\n\n /**\n * Auto-detect quick buy params from parent page URL\n * When enabled, SDK parses window.location.search for:\n * - product_id, variant_id, qty/quantity, session_mode\n * Useful for ad-driven traffic to embedded checkout pages\n * @default false\n */\n autoDetectQuickBuy?: boolean;\n\n /**\n * Called when checkout iframe is ready\n */\n onReady?: () => void;\n\n /**\n * Called when checkout is opened\n */\n onOpen?: () => void;\n\n /**\n * Called when checkout is closed\n */\n onClose?: () => void;\n\n /**\n * Called when order is completed\n */\n onComplete?: (order: OrderData) => void;\n\n /**\n * Called when cart state changes\n */\n onCartUpdate?: (cart: CartData) => void;\n\n /**\n * Called when auth state changes\n */\n onAuthChange?: (auth: AuthChangeData) => void;\n\n /**\n * Called when checkout encounters a configuration error\n */\n onError?: (error: ErrorData) => void;\n}\n\n/**\n * Return value from useCheckout hook\n */\nexport interface UseCheckoutReturn {\n /**\n * Open the cart drawer\n */\n openCart: () => void;\n\n /**\n * Open the checkout drawer directly (for Buy Now flow)\n */\n openCheckout: () => void;\n\n /**\n * Close the checkout overlay\n */\n close: () => void;\n\n /**\n * Update auth tokens (when user logs in/out on parent site)\n */\n updateTokens: (accessToken: string, refreshToken?: string) => void;\n\n /**\n * Add item to cart\n * @param productId - Product ID (required)\n * @param variantId - Variant ID (required, null for non-variant products)\n * @param quantity - Quantity to add (default: 1)\n */\n addToCart: (productId: string, variantId: string | null, quantity?: number) => void;\n\n /**\n * Whether checkout is ready to use\n */\n isReady: boolean;\n\n /**\n * Whether checkout overlay is currently open\n */\n isOpen: boolean;\n\n /**\n * Number of items in cart\n */\n cartCount: number;\n\n /**\n * Cart subtotal amount\n */\n cartTotal: number;\n\n /**\n * Cart currency code\n */\n cartCurrency: string;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * React hook for Commerce Engine Checkout\n *\n * @param options - Checkout configuration\n * @returns Checkout state and methods\n */\nexport function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn {\n const checkoutRef = useRef<Checkout | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [cart, setCart] = useState<CartData>({ count: 0, total: 0, currency: \"INR\" });\n\n // Store options in ref to avoid recreating checkout on callback changes\n // This allows stable callbacks while still using latest callback values\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n // Destructure stable keys for dependency array\n const { url, storeId, apiKey } = options;\n\n // Initialize checkout on mount or when key config changes\n useEffect(() => {\n // Skip on server\n if (typeof window === \"undefined\") return;\n\n // Get current options from ref for non-key values\n const opts = optionsRef.current;\n\n const config: CheckoutConfig = {\n url,\n storeId,\n apiKey,\n theme: opts.theme,\n authMode: opts.authMode,\n accessToken: opts.accessToken,\n refreshToken: opts.refreshToken,\n quickBuy: opts.quickBuy,\n sessionMode: opts.sessionMode,\n autoDetectQuickBuy: opts.autoDetectQuickBuy,\n appearance: {\n zIndex: opts.zIndex,\n },\n onReady: () => {\n setIsReady(true);\n optionsRef.current.onReady?.();\n },\n onOpen: () => {\n setIsOpen(true);\n optionsRef.current.onOpen?.();\n },\n onClose: () => {\n setIsOpen(false);\n optionsRef.current.onClose?.();\n },\n onComplete: (order) => {\n optionsRef.current.onComplete?.(order);\n },\n onCartUpdate: (cartData) => {\n setCart(cartData);\n optionsRef.current.onCartUpdate?.(cartData);\n },\n onAuthChange: (auth) => {\n optionsRef.current.onAuthChange?.(auth);\n },\n onError: (error) => {\n // Still set ready so buttons are enabled (error drawer will show)\n setIsReady(true);\n optionsRef.current.onError?.(error);\n },\n };\n\n const checkout = new Checkout(config);\n checkoutRef.current = checkout;\n\n return () => {\n checkout.destroy();\n checkoutRef.current = null;\n setIsReady(false);\n setIsOpen(false);\n };\n // Only reinitialize when URL or credentials change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey]);\n\n // Stable callback refs\n const openCart = useCallback(() => {\n checkoutRef.current?.openCart();\n }, []);\n\n const openCheckout = useCallback(() => {\n checkoutRef.current?.openCheckout();\n }, []);\n\n const close = useCallback(() => {\n checkoutRef.current?.close();\n }, []);\n\n const updateTokens = useCallback((accessToken: string, refreshToken?: string) => {\n checkoutRef.current?.updateTokens(accessToken, refreshToken);\n }, []);\n\n const addToCart = useCallback(\n (productId: string, variantId: string | null, quantity?: number) => {\n checkoutRef.current?.addToCart(productId, variantId, quantity);\n },\n []\n );\n\n return {\n openCart,\n openCheckout,\n close,\n updateTokens,\n addToCart,\n isReady,\n isOpen,\n cartCount: cart.count,\n cartTotal: cart.total,\n cartCurrency: cart.currency,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgOA,SAAgB,YAAY,SAAgD;CAC1E,MAAM,gCAAsC,KAAK;CACjD,MAAM,CAAC,SAAS,kCAAuB,MAAM;CAC7C,MAAM,CAAC,QAAQ,iCAAsB,MAAM;CAC3C,MAAM,CAAC,MAAM,+BAA8B;EAAE,OAAO;EAAG,OAAO;EAAG,UAAU;EAAO,CAAC;CAInF,MAAM,+BAAoB,QAAQ;AAClC,YAAW,UAAU;CAGrB,MAAM,EAAE,KAAK,SAAS,WAAW;AAGjC,4BAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EA6CxB,MAAM,WAAW,IAAIA,2BA3CU;GAC7B;GACA;GACA;GACA,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,UAAU,KAAK;GACf,aAAa,KAAK;GAClB,oBAAoB,KAAK;GACzB,YAAY,EACV,QAAQ,KAAK,QACd;GACD,eAAe;AACb,eAAW,KAAK;AAChB,eAAW,QAAQ,WAAW;;GAEhC,cAAc;AACZ,cAAU,KAAK;AACf,eAAW,QAAQ,UAAU;;GAE/B,eAAe;AACb,cAAU,MAAM;AAChB,eAAW,QAAQ,WAAW;;GAEhC,aAAa,UAAU;AACrB,eAAW,QAAQ,aAAa,MAAM;;GAExC,eAAe,aAAa;AAC1B,YAAQ,SAAS;AACjB,eAAW,QAAQ,eAAe,SAAS;;GAE7C,eAAe,SAAS;AACtB,eAAW,QAAQ,eAAe,KAAK;;GAEzC,UAAU,UAAU;AAElB,eAAW,KAAK;AAChB,eAAW,QAAQ,UAAU,MAAM;;GAEtC,CAEoC;AACrC,cAAY,UAAU;AAEtB,eAAa;AACX,YAAS,SAAS;AAClB,eAAY,UAAU;AACtB,cAAW,MAAM;AACjB,aAAU,MAAM;;IAIjB;EAAC;EAAK;EAAS;EAAO,CAAC;AA0B1B,QAAO;EACL,uCAxBiC;AACjC,eAAY,SAAS,UAAU;KAC9B,EAAE,CAAC;EAuBJ,2CArBqC;AACrC,eAAY,SAAS,cAAc;KAClC,EAAE,CAAC;EAoBJ,oCAlB8B;AAC9B,eAAY,SAAS,OAAO;KAC3B,EAAE,CAAC;EAiBJ,sCAfgC,aAAqB,iBAA0B;AAC/E,eAAY,SAAS,aAAa,aAAa,aAAa;KAC3D,EAAE,CAAC;EAcJ,mCAXC,WAAmB,WAA0B,aAAsB;AAClE,eAAY,SAAS,UAAU,WAAW,WAAW,SAAS;KAEhE,EAAE,CACH;EAQC;EACA;EACA,WAAW,KAAK;EAChB,WAAW,KAAK;EAChB,cAAc,KAAK;EACpB"}
@@ -0,0 +1,153 @@
1
+ import { AddToCartItem, AuthChangeData, AuthChangeData as AuthChangeData$1, AuthMode, AuthMode as AuthMode$1, CartData, CartData as CartData$1, ErrorData, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1 } from "@commercengine/js";
2
+
3
+ //#region src/use-checkout.d.ts
4
+
5
+ /**
6
+ * Options for useCheckout hook
7
+ */
8
+ interface UseCheckoutOptions {
9
+ /**
10
+ * Your Commerce Engine Store ID
11
+ * @example "store_abc123"
12
+ */
13
+ storeId?: string;
14
+ /**
15
+ * Your Commerce Engine API Key
16
+ * @example "ak_test_xyz789"
17
+ */
18
+ apiKey?: string;
19
+ /**
20
+ * Checkout URL for local development
21
+ * In production, URL is resolved from storeId/apiKey
22
+ */
23
+ url?: string;
24
+ /**
25
+ * Theme preference
26
+ * @default "system"
27
+ */
28
+ theme?: "light" | "dark" | "system";
29
+ /**
30
+ * Z-index for the checkout overlay
31
+ * @default 99999
32
+ */
33
+ zIndex?: number;
34
+ /**
35
+ * Authentication mode
36
+ * - 'managed': Checkout manages token lifecycle (default)
37
+ * - 'provided': Parent manages tokens, checkout uses in-memory only
38
+ * @default "managed"
39
+ */
40
+ authMode?: AuthMode$1;
41
+ /**
42
+ * Initial access token (if user already logged in)
43
+ */
44
+ accessToken?: string;
45
+ /**
46
+ * Initial refresh token
47
+ */
48
+ refreshToken?: string;
49
+ /**
50
+ * Quick buy configuration for "Buy Now" flows
51
+ * When provided, adds the product to cart on initialization
52
+ */
53
+ quickBuy?: QuickBuyConfig$1;
54
+ /**
55
+ * Session behavior when quick buy is used
56
+ * @default "continue-existing"
57
+ */
58
+ sessionMode?: SessionMode$1;
59
+ /**
60
+ * Auto-detect quick buy params from parent page URL
61
+ * When enabled, SDK parses window.location.search for:
62
+ * - product_id, variant_id, qty/quantity, session_mode
63
+ * Useful for ad-driven traffic to embedded checkout pages
64
+ * @default false
65
+ */
66
+ autoDetectQuickBuy?: boolean;
67
+ /**
68
+ * Called when checkout iframe is ready
69
+ */
70
+ onReady?: () => void;
71
+ /**
72
+ * Called when checkout is opened
73
+ */
74
+ onOpen?: () => void;
75
+ /**
76
+ * Called when checkout is closed
77
+ */
78
+ onClose?: () => void;
79
+ /**
80
+ * Called when order is completed
81
+ */
82
+ onComplete?: (order: OrderData$1) => void;
83
+ /**
84
+ * Called when cart state changes
85
+ */
86
+ onCartUpdate?: (cart: CartData$1) => void;
87
+ /**
88
+ * Called when auth state changes
89
+ */
90
+ onAuthChange?: (auth: AuthChangeData$1) => void;
91
+ /**
92
+ * Called when checkout encounters a configuration error
93
+ */
94
+ onError?: (error: ErrorData) => void;
95
+ }
96
+ /**
97
+ * Return value from useCheckout hook
98
+ */
99
+ interface UseCheckoutReturn {
100
+ /**
101
+ * Open the cart drawer
102
+ */
103
+ openCart: () => void;
104
+ /**
105
+ * Open the checkout drawer directly (for Buy Now flow)
106
+ */
107
+ openCheckout: () => void;
108
+ /**
109
+ * Close the checkout overlay
110
+ */
111
+ close: () => void;
112
+ /**
113
+ * Update auth tokens (when user logs in/out on parent site)
114
+ */
115
+ updateTokens: (accessToken: string, refreshToken?: string) => void;
116
+ /**
117
+ * Add item to cart
118
+ * @param productId - Product ID (required)
119
+ * @param variantId - Variant ID (required, null for non-variant products)
120
+ * @param quantity - Quantity to add (default: 1)
121
+ */
122
+ addToCart: (productId: string, variantId: string | null, quantity?: number) => void;
123
+ /**
124
+ * Whether checkout is ready to use
125
+ */
126
+ isReady: boolean;
127
+ /**
128
+ * Whether checkout overlay is currently open
129
+ */
130
+ isOpen: boolean;
131
+ /**
132
+ * Number of items in cart
133
+ */
134
+ cartCount: number;
135
+ /**
136
+ * Cart subtotal amount
137
+ */
138
+ cartTotal: number;
139
+ /**
140
+ * Cart currency code
141
+ */
142
+ cartCurrency: string;
143
+ }
144
+ /**
145
+ * React hook for Commerce Engine Checkout
146
+ *
147
+ * @param options - Checkout configuration
148
+ * @returns Checkout state and methods
149
+ */
150
+ declare function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn;
151
+ //#endregion
152
+ export { type AddToCartItem, type AuthChangeData, type AuthMode, type CartData, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, useCheckout };
153
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAkDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAqCJ;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;wBAKA;;;;oBAKJ;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
@@ -0,0 +1,153 @@
1
+ import { AddToCartItem, AuthChangeData, AuthChangeData as AuthChangeData$1, AuthMode, AuthMode as AuthMode$1, CartData, CartData as CartData$1, ErrorData, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1 } from "@commercengine/js";
2
+
3
+ //#region src/use-checkout.d.ts
4
+
5
+ /**
6
+ * Options for useCheckout hook
7
+ */
8
+ interface UseCheckoutOptions {
9
+ /**
10
+ * Your Commerce Engine Store ID
11
+ * @example "store_abc123"
12
+ */
13
+ storeId?: string;
14
+ /**
15
+ * Your Commerce Engine API Key
16
+ * @example "ak_test_xyz789"
17
+ */
18
+ apiKey?: string;
19
+ /**
20
+ * Checkout URL for local development
21
+ * In production, URL is resolved from storeId/apiKey
22
+ */
23
+ url?: string;
24
+ /**
25
+ * Theme preference
26
+ * @default "system"
27
+ */
28
+ theme?: "light" | "dark" | "system";
29
+ /**
30
+ * Z-index for the checkout overlay
31
+ * @default 99999
32
+ */
33
+ zIndex?: number;
34
+ /**
35
+ * Authentication mode
36
+ * - 'managed': Checkout manages token lifecycle (default)
37
+ * - 'provided': Parent manages tokens, checkout uses in-memory only
38
+ * @default "managed"
39
+ */
40
+ authMode?: AuthMode$1;
41
+ /**
42
+ * Initial access token (if user already logged in)
43
+ */
44
+ accessToken?: string;
45
+ /**
46
+ * Initial refresh token
47
+ */
48
+ refreshToken?: string;
49
+ /**
50
+ * Quick buy configuration for "Buy Now" flows
51
+ * When provided, adds the product to cart on initialization
52
+ */
53
+ quickBuy?: QuickBuyConfig$1;
54
+ /**
55
+ * Session behavior when quick buy is used
56
+ * @default "continue-existing"
57
+ */
58
+ sessionMode?: SessionMode$1;
59
+ /**
60
+ * Auto-detect quick buy params from parent page URL
61
+ * When enabled, SDK parses window.location.search for:
62
+ * - product_id, variant_id, qty/quantity, session_mode
63
+ * Useful for ad-driven traffic to embedded checkout pages
64
+ * @default false
65
+ */
66
+ autoDetectQuickBuy?: boolean;
67
+ /**
68
+ * Called when checkout iframe is ready
69
+ */
70
+ onReady?: () => void;
71
+ /**
72
+ * Called when checkout is opened
73
+ */
74
+ onOpen?: () => void;
75
+ /**
76
+ * Called when checkout is closed
77
+ */
78
+ onClose?: () => void;
79
+ /**
80
+ * Called when order is completed
81
+ */
82
+ onComplete?: (order: OrderData$1) => void;
83
+ /**
84
+ * Called when cart state changes
85
+ */
86
+ onCartUpdate?: (cart: CartData$1) => void;
87
+ /**
88
+ * Called when auth state changes
89
+ */
90
+ onAuthChange?: (auth: AuthChangeData$1) => void;
91
+ /**
92
+ * Called when checkout encounters a configuration error
93
+ */
94
+ onError?: (error: ErrorData) => void;
95
+ }
96
+ /**
97
+ * Return value from useCheckout hook
98
+ */
99
+ interface UseCheckoutReturn {
100
+ /**
101
+ * Open the cart drawer
102
+ */
103
+ openCart: () => void;
104
+ /**
105
+ * Open the checkout drawer directly (for Buy Now flow)
106
+ */
107
+ openCheckout: () => void;
108
+ /**
109
+ * Close the checkout overlay
110
+ */
111
+ close: () => void;
112
+ /**
113
+ * Update auth tokens (when user logs in/out on parent site)
114
+ */
115
+ updateTokens: (accessToken: string, refreshToken?: string) => void;
116
+ /**
117
+ * Add item to cart
118
+ * @param productId - Product ID (required)
119
+ * @param variantId - Variant ID (required, null for non-variant products)
120
+ * @param quantity - Quantity to add (default: 1)
121
+ */
122
+ addToCart: (productId: string, variantId: string | null, quantity?: number) => void;
123
+ /**
124
+ * Whether checkout is ready to use
125
+ */
126
+ isReady: boolean;
127
+ /**
128
+ * Whether checkout overlay is currently open
129
+ */
130
+ isOpen: boolean;
131
+ /**
132
+ * Number of items in cart
133
+ */
134
+ cartCount: number;
135
+ /**
136
+ * Cart subtotal amount
137
+ */
138
+ cartTotal: number;
139
+ /**
140
+ * Cart currency code
141
+ */
142
+ cartCurrency: string;
143
+ }
144
+ /**
145
+ * React hook for Commerce Engine Checkout
146
+ *
147
+ * @param options - Checkout configuration
148
+ * @returns Checkout state and methods
149
+ */
150
+ declare function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn;
151
+ //#endregion
152
+ export { type AddToCartItem, type AuthChangeData, type AuthMode, type CartData, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, useCheckout };
153
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAkDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAqCJ;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;wBAKA;;;;oBAKJ;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
package/dist/index.mjs ADDED
@@ -0,0 +1,132 @@
1
+ import { Checkout } from "@commercengine/js";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
+
4
+ //#region src/use-checkout.ts
5
+ /**
6
+ * useCheckout Hook
7
+ *
8
+ * React hook for Commerce Engine Checkout integration.
9
+ * Handles checkout initialization, state management, and cleanup.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useCheckout } from "@commercengine/react";
14
+ *
15
+ * function MyStore() {
16
+ * const { openCart, openCheckout, cartCount, isReady } = useCheckout({
17
+ * storeId: "store_xxx",
18
+ * apiKey: "ak_xxx",
19
+ * theme: "dark",
20
+ * onComplete: (order) => {
21
+ * console.log("Order placed:", order.orderNumber);
22
+ * window.location.href = "/thank-you";
23
+ * },
24
+ * });
25
+ *
26
+ * return (
27
+ * <button onClick={openCart} disabled={!isReady}>
28
+ * Cart ({cartCount})
29
+ * </button>
30
+ * );
31
+ * }
32
+ * ```
33
+ */
34
+ /**
35
+ * React hook for Commerce Engine Checkout
36
+ *
37
+ * @param options - Checkout configuration
38
+ * @returns Checkout state and methods
39
+ */
40
+ function useCheckout(options) {
41
+ const checkoutRef = useRef(null);
42
+ const [isReady, setIsReady] = useState(false);
43
+ const [isOpen, setIsOpen] = useState(false);
44
+ const [cart, setCart] = useState({
45
+ count: 0,
46
+ total: 0,
47
+ currency: "INR"
48
+ });
49
+ const optionsRef = useRef(options);
50
+ optionsRef.current = options;
51
+ const { url, storeId, apiKey } = options;
52
+ useEffect(() => {
53
+ if (typeof window === "undefined") return;
54
+ const opts = optionsRef.current;
55
+ const checkout = new Checkout({
56
+ url,
57
+ storeId,
58
+ apiKey,
59
+ theme: opts.theme,
60
+ authMode: opts.authMode,
61
+ accessToken: opts.accessToken,
62
+ refreshToken: opts.refreshToken,
63
+ quickBuy: opts.quickBuy,
64
+ sessionMode: opts.sessionMode,
65
+ autoDetectQuickBuy: opts.autoDetectQuickBuy,
66
+ appearance: { zIndex: opts.zIndex },
67
+ onReady: () => {
68
+ setIsReady(true);
69
+ optionsRef.current.onReady?.();
70
+ },
71
+ onOpen: () => {
72
+ setIsOpen(true);
73
+ optionsRef.current.onOpen?.();
74
+ },
75
+ onClose: () => {
76
+ setIsOpen(false);
77
+ optionsRef.current.onClose?.();
78
+ },
79
+ onComplete: (order) => {
80
+ optionsRef.current.onComplete?.(order);
81
+ },
82
+ onCartUpdate: (cartData) => {
83
+ setCart(cartData);
84
+ optionsRef.current.onCartUpdate?.(cartData);
85
+ },
86
+ onAuthChange: (auth) => {
87
+ optionsRef.current.onAuthChange?.(auth);
88
+ },
89
+ onError: (error) => {
90
+ setIsReady(true);
91
+ optionsRef.current.onError?.(error);
92
+ }
93
+ });
94
+ checkoutRef.current = checkout;
95
+ return () => {
96
+ checkout.destroy();
97
+ checkoutRef.current = null;
98
+ setIsReady(false);
99
+ setIsOpen(false);
100
+ };
101
+ }, [
102
+ url,
103
+ storeId,
104
+ apiKey
105
+ ]);
106
+ return {
107
+ openCart: useCallback(() => {
108
+ checkoutRef.current?.openCart();
109
+ }, []),
110
+ openCheckout: useCallback(() => {
111
+ checkoutRef.current?.openCheckout();
112
+ }, []),
113
+ close: useCallback(() => {
114
+ checkoutRef.current?.close();
115
+ }, []),
116
+ updateTokens: useCallback((accessToken, refreshToken) => {
117
+ checkoutRef.current?.updateTokens(accessToken, refreshToken);
118
+ }, []),
119
+ addToCart: useCallback((productId, variantId, quantity) => {
120
+ checkoutRef.current?.addToCart(productId, variantId, quantity);
121
+ }, []),
122
+ isReady,
123
+ isOpen,
124
+ cartCount: cart.count,
125
+ cartTotal: cart.total,
126
+ cartCurrency: cart.currency
127
+ };
128
+ }
129
+
130
+ //#endregion
131
+ export { useCheckout };
132
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":["/**\n * useCheckout Hook\n *\n * React hook for Commerce Engine Checkout integration.\n * Handles checkout initialization, state management, and cleanup.\n *\n * @example\n * ```tsx\n * import { useCheckout } from \"@commercengine/react\";\n *\n * function MyStore() {\n * const { openCart, openCheckout, cartCount, isReady } = useCheckout({\n * storeId: \"store_xxx\",\n * apiKey: \"ak_xxx\",\n * theme: \"dark\",\n * onComplete: (order) => {\n * console.log(\"Order placed:\", order.orderNumber);\n * window.location.href = \"/thank-you\";\n * },\n * });\n *\n * return (\n * <button onClick={openCart} disabled={!isReady}>\n * Cart ({cartCount})\n * </button>\n * );\n * }\n * ```\n */\n\nimport {\n type AuthChangeData,\n type AuthMode,\n type CartData,\n Checkout,\n type CheckoutConfig,\n type ErrorData,\n type OrderData,\n type QuickBuyConfig,\n type SessionMode,\n} from \"@commercengine/js\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for useCheckout hook\n */\nexport interface UseCheckoutOptions {\n /**\n * Your Commerce Engine Store ID\n * @example \"store_abc123\"\n */\n storeId?: string;\n\n /**\n * Your Commerce Engine API Key\n * @example \"ak_test_xyz789\"\n */\n apiKey?: string;\n\n /**\n * Checkout URL for local development\n * In production, URL is resolved from storeId/apiKey\n */\n url?: string;\n\n /**\n * Theme preference\n * @default \"system\"\n */\n theme?: \"light\" | \"dark\" | \"system\";\n\n /**\n * Z-index for the checkout overlay\n * @default 99999\n */\n zIndex?: number;\n\n /**\n * Authentication mode\n * - 'managed': Checkout manages token lifecycle (default)\n * - 'provided': Parent manages tokens, checkout uses in-memory only\n * @default \"managed\"\n */\n authMode?: AuthMode;\n\n /**\n * Initial access token (if user already logged in)\n */\n accessToken?: string;\n\n /**\n * Initial refresh token\n */\n refreshToken?: string;\n\n /**\n * Quick buy configuration for \"Buy Now\" flows\n * When provided, adds the product to cart on initialization\n */\n quickBuy?: QuickBuyConfig;\n\n /**\n * Session behavior when quick buy is used\n * @default \"continue-existing\"\n */\n sessionMode?: SessionMode;\n\n /**\n * Auto-detect quick buy params from parent page URL\n * When enabled, SDK parses window.location.search for:\n * - product_id, variant_id, qty/quantity, session_mode\n * Useful for ad-driven traffic to embedded checkout pages\n * @default false\n */\n autoDetectQuickBuy?: boolean;\n\n /**\n * Called when checkout iframe is ready\n */\n onReady?: () => void;\n\n /**\n * Called when checkout is opened\n */\n onOpen?: () => void;\n\n /**\n * Called when checkout is closed\n */\n onClose?: () => void;\n\n /**\n * Called when order is completed\n */\n onComplete?: (order: OrderData) => void;\n\n /**\n * Called when cart state changes\n */\n onCartUpdate?: (cart: CartData) => void;\n\n /**\n * Called when auth state changes\n */\n onAuthChange?: (auth: AuthChangeData) => void;\n\n /**\n * Called when checkout encounters a configuration error\n */\n onError?: (error: ErrorData) => void;\n}\n\n/**\n * Return value from useCheckout hook\n */\nexport interface UseCheckoutReturn {\n /**\n * Open the cart drawer\n */\n openCart: () => void;\n\n /**\n * Open the checkout drawer directly (for Buy Now flow)\n */\n openCheckout: () => void;\n\n /**\n * Close the checkout overlay\n */\n close: () => void;\n\n /**\n * Update auth tokens (when user logs in/out on parent site)\n */\n updateTokens: (accessToken: string, refreshToken?: string) => void;\n\n /**\n * Add item to cart\n * @param productId - Product ID (required)\n * @param variantId - Variant ID (required, null for non-variant products)\n * @param quantity - Quantity to add (default: 1)\n */\n addToCart: (productId: string, variantId: string | null, quantity?: number) => void;\n\n /**\n * Whether checkout is ready to use\n */\n isReady: boolean;\n\n /**\n * Whether checkout overlay is currently open\n */\n isOpen: boolean;\n\n /**\n * Number of items in cart\n */\n cartCount: number;\n\n /**\n * Cart subtotal amount\n */\n cartTotal: number;\n\n /**\n * Cart currency code\n */\n cartCurrency: string;\n}\n\n// =============================================================================\n// HOOK\n// =============================================================================\n\n/**\n * React hook for Commerce Engine Checkout\n *\n * @param options - Checkout configuration\n * @returns Checkout state and methods\n */\nexport function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn {\n const checkoutRef = useRef<Checkout | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [cart, setCart] = useState<CartData>({ count: 0, total: 0, currency: \"INR\" });\n\n // Store options in ref to avoid recreating checkout on callback changes\n // This allows stable callbacks while still using latest callback values\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n // Destructure stable keys for dependency array\n const { url, storeId, apiKey } = options;\n\n // Initialize checkout on mount or when key config changes\n useEffect(() => {\n // Skip on server\n if (typeof window === \"undefined\") return;\n\n // Get current options from ref for non-key values\n const opts = optionsRef.current;\n\n const config: CheckoutConfig = {\n url,\n storeId,\n apiKey,\n theme: opts.theme,\n authMode: opts.authMode,\n accessToken: opts.accessToken,\n refreshToken: opts.refreshToken,\n quickBuy: opts.quickBuy,\n sessionMode: opts.sessionMode,\n autoDetectQuickBuy: opts.autoDetectQuickBuy,\n appearance: {\n zIndex: opts.zIndex,\n },\n onReady: () => {\n setIsReady(true);\n optionsRef.current.onReady?.();\n },\n onOpen: () => {\n setIsOpen(true);\n optionsRef.current.onOpen?.();\n },\n onClose: () => {\n setIsOpen(false);\n optionsRef.current.onClose?.();\n },\n onComplete: (order) => {\n optionsRef.current.onComplete?.(order);\n },\n onCartUpdate: (cartData) => {\n setCart(cartData);\n optionsRef.current.onCartUpdate?.(cartData);\n },\n onAuthChange: (auth) => {\n optionsRef.current.onAuthChange?.(auth);\n },\n onError: (error) => {\n // Still set ready so buttons are enabled (error drawer will show)\n setIsReady(true);\n optionsRef.current.onError?.(error);\n },\n };\n\n const checkout = new Checkout(config);\n checkoutRef.current = checkout;\n\n return () => {\n checkout.destroy();\n checkoutRef.current = null;\n setIsReady(false);\n setIsOpen(false);\n };\n // Only reinitialize when URL or credentials change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey]);\n\n // Stable callback refs\n const openCart = useCallback(() => {\n checkoutRef.current?.openCart();\n }, []);\n\n const openCheckout = useCallback(() => {\n checkoutRef.current?.openCheckout();\n }, []);\n\n const close = useCallback(() => {\n checkoutRef.current?.close();\n }, []);\n\n const updateTokens = useCallback((accessToken: string, refreshToken?: string) => {\n checkoutRef.current?.updateTokens(accessToken, refreshToken);\n }, []);\n\n const addToCart = useCallback(\n (productId: string, variantId: string | null, quantity?: number) => {\n checkoutRef.current?.addToCart(productId, variantId, quantity);\n },\n []\n );\n\n return {\n openCart,\n openCheckout,\n close,\n updateTokens,\n addToCart,\n isReady,\n isOpen,\n cartCount: cart.count,\n cartTotal: cart.total,\n cartCurrency: cart.currency,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgOA,SAAgB,YAAY,SAAgD;CAC1E,MAAM,cAAc,OAAwB,KAAK;CACjD,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAC3C,MAAM,CAAC,MAAM,WAAW,SAAmB;EAAE,OAAO;EAAG,OAAO;EAAG,UAAU;EAAO,CAAC;CAInF,MAAM,aAAa,OAAO,QAAQ;AAClC,YAAW,UAAU;CAGrB,MAAM,EAAE,KAAK,SAAS,WAAW;AAGjC,iBAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EA6CxB,MAAM,WAAW,IAAI,SA3CU;GAC7B;GACA;GACA;GACA,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,aAAa,KAAK;GAClB,cAAc,KAAK;GACnB,UAAU,KAAK;GACf,aAAa,KAAK;GAClB,oBAAoB,KAAK;GACzB,YAAY,EACV,QAAQ,KAAK,QACd;GACD,eAAe;AACb,eAAW,KAAK;AAChB,eAAW,QAAQ,WAAW;;GAEhC,cAAc;AACZ,cAAU,KAAK;AACf,eAAW,QAAQ,UAAU;;GAE/B,eAAe;AACb,cAAU,MAAM;AAChB,eAAW,QAAQ,WAAW;;GAEhC,aAAa,UAAU;AACrB,eAAW,QAAQ,aAAa,MAAM;;GAExC,eAAe,aAAa;AAC1B,YAAQ,SAAS;AACjB,eAAW,QAAQ,eAAe,SAAS;;GAE7C,eAAe,SAAS;AACtB,eAAW,QAAQ,eAAe,KAAK;;GAEzC,UAAU,UAAU;AAElB,eAAW,KAAK;AAChB,eAAW,QAAQ,UAAU,MAAM;;GAEtC,CAEoC;AACrC,cAAY,UAAU;AAEtB,eAAa;AACX,YAAS,SAAS;AAClB,eAAY,UAAU;AACtB,cAAW,MAAM;AACjB,aAAU,MAAM;;IAIjB;EAAC;EAAK;EAAS;EAAO,CAAC;AA0B1B,QAAO;EACL,UAxBe,kBAAkB;AACjC,eAAY,SAAS,UAAU;KAC9B,EAAE,CAAC;EAuBJ,cArBmB,kBAAkB;AACrC,eAAY,SAAS,cAAc;KAClC,EAAE,CAAC;EAoBJ,OAlBY,kBAAkB;AAC9B,eAAY,SAAS,OAAO;KAC3B,EAAE,CAAC;EAiBJ,cAfmB,aAAa,aAAqB,iBAA0B;AAC/E,eAAY,SAAS,aAAa,aAAa,aAAa;KAC3D,EAAE,CAAC;EAcJ,WAZgB,aACf,WAAmB,WAA0B,aAAsB;AAClE,eAAY,SAAS,UAAU,WAAW,WAAW,SAAS;KAEhE,EAAE,CACH;EAQC;EACA;EACA,WAAW,KAAK;EAChB,WAAW,KAAK;EAChB,cAAc,KAAK;EACpB"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@commercengine/react",
3
+ "version": "0.1.0",
4
+ "description": "Commerce Engine Checkout - React SDK",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.mjs",
8
+ "types": "dist/index.d.mts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.mts",
13
+ "default": "./dist/index.mjs"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "dependencies": {
26
+ "@commercengine/js": "0.1.0"
27
+ },
28
+ "peerDependencies": {
29
+ "react": ">=17.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/react": "^18.3.18",
33
+ "react": "^18.3.1",
34
+ "tsdown": "^0.18.4",
35
+ "typescript": "^5.9.3"
36
+ },
37
+ "keywords": [
38
+ "commercengine",
39
+ "checkout",
40
+ "react",
41
+ "hook",
42
+ "ecommerce"
43
+ ],
44
+ "license": "MIT",
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "homepage": "https://docs.commercengine.io",
49
+ "scripts": {
50
+ "dev": "tsdown --watch",
51
+ "build": "tsdown"
52
+ }
53
+ }