@economist/web-apple-pay 1.9.3 → 1.9.5

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/dist/index.js CHANGED
@@ -1304,11 +1304,11 @@ var redirectToCheckoutFallback = (params) => {
1304
1304
  };
1305
1305
 
1306
1306
  // src/constants.ts
1307
- var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint3) => {
1308
- ApplePayEntryPoint3["PAYWALL"] = "article_paywall";
1309
- ApplePayEntryPoint3["REGWALL"] = "article_regwall";
1310
- ApplePayEntryPoint3["DUAL_OFFER_BANNER"] = "dual_offer_banner";
1311
- return ApplePayEntryPoint3;
1307
+ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
1308
+ ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
1309
+ ApplePayEntryPoint2["REGWALL"] = "article_regwall";
1310
+ ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
1311
+ return ApplePayEntryPoint2;
1312
1312
  })(ApplePayEntryPoint || {});
1313
1313
  var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
1314
1314
  var APPLE_PAY_EXPRESS_VARIANTS = {
@@ -1353,7 +1353,7 @@ var track = (action, extra) => {
1353
1353
  ...extra
1354
1354
  });
1355
1355
  };
1356
- var trackApplePayExperimentExposure = (variant) => {
1356
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
1357
1357
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
1358
1358
  if (!isActiveVariant) {
1359
1359
  return;
@@ -1369,7 +1369,8 @@ var trackApplePayExperimentExposure = (variant) => {
1369
1369
  emitTedlEvent({
1370
1370
  name: "$exposure",
1371
1371
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
1372
- variant
1372
+ variant,
1373
+ ...experimentKey ? { experiment_key: experimentKey } : {}
1373
1374
  });
1374
1375
  };
1375
1376
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -1995,6 +1996,17 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1995
1996
  return [...zoneCountries];
1996
1997
  };
1997
1998
 
1999
+ // src/utils/getExperimentKeyFromNextData.ts
2000
+ var getExperimentKeyFromNextData = (flagKey) => {
2001
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
2002
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
2003
+ return typeof experimentKey === "string" ? experimentKey : void 0;
2004
+ };
2005
+
2006
+ // src/utils/applePayExpressEligibility.ts
2007
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
2008
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
2009
+
1998
2010
  // src/apple-pay-button.ts
1999
2011
  var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
2000
2012
  var TOTAL_LABEL = "The Economist";
@@ -2026,6 +2038,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2026
2038
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
2027
2039
  * fallback will be removed.
2028
2040
  *
2041
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
2042
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
2043
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
2044
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
2045
+ * the dual-offer banner is only mounted for anonymous visitors.
2046
+ *
2029
2047
  * @param offer - The offer to display in the Apple Pay flow.
2030
2048
  * @param country - The user's country code.
2031
2049
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -2037,16 +2055,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2037
2055
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
2038
2056
  return null;
2039
2057
  }
2058
+ const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2059
+ FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2060
+ );
2061
+ const isBannerEntryPoint = !entryPoint || entryPoint === "dual_offer_banner" /* DUAL_OFFER_BANNER */;
2062
+ const isEligible = !isBannerEntryPoint || isEligibleForApplePayExpressExperiment();
2063
+ if (isBannerEntryPoint && !hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
2064
+ return null;
2065
+ }
2040
2066
  const experimentValue = window.experimentIntegration?.getVariant?.(
2041
2067
  APPLE_PAY_EXPRESS_EXPERIMENT_KEY
2042
2068
  );
2043
- if (experimentValue) {
2044
- trackApplePayExperimentExposure(experimentValue);
2069
+ const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2070
+ if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
2071
+ void isApplePayAvailable().then((available) => {
2072
+ if (available) {
2073
+ trackApplePayExperimentExposure(
2074
+ experimentValue,
2075
+ getExperimentKeyFromNextData(APPLE_PAY_EXPRESS_EXPERIMENT_KEY)
2076
+ );
2077
+ }
2078
+ });
2045
2079
  }
2046
2080
  const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2047
- const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2048
- FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2049
- );
2050
2081
  if (!isTreatment && !hasUrlParamFlag) {
2051
2082
  return null;
2052
2083
  }
@@ -20,6 +20,12 @@ export declare class ApplePayButton extends HTMLElement {
20
20
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
21
21
  * fallback will be removed.
22
22
  *
23
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
24
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
25
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
26
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
27
+ * the dual-offer banner is only mounted for anonymous visitors.
28
+ *
23
29
  * @param offer - The offer to display in the Apple Pay flow.
24
30
  * @param country - The user's country code.
25
31
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -1342,7 +1342,7 @@ var track = (action, extra) => {
1342
1342
  ...extra
1343
1343
  });
