@zonos/elements 1.3.261 → 1.3.262

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.
Files changed (105) hide show
  1. package/dist/cjs/index.cjs.js +12 -9
  2. package/dist/cjs/{paypal-73a542cb.js → paypal-e278f405.js} +140 -6
  3. package/dist/cjs/submitGtag-4241212b.js +167 -0
  4. package/dist/cjs/zonos-card_5.cjs.entry.js +2 -2
  5. package/dist/cjs/zonos-cart-items_12.cjs.entry.js +30 -21
  6. package/dist/cjs/zonos-checkout.cjs.entry.js +7 -7
  7. package/dist/cjs/zonos-collect-finish_6.cjs.entry.js +8 -8
  8. package/dist/cjs/zonos-collect.cjs.entry.js +2 -2
  9. package/dist/cjs/zonos-controller.cjs.entry.js +3 -3
  10. package/dist/cjs/zonos-invoice-finish_5.cjs.entry.js +8 -8
  11. package/dist/cjs/zonos-invoice.cjs.entry.js +2 -2
  12. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout-finish/zonos-checkout-finish.js +12 -12
  13. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout-payment/zonos-checkout-payment.css +7 -0
  14. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout-payment/zonos-checkout-payment.js +7 -3
  15. package/dist/collection/components/checkout/zonos-checkout/zonos-checkout.js +6 -6
  16. package/dist/collection/components/checkout/zonos-checkout/zonos-customer-info/zonos-customer-info.css +7 -0
  17. package/dist/collection/components/checkout/zonos-checkout/zonos-customer-info/zonos-customer-info.js +5 -1
  18. package/dist/collection/components/checkout/zonos-checkout/zonos-shipping/zonos-shipping.css +7 -0
  19. package/dist/collection/components/checkout/zonos-checkout/zonos-shipping/zonos-shipping.js +6 -3
  20. package/dist/collection/components/checkout/zonos-collect/zonos-collect-finish/zonos-collect-finish.js +6 -6
  21. package/dist/collection/components/checkout/zonos-collect/zonos-collect-payment/zonos-collect-payment.js +2 -2
  22. package/dist/collection/components/checkout/zonos-invoice/zonos-invoice-finish/zonos-invoice-finish.js +6 -6
  23. package/dist/collection/components/checkout/zonos-invoice/zonos-invoice-payment/zonos-invoice-payment.js +2 -2
  24. package/dist/collection/components/main/zonos-controller.js +2 -2
  25. package/dist/collection/components/store/checkout/paypal.js +4 -4
  26. package/dist/collection/components/utils/analytics/analyticsRelayState.js +112 -0
  27. package/dist/collection/components/utils/analytics/mapToFbEvent.js +66 -0
  28. package/dist/collection/components/utils/submitAnalytics.js +16 -0
  29. package/dist/collection/components/utils/submitFbq.js +56 -0
  30. package/dist/collection/components/utils/submitGtag.js +15 -78
  31. package/dist/collection/scripts/_zonosBase.js +5 -2
  32. package/dist/collection/types/analyticsRelay.js +2 -2
  33. package/dist/esm/index.js +12 -9
  34. package/dist/esm/{paypal-38ca5d21.js → paypal-d8804da5.js} +142 -9
  35. package/dist/esm/submitGtag-7f5c5bb5.js +162 -0
  36. package/dist/esm/zonos-card_5.entry.js +2 -2
  37. package/dist/esm/zonos-cart-items_12.entry.js +30 -21
  38. package/dist/esm/zonos-checkout.entry.js +7 -7
  39. package/dist/esm/zonos-collect-finish_6.entry.js +8 -8
  40. package/dist/esm/zonos-collect.entry.js +2 -2
  41. package/dist/esm/zonos-controller.entry.js +3 -3
  42. package/dist/esm/zonos-invoice-finish_5.entry.js +8 -8
  43. package/dist/esm/zonos-invoice.entry.js +2 -2
  44. package/dist/esm-es5/index.js +1 -1
  45. package/dist/esm-es5/paypal-d8804da5.js +17 -0
  46. package/dist/esm-es5/submitGtag-7f5c5bb5.js +1 -0
  47. package/dist/esm-es5/zonos-card_5.entry.js +1 -1
  48. package/dist/esm-es5/zonos-cart-items_12.entry.js +1 -1
  49. package/dist/esm-es5/zonos-checkout.entry.js +1 -1
  50. package/dist/esm-es5/zonos-collect-finish_6.entry.js +1 -1
  51. package/dist/esm-es5/zonos-collect.entry.js +1 -1
  52. package/dist/esm-es5/zonos-controller.entry.js +1 -1
  53. package/dist/esm-es5/zonos-invoice-finish_5.entry.js +1 -1
  54. package/dist/esm-es5/zonos-invoice.entry.js +1 -1
  55. package/dist/scripts/analyticsRelayOnInit.js +1 -1
  56. package/dist/scripts/index.d.ts +11 -0
  57. package/dist/scripts/index.js +1 -1
  58. package/dist/scripts/loadZonos.js +1 -1
  59. package/dist/scripts/zonos.js +1 -1
  60. package/dist/types/components/utils/analytics/analyticsRelayState.d.ts +43 -0
  61. package/dist/types/components/utils/analytics/mapToFbEvent.d.ts +11 -0
  62. package/dist/types/components/utils/submitAnalytics.d.ts +12 -0
  63. package/dist/types/components/utils/submitFbq.d.ts +14 -0
  64. package/dist/types/components/utils/submitGtag.d.ts +4 -9
  65. package/dist/types/scripts/_zonosBase.d.ts +11 -0
  66. package/dist/types/types/analyticsRelay.d.ts +19 -3
  67. package/dist/zonos-elements/index.esm.js +1 -1
  68. package/dist/zonos-elements/p-022ddd4a.system.entry.js +1 -0
  69. package/dist/zonos-elements/{p-6726fee0.entry.js → p-06ef4d79.entry.js} +1 -1
  70. package/dist/zonos-elements/p-29b60bf3.system.js +1 -1
  71. package/dist/zonos-elements/{p-e684e68f.entry.js → p-3deb91cb.entry.js} +1 -1
  72. package/dist/zonos-elements/{p-eca03303.system.entry.js → p-56c11359.system.entry.js} +1 -1
  73. package/dist/zonos-elements/p-5dd78b4b.js +1 -0
  74. package/dist/zonos-elements/{p-d2ef0416.system.entry.js → p-66934a78.system.entry.js} +1 -1
  75. package/dist/zonos-elements/{p-e14f421d.system.entry.js → p-7237f43b.system.entry.js} +1 -1
  76. package/dist/zonos-elements/p-72a181b5.entry.js +1 -0
  77. package/dist/zonos-elements/p-75a27c68.entry.js +1 -0
  78. package/dist/zonos-elements/{p-3c3139d2.system.entry.js → p-7df3e44b.system.entry.js} +1 -1
  79. package/dist/zonos-elements/p-838e335c.entry.js +1 -0
  80. package/dist/zonos-elements/p-947f5092.js +17 -0
  81. package/dist/zonos-elements/{p-1917202e.system.entry.js → p-9de27162.system.entry.js} +1 -1
  82. package/dist/zonos-elements/{p-be1032ab.system.entry.js → p-a2b3c1ef.system.entry.js} +1 -1
  83. package/dist/zonos-elements/p-a98b8b68.system.js +18 -0
  84. package/dist/zonos-elements/p-ca411d97.entry.js +1 -0
  85. package/dist/zonos-elements/p-cab6bd98.system.js +1 -0
  86. package/dist/zonos-elements/p-dee6adff.system.js +1 -0
  87. package/dist/zonos-elements/{p-2c9714e8.system.entry.js → p-e36e724b.system.entry.js} +1 -1
  88. package/dist/zonos-elements/{p-8df3c6a0.entry.js → p-e673a4d9.entry.js} +1 -1
  89. package/dist/zonos-elements/{p-7793d334.entry.js → p-f2909fb8.entry.js} +1 -1
  90. package/dist/zonos-elements/zonos-elements.esm.js +1 -1
  91. package/package.json +1 -1
  92. package/dist/cjs/submitGtag-9ac5a42e.js +0 -116
  93. package/dist/esm/submitGtag-543058f9.js +0 -113
  94. package/dist/esm-es5/paypal-38ca5d21.js +0 -17
  95. package/dist/esm-es5/submitGtag-543058f9.js +0 -1
  96. package/dist/zonos-elements/p-03e53ef5.entry.js +0 -1
  97. package/dist/zonos-elements/p-17a8a514.system.js +0 -1
  98. package/dist/zonos-elements/p-24407504.js +0 -17
  99. package/dist/zonos-elements/p-31bd3851.system.js +0 -1
  100. package/dist/zonos-elements/p-387f6a4d.js +0 -1
  101. package/dist/zonos-elements/p-47bde0ba.system.js +0 -18
  102. package/dist/zonos-elements/p-5dff9d51.system.entry.js +0 -1
  103. package/dist/zonos-elements/p-9cfd1dc3.entry.js +0 -1
  104. package/dist/zonos-elements/p-eeff2b04.entry.js +0 -1
  105. package/dist/zonos-elements/p-f4030586.entry.js +0 -1
