omni-sync-sdk 0.20.2 → 0.21.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/LICENSE +0 -0
- package/dist/index.d.mts +131 -14
- package/dist/index.d.ts +131 -14
- package/dist/index.js +192 -8
- package/dist/index.mjs +192 -8
- package/package.json +9 -10
package/LICENSE
ADDED
|
File without changes
|
package/dist/index.d.mts
CHANGED
|
@@ -1692,15 +1692,27 @@ interface ShippingRate {
|
|
|
1692
1692
|
* **Note:** Order is created automatically via webhook when payment succeeds.
|
|
1693
1693
|
* No need to call `completeCheckout()` - it happens automatically.
|
|
1694
1694
|
*
|
|
1695
|
+
* **IMPORTANT: Order Summary Display**
|
|
1696
|
+
* Always use `checkout.lineItems` for displaying the Order Summary during checkout!
|
|
1697
|
+
* This is especially important for **partial checkout** (AliExpress-style) where the user
|
|
1698
|
+
* selects only some items from their cart. The `lineItems` array contains ONLY the items
|
|
1699
|
+
* being purchased in this checkout, NOT the entire cart.
|
|
1700
|
+
*
|
|
1695
1701
|
* **IMPORTANT: Price fields are strings**
|
|
1696
1702
|
* All monetary fields (subtotal, discountAmount, shippingAmount, taxAmount, total)
|
|
1697
1703
|
* are strings to preserve decimal precision. Use parseFloat() for calculations.
|
|
1698
1704
|
*
|
|
1699
1705
|
* @example
|
|
1700
1706
|
* ```typescript
|
|
1701
|
-
* // Display checkout summary
|
|
1707
|
+
* // Display checkout summary - use checkout.lineItems, NOT localCart!
|
|
1702
1708
|
* const checkout = await omni.getCheckout(checkoutId);
|
|
1703
1709
|
*
|
|
1710
|
+
* // Order Summary - ALWAYS use checkout.lineItems
|
|
1711
|
+
* checkout.lineItems.forEach(item => {
|
|
1712
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
1713
|
+
* });
|
|
1714
|
+
*
|
|
1715
|
+
* // Totals
|
|
1704
1716
|
* const subtotal = parseFloat(checkout.subtotal);
|
|
1705
1717
|
* const discount = parseFloat(checkout.discountAmount);
|
|
1706
1718
|
* const shipping = parseFloat(checkout.shippingAmount);
|
|
@@ -1712,11 +1724,6 @@ interface ShippingRate {
|
|
|
1712
1724
|
* console.log(`Shipping: $${shipping.toFixed(2)}`);
|
|
1713
1725
|
* console.log(`Tax: $${tax.toFixed(2)}`);
|
|
1714
1726
|
* console.log(`Total: $${total.toFixed(2)}`);
|
|
1715
|
-
*
|
|
1716
|
-
* // Access line items (nested structure)
|
|
1717
|
-
* checkout.lineItems.forEach(item => {
|
|
1718
|
-
* console.log(item.product.name, item.quantity);
|
|
1719
|
-
* });
|
|
1720
1727
|
* ```
|
|
1721
1728
|
*
|
|
1722
1729
|
* @see CheckoutLineItem for item structure
|
|
@@ -3057,6 +3064,11 @@ declare class OmniSyncClient {
|
|
|
3057
3064
|
* When a cart has this ID, operations use localStorage instead of server API.
|
|
3058
3065
|
*/
|
|
3059
3066
|
private readonly VIRTUAL_LOCAL_CART_ID;
|
|
3067
|
+
/**
|
|
3068
|
+
* localStorage key for persisting active checkout across page redirects.
|
|
3069
|
+
* This is needed because Stripe redirects lose in-memory state.
|
|
3070
|
+
*/
|
|
3071
|
+
private readonly ACTIVE_CHECKOUT_KEY;
|
|
3060
3072
|
private readonly onAuthError?;
|
|
3061
3073
|
constructor(options: OmniSyncClientOptions);
|
|
3062
3074
|
/**
|
|
@@ -4185,6 +4197,11 @@ declare class OmniSyncClient {
|
|
|
4185
4197
|
* @internal
|
|
4186
4198
|
*/
|
|
4187
4199
|
private getOrCreateCustomerCart;
|
|
4200
|
+
/**
|
|
4201
|
+
* Fetch the customer's existing cart from server
|
|
4202
|
+
* @internal
|
|
4203
|
+
*/
|
|
4204
|
+
private fetchCustomerCart;
|
|
4188
4205
|
/**
|
|
4189
4206
|
* Smart add to cart - automatically uses localStorage or server based on auth state
|
|
4190
4207
|
*
|
|
@@ -4743,6 +4760,11 @@ declare class OmniSyncClient {
|
|
|
4743
4760
|
* Pass `selectedIndices` to checkout only specific items from the local cart.
|
|
4744
4761
|
* Use the index of each item in the cart.items array.
|
|
4745
4762
|
*
|
|
4763
|
+
* **IMPORTANT - Order Summary Display:**
|
|
4764
|
+
* After calling this function, use `getCheckout(checkoutId)` to get the checkout
|
|
4765
|
+
* and display `checkout.lineItems` in your Order Summary - NOT the local cart items!
|
|
4766
|
+
* The checkout.lineItems contains ONLY the selected items for this checkout.
|
|
4767
|
+
*
|
|
4746
4768
|
* @param options.selectedIndices - Optional array of item indices for partial checkout
|
|
4747
4769
|
* @returns Tracking result with checkoutId if enabled
|
|
4748
4770
|
*
|
|
@@ -4755,19 +4777,22 @@ declare class OmniSyncClient {
|
|
|
4755
4777
|
* const result = await omni.startGuestCheckout({ selectedIndices: [0, 2] });
|
|
4756
4778
|
*
|
|
4757
4779
|
* if (result.tracked) {
|
|
4758
|
-
* //
|
|
4759
|
-
*
|
|
4780
|
+
* // IMPORTANT: Fetch checkout and use checkout.lineItems for Order Summary!
|
|
4781
|
+
* const checkout = await omni.getCheckout(result.checkoutId);
|
|
4782
|
+
*
|
|
4783
|
+
* // Display Order Summary using checkout.lineItems (NOT localCart.items!)
|
|
4784
|
+
* // checkout.lineItems contains ONLY the selected items
|
|
4785
|
+
* checkout.lineItems.forEach(item => {
|
|
4786
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
4787
|
+
* });
|
|
4760
4788
|
*
|
|
4761
4789
|
* // Update checkout with address
|
|
4762
|
-
* await omni.
|
|
4790
|
+
* await omni.updateGuestCheckoutAddress(result.checkoutId, {
|
|
4763
4791
|
* shippingAddress: { ... },
|
|
4764
4792
|
* });
|
|
4765
4793
|
*
|
|
4766
|
-
* //
|
|
4767
|
-
*
|
|
4768
|
-
*
|
|
4769
|
-
* // For partial checkout: remove only purchased items
|
|
4770
|
-
* omni.removeLocalCartItemsByIndex([0, 2]);
|
|
4794
|
+
* // After payment success, call handlePaymentSuccess() to clear cart
|
|
4795
|
+
* omni.handlePaymentSuccess(result.checkoutId);
|
|
4771
4796
|
* } else {
|
|
4772
4797
|
* // Tracking not enabled, use regular submitGuestOrder
|
|
4773
4798
|
* const order = await omni.submitGuestOrder();
|
|
@@ -4777,6 +4802,21 @@ declare class OmniSyncClient {
|
|
|
4777
4802
|
startGuestCheckout(options?: {
|
|
4778
4803
|
selectedIndices?: number[];
|
|
4779
4804
|
}): Promise<GuestCheckoutStartResponse>;
|
|
4805
|
+
/**
|
|
4806
|
+
* Save active checkout to localStorage (persists across page redirects)
|
|
4807
|
+
* @internal
|
|
4808
|
+
*/
|
|
4809
|
+
private saveActiveCheckout;
|
|
4810
|
+
/**
|
|
4811
|
+
* Load active checkout from localStorage
|
|
4812
|
+
* @internal
|
|
4813
|
+
*/
|
|
4814
|
+
private loadActiveCheckout;
|
|
4815
|
+
/**
|
|
4816
|
+
* Clear active checkout from localStorage
|
|
4817
|
+
* @internal
|
|
4818
|
+
*/
|
|
4819
|
+
private clearActiveCheckoutStorage;
|
|
4780
4820
|
/**
|
|
4781
4821
|
* Remove specific items from local cart by their indices.
|
|
4782
4822
|
* Use after partial checkout to remove only the purchased items.
|
|
@@ -4824,6 +4864,83 @@ declare class OmniSyncClient {
|
|
|
4824
4864
|
clearCartOnSuccess?: boolean;
|
|
4825
4865
|
selectedIndices?: number[];
|
|
4826
4866
|
}): Promise<GuestOrderResponse>;
|
|
4867
|
+
/**
|
|
4868
|
+
* Get the active guest checkout session info.
|
|
4869
|
+
* Use this to check if there's an active checkout before handling payment success.
|
|
4870
|
+
*
|
|
4871
|
+
* @returns The active checkout info or null if no checkout is active
|
|
4872
|
+
*
|
|
4873
|
+
* @example
|
|
4874
|
+
* ```typescript
|
|
4875
|
+
* const activeCheckout = omni.getActiveGuestCheckout();
|
|
4876
|
+
* if (activeCheckout) {
|
|
4877
|
+
* console.log('Active checkout:', activeCheckout.checkoutId);
|
|
4878
|
+
* console.log('Partial checkout:', activeCheckout.selectedIndices?.length);
|
|
4879
|
+
* }
|
|
4880
|
+
* ```
|
|
4881
|
+
*/
|
|
4882
|
+
getActiveGuestCheckout(): {
|
|
4883
|
+
checkoutId: string;
|
|
4884
|
+
cartId: string;
|
|
4885
|
+
selectedIndices?: number[];
|
|
4886
|
+
} | null;
|
|
4887
|
+
/**
|
|
4888
|
+
* Handle payment success - automatically clears the cart (both local and server).
|
|
4889
|
+
*
|
|
4890
|
+
* Call this after Stripe payment succeeds (payment_intent.succeeded or confirmPayment success).
|
|
4891
|
+
* This handles ALL checkout scenarios:
|
|
4892
|
+
*
|
|
4893
|
+
* **For guest users (local cart):**
|
|
4894
|
+
* - Full checkout: clears entire localStorage cart
|
|
4895
|
+
* - Partial checkout: removes only the purchased items
|
|
4896
|
+
*
|
|
4897
|
+
* **For logged-in users (server cart):**
|
|
4898
|
+
* - Clears the cached cart ID so next `smartGetCart()` fetches fresh data
|
|
4899
|
+
* - The server cart is already marked as CONVERTED by the webhook
|
|
4900
|
+
*
|
|
4901
|
+
* **IMPORTANT:** Call this from your payment success handler (e.g., after stripe.confirmPayment succeeds,
|
|
4902
|
+
* or on your success page after redirect). This works for both guests AND logged-in users!
|
|
4903
|
+
*
|
|
4904
|
+
* @param checkoutId - Optional checkout ID for validation
|
|
4905
|
+
* @returns Object indicating whether cart was cleared and how
|
|
4906
|
+
*
|
|
4907
|
+
* @example
|
|
4908
|
+
* ```typescript
|
|
4909
|
+
* // After stripe.confirmPayment() succeeds (works for guests AND logged-in users)
|
|
4910
|
+
* const { error, paymentIntent } = await stripe.confirmPayment({
|
|
4911
|
+
* elements,
|
|
4912
|
+
* confirmParams: { return_url: '/checkout/success' },
|
|
4913
|
+
* redirect: 'if_required',
|
|
4914
|
+
* });
|
|
4915
|
+
*
|
|
4916
|
+
* if (!error && paymentIntent?.status === 'succeeded') {
|
|
4917
|
+
* // Clear the cart automatically - handles all scenarios!
|
|
4918
|
+
* const result = omni.handlePaymentSuccess(checkoutId);
|
|
4919
|
+
* console.log('Cart cleared:', result.cleared);
|
|
4920
|
+
* console.log('User type:', result.userType); // 'guest' or 'customer'
|
|
4921
|
+
* }
|
|
4922
|
+
* ```
|
|
4923
|
+
*
|
|
4924
|
+
* @example
|
|
4925
|
+
* ```typescript
|
|
4926
|
+
* // On success page (after redirect)
|
|
4927
|
+
* const checkoutId = new URLSearchParams(location.search).get('checkout_id');
|
|
4928
|
+
* if (checkoutId) {
|
|
4929
|
+
* omni.handlePaymentSuccess(checkoutId);
|
|
4930
|
+
* }
|
|
4931
|
+
* ```
|
|
4932
|
+
*/
|
|
4933
|
+
handlePaymentSuccess(checkoutId?: string): {
|
|
4934
|
+
cleared: boolean;
|
|
4935
|
+
mode: 'full' | 'partial' | 'none';
|
|
4936
|
+
userType: 'guest' | 'customer';
|
|
4937
|
+
itemsRemoved?: number;
|
|
4938
|
+
};
|
|
4939
|
+
/**
|
|
4940
|
+
* Clear the active guest checkout tracking without clearing the cart.
|
|
4941
|
+
* Use this if the user abandons checkout or navigates away.
|
|
4942
|
+
*/
|
|
4943
|
+
clearActiveGuestCheckout(): void;
|
|
4827
4944
|
/**
|
|
4828
4945
|
* Create order from custom data (not from local cart)
|
|
4829
4946
|
* Use this if you manage cart state yourself
|
package/dist/index.d.ts
CHANGED
|
@@ -1692,15 +1692,27 @@ interface ShippingRate {
|
|
|
1692
1692
|
* **Note:** Order is created automatically via webhook when payment succeeds.
|
|
1693
1693
|
* No need to call `completeCheckout()` - it happens automatically.
|
|
1694
1694
|
*
|
|
1695
|
+
* **IMPORTANT: Order Summary Display**
|
|
1696
|
+
* Always use `checkout.lineItems` for displaying the Order Summary during checkout!
|
|
1697
|
+
* This is especially important for **partial checkout** (AliExpress-style) where the user
|
|
1698
|
+
* selects only some items from their cart. The `lineItems` array contains ONLY the items
|
|
1699
|
+
* being purchased in this checkout, NOT the entire cart.
|
|
1700
|
+
*
|
|
1695
1701
|
* **IMPORTANT: Price fields are strings**
|
|
1696
1702
|
* All monetary fields (subtotal, discountAmount, shippingAmount, taxAmount, total)
|
|
1697
1703
|
* are strings to preserve decimal precision. Use parseFloat() for calculations.
|
|
1698
1704
|
*
|
|
1699
1705
|
* @example
|
|
1700
1706
|
* ```typescript
|
|
1701
|
-
* // Display checkout summary
|
|
1707
|
+
* // Display checkout summary - use checkout.lineItems, NOT localCart!
|
|
1702
1708
|
* const checkout = await omni.getCheckout(checkoutId);
|
|
1703
1709
|
*
|
|
1710
|
+
* // Order Summary - ALWAYS use checkout.lineItems
|
|
1711
|
+
* checkout.lineItems.forEach(item => {
|
|
1712
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
1713
|
+
* });
|
|
1714
|
+
*
|
|
1715
|
+
* // Totals
|
|
1704
1716
|
* const subtotal = parseFloat(checkout.subtotal);
|
|
1705
1717
|
* const discount = parseFloat(checkout.discountAmount);
|
|
1706
1718
|
* const shipping = parseFloat(checkout.shippingAmount);
|
|
@@ -1712,11 +1724,6 @@ interface ShippingRate {
|
|
|
1712
1724
|
* console.log(`Shipping: $${shipping.toFixed(2)}`);
|
|
1713
1725
|
* console.log(`Tax: $${tax.toFixed(2)}`);
|
|
1714
1726
|
* console.log(`Total: $${total.toFixed(2)}`);
|
|
1715
|
-
*
|
|
1716
|
-
* // Access line items (nested structure)
|
|
1717
|
-
* checkout.lineItems.forEach(item => {
|
|
1718
|
-
* console.log(item.product.name, item.quantity);
|
|
1719
|
-
* });
|
|
1720
1727
|
* ```
|
|
1721
1728
|
*
|
|
1722
1729
|
* @see CheckoutLineItem for item structure
|
|
@@ -3057,6 +3064,11 @@ declare class OmniSyncClient {
|
|
|
3057
3064
|
* When a cart has this ID, operations use localStorage instead of server API.
|
|
3058
3065
|
*/
|
|
3059
3066
|
private readonly VIRTUAL_LOCAL_CART_ID;
|
|
3067
|
+
/**
|
|
3068
|
+
* localStorage key for persisting active checkout across page redirects.
|
|
3069
|
+
* This is needed because Stripe redirects lose in-memory state.
|
|
3070
|
+
*/
|
|
3071
|
+
private readonly ACTIVE_CHECKOUT_KEY;
|
|
3060
3072
|
private readonly onAuthError?;
|
|
3061
3073
|
constructor(options: OmniSyncClientOptions);
|
|
3062
3074
|
/**
|
|
@@ -4185,6 +4197,11 @@ declare class OmniSyncClient {
|
|
|
4185
4197
|
* @internal
|
|
4186
4198
|
*/
|
|
4187
4199
|
private getOrCreateCustomerCart;
|
|
4200
|
+
/**
|
|
4201
|
+
* Fetch the customer's existing cart from server
|
|
4202
|
+
* @internal
|
|
4203
|
+
*/
|
|
4204
|
+
private fetchCustomerCart;
|
|
4188
4205
|
/**
|
|
4189
4206
|
* Smart add to cart - automatically uses localStorage or server based on auth state
|
|
4190
4207
|
*
|
|
@@ -4743,6 +4760,11 @@ declare class OmniSyncClient {
|
|
|
4743
4760
|
* Pass `selectedIndices` to checkout only specific items from the local cart.
|
|
4744
4761
|
* Use the index of each item in the cart.items array.
|
|
4745
4762
|
*
|
|
4763
|
+
* **IMPORTANT - Order Summary Display:**
|
|
4764
|
+
* After calling this function, use `getCheckout(checkoutId)` to get the checkout
|
|
4765
|
+
* and display `checkout.lineItems` in your Order Summary - NOT the local cart items!
|
|
4766
|
+
* The checkout.lineItems contains ONLY the selected items for this checkout.
|
|
4767
|
+
*
|
|
4746
4768
|
* @param options.selectedIndices - Optional array of item indices for partial checkout
|
|
4747
4769
|
* @returns Tracking result with checkoutId if enabled
|
|
4748
4770
|
*
|
|
@@ -4755,19 +4777,22 @@ declare class OmniSyncClient {
|
|
|
4755
4777
|
* const result = await omni.startGuestCheckout({ selectedIndices: [0, 2] });
|
|
4756
4778
|
*
|
|
4757
4779
|
* if (result.tracked) {
|
|
4758
|
-
* //
|
|
4759
|
-
*
|
|
4780
|
+
* // IMPORTANT: Fetch checkout and use checkout.lineItems for Order Summary!
|
|
4781
|
+
* const checkout = await omni.getCheckout(result.checkoutId);
|
|
4782
|
+
*
|
|
4783
|
+
* // Display Order Summary using checkout.lineItems (NOT localCart.items!)
|
|
4784
|
+
* // checkout.lineItems contains ONLY the selected items
|
|
4785
|
+
* checkout.lineItems.forEach(item => {
|
|
4786
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
4787
|
+
* });
|
|
4760
4788
|
*
|
|
4761
4789
|
* // Update checkout with address
|
|
4762
|
-
* await omni.
|
|
4790
|
+
* await omni.updateGuestCheckoutAddress(result.checkoutId, {
|
|
4763
4791
|
* shippingAddress: { ... },
|
|
4764
4792
|
* });
|
|
4765
4793
|
*
|
|
4766
|
-
* //
|
|
4767
|
-
*
|
|
4768
|
-
*
|
|
4769
|
-
* // For partial checkout: remove only purchased items
|
|
4770
|
-
* omni.removeLocalCartItemsByIndex([0, 2]);
|
|
4794
|
+
* // After payment success, call handlePaymentSuccess() to clear cart
|
|
4795
|
+
* omni.handlePaymentSuccess(result.checkoutId);
|
|
4771
4796
|
* } else {
|
|
4772
4797
|
* // Tracking not enabled, use regular submitGuestOrder
|
|
4773
4798
|
* const order = await omni.submitGuestOrder();
|
|
@@ -4777,6 +4802,21 @@ declare class OmniSyncClient {
|
|
|
4777
4802
|
startGuestCheckout(options?: {
|
|
4778
4803
|
selectedIndices?: number[];
|
|
4779
4804
|
}): Promise<GuestCheckoutStartResponse>;
|
|
4805
|
+
/**
|
|
4806
|
+
* Save active checkout to localStorage (persists across page redirects)
|
|
4807
|
+
* @internal
|
|
4808
|
+
*/
|
|
4809
|
+
private saveActiveCheckout;
|
|
4810
|
+
/**
|
|
4811
|
+
* Load active checkout from localStorage
|
|
4812
|
+
* @internal
|
|
4813
|
+
*/
|
|
4814
|
+
private loadActiveCheckout;
|
|
4815
|
+
/**
|
|
4816
|
+
* Clear active checkout from localStorage
|
|
4817
|
+
* @internal
|
|
4818
|
+
*/
|
|
4819
|
+
private clearActiveCheckoutStorage;
|
|
4780
4820
|
/**
|
|
4781
4821
|
* Remove specific items from local cart by their indices.
|
|
4782
4822
|
* Use after partial checkout to remove only the purchased items.
|
|
@@ -4824,6 +4864,83 @@ declare class OmniSyncClient {
|
|
|
4824
4864
|
clearCartOnSuccess?: boolean;
|
|
4825
4865
|
selectedIndices?: number[];
|
|
4826
4866
|
}): Promise<GuestOrderResponse>;
|
|
4867
|
+
/**
|
|
4868
|
+
* Get the active guest checkout session info.
|
|
4869
|
+
* Use this to check if there's an active checkout before handling payment success.
|
|
4870
|
+
*
|
|
4871
|
+
* @returns The active checkout info or null if no checkout is active
|
|
4872
|
+
*
|
|
4873
|
+
* @example
|
|
4874
|
+
* ```typescript
|
|
4875
|
+
* const activeCheckout = omni.getActiveGuestCheckout();
|
|
4876
|
+
* if (activeCheckout) {
|
|
4877
|
+
* console.log('Active checkout:', activeCheckout.checkoutId);
|
|
4878
|
+
* console.log('Partial checkout:', activeCheckout.selectedIndices?.length);
|
|
4879
|
+
* }
|
|
4880
|
+
* ```
|
|
4881
|
+
*/
|
|
4882
|
+
getActiveGuestCheckout(): {
|
|
4883
|
+
checkoutId: string;
|
|
4884
|
+
cartId: string;
|
|
4885
|
+
selectedIndices?: number[];
|
|
4886
|
+
} | null;
|
|
4887
|
+
/**
|
|
4888
|
+
* Handle payment success - automatically clears the cart (both local and server).
|
|
4889
|
+
*
|
|
4890
|
+
* Call this after Stripe payment succeeds (payment_intent.succeeded or confirmPayment success).
|
|
4891
|
+
* This handles ALL checkout scenarios:
|
|
4892
|
+
*
|
|
4893
|
+
* **For guest users (local cart):**
|
|
4894
|
+
* - Full checkout: clears entire localStorage cart
|
|
4895
|
+
* - Partial checkout: removes only the purchased items
|
|
4896
|
+
*
|
|
4897
|
+
* **For logged-in users (server cart):**
|
|
4898
|
+
* - Clears the cached cart ID so next `smartGetCart()` fetches fresh data
|
|
4899
|
+
* - The server cart is already marked as CONVERTED by the webhook
|
|
4900
|
+
*
|
|
4901
|
+
* **IMPORTANT:** Call this from your payment success handler (e.g., after stripe.confirmPayment succeeds,
|
|
4902
|
+
* or on your success page after redirect). This works for both guests AND logged-in users!
|
|
4903
|
+
*
|
|
4904
|
+
* @param checkoutId - Optional checkout ID for validation
|
|
4905
|
+
* @returns Object indicating whether cart was cleared and how
|
|
4906
|
+
*
|
|
4907
|
+
* @example
|
|
4908
|
+
* ```typescript
|
|
4909
|
+
* // After stripe.confirmPayment() succeeds (works for guests AND logged-in users)
|
|
4910
|
+
* const { error, paymentIntent } = await stripe.confirmPayment({
|
|
4911
|
+
* elements,
|
|
4912
|
+
* confirmParams: { return_url: '/checkout/success' },
|
|
4913
|
+
* redirect: 'if_required',
|
|
4914
|
+
* });
|
|
4915
|
+
*
|
|
4916
|
+
* if (!error && paymentIntent?.status === 'succeeded') {
|
|
4917
|
+
* // Clear the cart automatically - handles all scenarios!
|
|
4918
|
+
* const result = omni.handlePaymentSuccess(checkoutId);
|
|
4919
|
+
* console.log('Cart cleared:', result.cleared);
|
|
4920
|
+
* console.log('User type:', result.userType); // 'guest' or 'customer'
|
|
4921
|
+
* }
|
|
4922
|
+
* ```
|
|
4923
|
+
*
|
|
4924
|
+
* @example
|
|
4925
|
+
* ```typescript
|
|
4926
|
+
* // On success page (after redirect)
|
|
4927
|
+
* const checkoutId = new URLSearchParams(location.search).get('checkout_id');
|
|
4928
|
+
* if (checkoutId) {
|
|
4929
|
+
* omni.handlePaymentSuccess(checkoutId);
|
|
4930
|
+
* }
|
|
4931
|
+
* ```
|
|
4932
|
+
*/
|
|
4933
|
+
handlePaymentSuccess(checkoutId?: string): {
|
|
4934
|
+
cleared: boolean;
|
|
4935
|
+
mode: 'full' | 'partial' | 'none';
|
|
4936
|
+
userType: 'guest' | 'customer';
|
|
4937
|
+
itemsRemoved?: number;
|
|
4938
|
+
};
|
|
4939
|
+
/**
|
|
4940
|
+
* Clear the active guest checkout tracking without clearing the cart.
|
|
4941
|
+
* Use this if the user abandons checkout or navigates away.
|
|
4942
|
+
*/
|
|
4943
|
+
clearActiveGuestCheckout(): void;
|
|
4827
4944
|
/**
|
|
4828
4945
|
* Create order from custom data (not from local cart)
|
|
4829
4946
|
* Use this if you manage cart state yourself
|
package/dist/index.js
CHANGED
|
@@ -54,6 +54,11 @@ var OmniSyncClient = class {
|
|
|
54
54
|
* When a cart has this ID, operations use localStorage instead of server API.
|
|
55
55
|
*/
|
|
56
56
|
this.VIRTUAL_LOCAL_CART_ID = "__local__";
|
|
57
|
+
/**
|
|
58
|
+
* localStorage key for persisting active checkout across page redirects.
|
|
59
|
+
* This is needed because Stripe redirects lose in-memory state.
|
|
60
|
+
*/
|
|
61
|
+
this.ACTIVE_CHECKOUT_KEY = "omni_active_checkout";
|
|
57
62
|
// -------------------- Local Cart (Client-Side for Guests) --------------------
|
|
58
63
|
// These methods store cart data in localStorage - NO API calls!
|
|
59
64
|
// Use for guest users in vibe-coded sites
|
|
@@ -2032,6 +2037,14 @@ var OmniSyncClient = class {
|
|
|
2032
2037
|
this.customerCartId = null;
|
|
2033
2038
|
}
|
|
2034
2039
|
}
|
|
2040
|
+
try {
|
|
2041
|
+
const cart2 = await this.fetchCustomerCart();
|
|
2042
|
+
if (cart2.status === "ACTIVE") {
|
|
2043
|
+
this.customerCartId = cart2.id;
|
|
2044
|
+
return cart2;
|
|
2045
|
+
}
|
|
2046
|
+
} catch {
|
|
2047
|
+
}
|
|
2035
2048
|
const cart = await this.createCart();
|
|
2036
2049
|
this.customerCartId = cart.id;
|
|
2037
2050
|
if (this.customerToken) {
|
|
@@ -2042,6 +2055,22 @@ var OmniSyncClient = class {
|
|
|
2042
2055
|
}
|
|
2043
2056
|
return cart;
|
|
2044
2057
|
}
|
|
2058
|
+
/**
|
|
2059
|
+
* Fetch the customer's existing cart from server
|
|
2060
|
+
* @internal
|
|
2061
|
+
*/
|
|
2062
|
+
async fetchCustomerCart() {
|
|
2063
|
+
if (!this.customerToken) {
|
|
2064
|
+
throw new OmniSyncError("Customer token required", 401);
|
|
2065
|
+
}
|
|
2066
|
+
if (this.isVibeCodedMode()) {
|
|
2067
|
+
return this.vibeCodedRequest("GET", "/customers/me/cart");
|
|
2068
|
+
}
|
|
2069
|
+
if (this.storeId && !this.apiKey) {
|
|
2070
|
+
return this.storefrontRequest("GET", "/customers/me/cart");
|
|
2071
|
+
}
|
|
2072
|
+
throw new OmniSyncError("fetchCustomerCart requires vibe-coded or storefront mode", 400);
|
|
2073
|
+
}
|
|
2045
2074
|
/**
|
|
2046
2075
|
* Smart add to cart - automatically uses localStorage or server based on auth state
|
|
2047
2076
|
*
|
|
@@ -3045,6 +3074,11 @@ var OmniSyncClient = class {
|
|
|
3045
3074
|
* Pass `selectedIndices` to checkout only specific items from the local cart.
|
|
3046
3075
|
* Use the index of each item in the cart.items array.
|
|
3047
3076
|
*
|
|
3077
|
+
* **IMPORTANT - Order Summary Display:**
|
|
3078
|
+
* After calling this function, use `getCheckout(checkoutId)` to get the checkout
|
|
3079
|
+
* and display `checkout.lineItems` in your Order Summary - NOT the local cart items!
|
|
3080
|
+
* The checkout.lineItems contains ONLY the selected items for this checkout.
|
|
3081
|
+
*
|
|
3048
3082
|
* @param options.selectedIndices - Optional array of item indices for partial checkout
|
|
3049
3083
|
* @returns Tracking result with checkoutId if enabled
|
|
3050
3084
|
*
|
|
@@ -3057,19 +3091,22 @@ var OmniSyncClient = class {
|
|
|
3057
3091
|
* const result = await omni.startGuestCheckout({ selectedIndices: [0, 2] });
|
|
3058
3092
|
*
|
|
3059
3093
|
* if (result.tracked) {
|
|
3060
|
-
* //
|
|
3061
|
-
*
|
|
3094
|
+
* // IMPORTANT: Fetch checkout and use checkout.lineItems for Order Summary!
|
|
3095
|
+
* const checkout = await omni.getCheckout(result.checkoutId);
|
|
3096
|
+
*
|
|
3097
|
+
* // Display Order Summary using checkout.lineItems (NOT localCart.items!)
|
|
3098
|
+
* // checkout.lineItems contains ONLY the selected items
|
|
3099
|
+
* checkout.lineItems.forEach(item => {
|
|
3100
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
3101
|
+
* });
|
|
3062
3102
|
*
|
|
3063
3103
|
* // Update checkout with address
|
|
3064
|
-
* await omni.
|
|
3104
|
+
* await omni.updateGuestCheckoutAddress(result.checkoutId, {
|
|
3065
3105
|
* shippingAddress: { ... },
|
|
3066
3106
|
* });
|
|
3067
3107
|
*
|
|
3068
|
-
* //
|
|
3069
|
-
*
|
|
3070
|
-
*
|
|
3071
|
-
* // For partial checkout: remove only purchased items
|
|
3072
|
-
* omni.removeLocalCartItemsByIndex([0, 2]);
|
|
3108
|
+
* // After payment success, call handlePaymentSuccess() to clear cart
|
|
3109
|
+
* omni.handlePaymentSuccess(result.checkoutId);
|
|
3073
3110
|
* } else {
|
|
3074
3111
|
* // Tracking not enabled, use regular submitGuestOrder
|
|
3075
3112
|
* const order = await omni.submitGuestOrder();
|
|
@@ -3097,8 +3134,48 @@ var OmniSyncClient = class {
|
|
|
3097
3134
|
customer: cart.customer
|
|
3098
3135
|
}
|
|
3099
3136
|
);
|
|
3137
|
+
if (response.tracked && response.checkoutId && response.cartId) {
|
|
3138
|
+
this.saveActiveCheckout({
|
|
3139
|
+
checkoutId: response.checkoutId,
|
|
3140
|
+
cartId: response.cartId,
|
|
3141
|
+
selectedIndices: options?.selectedIndices
|
|
3142
|
+
});
|
|
3143
|
+
}
|
|
3100
3144
|
return response;
|
|
3101
3145
|
}
|
|
3146
|
+
/**
|
|
3147
|
+
* Save active checkout to localStorage (persists across page redirects)
|
|
3148
|
+
* @internal
|
|
3149
|
+
*/
|
|
3150
|
+
saveActiveCheckout(checkout) {
|
|
3151
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
3152
|
+
localStorage.setItem(this.ACTIVE_CHECKOUT_KEY, JSON.stringify(checkout));
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Load active checkout from localStorage
|
|
3157
|
+
* @internal
|
|
3158
|
+
*/
|
|
3159
|
+
loadActiveCheckout() {
|
|
3160
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
3161
|
+
return null;
|
|
3162
|
+
}
|
|
3163
|
+
try {
|
|
3164
|
+
const data = localStorage.getItem(this.ACTIVE_CHECKOUT_KEY);
|
|
3165
|
+
return data ? JSON.parse(data) : null;
|
|
3166
|
+
} catch {
|
|
3167
|
+
return null;
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
/**
|
|
3171
|
+
* Clear active checkout from localStorage
|
|
3172
|
+
* @internal
|
|
3173
|
+
*/
|
|
3174
|
+
clearActiveCheckoutStorage() {
|
|
3175
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
3176
|
+
localStorage.removeItem(this.ACTIVE_CHECKOUT_KEY);
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3102
3179
|
/**
|
|
3103
3180
|
* Remove specific items from local cart by their indices.
|
|
3104
3181
|
* Use after partial checkout to remove only the purchased items.
|
|
@@ -3189,6 +3266,113 @@ var OmniSyncClient = class {
|
|
|
3189
3266
|
}
|
|
3190
3267
|
return result;
|
|
3191
3268
|
}
|
|
3269
|
+
/**
|
|
3270
|
+
* Get the active guest checkout session info.
|
|
3271
|
+
* Use this to check if there's an active checkout before handling payment success.
|
|
3272
|
+
*
|
|
3273
|
+
* @returns The active checkout info or null if no checkout is active
|
|
3274
|
+
*
|
|
3275
|
+
* @example
|
|
3276
|
+
* ```typescript
|
|
3277
|
+
* const activeCheckout = omni.getActiveGuestCheckout();
|
|
3278
|
+
* if (activeCheckout) {
|
|
3279
|
+
* console.log('Active checkout:', activeCheckout.checkoutId);
|
|
3280
|
+
* console.log('Partial checkout:', activeCheckout.selectedIndices?.length);
|
|
3281
|
+
* }
|
|
3282
|
+
* ```
|
|
3283
|
+
*/
|
|
3284
|
+
getActiveGuestCheckout() {
|
|
3285
|
+
return this.loadActiveCheckout();
|
|
3286
|
+
}
|
|
3287
|
+
/**
|
|
3288
|
+
* Handle payment success - automatically clears the cart (both local and server).
|
|
3289
|
+
*
|
|
3290
|
+
* Call this after Stripe payment succeeds (payment_intent.succeeded or confirmPayment success).
|
|
3291
|
+
* This handles ALL checkout scenarios:
|
|
3292
|
+
*
|
|
3293
|
+
* **For guest users (local cart):**
|
|
3294
|
+
* - Full checkout: clears entire localStorage cart
|
|
3295
|
+
* - Partial checkout: removes only the purchased items
|
|
3296
|
+
*
|
|
3297
|
+
* **For logged-in users (server cart):**
|
|
3298
|
+
* - Clears the cached cart ID so next `smartGetCart()` fetches fresh data
|
|
3299
|
+
* - The server cart is already marked as CONVERTED by the webhook
|
|
3300
|
+
*
|
|
3301
|
+
* **IMPORTANT:** Call this from your payment success handler (e.g., after stripe.confirmPayment succeeds,
|
|
3302
|
+
* or on your success page after redirect). This works for both guests AND logged-in users!
|
|
3303
|
+
*
|
|
3304
|
+
* @param checkoutId - Optional checkout ID for validation
|
|
3305
|
+
* @returns Object indicating whether cart was cleared and how
|
|
3306
|
+
*
|
|
3307
|
+
* @example
|
|
3308
|
+
* ```typescript
|
|
3309
|
+
* // After stripe.confirmPayment() succeeds (works for guests AND logged-in users)
|
|
3310
|
+
* const { error, paymentIntent } = await stripe.confirmPayment({
|
|
3311
|
+
* elements,
|
|
3312
|
+
* confirmParams: { return_url: '/checkout/success' },
|
|
3313
|
+
* redirect: 'if_required',
|
|
3314
|
+
* });
|
|
3315
|
+
*
|
|
3316
|
+
* if (!error && paymentIntent?.status === 'succeeded') {
|
|
3317
|
+
* // Clear the cart automatically - handles all scenarios!
|
|
3318
|
+
* const result = omni.handlePaymentSuccess(checkoutId);
|
|
3319
|
+
* console.log('Cart cleared:', result.cleared);
|
|
3320
|
+
* console.log('User type:', result.userType); // 'guest' or 'customer'
|
|
3321
|
+
* }
|
|
3322
|
+
* ```
|
|
3323
|
+
*
|
|
3324
|
+
* @example
|
|
3325
|
+
* ```typescript
|
|
3326
|
+
* // On success page (after redirect)
|
|
3327
|
+
* const checkoutId = new URLSearchParams(location.search).get('checkout_id');
|
|
3328
|
+
* if (checkoutId) {
|
|
3329
|
+
* omni.handlePaymentSuccess(checkoutId);
|
|
3330
|
+
* }
|
|
3331
|
+
* ```
|
|
3332
|
+
*/
|
|
3333
|
+
handlePaymentSuccess(checkoutId) {
|
|
3334
|
+
const isLoggedIn = this.isCustomerLoggedIn();
|
|
3335
|
+
if (isLoggedIn) {
|
|
3336
|
+
this.customerCartId = null;
|
|
3337
|
+
}
|
|
3338
|
+
const activeCheckout = this.loadActiveCheckout();
|
|
3339
|
+
if (checkoutId && activeCheckout && activeCheckout.checkoutId !== checkoutId) {
|
|
3340
|
+
console.warn(
|
|
3341
|
+
`handlePaymentSuccess: checkoutId mismatch. Expected ${activeCheckout.checkoutId}, got ${checkoutId}. Proceeding with cleanup.`
|
|
3342
|
+
);
|
|
3343
|
+
}
|
|
3344
|
+
this.clearActiveCheckoutStorage();
|
|
3345
|
+
if (isLoggedIn) {
|
|
3346
|
+
this.clearLocalCart();
|
|
3347
|
+
return {
|
|
3348
|
+
cleared: true,
|
|
3349
|
+
mode: "full",
|
|
3350
|
+
userType: "customer"
|
|
3351
|
+
};
|
|
3352
|
+
}
|
|
3353
|
+
if (activeCheckout?.selectedIndices && activeCheckout.selectedIndices.length > 0) {
|
|
3354
|
+
this.removeLocalCartItemsByIndex(activeCheckout.selectedIndices);
|
|
3355
|
+
return {
|
|
3356
|
+
cleared: true,
|
|
3357
|
+
mode: "partial",
|
|
3358
|
+
userType: "guest",
|
|
3359
|
+
itemsRemoved: activeCheckout.selectedIndices.length
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
this.clearLocalCart();
|
|
3363
|
+
return {
|
|
3364
|
+
cleared: true,
|
|
3365
|
+
mode: "full",
|
|
3366
|
+
userType: "guest"
|
|
3367
|
+
};
|
|
3368
|
+
}
|
|
3369
|
+
/**
|
|
3370
|
+
* Clear the active guest checkout tracking without clearing the cart.
|
|
3371
|
+
* Use this if the user abandons checkout or navigates away.
|
|
3372
|
+
*/
|
|
3373
|
+
clearActiveGuestCheckout() {
|
|
3374
|
+
this.clearActiveCheckoutStorage();
|
|
3375
|
+
}
|
|
3192
3376
|
/**
|
|
3193
3377
|
* Create order from custom data (not from local cart)
|
|
3194
3378
|
* Use this if you manage cart state yourself
|
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,11 @@ var OmniSyncClient = class {
|
|
|
17
17
|
* When a cart has this ID, operations use localStorage instead of server API.
|
|
18
18
|
*/
|
|
19
19
|
this.VIRTUAL_LOCAL_CART_ID = "__local__";
|
|
20
|
+
/**
|
|
21
|
+
* localStorage key for persisting active checkout across page redirects.
|
|
22
|
+
* This is needed because Stripe redirects lose in-memory state.
|
|
23
|
+
*/
|
|
24
|
+
this.ACTIVE_CHECKOUT_KEY = "omni_active_checkout";
|
|
20
25
|
// -------------------- Local Cart (Client-Side for Guests) --------------------
|
|
21
26
|
// These methods store cart data in localStorage - NO API calls!
|
|
22
27
|
// Use for guest users in vibe-coded sites
|
|
@@ -1995,6 +2000,14 @@ var OmniSyncClient = class {
|
|
|
1995
2000
|
this.customerCartId = null;
|
|
1996
2001
|
}
|
|
1997
2002
|
}
|
|
2003
|
+
try {
|
|
2004
|
+
const cart2 = await this.fetchCustomerCart();
|
|
2005
|
+
if (cart2.status === "ACTIVE") {
|
|
2006
|
+
this.customerCartId = cart2.id;
|
|
2007
|
+
return cart2;
|
|
2008
|
+
}
|
|
2009
|
+
} catch {
|
|
2010
|
+
}
|
|
1998
2011
|
const cart = await this.createCart();
|
|
1999
2012
|
this.customerCartId = cart.id;
|
|
2000
2013
|
if (this.customerToken) {
|
|
@@ -2005,6 +2018,22 @@ var OmniSyncClient = class {
|
|
|
2005
2018
|
}
|
|
2006
2019
|
return cart;
|
|
2007
2020
|
}
|
|
2021
|
+
/**
|
|
2022
|
+
* Fetch the customer's existing cart from server
|
|
2023
|
+
* @internal
|
|
2024
|
+
*/
|
|
2025
|
+
async fetchCustomerCart() {
|
|
2026
|
+
if (!this.customerToken) {
|
|
2027
|
+
throw new OmniSyncError("Customer token required", 401);
|
|
2028
|
+
}
|
|
2029
|
+
if (this.isVibeCodedMode()) {
|
|
2030
|
+
return this.vibeCodedRequest("GET", "/customers/me/cart");
|
|
2031
|
+
}
|
|
2032
|
+
if (this.storeId && !this.apiKey) {
|
|
2033
|
+
return this.storefrontRequest("GET", "/customers/me/cart");
|
|
2034
|
+
}
|
|
2035
|
+
throw new OmniSyncError("fetchCustomerCart requires vibe-coded or storefront mode", 400);
|
|
2036
|
+
}
|
|
2008
2037
|
/**
|
|
2009
2038
|
* Smart add to cart - automatically uses localStorage or server based on auth state
|
|
2010
2039
|
*
|
|
@@ -3008,6 +3037,11 @@ var OmniSyncClient = class {
|
|
|
3008
3037
|
* Pass `selectedIndices` to checkout only specific items from the local cart.
|
|
3009
3038
|
* Use the index of each item in the cart.items array.
|
|
3010
3039
|
*
|
|
3040
|
+
* **IMPORTANT - Order Summary Display:**
|
|
3041
|
+
* After calling this function, use `getCheckout(checkoutId)` to get the checkout
|
|
3042
|
+
* and display `checkout.lineItems` in your Order Summary - NOT the local cart items!
|
|
3043
|
+
* The checkout.lineItems contains ONLY the selected items for this checkout.
|
|
3044
|
+
*
|
|
3011
3045
|
* @param options.selectedIndices - Optional array of item indices for partial checkout
|
|
3012
3046
|
* @returns Tracking result with checkoutId if enabled
|
|
3013
3047
|
*
|
|
@@ -3020,19 +3054,22 @@ var OmniSyncClient = class {
|
|
|
3020
3054
|
* const result = await omni.startGuestCheckout({ selectedIndices: [0, 2] });
|
|
3021
3055
|
*
|
|
3022
3056
|
* if (result.tracked) {
|
|
3023
|
-
* //
|
|
3024
|
-
*
|
|
3057
|
+
* // IMPORTANT: Fetch checkout and use checkout.lineItems for Order Summary!
|
|
3058
|
+
* const checkout = await omni.getCheckout(result.checkoutId);
|
|
3059
|
+
*
|
|
3060
|
+
* // Display Order Summary using checkout.lineItems (NOT localCart.items!)
|
|
3061
|
+
* // checkout.lineItems contains ONLY the selected items
|
|
3062
|
+
* checkout.lineItems.forEach(item => {
|
|
3063
|
+
* console.log(item.product.name, item.quantity, item.unitPrice);
|
|
3064
|
+
* });
|
|
3025
3065
|
*
|
|
3026
3066
|
* // Update checkout with address
|
|
3027
|
-
* await omni.
|
|
3067
|
+
* await omni.updateGuestCheckoutAddress(result.checkoutId, {
|
|
3028
3068
|
* shippingAddress: { ... },
|
|
3029
3069
|
* });
|
|
3030
3070
|
*
|
|
3031
|
-
* //
|
|
3032
|
-
*
|
|
3033
|
-
*
|
|
3034
|
-
* // For partial checkout: remove only purchased items
|
|
3035
|
-
* omni.removeLocalCartItemsByIndex([0, 2]);
|
|
3071
|
+
* // After payment success, call handlePaymentSuccess() to clear cart
|
|
3072
|
+
* omni.handlePaymentSuccess(result.checkoutId);
|
|
3036
3073
|
* } else {
|
|
3037
3074
|
* // Tracking not enabled, use regular submitGuestOrder
|
|
3038
3075
|
* const order = await omni.submitGuestOrder();
|
|
@@ -3060,8 +3097,48 @@ var OmniSyncClient = class {
|
|
|
3060
3097
|
customer: cart.customer
|
|
3061
3098
|
}
|
|
3062
3099
|
);
|
|
3100
|
+
if (response.tracked && response.checkoutId && response.cartId) {
|
|
3101
|
+
this.saveActiveCheckout({
|
|
3102
|
+
checkoutId: response.checkoutId,
|
|
3103
|
+
cartId: response.cartId,
|
|
3104
|
+
selectedIndices: options?.selectedIndices
|
|
3105
|
+
});
|
|
3106
|
+
}
|
|
3063
3107
|
return response;
|
|
3064
3108
|
}
|
|
3109
|
+
/**
|
|
3110
|
+
* Save active checkout to localStorage (persists across page redirects)
|
|
3111
|
+
* @internal
|
|
3112
|
+
*/
|
|
3113
|
+
saveActiveCheckout(checkout) {
|
|
3114
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
3115
|
+
localStorage.setItem(this.ACTIVE_CHECKOUT_KEY, JSON.stringify(checkout));
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
/**
|
|
3119
|
+
* Load active checkout from localStorage
|
|
3120
|
+
* @internal
|
|
3121
|
+
*/
|
|
3122
|
+
loadActiveCheckout() {
|
|
3123
|
+
if (typeof window === "undefined" || !window.localStorage) {
|
|
3124
|
+
return null;
|
|
3125
|
+
}
|
|
3126
|
+
try {
|
|
3127
|
+
const data = localStorage.getItem(this.ACTIVE_CHECKOUT_KEY);
|
|
3128
|
+
return data ? JSON.parse(data) : null;
|
|
3129
|
+
} catch {
|
|
3130
|
+
return null;
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
/**
|
|
3134
|
+
* Clear active checkout from localStorage
|
|
3135
|
+
* @internal
|
|
3136
|
+
*/
|
|
3137
|
+
clearActiveCheckoutStorage() {
|
|
3138
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
3139
|
+
localStorage.removeItem(this.ACTIVE_CHECKOUT_KEY);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3065
3142
|
/**
|
|
3066
3143
|
* Remove specific items from local cart by their indices.
|
|
3067
3144
|
* Use after partial checkout to remove only the purchased items.
|
|
@@ -3152,6 +3229,113 @@ var OmniSyncClient = class {
|
|
|
3152
3229
|
}
|
|
3153
3230
|
return result;
|
|
3154
3231
|
}
|
|
3232
|
+
/**
|
|
3233
|
+
* Get the active guest checkout session info.
|
|
3234
|
+
* Use this to check if there's an active checkout before handling payment success.
|
|
3235
|
+
*
|
|
3236
|
+
* @returns The active checkout info or null if no checkout is active
|
|
3237
|
+
*
|
|
3238
|
+
* @example
|
|
3239
|
+
* ```typescript
|
|
3240
|
+
* const activeCheckout = omni.getActiveGuestCheckout();
|
|
3241
|
+
* if (activeCheckout) {
|
|
3242
|
+
* console.log('Active checkout:', activeCheckout.checkoutId);
|
|
3243
|
+
* console.log('Partial checkout:', activeCheckout.selectedIndices?.length);
|
|
3244
|
+
* }
|
|
3245
|
+
* ```
|
|
3246
|
+
*/
|
|
3247
|
+
getActiveGuestCheckout() {
|
|
3248
|
+
return this.loadActiveCheckout();
|
|
3249
|
+
}
|
|
3250
|
+
/**
|
|
3251
|
+
* Handle payment success - automatically clears the cart (both local and server).
|
|
3252
|
+
*
|
|
3253
|
+
* Call this after Stripe payment succeeds (payment_intent.succeeded or confirmPayment success).
|
|
3254
|
+
* This handles ALL checkout scenarios:
|
|
3255
|
+
*
|
|
3256
|
+
* **For guest users (local cart):**
|
|
3257
|
+
* - Full checkout: clears entire localStorage cart
|
|
3258
|
+
* - Partial checkout: removes only the purchased items
|
|
3259
|
+
*
|
|
3260
|
+
* **For logged-in users (server cart):**
|
|
3261
|
+
* - Clears the cached cart ID so next `smartGetCart()` fetches fresh data
|
|
3262
|
+
* - The server cart is already marked as CONVERTED by the webhook
|
|
3263
|
+
*
|
|
3264
|
+
* **IMPORTANT:** Call this from your payment success handler (e.g., after stripe.confirmPayment succeeds,
|
|
3265
|
+
* or on your success page after redirect). This works for both guests AND logged-in users!
|
|
3266
|
+
*
|
|
3267
|
+
* @param checkoutId - Optional checkout ID for validation
|
|
3268
|
+
* @returns Object indicating whether cart was cleared and how
|
|
3269
|
+
*
|
|
3270
|
+
* @example
|
|
3271
|
+
* ```typescript
|
|
3272
|
+
* // After stripe.confirmPayment() succeeds (works for guests AND logged-in users)
|
|
3273
|
+
* const { error, paymentIntent } = await stripe.confirmPayment({
|
|
3274
|
+
* elements,
|
|
3275
|
+
* confirmParams: { return_url: '/checkout/success' },
|
|
3276
|
+
* redirect: 'if_required',
|
|
3277
|
+
* });
|
|
3278
|
+
*
|
|
3279
|
+
* if (!error && paymentIntent?.status === 'succeeded') {
|
|
3280
|
+
* // Clear the cart automatically - handles all scenarios!
|
|
3281
|
+
* const result = omni.handlePaymentSuccess(checkoutId);
|
|
3282
|
+
* console.log('Cart cleared:', result.cleared);
|
|
3283
|
+
* console.log('User type:', result.userType); // 'guest' or 'customer'
|
|
3284
|
+
* }
|
|
3285
|
+
* ```
|
|
3286
|
+
*
|
|
3287
|
+
* @example
|
|
3288
|
+
* ```typescript
|
|
3289
|
+
* // On success page (after redirect)
|
|
3290
|
+
* const checkoutId = new URLSearchParams(location.search).get('checkout_id');
|
|
3291
|
+
* if (checkoutId) {
|
|
3292
|
+
* omni.handlePaymentSuccess(checkoutId);
|
|
3293
|
+
* }
|
|
3294
|
+
* ```
|
|
3295
|
+
*/
|
|
3296
|
+
handlePaymentSuccess(checkoutId) {
|
|
3297
|
+
const isLoggedIn = this.isCustomerLoggedIn();
|
|
3298
|
+
if (isLoggedIn) {
|
|
3299
|
+
this.customerCartId = null;
|
|
3300
|
+
}
|
|
3301
|
+
const activeCheckout = this.loadActiveCheckout();
|
|
3302
|
+
if (checkoutId && activeCheckout && activeCheckout.checkoutId !== checkoutId) {
|
|
3303
|
+
console.warn(
|
|
3304
|
+
`handlePaymentSuccess: checkoutId mismatch. Expected ${activeCheckout.checkoutId}, got ${checkoutId}. Proceeding with cleanup.`
|
|
3305
|
+
);
|
|
3306
|
+
}
|
|
3307
|
+
this.clearActiveCheckoutStorage();
|
|
3308
|
+
if (isLoggedIn) {
|
|
3309
|
+
this.clearLocalCart();
|
|
3310
|
+
return {
|
|
3311
|
+
cleared: true,
|
|
3312
|
+
mode: "full",
|
|
3313
|
+
userType: "customer"
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
if (activeCheckout?.selectedIndices && activeCheckout.selectedIndices.length > 0) {
|
|
3317
|
+
this.removeLocalCartItemsByIndex(activeCheckout.selectedIndices);
|
|
3318
|
+
return {
|
|
3319
|
+
cleared: true,
|
|
3320
|
+
mode: "partial",
|
|
3321
|
+
userType: "guest",
|
|
3322
|
+
itemsRemoved: activeCheckout.selectedIndices.length
|
|
3323
|
+
};
|
|
3324
|
+
}
|
|
3325
|
+
this.clearLocalCart();
|
|
3326
|
+
return {
|
|
3327
|
+
cleared: true,
|
|
3328
|
+
mode: "full",
|
|
3329
|
+
userType: "guest"
|
|
3330
|
+
};
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Clear the active guest checkout tracking without clearing the cart.
|
|
3334
|
+
* Use this if the user abandons checkout or navigates away.
|
|
3335
|
+
*/
|
|
3336
|
+
clearActiveGuestCheckout() {
|
|
3337
|
+
this.clearActiveCheckoutStorage();
|
|
3338
|
+
}
|
|
3155
3339
|
/**
|
|
3156
3340
|
* Create order from custom data (not from local cart)
|
|
3157
3341
|
* Use this if you manage cart state yourself
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-sync-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Official SDK for building e-commerce storefronts with OmniSync Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,14 +16,6 @@
|
|
|
16
16
|
"dist",
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
-
"lint": "eslint \"src/**/*.ts\"",
|
|
23
|
-
"test": "vitest run",
|
|
24
|
-
"test:watch": "vitest",
|
|
25
|
-
"prepublishOnly": "pnpm build"
|
|
26
|
-
},
|
|
27
19
|
"keywords": [
|
|
28
20
|
"omni-sync",
|
|
29
21
|
"e-commerce",
|
|
@@ -72,5 +64,12 @@
|
|
|
72
64
|
"typescript": {
|
|
73
65
|
"optional": true
|
|
74
66
|
}
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
70
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
71
|
+
"lint": "eslint \"src/**/*.ts\"",
|
|
72
|
+
"test": "vitest run",
|
|
73
|
+
"test:watch": "vitest"
|
|
75
74
|
}
|
|
76
|
-
}
|
|
75
|
+
}
|