1344
1344
  };
1345
- var trackApplePayExperimentExposure = (variant) => {
1345
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
1346
1346
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
1347
1347
  if (!isActiveVariant) {
1348
1348
  return;
@@ -1358,7 +1358,8 @@ var trackApplePayExperimentExposure = (variant) => {
1358
1358
  emitTedlEvent({
1359
1359
  name: "$exposure",
1360
1360
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
1361
- variant
1361
+ variant,
1362
+ ...experimentKey ? { experiment_key: experimentKey } : {}
1362
1363
  });
1363
1364
  };
1364
1365
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -1984,6 +1985,17 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1984
1985
  return [...zoneCountries];
1985
1986
  };
1986
1987
 
1988
+ // src/utils/getExperimentKeyFromNextData.ts
1989
+ var getExperimentKeyFromNextData = (flagKey) => {
1990
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
1991
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
1992
+ return typeof experimentKey === "string" ? experimentKey : void 0;
1993
+ };
1994
+
1995
+ // src/utils/applePayExpressEligibility.ts
1996
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
1997
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
1998
+
1987
1999
  // src/apple-pay-button.ts
1988
2000
  var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1989
2001
  var TOTAL_LABEL = "The Economist";
@@ -2015,6 +2027,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2015
2027
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
2016
2028
  * fallback will be removed.
2017
2029
  *
2030
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
2031
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
2032
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
2033
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
2034
+ * the dual-offer banner is only mounted for anonymous visitors.
2035
+ *
2018
2036
  * @param offer - The offer to display in the Apple Pay flow.
2019
2037
  * @param country - The user's country code.
2020
2038
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -2026,16 +2044,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2026
2044
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
2027
2045
  return null;
2028
2046
  }
2047
+ const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2048
+ FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2049
+ );
2050
+ const isBannerEntryPoint = !entryPoint || entryPoint === "dual_offer_banner" /* DUAL_OFFER_BANNER */;
2051
+ const isEligible = !isBannerEntryPoint || isEligibleForApplePayExpressExperiment();
2052
+ if (isBannerEntryPoint && !hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
2053
+ return null;
2054
+ }
2029
2055
  const experimentValue = window.experimentIntegration?.getVariant?.(
2030
2056
  APPLE_PAY_EXPRESS_EXPERIMENT_KEY
2031
2057
  );
2032
- if (experimentValue) {
2033
- trackApplePayExperimentExposure(experimentValue);
2058
+ const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2059
+ if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
2060
+ void isApplePayAvailable().then((available) => {
2061
+ if (available) {
2062
+ trackApplePayExperimentExposure(
2063
+ experimentValue,
2064
+ getExperimentKeyFromNextData(APPLE_PAY_EXPRESS_EXPERIMENT_KEY)
2065
+ );
2066
+ }
2067
+ });
2034
2068
  }
2035
2069
  const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2036
- const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2037
- FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2038
- );
2039
2070
  if (!isTreatment && !hasUrlParamFlag) {
2040
2071
  return null;
2041
2072
  }
@@ -1350,7 +1350,7 @@ var track = (action, extra) => {
1350
1350
  ...extra
1351
1351
  });
1352
1352
  };
1353
- var trackApplePayExperimentExposure = (variant) => {
1353
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
1354
1354
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
1355
1355
  if (!isActiveVariant) {
1356
1356
  return;
@@ -1366,7 +1366,8 @@ var trackApplePayExperimentExposure = (variant) => {
1366
1366
  emitTedlEvent({
1367
1367
  name: "$exposure",
1368
1368
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
1369
- variant
1369
+ variant,
1370
+ ...experimentKey ? { experiment_key: experimentKey } : {}
1370
1371
  });
1371
1372
  };
1372
1373
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -1992,6 +1993,17 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1992
1993
  return [...zoneCountries];
1993
1994
  };
1994
1995
 
1996
+ // src/utils/getExperimentKeyFromNextData.ts
1997
+ var getExperimentKeyFromNextData = (flagKey) => {
1998
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
1999
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
2000
+ return typeof experimentKey === "string" ? experimentKey : void 0;
2001
+ };
2002
+
2003
+ // src/utils/applePayExpressEligibility.ts
2004
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
2005
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
2006
+
1995
2007
  // src/apple-pay-button.ts
1996
2008
  var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1997
2009
  var TOTAL_LABEL = "The Economist";
@@ -2023,6 +2035,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2023
2035
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
2024
2036
  * fallback will be removed.
2025
2037
  *
2038
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
2039
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
2040
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
2041
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
2042
+ * the dual-offer banner is only mounted for anonymous visitors.
2043
+ *
2026
2044
  * @param offer - The offer to display in the Apple Pay flow.
2027
2045
  * @param country - The user's country code.
2028
2046
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -2034,16 +2052,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2034
2052
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
2035
2053
  return null;
2036
2054
  }