@@ -0,0 +1,66 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s)
4
+ if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ /**
14
+ * Mapping from our internal event names (GA-style) to Facebook Pixel standard event names.
15
+ * @see https://developers.facebook.com/docs/meta-pixel/reference#standard-events
16
+ *
17
+ * Events without an entry have no FB standard equivalent — they are still fired as a custom event
18
+ * via `fbq('trackCustom', ...)` so merchants can target them.
19
+ */
20
+ const FB_STANDARD_EVENT_BY_INTERNAL_EVENT = {
21
+ purchase: 'Purchase',
22
+ 'zonos-checkout-payment-info': 'AddPaymentInfo',
23
+ 'zonos-checkout-start': 'InitiateCheckout',
24
+ };
25
+ export const getFbStandardEventName = (event) => { var _a; return (_a = FB_STANDARD_EVENT_BY_INTERNAL_EVENT[event]) !== null && _a !== void 0 ? _a : null; };
26
+ const isPurchaseMetadata = (metadata) => {
27
+ if (!metadata)
28
+ return false;
29
+ return Array.isArray(metadata.items);
30
+ };
31
+ /**
32
+ * Convert a GA-style event payload into a Facebook Pixel parameter object.
33
+ *
34
+ * GA `items: [{ item_id, item_name, price, quantity }]` is converted into FB's
35
+ * `contents: [{ id, quantity, item_price }]` with derived `content_ids`, `num_items`,
36
+ * and `content_type: 'product'`. Other primitive params (e.g. `checkoutSessionId`,
37
+ * `paymentMethod`, `serviceLevelId`) are forwarded as-is so merchants can build
38
+ * custom audiences on them.
39
+ */
40
+ export const buildFbqParams = (metadata) => {
41
+ if (!metadata)
42
+ return {};
43
+ if (!isPurchaseMetadata(metadata)) {
44
+ // Forward primitive metadata as-is for custom events
45
+ return Object.assign({}, metadata);
46
+ }
47
+ const { currency, items, transaction_id, value } = metadata, rest = __rest(metadata, ["currency", "items", "transaction_id", "value"]);
48
+ const contents = items.map(item => ({
49
+ id: item.item_id,
50
+ item_price: item.price,
51
+ quantity: item.quantity,
52
+ }));
53
+ const contentIds = items.map(item => item.item_id);
54
+ const numItems = items.reduce((acc, item) => acc + item.quantity, 0);
55
+ const params = Object.assign(Object.assign({}, rest), { content_ids: contentIds, content_type: 'product', contents, num_items: numItems });
56
+ if (transaction_id) {
57
+ params.order_id = transaction_id;
58
+ }
59
+ if (currency !== undefined) {
60
+ params.currency = currency;
61
+ }
62
+ if (value !== undefined) {
63
+ params.value = value;
64
+ }
65
+ return params;
66
+ };
@@ -0,0 +1,16 @@
1
+ import { submitFbq } from "./submitFbq";
2
+ import { submitGtag, } from "./submitGtag";
3
+ /**
4
+ * Fan out an analytics event to every enabled provider.
5
+ *
6
+ * - Calls `submitGtag` (Google Analytics) — always sends the original event name.
7
+ * - Calls `submitFbq` (Facebook Pixel) — sends the original event name as a custom event,
8
+ * and additionally fires the matching FB standard event when one exists
9
+ * (e.g. `purchase` → `Purchase`, `zonos-checkout-start` → `InitiateCheckout`).
10
+ *
11
+ * Each submitter no-ops when its provider is disabled in `analyticsProviders` settings.
12
+ */
13
+ export const submitAnalytics = (input) => {
14
+ submitGtag(input);
15
+ submitFbq(input);
16
+ };
@@ -0,0 +1,56 @@
1
+ import { zonosStore } from "../store/zonosStore";
2
+ import { enqueueRelayEvent, isAnalyticsRelayInIframe, } from "./analytics/analyticsRelayState";
3
+ import { buildFbqParams, getFbStandardEventName, } from "./analytics/mapToFbEvent";
4
+ import { getIsTestMode } from "./checkout/getIsTestMode";
5
+ import { log } from "./logging/log";
6
+ const isFacebookPixelEnabled = () => {
7
+ const provider = zonosStore.checkoutSettings.analyticsProviders.find(item => item.type === 'FACEBOOK_PIXEL');
8
+ return !!provider && provider.status === 'ENABLED';
9
+ };
10
+ const fireFbq = (mode, event, params) => {
11
+ if (isAnalyticsRelayInIframe()) {
12
+ // fbq does not work in the iframe (Facebook Pixel must be on the parent for proper attribution).
13
+ // Relay to parent which will call fbq() once the FB Pixel script is ready.
14
+ enqueueRelayEvent({
15
+ event,
16
+ fbqMode: mode,
17
+ payload: params,
18
+ provider: 'fbq',
19
+ });
20
+ return;
21
+ }
22
+ if (typeof window.fbq === 'function') {
23
+ log('Zonos submits fbq event', 'log', `${mode}:${event}`);
24
+ window.fbq(mode, event, params);
25
+ }
26
+ };
27
+ /**
28
+ * Submit a Facebook Pixel event matching the gtag event payload shape.
29
+ *
30
+ * Behavior:
31
+ * - Always fires `fbq('trackCustom', event, params)` so merchants see `zonos-xxx` events.
32
+ * - If the event has a Facebook standard equivalent (e.g. `purchase` → `Purchase`,
33
+ * `zonos-checkout-start` → `InitiateCheckout`, `zonos-checkout-payment-info` →
34
+ * `AddPaymentInfo`), additionally fires `fbq('track', standardEvent, params)` with
35
+ * FB-formatted parameters.
36
+ *
37
+ * @see https://developers.facebook.com/docs/meta-pixel/reference
38
+ */
39
+ export const submitFbq = ({ event, metadata }) => {
40
+ if (!isFacebookPixelEnabled()) {
41
+ return;
42
+ }
43
+ const isTestMode = getIsTestMode();
44
+ const baseParams = buildFbqParams(metadata);
45
+ const params = Object.assign(Object.assign({}, baseParams), (isTestMode && { isTestMode: true }));
46
+ // filter null values
47
+ const filteredParams = Object.fromEntries(Object.entries(params).filter(([_, value]) => value !== null));
48
+ // 1) Always emit the original event as a custom event so merchants can target zonos-xxx names.
49
+ fireFbq('trackCustom', event, filteredParams);
50
+ // 2) Emit FB standard equivalent if one exists. Skipped when the event itself is the standard
51
+ // name to avoid double-firing (e.g. 'purchase' -> 'Purchase').
52
+ const fbStandardEvent = getFbStandardEventName(event);
53
+ if (fbStandardEvent && fbStandardEvent !== event) {
54
+ fireFbq('track', fbStandardEvent, filteredParams);
55
+ }
56
+ };
@@ -1,99 +1,36 @@
1
1
  import { zonosStore } from "../store/zonosStore";
