@commercengine/react 0.2.1 → 0.3.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 CHANGED
@@ -69,10 +69,18 @@ interface UseCheckoutOptions {
69
69
  onClose?: () => void;
70
70
  onComplete?: (order: OrderData) => void;
71
71
  onCartUpdate?: (cart: CartData) => void;
72
- onAuthChange?: (auth: AuthChangeData) => void;
72
+ onLogin?: (data: AuthLoginData) => void;
73
+ onLogout?: (data: AuthLogoutData) => void;
74
+ onTokenRefresh?: (data: AuthRefreshData) => void;
75
+ onSessionError?: () => void;
76
+ onError?: (error: ErrorData) => void;
73
77
  }
74
78
  ```
75
79
 
80
+ **Auth Modes:**
81
+ - **`managed`** (default): Checkout manages token lifecycle with auto-refresh
82
+ - **`provided`**: Parent manages tokens. Checkout uses in-memory only, syncs changes via events
83
+
76
84
  **Session Modes:**
77
85
  - **`continue-existing`** (default): Add quick-buy item to existing cart
78
86
  - **`force-new`**: Delete existing cart and start fresh with only the quick-buy item
@@ -112,13 +120,18 @@ function Store() {
112
120
  onCartUpdate: (cart) => {
113
121
  console.log("Cart updated:", cart.count, cart.total);
114
122
  },
115
- onAuthChange: ({ type, accessToken }) => {
116
- if (type === "login") {
117
- // Sync to your auth system
118
- setSession({ accessToken });
119
- } else if (type === "logout") {
120
- setSession(null);
121
- }
123
+ onLogin: ({ accessToken, user, loginMethod }) => {
124
+ // User logged in - sync to your auth system
125
+ console.log("User logged in via", loginMethod, ":", user?.email || user?.phone);
126
+ setSession({ accessToken });
127
+ },
128
+ onLogout: () => {
129
+ // User logged out - now has anonymous tokens
130
+ setSession(null);
131
+ },
132
+ onSessionError: () => {
133
+ // Session corrupted - SDK cleared tokens, user needs to re-authenticate
134
+ setSession(null);
122
135
  },
123
136
  });
124
137
 
@@ -265,12 +278,14 @@ function App() {
265
278
  accessToken: session?.accessToken,
266
279
  refreshToken: session?.refreshToken,
267
280
  // Sync when user logs in via checkout
268
- onAuthChange: ({ type, accessToken, refreshToken }) => {
269
- if (type === "login") {
270
- setSession({ accessToken, refreshToken });
271
- } else if (type === "logout") {
272
- setSession(null);
273
- }
281
+ onLogin: ({ accessToken, refreshToken }) => {
282
+ setSession({ accessToken, refreshToken });
283
+ },
284
+ onLogout: () => {
285
+ setSession(null);
286
+ },
287
+ onSessionError: () => {
288
+ setSession(null);
274
289
  },
275
290
  });
276
291
 
@@ -353,7 +368,12 @@ import {
353
368
  type UseCheckoutReturn,
354
369
  type CartData,
355
370
  type OrderData,
356
- type AuthChangeData,
371
+ type AuthLoginData,
372
+ type AuthLogoutData,
373
+ type AuthRefreshData,
374
+ type UserInfo,
375
+ type LoginMethod,
376
+ type Channel,
357
377
  } from "@commercengine/react";
358
378
  ```
359
379
 
package/dist/index.cjs CHANGED
@@ -84,8 +84,17 @@ function useCheckout(options) {
84
84
  setCart(cartData);
85
85
  optionsRef.current.onCartUpdate?.(cartData);
86
86
  },