2055
+ const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2056
+ FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2057
+ );
2058
+ const isBannerEntryPoint = !entryPoint || entryPoint === "dual_offer_banner" /* DUAL_OFFER_BANNER */;
2059
+ const isEligible = !isBannerEntryPoint || isEligibleForApplePayExpressExperiment();
2060
+ if (isBannerEntryPoint && !hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
2061
+ return null;
2062
+ }
2037
2063
  const experimentValue = window.experimentIntegration?.getVariant?.(
2038
2064
  APPLE_PAY_EXPRESS_EXPERIMENT_KEY
2039
2065
  );
2040
- if (experimentValue) {
2041
- trackApplePayExperimentExposure(experimentValue);
2066
+ const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2067
+ if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
2068
+ void isApplePayAvailable().then((available) => {
2069
+ if (available) {
2070
+ trackApplePayExperimentExposure(
2071
+ experimentValue,
2072
+ getExperimentKeyFromNextData(APPLE_PAY_EXPRESS_EXPERIMENT_KEY)
2073
+ );
2074
+ }
2075
+ });
2042
2076
  }
2043
2077
  const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2044
- const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2045
- FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2046
- );
2047
2078
  if (!isTreatment && !hasUrlParamFlag) {
2048
2079
  return null;
2049
2080
  }
@@ -1342,7 +1342,7 @@ var track = (action, extra) => {
1342
1342
  ...extra
1343
1343
  });
1344
1344
  };
1345
- var trackApplePayExperimentExposure = (variant) => {
1345
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
1346
1346
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
1347
1347
  if (!isActiveVariant) {
1348
1348
  return;
@@ -1358,7 +1358,8 @@ var trackApplePayExperimentExposure = (variant) => {
1358
1358
  emitTedlEvent({
1359
1359
  name: "$exposure",
1360
1360
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
1361
- variant
1361
+ variant,
1362
+ ...experimentKey ? { experiment_key: experimentKey } : {}
1362
1363
  });
1363
1364
  };
1364
1365
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -1984,6 +1985,17 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1984
1985
  return [...zoneCountries];
1985
1986
  };
1986
1987
 
1988
+ // src/utils/getExperimentKeyFromNextData.ts
1989
+ var getExperimentKeyFromNextData = (flagKey) => {
1990
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
1991
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
1992
+ return typeof experimentKey === "string" ? experimentKey : void 0;
1993
+ };
1994
+
1995
+ // src/utils/applePayExpressEligibility.ts
1996
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
1997
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
1998
+
1987
1999
  // src/apple-pay-button.ts
1988
2000
  var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1989
2001
  var TOTAL_LABEL = "The Economist";
@@ -2015,6 +2027,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2015
2027
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
2016
2028
  * fallback will be removed.
2017
2029
  *
2030
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
2031
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
2032
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
2033
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
2034
+ * the dual-offer banner is only mounted for anonymous visitors.
2035
+ *
2018
2036
  * @param offer - The offer to display in the Apple Pay flow.
2019
2037
  * @param country - The user's country code.
2020
2038
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -2026,16 +2044,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2026
2044
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
2027
2045
  return null;
2028
2046
  }
2047
+ const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2048
+ FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2049
+ );
2050
+ const isBannerEntryPoint = !entryPoint || entryPoint === "dual_offer_banner" /* DUAL_OFFER_BANNER */;
2051
+ const isEligible = !isBannerEntryPoint || isEligibleForApplePayExpressExperiment();
2052
+ if (isBannerEntryPoint && !hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
2053
+ return null;
2054
+ }
2029
2055
  const experimentValue = window.experimentIntegration?.getVariant?.(
2030
2056
  APPLE_PAY_EXPRESS_EXPERIMENT_KEY
2031
2057
  );
2032
- if (experimentValue) {
2033
- trackApplePayExperimentExposure(experimentValue);
2058
+ const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2059
+ if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
2060
+ void isApplePayAvailable().then((available) => {
2061
+ if (available) {
2062
+ trackApplePayExperimentExposure(
2063
+ experimentValue,
2064
+ getExperimentKeyFromNextData(APPLE_PAY_EXPRESS_EXPERIMENT_KEY)
2065
+ );
2066
+ }
2067
+ });
2034
2068
  }
2035
2069
  const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2036
