@zonos/elements 1.3.251 → 1.3.253

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.
@@ -133,7 +133,7 @@ const getZonosQaUrl = () => {
133
133
  return null;
134
134
  }
135
135
  const qaUrl = extractZonosQaUrl(window.location.href);
136
- const cdnUrl = "https://v1.3.251.js.zonos.com";
136
+ const cdnUrl = "https://v1.3.253.js.zonos.com";
137
137
  // when the qaUrl is not set and the built URL is from the test domain, use the test domain for testing
138
138
  if (!qaUrl &&
139
139
  (cdnUrl.includes('test.') ||
@@ -381,10 +381,10 @@ const zonosLoadUrl = (() => {
381
381
  return null;
382
382
  })();
383
383
  const startLoadTime = Date.now();
384
- const ZONOS_URL = "https://v1.3.251.js.zonos.com";
385
- const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.251";
386
- const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.251";
387
- const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.251";
384
+ const ZONOS_URL = "https://v1.3.253.js.zonos.com";
385
+ const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.253";
386
+ const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.253";
387
+ const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.253";
388
388
  const GOOGLE_FONT_URL = 'https://fonts.googleapis.com';
389
389
  const GOOGLE_FONT_REGEX = /^https:\/\/fonts\.googleapis\.com/;
390
390
  class Zonos {
@@ -402,7 +402,7 @@ Zonos.iframeLogType = typeof window !== 'undefined'
402
402
  ? new URLSearchParams(window.location.search).get('iframeLogType')
403
403
  : null;
404
404
  Zonos.isBigCommerce = false;
405
- Zonos.releaseDate = "1775502731069";
405
+ Zonos.releaseDate = "1775689881541";
406
406
  Zonos.isLegacyCheckout = false;
407
407
  Zonos.googleAnalyticId = null;
408
408
  Zonos.googleAnalyticReady = false;
@@ -425,7 +425,7 @@ Zonos.isNpm = true;
425
425
  Zonos.zonosQaUrl = null;
426
426
  Zonos.zonosQaUrlApi = null;
427
427
  Zonos.trackEventLogs = [];
428
- Zonos.version = `v${"1.3.251"}`;
428
+ Zonos.version = `v${"1.3.253"}`;
429
429
  Zonos.modeAlerted = false;
430
430
  Zonos.cartData = null;
431
431
  Zonos.paypal = null;
@@ -138,6 +138,102 @@ providedCountryCode) => {
138
138
  };
139
139
 
140
140
  const FALLBACK_SHIP_TO_COUNTRY_SELECTOR = 'select[name="shippingAddress.countryCode"]';
141
+ /**
142
+ * Fetch the checkout/cart ID from the BigCommerce Storefront Cart API.
143
+ * The `/checkout` page URL does not include the checkout ID, so we
144
+ * retrieve it from `/api/storefront/cart` which returns the active cart(s).
145
+ */
146
+ const fetchCheckoutId = async () => {
147
+ var _a, _b;
148
+ try {
149
+ const response = await fetch('/api/storefront/cart', {
150
+ credentials: 'same-origin',
151
+ headers: {
152
+ Accept: 'application/json',
153
+ },
154
+ });
155
+ if (!response.ok) {
156
+ VarianceTest.log(`Failed to fetch BigCommerce cart: ${String(response.status)}`, 'error');
157
+ return null;
158
+ }
159
+ const carts = (await response.json());
160
+ return (_b = (_a = carts === null || carts === void 0 ? void 0 : carts[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
161
+ }
162
+ catch (error) {
163
+ handleFetch.logError('Error fetching BigCommerce cart data', error);
164
+ return null;
165
+ }
166
+ };
167
+ /**
168
+ * Fetch checkout data from the BigCommerce Storefront API.
169
+ * This API is cookie-authenticated (same-origin), so no token is needed.
170
+ */
171
+ const fetchBigCommerceCheckout = async (checkoutId) => {
172
+ try {
173
+ const response = await fetch(`/api/storefront/checkouts/${checkoutId}`, {
174
+ credentials: 'same-origin',
175
+ headers: {
176
+ Accept: 'application/json',
177
+ 'Content-Type': 'application/json',
178
+ },
179
+ });
180
+ if (!response.ok) {
181
+ VarianceTest.log(`Failed to fetch BigCommerce checkout: ${String(response.status)}`, 'error');
182
+ return null;
183
+ }
184
+ return (await response.json());
185
+ }
186
+ catch (error) {
187
+ handleFetch.logError('Error fetching BigCommerce checkout data', error);
188
+ return null;
189
+ }
190
+ };
191
+ /**
192
+ * Check if the logged-in user already has a shipping address on the checkout
193
+ * that is internationally shippable. If so, save the address to session
194
+ * and redirect to the home page to open the international checkout.
195
+ */
196
+ const checkLoggedInUserShippingAddress = async ({ onInternationalCheckoutSelected, }) => {
197
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
198
+ const checkoutId = await fetchCheckoutId();
199
+ if (!checkoutId) {
200
+ return false;
201
+ }
202
+ const checkout = await fetchBigCommerceCheckout(checkoutId);
203
+ const shippingAddress = (_b = (_a = checkout === null || checkout === void 0 ? void 0 : checkout.consignments) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.shippingAddress;
204
+ if (!(shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.countryCode)) {
205
+ return false;
206
+ }
207
+ const countryCode = shippingAddress.countryCode;
208
+ if (!isShippableCountry(false, countryCode)) {
209
+ return false;
210
+ }
211
+ VarianceTest.log(`Logged-in user has international shipping address: ${countryCode}, redirecting`, 'info');
212
+ if (onInternationalCheckoutSelected) {
213
+ await onInternationalCheckoutSelected();
214
+ }
215
+ // Update localization store with the detected country
216
+ localization.localizationStoreUpdateSelectedCountryCode({
217
+ isInitializing: false,
218
+ newSelectedCountryCode: countryCode,
219
+ });
220
+ // Save the shipping address to session storage for the international checkout
221
+ cart.stripeStoreSaveDomesticShippingSession({
222
+ address1: (_c = shippingAddress.address1) !== null && _c !== void 0 ? _c : '',
223
+ address2: (_d = shippingAddress.address2) !== null && _d !== void 0 ? _d : '',
224
+ city: (_e = shippingAddress.city) !== null && _e !== void 0 ? _e : '',
225
+ countryCode,
226
+ firstName: (_f = shippingAddress.firstName) !== null && _f !== void 0 ? _f : '',
227
+ lastName: (_g = shippingAddress.lastName) !== null && _g !== void 0 ? _g : '',
228
+ phone: (_h = shippingAddress.phone) !== null && _h !== void 0 ? _h : '',
229
+ postalCode: (_j = shippingAddress.postalCode) !== null && _j !== void 0 ? _j : '',
230
+ state: (_k = shippingAddress.stateOrProvince) !== null && _k !== void 0 ? _k : '',
231
+ });
232
+ // Redirect to home page — the home page will open the international checkout
233
+ // when it detects the domestic shipping session
234
+ window.location.href = '/';
235
+ return true;
236
+ };
141
237
  /**
142
238
  * Watch for changes in domestic checkout step. Redirects user to home page to open international checkout when user selects a country in the international shipping zone.
143
239
  * @note Only works on default bigcommerce checkout page
@@ -200,7 +296,8 @@ const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedirectedB
200
296
  };
201
297
  let isProcessing = false;
202
298
  let intervalCreated = false;
203
- const observer = new MutationObserver(() => {
299
+ let isCheckingLoggedInUserShippingAddress = false;
300
+ const observer = new MutationObserver(async () => {
204
301
  var _a;
205
302
  const domesticRedirectedButton = document.querySelector(domesticRedirectedBtnSelector);
206
303
  const shippingAddressSession = cart.stripeStoreGetDomesticShippingSession();
@@ -218,13 +315,35 @@ const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedirectedB
218
315
  }
219
316
  const isBigcommerceDomesticCheckoutPage = window.location.pathname.includes('/checkout') &&
220
317
  window.Zonos.isBigCommerce;
221
- const shipToCountryElement = document.querySelector(((_a = zonosStore.zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
222
- FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
223
318
  // Should just disconnect the observer if it's not bigcommerce domestic checkout page
224
319
  if (!isBigcommerceDomesticCheckoutPage) {
225
320
  observer.disconnect();
226
321
  return;
227
322
  }
323
+ // For logged-in users, check if their saved address on the checkout is international
324
+ // before the shipping form is even rendered.
325
+ // Guard against repeated calls — the observer fires on every DOM mutation.
326
+ if (isCheckingLoggedInUserShippingAddress) {
327
+ return;
328
+ }
329
+ isCheckingLoggedInUserShippingAddress = true;
330
+ try {
331
+ const redirected = await checkLoggedInUserShippingAddress({
332
+ onInternationalCheckoutSelected,
333
+ });
334
+ if (redirected) {
335
+ observer.disconnect();
336
+ return;
337
+ }
338
+ }
339
+ catch (error) {
340
+ handleFetch.logError('Error checking logged-in user shipping address', error);
341
+ }
342
+ finally {
343
+ isCheckingLoggedInUserShippingAddress = false;
344
+ }
345
+ const shipToCountryElement = document.querySelector(((_a = zonosStore.zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
346
+ FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
228
347
  // Shouldn't do anything if it's not bigcommerce domestic checkout page
229
348
  if (!shipToCountryElement) {
230
349
  // do nothing if shipping country and the continue button is not found
@@ -1923,6 +2042,14 @@ const ZonosCheckout = class {
1923
2042
  zonosStore.zonosStore.sourceCurrency !== 'USD') {
1924
2043
  return;
1925
2044
  }
2045
+ // Only redirect when checkout modal is opened
2046
+ if (!this.open) {
2047
+ return;
2048
+ }
2049
+ // Check if the page is checkout page, if so, do nothing since they're already at the right page
2050
+ if (window.location.pathname.includes('/checkout')) {
2051
+ return;
2052
+ }
1926
2053
  const shippingCountry = addressEventData.value.address.country;
1927
2054
  if (shippingCountry &&
1928
2055
  zonosStore.zonosStore.disabledCountries.includes(shippingCountry)) {
@@ -1490,6 +1490,14 @@ export class ZonosCheckout {
1490
1490
  zonosStore.sourceCurrency !== 'USD') {
1491
1491
  return;
1492
1492
  }
1493
+ // Only redirect when checkout modal is opened
1494
+ if (!this.open) {
1495
+ return;
1496
+ }
1497
+ // Check if the page is checkout page, if so, do nothing since they're already at the right page
1498
+ if (window.location.pathname.includes('/checkout')) {
1499
+ return;
1500
+ }
1493
1501
  const shippingCountry = addressEventData.value.address.country;
1494
1502
  if (shippingCountry &&
1495
1503
  zonosStore.disabledCountries.includes(shippingCountry)) {
@@ -3,7 +3,104 @@ import { localizationStoreUpdateSelectedCountryCode } from "../../store/hello/lo
3
3
  import { zonosStore } from "../../store/zonosStore";
4
4
  import { isShippableCountry } from "./isShippableCountry";
5
5
  import { log } from "../logging/log";
6
+ import { logError } from "../logging/logError";
6
7
  const FALLBACK_SHIP_TO_COUNTRY_SELECTOR = 'select[name="shippingAddress.countryCode"]';
8
+ /**
9
+ * Fetch the checkout/cart ID from the BigCommerce Storefront Cart API.
10
+ * The `/checkout` page URL does not include the checkout ID, so we
11
+ * retrieve it from `/api/storefront/cart` which returns the active cart(s).
12
+ */
13
+ const fetchCheckoutId = async () => {
14
+ var _a, _b;
15
+ try {
16
+ const response = await fetch('/api/storefront/cart', {
17
+ credentials: 'same-origin',
18
+ headers: {
19
+ Accept: 'application/json',
20
+ },
21
+ });
22
+ if (!response.ok) {
23
+ log(`Failed to fetch BigCommerce cart: ${String(response.status)}`, 'error');
24
+ return null;
25
+ }
26
+ const carts = (await response.json());
27
+ return (_b = (_a = carts === null || carts === void 0 ? void 0 : carts[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
28
+ }
29
+ catch (error) {
30
+ logError('Error fetching BigCommerce cart data', error);
31
+ return null;
32
+ }
33
+ };
34
+ /**
35
+ * Fetch checkout data from the BigCommerce Storefront API.
36
+ * This API is cookie-authenticated (same-origin), so no token is needed.
37
+ */
38
+ const fetchBigCommerceCheckout = async (checkoutId) => {
39
+ try {
40
+ const response = await fetch(`/api/storefront/checkouts/${checkoutId}`, {
41
+ credentials: 'same-origin',
42
+ headers: {
43
+ Accept: 'application/json',
44
+ 'Content-Type': 'application/json',
45
+ },
46
+ });
47
+ if (!response.ok) {
48
+ log(`Failed to fetch BigCommerce checkout: ${String(response.status)}`, 'error');
49
+ return null;
50
+ }
51
+ return (await response.json());
52
+ }
53
+ catch (error) {
54
+ logError('Error fetching BigCommerce checkout data', error);
55
+ return null;
56
+ }
57
+ };
58
+ /**
59
+ * Check if the logged-in user already has a shipping address on the checkout
60
+ * that is internationally shippable. If so, save the address to session
61
+ * and redirect to the home page to open the international checkout.
62
+ */
63
+ const checkLoggedInUserShippingAddress = async ({ onInternationalCheckoutSelected, }) => {
64
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
65
+ const checkoutId = await fetchCheckoutId();
66
+ if (!checkoutId) {
67
+ return false;
68
+ }
69
+ const checkout = await fetchBigCommerceCheckout(checkoutId);
70
+ const shippingAddress = (_b = (_a = checkout === null || checkout === void 0 ? void 0 : checkout.consignments) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.shippingAddress;
71
+ if (!(shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.countryCode)) {
72
+ return false;
73
+ }
74
+ const countryCode = shippingAddress.countryCode;
75
+ if (!isShippableCountry(false, countryCode)) {
76
+ return false;
77
+ }
78
+ log(`Logged-in user has international shipping address: ${countryCode}, redirecting`, 'info');
79
+ if (onInternationalCheckoutSelected) {
80
+ await onInternationalCheckoutSelected();
81
+ }
82
+ // Update localization store with the detected country
83
+ localizationStoreUpdateSelectedCountryCode({
84
+ isInitializing: false,
85
+ newSelectedCountryCode: countryCode,
86
+ });
87
+ // Save the shipping address to session storage for the international checkout
88
+ stripeStoreSaveDomesticShippingSession({
89
+ address1: (_c = shippingAddress.address1) !== null && _c !== void 0 ? _c : '',
90
+ address2: (_d = shippingAddress.address2) !== null && _d !== void 0 ? _d : '',
91
+ city: (_e = shippingAddress.city) !== null && _e !== void 0 ? _e : '',
92
+ countryCode,
93
+ firstName: (_f = shippingAddress.firstName) !== null && _f !== void 0 ? _f : '',
94
+ lastName: (_g = shippingAddress.lastName) !== null && _g !== void 0 ? _g : '',
95
+ phone: (_h = shippingAddress.phone) !== null && _h !== void 0 ? _h : '',
96
+ postalCode: (_j = shippingAddress.postalCode) !== null && _j !== void 0 ? _j : '',
97
+ state: (_k = shippingAddress.stateOrProvince) !== null && _k !== void 0 ? _k : '',
98
+ });
99
+ // Redirect to home page — the home page will open the international checkout
100
+ // when it detects the domestic shipping session
101
+ window.location.href = '/';
102
+ return true;
103
+ };
7
104
  /**
8
105
  * Watch for changes in domestic checkout step. Redirects user to home page to open international checkout when user selects a country in the international shipping zone.
9
106
  * @note Only works on default bigcommerce checkout page
@@ -66,7 +163,8 @@ export const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedi
66
163
  };
67
164
  let isProcessing = false;
68
165
  let intervalCreated = false;
69
- const observer = new MutationObserver(() => {
166
+ let isCheckingLoggedInUserShippingAddress = false;
167
+ const observer = new MutationObserver(async () => {
70
168
  var _a;
71
169
  const domesticRedirectedButton = document.querySelector(domesticRedirectedBtnSelector);
72
170
  const shippingAddressSession = stripeStoreGetDomesticShippingSession();
@@ -84,13 +182,35 @@ export const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedi
84
182
  }
85
183
  const isBigcommerceDomesticCheckoutPage = window.location.pathname.includes('/checkout') &&
86
184
  window.Zonos.isBigCommerce;
87
- const shipToCountryElement = document.querySelector(((_a = zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
88
- FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
89
185
  // Should just disconnect the observer if it's not bigcommerce domestic checkout page
90
186
  if (!isBigcommerceDomesticCheckoutPage) {
91
187
  observer.disconnect();
92
188
  return;
93
189
  }
190
+ // For logged-in users, check if their saved address on the checkout is international
191
+ // before the shipping form is even rendered.
192
+ // Guard against repeated calls — the observer fires on every DOM mutation.
193
+ if (isCheckingLoggedInUserShippingAddress) {
194
+ return;
195
+ }
196
+ isCheckingLoggedInUserShippingAddress = true;
197
+ try {
198
+ const redirected = await checkLoggedInUserShippingAddress({
199
+ onInternationalCheckoutSelected,
200
+ });
201
+ if (redirected) {
202
+ observer.disconnect();
203
+ return;
204
+ }
205
+ }
206
+ catch (error) {
207
+ logError('Error checking logged-in user shipping address', error);
208
+ }
209
+ finally {
210
+ isCheckingLoggedInUserShippingAddress = false;
211
+ }
212
+ const shipToCountryElement = document.querySelector(((_a = zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
213
+ FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
94
214
  // Shouldn't do anything if it's not bigcommerce domestic checkout page
95
215
  if (!shipToCountryElement) {
96
216
  // do nothing if shipping country and the continue button is not found
package/dist/esm/index.js CHANGED
@@ -131,7 +131,7 @@ const getZonosQaUrl = () => {
131
131
  return null;
132
132
  }
133
133
  const qaUrl = extractZonosQaUrl(window.location.href);
134
- const cdnUrl = "https://v1.3.251.js.zonos.com";
134
+ const cdnUrl = "https://v1.3.253.js.zonos.com";
135
135
  // when the qaUrl is not set and the built URL is from the test domain, use the test domain for testing
136
136
  if (!qaUrl &&
137
137
  (cdnUrl.includes('test.') ||
@@ -379,10 +379,10 @@ const zonosLoadUrl = (() => {
379
379
  return null;
380
380
  })();
381
381
  const startLoadTime = Date.now();
382
- const ZONOS_URL = "https://v1.3.251.js.zonos.com";
383
- const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.251";
384
- const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.251";
385
- const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.251";
382
+ const ZONOS_URL = "https://v1.3.253.js.zonos.com";
383
+ const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.253";
384
+ const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.253";
385
+ const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.253";
386
386
  const GOOGLE_FONT_URL = 'https://fonts.googleapis.com';
387
387
  const GOOGLE_FONT_REGEX = /^https:\/\/fonts\.googleapis\.com/;
388
388
  class Zonos {
@@ -400,7 +400,7 @@ Zonos.iframeLogType = typeof window !== 'undefined'
400
400
  ? new URLSearchParams(window.location.search).get('iframeLogType')
401
401
  : null;
402
402
  Zonos.isBigCommerce = false;
403
- Zonos.releaseDate = "1775502731069";
403
+ Zonos.releaseDate = "1775689881541";
404
404
  Zonos.isLegacyCheckout = false;
405
405
  Zonos.googleAnalyticId = null;
406
406
  Zonos.googleAnalyticReady = false;
@@ -423,7 +423,7 @@ Zonos.isNpm = true;
423
423
  Zonos.zonosQaUrl = null;
424
424
  Zonos.zonosQaUrlApi = null;
425
425
  Zonos.trackEventLogs = [];
426
- Zonos.version = `v${"1.3.251"}`;
426
+ Zonos.version = `v${"1.3.253"}`;
427
427
  Zonos.modeAlerted = false;
428
428
  Zonos.cartData = null;
429
429
  Zonos.paypal = null;
@@ -4,7 +4,7 @@ import { p as paypalStoreHasPaypalEnabled, a as paypalStore, b as paypalInitScri
4
4
  import { f as filterValidTests, l as localizationStore, a as localizationStoreUpdateSelectedCountryCode, g as getZCountryUrlParam, s as storageStore, V as VARIANT_TEST_KEY_EXPIRATION, b as storageStoreSetEnabledVariantTestKeys, t as translate, c as localizationStoreOnChange, d as currencyFormat } from './localization-0ebc8356.js';
5
5
  import { z as zonosStore, g as getZonosStoreTheme, m as mergeConfig } from './zonosStore-5242a58d.js';
6
6
  import { b as buildCartItemsByTempCart } from './buildCartItemsByTempCart-a117f75d.js';
7
- import { h as handleFetch, b as getAdditionalLogMetadata, g as getIsTestMode, l as logError, j as jsonParse, s as sendErrorLog, a as getIsStagingMode, i as isCheckoutMobile } from './handleFetch-a844cac1.js';
7
+ import { h as handleFetch, l as logError, b as getAdditionalLogMetadata, g as getIsTestMode, j as jsonParse, s as sendErrorLog, a as getIsStagingMode, i as isCheckoutMobile } from './handleFetch-a844cac1.js';
8
8
  import { u as updateCheckoutSessionAttributes } from './updateCheckoutSessionAttributes-b9f7e982.js';
9
9
  import { _ as _getIsValidCartId, c as checkoutHiddenBtnSelector, a as checkoutHiddenInternationalBtnSelector, d as domesticRedirectedBtnSelector, g as getAbandonedCartRenewTokenValue } from './CheckoutConfig-724d7bae.js';
10
10
  import { l as log, g as getElapsedTime, b as allLogs } from './VarianceTest-572cecf5.js';
@@ -134,6 +134,102 @@ providedCountryCode) => {
134
134
  };
135
135
 
136
136
  const FALLBACK_SHIP_TO_COUNTRY_SELECTOR = 'select[name="shippingAddress.countryCode"]';
137
+ /**
138
+ * Fetch the checkout/cart ID from the BigCommerce Storefront Cart API.
139
+ * The `/checkout` page URL does not include the checkout ID, so we
140
+ * retrieve it from `/api/storefront/cart` which returns the active cart(s).
141
+ */
142
+ const fetchCheckoutId = async () => {
143
+ var _a, _b;
144
+ try {
145
+ const response = await fetch('/api/storefront/cart', {
146
+ credentials: 'same-origin',
147
+ headers: {
148
+ Accept: 'application/json',
149
+ },
150
+ });
151
+ if (!response.ok) {
152
+ log(`Failed to fetch BigCommerce cart: ${String(response.status)}`, 'error');
153
+ return null;
154
+ }
155
+ const carts = (await response.json());
156
+ return (_b = (_a = carts === null || carts === void 0 ? void 0 : carts[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : null;
157
+ }
158
+ catch (error) {
159
+ logError('Error fetching BigCommerce cart data', error);
160
+ return null;
161
+ }
162
+ };
163
+ /**
164
+ * Fetch checkout data from the BigCommerce Storefront API.
165
+ * This API is cookie-authenticated (same-origin), so no token is needed.
166
+ */
167
+ const fetchBigCommerceCheckout = async (checkoutId) => {
168
+ try {
169
+ const response = await fetch(`/api/storefront/checkouts/${checkoutId}`, {
170
+ credentials: 'same-origin',
171
+ headers: {
172
+ Accept: 'application/json',
173
+ 'Content-Type': 'application/json',
174
+ },
175
+ });
176
+ if (!response.ok) {
177
+ log(`Failed to fetch BigCommerce checkout: ${String(response.status)}`, 'error');
178
+ return null;
179
+ }
180
+ return (await response.json());
181
+ }
182
+ catch (error) {
183
+ logError('Error fetching BigCommerce checkout data', error);
184
+ return null;
185
+ }
186
+ };
187
+ /**
188
+ * Check if the logged-in user already has a shipping address on the checkout
189
+ * that is internationally shippable. If so, save the address to session
190
+ * and redirect to the home page to open the international checkout.
191
+ */
192
+ const checkLoggedInUserShippingAddress = async ({ onInternationalCheckoutSelected, }) => {
193
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
194
+ const checkoutId = await fetchCheckoutId();
195
+ if (!checkoutId) {
196
+ return false;
197
+ }
198
+ const checkout = await fetchBigCommerceCheckout(checkoutId);
199
+ const shippingAddress = (_b = (_a = checkout === null || checkout === void 0 ? void 0 : checkout.consignments) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.shippingAddress;
200
+ if (!(shippingAddress === null || shippingAddress === void 0 ? void 0 : shippingAddress.countryCode)) {
201
+ return false;
202
+ }
203
+ const countryCode = shippingAddress.countryCode;
204
+ if (!isShippableCountry(false, countryCode)) {
205
+ return false;
206
+ }
207
+ log(`Logged-in user has international shipping address: ${countryCode}, redirecting`, 'info');
208
+ if (onInternationalCheckoutSelected) {
209
+ await onInternationalCheckoutSelected();
210
+ }
211
+ // Update localization store with the detected country
212
+ localizationStoreUpdateSelectedCountryCode({
213
+ isInitializing: false,
214
+ newSelectedCountryCode: countryCode,
215
+ });
216
+ // Save the shipping address to session storage for the international checkout
217
+ stripeStoreSaveDomesticShippingSession({
218
+ address1: (_c = shippingAddress.address1) !== null && _c !== void 0 ? _c : '',
219
+ address2: (_d = shippingAddress.address2) !== null && _d !== void 0 ? _d : '',
220
+ city: (_e = shippingAddress.city) !== null && _e !== void 0 ? _e : '',
221
+ countryCode,
222
+ firstName: (_f = shippingAddress.firstName) !== null && _f !== void 0 ? _f : '',
223
+ lastName: (_g = shippingAddress.lastName) !== null && _g !== void 0 ? _g : '',
224
+ phone: (_h = shippingAddress.phone) !== null && _h !== void 0 ? _h : '',
225
+ postalCode: (_j = shippingAddress.postalCode) !== null && _j !== void 0 ? _j : '',
226
+ state: (_k = shippingAddress.stateOrProvince) !== null && _k !== void 0 ? _k : '',
227
+ });
228
+ // Redirect to home page — the home page will open the international checkout
229
+ // when it detects the domestic shipping session
230
+ window.location.href = '/';
231
+ return true;
232
+ };
137
233
  /**
138
234
  * Watch for changes in domestic checkout step. Redirects user to home page to open international checkout when user selects a country in the international shipping zone.
139
235
  * @note Only works on default bigcommerce checkout page
@@ -196,7 +292,8 @@ const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedirectedB
196
292
  };
197
293
  let isProcessing = false;
198
294
  let intervalCreated = false;
199
- const observer = new MutationObserver(() => {
295
+ let isCheckingLoggedInUserShippingAddress = false;
296
+ const observer = new MutationObserver(async () => {
200
297
  var _a;
201
298
  const domesticRedirectedButton = document.querySelector(domesticRedirectedBtnSelector);
202
299
  const shippingAddressSession = stripeStoreGetDomesticShippingSession();
@@ -214,13 +311,35 @@ const watchImmediateBigcommerceDomesticCheckoutRedirect = ({ domesticRedirectedB
214
311
  }
215
312
  const isBigcommerceDomesticCheckoutPage = window.location.pathname.includes('/checkout') &&
216
313
  window.Zonos.isBigCommerce;
217
- const shipToCountryElement = document.querySelector(((_a = zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
218
- FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
219
314
  // Should just disconnect the observer if it's not bigcommerce domestic checkout page
220
315
  if (!isBigcommerceDomesticCheckoutPage) {
221
316
  observer.disconnect();
222
317
  return;
223
318
  }
319
+ // For logged-in users, check if their saved address on the checkout is international
320
+ // before the shipping form is even rendered.
321
+ // Guard against repeated calls — the observer fires on every DOM mutation.
322
+ if (isCheckingLoggedInUserShippingAddress) {
323
+ return;
324
+ }
325
+ isCheckingLoggedInUserShippingAddress = true;
326
+ try {
327
+ const redirected = await checkLoggedInUserShippingAddress({
328
+ onInternationalCheckoutSelected,
329
+ });
330
+ if (redirected) {
331
+ observer.disconnect();
332
+ return;
333
+ }
334
+ }
335
+ catch (error) {
336
+ logError('Error checking logged-in user shipping address', error);
337
+ }
338
+ finally {
339
+ isCheckingLoggedInUserShippingAddress = false;
340
+ }
341
+ const shipToCountryElement = document.querySelector(((_a = zonosStore.genericSettings) === null || _a === void 0 ? void 0 : _a.bigcommerceDomesticCheckoutCountrySelector) ||
342
+ FALLBACK_SHIP_TO_COUNTRY_SELECTOR);
224
343
  // Shouldn't do anything if it's not bigcommerce domestic checkout page
225
344
  if (!shipToCountryElement) {
226
345
  // do nothing if shipping country and the continue button is not found
@@ -1919,6 +2038,14 @@ const ZonosCheckout = class {
1919
2038
  zonosStore.sourceCurrency !== 'USD') {
1920
2039
  return;
1921
2040
  }
2041
+ // Only redirect when checkout modal is opened
2042
+ if (!this.open) {
2043
+ return;
2044
+ }
2045
+ // Check if the page is checkout page, if so, do nothing since they're already at the right page
2046
+ if (window.location.pathname.includes('/checkout')) {
2047
+ return;
2048
+ }
1922
2049
  const shippingCountry = addressEventData.value.address.country;
1923
2050
  if (shippingCountry &&
1924
2051
  zonosStore.disabledCountries.includes(shippingCountry)) {