2
+ import { enqueueRelayEvent, ensureAnalyticsRelayPing as ensureAnalyticsRelayPingShared, isAnalyticsRelayInIframe, } from "./analytics/analyticsRelayState";
2
3
  import { getIsTestMode } from "./checkout/getIsTestMode";
3
4
  import { log } from "./logging/log";
4
- import { RELAY_PING_TYPE, RELAY_READY_TYPE, ZONOS_ANALYTIC_TYPE, } from "../../types/analyticsRelay";
5
- let parentGtagReady = false;
6
- let relayListenerAdded = false;
7
- const queuedEvents = [];
8
- function flushQueuedEvents() {
9
- while (queuedEvents.length > 0) {
10
- const { event, payload } = queuedEvents.shift();
11
- try {
12
- window.parent.postMessage({
13
- event,
14
- metadata: payload,
15
- type: ZONOS_ANALYTIC_TYPE,
16
- }, '*');
17
- }
18
- catch (_a) {
19
- // Ignore postMessage failures
20
- }
21
- }
22
- }
23
- function ensureRelayListener() {
24
- if (relayListenerAdded)
25
- return;
26
- relayListenerAdded = true;
27
- window.addEventListener('message', (e) => {
28
- var _a;
29
- if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === RELAY_READY_TYPE) {
30
- parentGtagReady = true;
31
- if (typeof window.Zonos !== 'undefined') {
32
- window.Zonos.googleAnalyticReady = true;
33
- }
34
- flushQueuedEvents();
35
- }
36
- });
37
- }
38
- function sendPingToParent() {
39
- try {
40
- const googleAnalyticId = typeof window.Zonos !== 'undefined'
41
- ? window.Zonos.googleAnalyticId
42
- : undefined;
43
- window.parent.postMessage({ googleAnalyticId, type: RELAY_PING_TYPE }, '*');
44
- }
45
- catch (_a) {
46
- // Ignore postMessage failures
47
- }
48
- }
49
5
  /**
50
- * Sends ping to parent with googleAnalyticId so parent can inject/configure GA and respond with ready.
51
- * Call after customHTML or custom script sets window.Zonos.googleAnalyticId.
6
+ * Re-export of the shared relay ping helper. Kept here for backward compatibility with
7
+ * existing import paths (e.g. `zonos-controller`).
52
8
  */