- const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2037
- FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2038
- );
2039
2070
  if (!isTreatment && !hasUrlParamFlag) {
2040
2071
  return null;
2041
2072
  }
package/dist/src/index.js CHANGED
@@ -1304,11 +1304,11 @@ var redirectToCheckoutFallback = (params) => {
1304
1304
  };
1305
1305
 
1306
1306
  // src/constants.ts
1307
- var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint3) => {
1308
- ApplePayEntryPoint3["PAYWALL"] = "article_paywall";
1309
- ApplePayEntryPoint3["REGWALL"] = "article_regwall";
1310
- ApplePayEntryPoint3["DUAL_OFFER_BANNER"] = "dual_offer_banner";
1311
- return ApplePayEntryPoint3;
1307
+ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
1308
+ ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
1309
+ ApplePayEntryPoint2["REGWALL"] = "article_regwall";
1310
+ ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
1311
+ return ApplePayEntryPoint2;
1312
1312
  })(ApplePayEntryPoint || {});
1313
1313
  var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
1314
1314
  var APPLE_PAY_EXPRESS_VARIANTS = {
@@ -1353,7 +1353,7 @@ var track = (action, extra) => {
1353
1353
  ...extra
1354
1354
  });
1355
1355
  };
1356
- var trackApplePayExperimentExposure = (variant) => {
1356
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
1357
1357
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
1358
1358
  if (!isActiveVariant) {
1359
1359
  return;
@@ -1369,7 +1369,8 @@ var trackApplePayExperimentExposure = (variant) => {
1369
1369
  emitTedlEvent({
1370
1370
  name: "$exposure",
1371
1371
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
1372
- variant
1372
+ variant,
1373
+ ...experimentKey ? { experiment_key: experimentKey } : {}
1373
1374
  });
1374
1375
  };
1375
1376
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -1995,6 +1996,17 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1995
1996
  return [...zoneCountries];
1996
1997
  };
1997
1998
 
1999
+ // src/utils/getExperimentKeyFromNextData.ts
2000
+ var getExperimentKeyFromNextData = (flagKey) => {
2001
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
2002
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
2003
+ return typeof experimentKey === "string" ? experimentKey : void 0;
2004
+ };
2005
+
2006
+ // src/utils/applePayExpressEligibility.ts
2007
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
2008
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
2009
+
1998
2010
  // src/apple-pay-button.ts
1999
2011
  var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
2000
2012
  var TOTAL_LABEL = "The Economist";
@@ -2026,6 +2038,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2026
2038
  * `window.experimentIntegration`. Once all consumers are migrated, the URL param
2027
2039
  * fallback will be removed.
2028
2040
  *
2041
+ * **SMA-3301 eligibility:** the homepage + Safari/iPhone eligibility gate
2042
+ * only applies to the `DUAL_OFFER_BANNER` entry point (or when `entryPoint`
2043
+ * is omitted). `PAYWALL`/`REGWALL` entry points render on article pages and
2044
+ * keep their pre-SMA-3301 behaviour unaffected. Anonymous is assumed because
2045
+ * the dual-offer banner is only mounted for anonymous visitors.
2046
+ *
2029
2047
  * @param offer - The offer to display in the Apple Pay flow.
2030
2048
  * @param country - The user's country code.
2031
2049
  * @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
@@ -2037,16 +2055,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2037
2055
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
2038
2056
  return null;
2039
2057
  }
2058
+ const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2059
+ FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2060
+ );
2061
+ const isBannerEntryPoint = !entryPoint || entryPoint === "dual_offer_banner" /* DUAL_OFFER_BANNER */;
2062
+ const isEligible = !isBannerEntryPoint || isEligibleForApplePayExpressExperiment();
2063
+ if (isBannerEntryPoint && !hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
2064
+ return null;
2065
+ }
2040
2066
  const experimentValue = window.experimentIntegration?.getVariant?.(
2041
2067
  APPLE_PAY_EXPRESS_EXPERIMENT_KEY
2042
2068
  );
2043
- if (experimentValue) {
2044
- trackApplePayExperimentExposure(experimentValue);
2069
+ const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2070
+ if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
2071
+ void isApplePayAvailable().then((available) => {
2072
+ if (available) {
2073
+ trackApplePayExperimentExposure(
2074
+ experimentValue,
2075
+ getExperimentKeyFromNextData(APPLE_PAY_EXPRESS_EXPERIMENT_KEY)
2076
+ );
2077
+ }
2078
+ });
2045
2079
  }
2046
2080
  const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