87
- onAuthChange: (auth) => {
88
- optionsRef.current.onAuthChange?.(auth);
87
+ onLogin: (data) => {
88
+ optionsRef.current.onLogin?.(data);
89
+ },
90
+ onLogout: (data) => {
91
+ optionsRef.current.onLogout?.(data);
92
+ },
93
+ onTokenRefresh: (data) => {
94
+ optionsRef.current.onTokenRefresh?.(data);
95
+ },
96
+ onSessionError: () => {
97
+ optionsRef.current.onSessionError?.();
89
98
  },
90
99
  onError: (error) => {
91
100
  setIsReady(true);
@@ -1 +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 Environment,\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 (overrides environment detection)\n * Only needed for custom checkout deployments\n */\n url?: string;\n\n /**\n * Environment for checkout URL resolution\n * - 'production': checkout.commercengine.com (default)\n * - 'staging': staging.checkout.commercengine.com\n *\n * For local development, use the `url` option instead.\n */\n environment?: Environment;\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, environment } = 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 environment,\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, credentials, or environment change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey, environment]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0OA,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,QAAQ,gBAAgB;AAG9C,4BAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EA8CxB,MAAM,WAAW,IAAIA,2BA5CU;GAC7B;GACA;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;EAAQ;EAAY,CAAC;AA0BvC,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"}
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 AuthLoginData,\n type AuthLogoutData,\n type AuthMode,\n type AuthRefreshData,\n type CartData,\n Checkout,\n type CheckoutConfig,\n type Environment,\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 (overrides environment detection)\n * Only needed for custom checkout deployments\n */\n url?: string;\n\n /**\n * Environment for checkout URL resolution\n * - 'production': checkout.commercengine.com (default)\n * - 'staging': staging.checkout.commercengine.com\n *\n * For local development, use the `url` option instead.\n */\n environment?: Environment;\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 user logs in via checkout\n */\n onLogin?: (data: AuthLoginData) => void;\n\n /**\n * Called when user logs out (receives new anonymous tokens)\n */\n onLogout?: (data: AuthLogoutData) => void;\n\n /**\n * Called when tokens are auto-refreshed by SDK\n */\n onTokenRefresh?: (data: AuthRefreshData) => void;\n\n /**\n * Called when session is corrupted and SDK clears all tokens.\n * User needs to re-authenticate.\n */\n onSessionError?: () => 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, environment } = 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 environment,\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 onLogin: (data) => {\n optionsRef.current.onLogin?.(data);\n },\n onLogout: (data) => {\n optionsRef.current.onLogout?.(data);\n },\n onTokenRefresh: (data) => {\n optionsRef.current.onTokenRefresh?.(data);\n },\n onSessionError: () => {\n optionsRef.current.onSessionError?.();\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, credentials, or environment change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey, environment]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4PA,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,QAAQ,gBAAgB;AAG9C,4BAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EAuDxB,MAAM,WAAW,IAAIA,2BArDU;GAC7B;GACA;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,UAAU,SAAS;AACjB,eAAW,QAAQ,UAAU,KAAK;;GAEpC,WAAW,SAAS;AAClB,eAAW,QAAQ,WAAW,KAAK;;GAErC,iBAAiB,SAAS;AACxB,eAAW,QAAQ,iBAAiB,KAAK;;GAE3C,sBAAsB;AACpB,eAAW,QAAQ,kBAAkB;;GAEvC,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;EAAQ;EAAY,CAAC;AA0BvC,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"}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AddToCartItem, AuthChangeData, AuthChangeData as AuthChangeData$1, AuthMode, AuthMode as AuthMode$1, CartData, CartData as CartData$1, Environment, ErrorData, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1 } from "@commercengine/js";
1
+ import { AddToCartItem, AuthLoginData, AuthLoginData as AuthLoginData$1, AuthLogoutData, AuthLogoutData as AuthLogoutData$1, AuthMode, AuthMode as AuthMode$1, AuthRefreshData, AuthRefreshData as AuthRefreshData$1, CartData, CartData as CartData$1, Channel, Environment, ErrorData, LoginMethod, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1, UserInfo } from "@commercengine/js";
2
2
 
3
3
  //#region src/use-checkout.d.ts
4
4
 