53
- export function ensureAnalyticsRelayPing() {
54
- if (typeof window === 'undefined' ||
55
- window.parent === window ||
56
- parentGtagReady) {
57
- return;
58
- }
59
- ensureRelayListener();
60
- sendPingToParent();
61
- }
9
+ export const ensureAnalyticsRelayPing = ensureAnalyticsRelayPingShared;
10
+ const isGoogleAnalyticsEnabled = () => {
11
+ const provider = zonosStore.checkoutSettings.analyticsProviders.find(item => item.type === 'GOOGLE_ANALYTICS');
12
+ return !!provider && provider.status === 'ENABLED';
13
+ };
62
14
  /**
63
15
  * Submit a gtag event if the gtag function is available.
64
16
  * When running inside an iframe, only posts to parent after the parent has
65
17
  * confirmed (via analyticsRelayOnInit) that gtag is available.
66
18
  */
67
19
  export const submitGtag = ({ event, metadata }) => {
68
- const googleAnalyticSetting = zonosStore.checkoutSettings.analyticsProviders.find(item => item.type === 'GOOGLE_ANALYTICS');
69
- // only submit if googleAnalytic in checkout setting is on.
70
- if (!googleAnalyticSetting || (googleAnalyticSetting === null || googleAnalyticSetting === void 0 ? void 0 : googleAnalyticSetting.status) === 'DISABLED') {
20
+ if (!isGoogleAnalyticsEnabled()) {
71
21
  return;
72
22
  }
73
23
  const isTestMode = getIsTestMode();
74
24
  const payload = Object.assign(Object.assign({}, metadata), (isTestMode && { isTestMode: true }));
75
25
  // filter null key
76
26
  const filteredPayload = Object.fromEntries(Object.entries(payload).filter(([_, value]) => value !== null));
77
- const isInIframe = typeof window !== 'undefined' && window.parent !== window;
78
- if (isInIframe) {
27
+ if (isAnalyticsRelayInIframe()) {
79
28
  // gtag does not work in iframe; must relay to parent via postMessage
80
- ensureRelayListener();
81
- if (parentGtagReady) {
82
- try {
83
- window.parent.postMessage({
84
- event,
85
- metadata: filteredPayload,
86
- type: ZONOS_ANALYTIC_TYPE,
87
- }, '*');
88
- }
89
- catch (_a) {
90
- // Ignore postMessage failures
91
- }
92
- }
93
- else {
94
- queuedEvents.push({ event, payload: filteredPayload });
95
- sendPingToParent();
96
- }
29
+ enqueueRelayEvent({
30
+ event,
31
+ payload: filteredPayload,
32
+ provider: 'gtag',
33
+ });
97
34
  return;
98
35
  }
99
36
  // Not in iframe: call gtag directly
@@ -53,6 +53,8 @@ Zonos.releaseDate = process.env.NEXT_PUBLIC_RELEASE_DATE;
53
53
  Zonos.isLegacyCheckout = false;
54
54
  Zonos.googleAnalyticId = null;
55
55
  Zonos.googleAnalyticReady = false;
56
+ Zonos.facebookPixelId = null;
57
+ Zonos.facebookPixelReady = false;
56
58
  Zonos.startLoadTime = startLoadTime;
57
59
  Zonos.domain = typeof window !== 'undefined'
58
60
  ? // domain that embeds the iframe
@@ -92,9 +94,10 @@ Zonos.init = async (params) => {
92
94
  log(`====== ZONOS DEBUG MODE: on (${_a.version}) ======`);
93
95
  _a.zonosApiKey = zonosApiKey;
94
96
  _a.storeId = storeId;
95
- // When not in iframe, GA is ready (gtag works directly). When in iframe, relay will set this after parent configures.
97
+ // When not in iframe, providers are ready (gtag/fbq work directly). When in iframe, relay sets these after parent configures.
96
98
  if (typeof window !== 'undefined' && window.parent === window) {
97
99
  _a.googleAnalyticReady = true;
100
+ _a.facebookPixelReady = true;
98
101
  }
99
102
  if (_a.isNpm) {
100
103
  log('====== ZONOS LOADING FROM NPM ======');
@@ -200,7 +203,7 @@ Zonos.injectCustomScriptForHostedCheckout = () => {
200
203
  const metadata = (cartData === null || cartData === void 0 ? void 0 : cartData.metadata) || [];
201
204
  const headerScript = metadata.find(meta => meta.key === 'customHeaderScript');
202
205
  const footerScript = metadata.find(meta => meta.key === 'customFooterScript');
203
- // googleAnalyticId is set by customHTML in checkoutSettings (e.g. <script>window.Zonos.googleAnalyticId = "G-XXX";</script>), injected by zonos-controller
206
+ // googleAnalyticId / facebookPixelId are set by customHTML in checkoutSettings (e.g. <script>window.Zonos.googleAnalyticId = "G-XXX"; window.Zonos.facebookPixelId = "1234567890";</script>), injected by zonos-controller
204
207
  // Only inject the script if checkout is on Zonos hosted checkout and custom script is available
205
208
  if (!window.Zonos.isLegacyCheckout || (!headerScript && !footerScript)) {
206
209
  log('Skip injecting custom script for hosted checkout', 'info', {
@@ -1,6 +1,6 @@
1
1
  /** Message type for zonos-analytic events sent from iframe to parent. */
2
2
  export const ZONOS_ANALYTIC_TYPE = 'zonos-analytic';
3
- /** Ping sent by iframe to configure parent's analytics relay (e.g. GA) and get ready signal. */
3
+ /** Ping sent by iframe to configure parent's analytics relay (e.g. GA, FB Pixel) and get ready signal. */
4
4
  export const RELAY_PING_TYPE = 'zonos-analytics-relay-ping';
5
- /** Response from parent when analytics relay (e.g. gtag) is ready. */
5
+ /** Response from parent when an analytics relay (e.g. gtag, fbq) is ready. */
6
6
  export const RELAY_READY_TYPE = 'zonos-analytics-relay-ready';
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.261.js.zonos.com";
134
+ const cdnUrl = "https://v1.3.262.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.261.js.zonos.com";
383
- const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.261";
384
- const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.261";
385
- const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.261";
382
+ const ZONOS_URL = "https://v1.3.262.js.zonos.com";
383
+ const JS_DELIVR_ZONOS_URL = zonosLoadUrl || "https://cdn.jsdelivr.net/npm/@zonos/elements@1.3.262";
384
+ const UNPKG_ZONOS_URL = "https://unpkg.com/@zonos/elements@1.3.262";
385
+ const CDNJS_ZONOS_URL = "https://cdnjs.cloudflare.com/ajax/libs/zonos-elements/1.3.262";
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,10 +400,12 @@ 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 = "1777476611591";
403
+ Zonos.releaseDate = "1777585626922";
404
404
  Zonos.isLegacyCheckout = false;
405
405
  Zonos.googleAnalyticId = null;
406
406
  Zonos.googleAnalyticReady = false;
407
+ Zonos.facebookPixelId = null;
408
+ Zonos.facebookPixelReady = false;
407
409
  Zonos.startLoadTime = startLoadTime;
408
410
  Zonos.domain = typeof window !== 'undefined'
409
411
  ? // domain that embeds the iframe
@@ -423,7 +425,7 @@ Zonos.isNpm = true;
423
425
  Zonos.zonosQaUrl = null;
424
426
  Zonos.zonosQaUrlApi = null;
425
427
  Zonos.trackEventLogs = [];
426
- Zonos.version = `v${"1.3.261"}`;
428
+ Zonos.version = `v${"1.3.262"}`;
427
429
  Zonos.modeAlerted = false;
428
430
  Zonos.cartData = null;
429
431
  Zonos.paypal = null;
@@ -443,9 +445,10 @@ Zonos.init = async (params) => {
443
445
  log(`====== ZONOS DEBUG MODE: on (${_a.version}) ======`);
444
446
  _a.zonosApiKey = zonosApiKey;
445
447
  _a.storeId = storeId;
446
- // When not in iframe, GA is ready (gtag works directly). When in iframe, relay will set this after parent configures.
448
+ // When not in iframe, providers are ready (gtag/fbq work directly). When in iframe, relay sets these after parent configures.
447
449
  if (typeof window !== 'undefined' && window.parent === window) {
448
450
  _a.googleAnalyticReady = true;
451
+ _a.facebookPixelReady = true;
449
452
  }
450
453
  if (_a.isNpm) {
451
454
  log('====== ZONOS LOADING FROM NPM ======');
@@ -551,7 +554,7 @@ Zonos.injectCustomScriptForHostedCheckout = () => {
551
554
  const metadata = (cartData === null || cartData === void 0 ? void 0 : cartData.metadata) || [];
552
555
  const headerScript = metadata.find(meta => meta.key === 'customHeaderScript');
553
556
  const footerScript = metadata.find(meta => meta.key === 'customFooterScript');
554
- // googleAnalyticId is set by customHTML in checkoutSettings (e.g. <script>window.Zonos.googleAnalyticId = "G-XXX";</script>), injected by zonos-controller
557
+ // googleAnalyticId / facebookPixelId are set by customHTML in checkoutSettings (e.g. <script>window.Zonos.googleAnalyticId = "G-XXX"; window.Zonos.facebookPixelId = "1234567890";</script>), injected by zonos-controller
555
558
  // Only inject the script if checkout is on Zonos hosted checkout and custom script is available
556
559
  if (!window.Zonos.isLegacyCheckout || (!headerScript && !footerScript)) {
557
560
  log('Skip injecting custom script for hosted checkout', 'info', {
@@ -1,10 +1,10 @@
1
- import { c as createStore, z as zonosStore } from './zonosStore-f1d45eac.js';
1
+ import { z as zonosStore, c as createStore } from './zonosStore-f1d45eac.js';
2
2
  import { t as trackConversionEvent, y as validateCheckoutSession, b as stripeStore, d as cartStore, v as stripeStoreHandleInventoryCheck, w as storeCreditStoreApplyCredit, x as storeCreditStoreCoversFullAmount, z as storeCreditStoreCreateOrder, r as cartStoreNextStep, h as cartStoreClearCheckoutInterval, F as storeCreditStoreGetEffectiveAmount } from './cart-c490d252.js';
3
3
  import { t as translate, s as storageStore } from './localization-542dbe20.js';
4
- import { h as handleFetch, l as logError, j as jsonParse } from './handleFetch-a844cac1.js';
4
+ import { h as handleFetch, g as getIsTestMode, l as logError, j as jsonParse } from './handleFetch-a844cac1.js';
5
5
  import { i as isContrastColor } from './isContrastColor-f9e65e70.js';
6
6
  import { l as log } from './VarianceTest-572cecf5.js';
7
- import { s as submitGtag } from './submitGtag-543058f9.js';
7
+ import { i as isAnalyticsRelayInIframe, e as enqueueRelayEvent, s as submitGtag } from './submitGtag-7f5c5bb5.js';
8
8
 
9
9
  /*!
10
10
  * paypal-js v8.4.2 (2025-09-04T17:21:30.135Z)
@@ -39,7 +39,7 @@ PERFORMANCE OF THIS SOFTWARE.
39
39
  /* global Reflect, Promise, SuppressedError, Symbol */
40
40
 
41
41
 
42
- function __rest(s, e) {
42
+ function __rest$1(s, e) {
43
43
  var t = {};
44
44
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
45
45
  t[p] = s[p];
@@ -86,7 +86,7 @@ function insertScriptElement(_a) {
86
86
  document.head.insertBefore(newScript, document.head.firstElementChild);
87
87
  }
88
88
  function processOptions(_a) {
89
- var customSdkBaseUrl = _a.sdkBaseUrl, environment = _a.environment, options = __rest(_a, ["sdkBaseUrl", "environment"]);
89
+ var customSdkBaseUrl = _a.sdkBaseUrl, environment = _a.environment, options = __rest$1(_a, ["sdkBaseUrl", "environment"]);
90
90
  var sdkBaseUrl = customSdkBaseUrl || processSdkBaseUrl(environment);
91
91
  var optionsWithStringIndex = options;
92
92
  var _b = Object.keys(optionsWithStringIndex)
@@ -256,6 +256,139 @@ const paypalCreateOrder = async ({ checkoutSessionId, intent, }) => {
256
256
  return { errors, json };
257
257
  };
258
258
 
259
+ var __rest = (undefined && undefined.__rest) || function (s, e) {
260
+ var t = {};
261
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
262
+ t[p] = s[p];
263
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
264
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
265
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
266
+ t[p[i]] = s[p[i]];
267
+ }
268
+ return t;
269
+ };
270
+ /**
271
+ * Mapping from our internal event names (GA-style) to Facebook Pixel standard event names.
272
+ * @see https://developers.facebook.com/docs/meta-pixel/reference#standard-events
273
+ *
274
+ * Events without an entry have no FB standard equivalent — they are still fired as a custom event
275
+ * via `fbq('trackCustom', ...)` so merchants can target them.
276
+ */
277
+ const FB_STANDARD_EVENT_BY_INTERNAL_EVENT = {
278
+ purchase: 'Purchase',
279
+ 'zonos-checkout-payment-info': 'AddPaymentInfo',
280
+ 'zonos-checkout-start': 'InitiateCheckout',
281
+ };
282
+ const getFbStandardEventName = (event) => { var _a; return (_a = FB_STANDARD_EVENT_BY_INTERNAL_EVENT[event]) !== null && _a !== void 0 ? _a : null; };
283
+ const isPurchaseMetadata = (metadata) => {
284
+ if (!metadata)
285
+ return false;
286
+ return Array.isArray(metadata.items);
287
+ };
288
+ /**
289
+ * Convert a GA-style event payload into a Facebook Pixel parameter object.
290
+ *
291
+ * GA `items: [{ item_id, item_name, price, quantity }]` is converted into FB's
292
+ * `contents: [{ id, quantity, item_price }]` with derived `content_ids`, `num_items`,
293
+ * and `content_type: 'product'`. Other primitive params (e.g. `checkoutSessionId`,
294
+ * `paymentMethod`, `serviceLevelId`) are forwarded as-is so merchants can build
295
+ * custom audiences on them.
296
+ */
297
+ const buildFbqParams = (metadata) => {
298
+ if (!metadata)
299
+ return {};
300
+ if (!isPurchaseMetadata(metadata)) {
301
+ // Forward primitive metadata as-is for custom events
302
+ return Object.assign({}, metadata);
303
+ }
304
+ const { currency, items, transaction_id, value } = metadata, rest = __rest(metadata, ["currency", "items", "transaction_id", "value"]);
305
+ const contents = items.map(item => ({
306
+ id: item.item_id,
307
+ item_price: item.price,
308
+ quantity: item.quantity,
309
+ }));
310
+ const contentIds = items.map(item => item.item_id);
311
+ const numItems = items.reduce((acc, item) => acc + item.quantity, 0);
312
+ const params = Object.assign(Object.assign({}, rest), { content_ids: contentIds, content_type: 'product', contents, num_items: numItems });
313
+ if (transaction_id) {
314
+ params.order_id = transaction_id;
315
+ }
316
+ if (currency !== undefined) {
317
+ params.currency = currency;
318
+ }
319
+ if (value !== undefined) {
320
+ params.value = value;
321
+ }
322
+ return params;
323
+ };
324
+
325
+ const isFacebookPixelEnabled = () => {
326
+ const provider = zonosStore.checkoutSettings.analyticsProviders.find(item => item.type === 'FACEBOOK_PIXEL');
327
+ return !!provider && provider.status === 'ENABLED';
328
+ };
329
+ const fireFbq = (mode, event, params) => {
330
+ if (isAnalyticsRelayInIframe()) {
331
+ // fbq does not work in the iframe (Facebook Pixel must be on the parent for proper attribution).
332
+ // Relay to parent which will call fbq() once the FB Pixel script is ready.
333
+ enqueueRelayEvent({
334
+ event,
335
+ fbqMode: mode,
336
+ payload: params,
337
+ provider: 'fbq',
338
+ });
339
+ return;
340
+ }
341
+ if (typeof window.fbq === 'function') {
342
+ log('Zonos submits fbq event', 'log', `${mode}:${event}`);
343
+ window.fbq(mode, event, params);
344
+ }
345
+ };
346
+ /**
347
+ * Submit a Facebook Pixel event matching the gtag event payload shape.
348
+ *
349
+ * Behavior:
350
+ * - Always fires `fbq('trackCustom', event, params)` so merchants see `zonos-xxx` events.
351
+ * - If the event has a Facebook standard equivalent (e.g. `purchase` → `Purchase`,
352
+ * `zonos-checkout-start` → `InitiateCheckout`, `zonos-checkout-payment-info` →
353
+ * `AddPaymentInfo`), additionally fires `fbq('track', standardEvent, params)` with
354
+ * FB-formatted parameters.
355
+ *
356
+ * @see https://developers.facebook.com/docs/meta-pixel/reference
357
+ */
358
+ const submitFbq = ({ event, metadata }) => {
359
+ if (!isFacebookPixelEnabled()) {
360
+ return;
361
+ }
362
+ const isTestMode = getIsTestMode();
363
+ const baseParams = buildFbqParams(metadata);
364
+ const params = Object.assign(Object.assign({}, baseParams), (isTestMode && { isTestMode: true }));
365
+ // filter null values
366
+ const filteredParams = Object.fromEntries(Object.entries(params).filter(([_, value]) => value !== null));
367
+ // 1) Always emit the original event as a custom event so merchants can target zonos-xxx names.
368
+ fireFbq('trackCustom', event, filteredParams);
369
+ // 2) Emit FB standard equivalent if one exists. Skipped when the event itself is the standard
370
+ // name to avoid double-firing (e.g. 'purchase' -> 'Purchase').
371
+ const fbStandardEvent = getFbStandardEventName(event);
372
+ if (fbStandardEvent && fbStandardEvent !== event) {
373
+ fireFbq('track', fbStandardEvent, filteredParams);
374
+ }
375
+ };
376
+
377
+ /**
378
+ * Fan out an analytics event to every enabled provider.
379
+ *
380
+ * - Calls `submitGtag` (Google Analytics) — always sends the original event name.
381
+ * - Calls `submitFbq` (Facebook Pixel) — sends the original event name as a custom event,
382
+ * and additionally fires the matching FB standard event when one exists
383
+ * (e.g. `purchase` → `Purchase`, `zonos-checkout-start` → `InitiateCheckout`).
384
+ *
385
+ * Each submitter no-ops when its provider is disabled in `analyticsProviders` settings.
386
+ */
387
+ const submitAnalytics = (input) => {
388
+ submitGtag(input);
389
+ submitFbq(input);
390
+ };
391
+
259
392
  const { onChange: paypalStoreOnChange, reset: paypalStoreReset, state: paypalStore, } = createStore(() => ({
260
393
  intent: 'capture',
261
394
  orderIdCreated: null,
@@ -336,7 +469,7 @@ const paypalButtonOptions = ({ checkoutSessionId, onPaypalFail, onPaypalSessionD
336
469
  // reset stripe error message
337
470
  stripeStore.hasPaymentError = false;
338
471
  stripeStore.customErrorMessage = null;
339
- submitGtag({
472
+ submitAnalytics({
340
473
  event: 'zonos-checkout-payment-fail',
341
474
  metadata: {
342
475
  checkoutSessionId,
@@ -401,7 +534,7 @@ const paypalButtonOptions = ({ checkoutSessionId, onPaypalFail, onPaypalSessionD
401
534
  // reset stripe error message
402
535
  stripeStore.hasPaymentError = false;
403
536
  stripeStore.customErrorMessage = null;
404
- submitGtag({
537
+ submitAnalytics({
405
538
  event: 'zonos-checkout-payment-fail',
406
539
  metadata: {
407
540
  checkoutSessionId,
@@ -417,7 +550,7 @@ const paypalButtonOptions = ({ checkoutSessionId, onPaypalFail, onPaypalSessionD
417
550
  // reset paypal error banner
418
551
  paypalStore.paypalErrorMessage = null;
419
552
  // submit google tag when the form is complete
420
- submitGtag({
553
+ submitAnalytics({
421
554
  event: 'zonos-checkout-payment-info',
422
555
  metadata: {
423
556
  checkoutSessionId,
@@ -538,4 +671,4 @@ const paypalStoreHasPaypalEnabled = () => {
538
671
  return paypalEnabledInSetting || !!paypalStore.paypalButtons.length;
539
672
  };
540
673
 
541
- export { paypalStore as a, paypalInitScript as b, paypalStoreReset as c, paypalStoreInitButtons as d, paypalStoreOnChange as e, paypalStoreHasPaypalEnabled as p };
674
+ export { paypalStore as a, paypalInitScript as b, paypalStoreReset as c, paypalStoreInitButtons as d, paypalStoreOnChange as e, paypalStoreHasPaypalEnabled as p, submitAnalytics as s };