2047
- const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
2048
- FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
2049
- );
2050
2081
  if (!isTreatment && !hasUrlParamFlag) {
2051
2082
  return null;
2052
2083
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Host-side eligibility for Apple Pay Express Feature Experiment (SMA-3301).
3
+ *
4
+ * Gates createIfEnabled before getVariant / $exposure so only the intended
5
+ * population (homepage + Safari/iPhone) participates. Anonymous is assumed
6
+ * because the dual-offer banner is only mounted for anonymous visitors.
7
+ * Exposure is further gated on isApplePayAvailable() (BYPASS_APPLE_PAY_CHECKS
8
+ * respected). Amplitude audience targeting uses generic user_properties from
9
+ * Engagement.
10
+ */
11
+ export declare const isApplePayExpressHomepage: (pathname?: string) => boolean;
12
+ /**
13
+ * True when the visitor may enter the Apple Pay Express experiment path
14
+ * (assignment read + $exposure + optional treatment button).
15
+ */
16
+ export declare const isEligibleForApplePayExpressExperiment: () => boolean;
@@ -0,0 +1,14 @@
1
+ // src/clients/payment-checkout/detects.ts
2
+ var isAppleDeviceOrSafari = () => {
3
+ const isIOSOrMacTouchDevice = /iPad|iPhone|iPod/.test(navigator.userAgent) || navigator.maxTouchPoints > 1 && /Macintosh/.test(navigator.userAgent);
4
+ const isSafariBrowser = navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") === -1;
5
+ return isIOSOrMacTouchDevice || isSafariBrowser;
6
+ };
7
+
8
+ // src/utils/applePayExpressEligibility.ts
9
+ var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
10
+ var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
11
+ export {
12
+ isApplePayExpressHomepage,
13
+ isEligibleForApplePayExpressExperiment
14
+ };
@@ -50,11 +50,12 @@ export type ImpressionMetadata = {
50
50
  /**
51
51
  * Amplitude Experiment exposure for Apple Pay Express (SMA-3301).
52
52
  *
53
- * Fired when createIfEnabled evaluates an assigned variant (control or
54
- * treatment). Deduped per pathname + variant so repeated banner renders on
55
- * the same page do not over-count.
53
+ * Fired from createIfEnabled only after isApplePayAvailable() succeeds
54
+ * (control or treatment). Deduped per pathname + variant so repeated banner
55
+ * renders on the same page do not over-count. Includes experiment_key from
56
+ * Engagement SSR (__NEXT_DATA__) when present for run attribution.
56
57
  */
57
- export declare const trackApplePayExperimentExposure: (variant: string) => void;
58
+ export declare const trackApplePayExperimentExposure: (variant: string, experimentKey?: string) => void;
58
59
  /** Wallet button displayed — emits all 5 required analytics dimensions. */
59
60
  export declare const trackExpressWalletImpression: (skuId: string, { entryPoint, country }: ImpressionMetadata) => void;
60
61
  /** Wallet button clicked */
@@ -42,7 +42,7 @@ var track = (action, extra) => {
42
42
  ...extra
43
43
  });
44
44
  };
45
- var trackApplePayExperimentExposure = (variant) => {
45
+ var trackApplePayExperimentExposure = (variant, experimentKey) => {
46
46
  const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
47
47
  if (!isActiveVariant) {
48
48
  return;
@@ -58,7 +58,8 @@ var trackApplePayExperimentExposure = (variant) => {
58
58
  emitTedlEvent({
59
59
  name: "$exposure",
60
60
  flag_key: APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
61
- variant
61
+ variant,
62
+ ...experimentKey ? { experiment_key: experimentKey } : {}
62
63
  });
63
64
  };
64
65
  var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Reads Amplitude experiment run key from Engagement SSR page props.
3
+ *
4
+ * Engagement already stores full fetchVariants entries on
5
+ * `window.__NEXT_DATA__.props.pageProps.experiments` (including
6
+ * `metadata.experimentKey`). Avoids extending the CDN bridge API.
7
+ */
8
+ export declare const getExperimentKeyFromNextData: (flagKey: string) => string | undefined;
@@ -0,0 +1,9 @@
1
+ // src/utils/getExperimentKeyFromNextData.ts
2
+ var getExperimentKeyFromNextData = (flagKey) => {
3
+ const experiments = window.__NEXT_DATA__?.props?.pageProps?.experiments;
4
+ const experimentKey = experiments?.[flagKey]?.metadata?.experimentKey;
5
+ return typeof experimentKey === "string" ? experimentKey : void 0;
6
+ };
7
+ export {
8
+ getExperimentKeyFromNextData
9
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@economist/web-apple-pay",
3
3
  "description": "Web component package for Apple Pay checkout UI",
4
- "version": "1.9.3",
4
+ "version": "1.9.5",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",