@@ -93,9 +93,22 @@ interface UseCheckoutOptions {
93
93
  */
94
94
  onCartUpdate?: (cart: CartData$1) => void;
95
95
  /**
96
- * Called when auth state changes
96
+ * Called when user logs in via checkout
97
97
  */
98
- onAuthChange?: (auth: AuthChangeData$1) => void;
98
+ onLogin?: (data: AuthLoginData$1) => void;
99
+ /**
100
+ * Called when user logs out (receives new anonymous tokens)
101
+ */
102
+ onLogout?: (data: AuthLogoutData$1) => void;
103
+ /**
104
+ * Called when tokens are auto-refreshed by SDK
105
+ */
106
+ onTokenRefresh?: (data: AuthRefreshData$1) => void;
107
+ /**
108
+ * Called when session is corrupted and SDK clears all tokens.
109
+ * User needs to re-authenticate.
110
+ */
111
+ onSessionError?: () => void;
99
112
  /**
100
113
  * Called when checkout encounters a configuration error
101
114
  */
@@ -157,5 +170,5 @@ interface UseCheckoutReturn {
157
170
  */
158
171
  declare function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn;
159
172
  //#endregion
160
- export { type AddToCartItem, type AuthChangeData, type AuthMode, type CartData, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, useCheckout };
173
+ export { type AddToCartItem, type AuthLoginData, type AuthLogoutData, type AuthMode, type AuthRefreshData, type CartData, type Channel, type LoginMethod, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, type UserInfo, useCheckout };
161
174
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAmDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;gBA0BD;;;;;;;;;;;;;;;;;aAoBH;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;wBAKA;;;;oBAKJ;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAqDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;gBA0BD;;;;;;;;;;;;;;;;;aAoBH;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;mBAKL;;;;oBAKC;;;;0BAKM;;;;;;;;;oBAWN;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AddToCartItem, AuthChangeData, AuthChangeData as AuthChangeData$1, AuthMode, AuthMode as AuthMode$1, CartData, CartData as CartData$1, Environment, ErrorData, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1 } from "@commercengine/js";
1
+ import { AddToCartItem, AuthLoginData, AuthLoginData as AuthLoginData$1, AuthLogoutData, AuthLogoutData as AuthLogoutData$1, AuthMode, AuthMode as AuthMode$1, AuthRefreshData, AuthRefreshData as AuthRefreshData$1, CartData, CartData as CartData$1, Channel, Environment, ErrorData, LoginMethod, OrderData, OrderData as OrderData$1, QuickBuyConfig, QuickBuyConfig as QuickBuyConfig$1, SessionMode, SessionMode as SessionMode$1, UserInfo } from "@commercengine/js";
2
2
 
3
3
  //#region src/use-checkout.d.ts
4
4
 
@@ -93,9 +93,22 @@ interface UseCheckoutOptions {
93
93
  */
94
94
  onCartUpdate?: (cart: CartData$1) => void;
95
95
  /**
96
- * Called when auth state changes
96
+ * Called when user logs in via checkout
97
97
  */
98
- onAuthChange?: (auth: AuthChangeData$1) => void;
98
+ onLogin?: (data: AuthLoginData$1) => void;
99
+ /**
100
+ * Called when user logs out (receives new anonymous tokens)
101
+ */
102
+ onLogout?: (data: AuthLogoutData$1) => void;
103
+ /**
104
+ * Called when tokens are auto-refreshed by SDK
105
+ */
106
+ onTokenRefresh?: (data: AuthRefreshData$1) => void;
107
+ /**
108
+ * Called when session is corrupted and SDK clears all tokens.
109
+ * User needs to re-authenticate.
110
+ */
111
+ onSessionError?: () => void;
99
112
  /**
100
113
  * Called when checkout encounters a configuration error
101
114
  */
@@ -157,5 +170,5 @@ interface UseCheckoutReturn {
157
170
  */
158
171
  declare function useCheckout(options: UseCheckoutOptions): UseCheckoutReturn;
159
172
  //#endregion
160
- export { type AddToCartItem, type AuthChangeData, type AuthMode, type CartData, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, useCheckout };
173
+ export { type AddToCartItem, type AuthLoginData, type AuthLogoutData, type AuthMode, type AuthRefreshData, type CartData, type Channel, type LoginMethod, type OrderData, type QuickBuyConfig, type SessionMode, type UseCheckoutOptions, type UseCheckoutReturn, type UserInfo, useCheckout };
161
174
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAmDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;gBA0BD;;;;;;;;;;;;;;;;;aAoBH;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;wBAKA;;;;oBAKJ;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/use-checkout.ts"],"sourcesContent":[],"mappings":";;;;;;;UAqDiB,kBAAA;;;;;;;;;;;;;;;;;;;;;;;gBA0BD;;;;;;;;;;;;;;;;;aAoBH;;;;;;;;;;;;;aAgBA;;;;;gBAMG;;;;;;;;;;;;;;;;;;;;;;;;uBA6BO;;;;wBAKC;;;;mBAKL;;;;oBAKC;;;;0BAKM;;;;;;;;;oBAWN;;;;;UAMH,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiED,WAAA,UAAqB,qBAAqB"}
package/dist/index.mjs CHANGED
@@ -84,8 +84,17 @@ function useCheckout(options) {
84
84
  setCart(cartData);
85
85
  optionsRef.current.onCartUpdate?.(cartData);
86
86
  },
87
- onAuthChange: (auth) => {
88
- optionsRef.current.onAuthChange?.(auth);
87
+ onLogin: (data) => {
88
+ optionsRef.current.onLogin?.(data);
89
+ },
90
+ onLogout: (data) => {
91
+ optionsRef.current.onLogout?.(data);
92
+ },
93
+ onTokenRefresh: (data) => {
94
+ optionsRef.current.onTokenRefresh?.(data);
95
+ },
96
+ onSessionError: () => {
97
+ optionsRef.current.onSessionError?.();
89
98
  },
90
99
  onError: (error) => {
91
100
  setIsReady(true);
@@ -1 +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 Environment,\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 (overrides environment detection)\n * Only needed for custom checkout deployments\n */\n url?: string;\n\n /**\n * Environment for checkout URL resolution\n * - 'production': checkout.commercengine.com (default)\n * - 'staging': staging.checkout.commercengine.com\n *\n * For local development, use the `url` option instead.\n */\n environment?: Environment;\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, environment } = 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 environment,\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, credentials, or environment change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey, environment]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0OA,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,QAAQ,gBAAgB;AAG9C,iBAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EA8CxB,MAAM,WAAW,IAAI,SA5CU;GAC7B;GACA;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;EAAQ;EAAY,CAAC;AA0BvC,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"}
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 AuthLoginData,\n type AuthLogoutData,\n type AuthMode,\n type AuthRefreshData,\n type CartData,\n Checkout,\n type CheckoutConfig,\n type Environment,\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 (overrides environment detection)\n * Only needed for custom checkout deployments\n */\n url?: string;\n\n /**\n * Environment for checkout URL resolution\n * - 'production': checkout.commercengine.com (default)\n * - 'staging': staging.checkout.commercengine.com\n *\n * For local development, use the `url` option instead.\n */\n environment?: Environment;\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 user logs in via checkout\n */\n onLogin?: (data: AuthLoginData) => void;\n\n /**\n * Called when user logs out (receives new anonymous tokens)\n */\n onLogout?: (data: AuthLogoutData) => void;\n\n /**\n * Called when tokens are auto-refreshed by SDK\n */\n onTokenRefresh?: (data: AuthRefreshData) => void;\n\n /**\n * Called when session is corrupted and SDK clears all tokens.\n * User needs to re-authenticate.\n */\n onSessionError?: () => 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, environment } = 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 environment,\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 onLogin: (data) => {\n optionsRef.current.onLogin?.(data);\n },\n onLogout: (data) => {\n optionsRef.current.onLogout?.(data);\n },\n onTokenRefresh: (data) => {\n optionsRef.current.onTokenRefresh?.(data);\n },\n onSessionError: () => {\n optionsRef.current.onSessionError?.();\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, credentials, or environment change\n // Other options like theme, tokens, callbacks are read from optionsRef\n }, [url, storeId, apiKey, environment]);\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4PA,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,QAAQ,gBAAgB;AAG9C,iBAAgB;AAEd,MAAI,OAAO,WAAW,YAAa;EAGnC,MAAM,OAAO,WAAW;EAuDxB,MAAM,WAAW,IAAI,SArDU;GAC7B;GACA;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,UAAU,SAAS;AACjB,eAAW,QAAQ,UAAU,KAAK;;GAEpC,WAAW,SAAS;AAClB,eAAW,QAAQ,WAAW,KAAK;;GAErC,iBAAiB,SAAS;AACxB,eAAW,QAAQ,iBAAiB,KAAK;;GAE3C,sBAAsB;AACpB,eAAW,QAAQ,kBAAkB;;GAEvC,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;EAAQ;EAAY,CAAC;AA0BvC,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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commercengine/react",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Commerce Engine Checkout - React SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -23,7 +23,7 @@
23
23
  "dist"
24
24
  ],
25
25
  "dependencies": {
26
- "@commercengine/js": "0.2.0"
26
+ "@commercengine/js": "0.3.0"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "react": ">=17.0.0"