@economist/web-apple-pay 1.9.4 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +67 -20
- package/dist/src/apple-pay-button.d.ts +11 -3
- package/dist/src/apple-pay-button.js +59 -15
- package/dist/src/apple-pay-button.stories.js +59 -15
- package/dist/src/apple-pay-modal.stories.js +59 -15
- package/dist/src/constants.d.ts +18 -2
- package/dist/src/constants.js +2 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +67 -20
- package/dist/src/utils/applePayExpressEligibility.d.ts +20 -0
- package/dist/src/utils/applePayExpressEligibility.js +16 -0
- package/dist/src/utils/expressCheckoutTracking.d.ts +10 -5
- package/dist/src/utils/expressCheckoutTracking.js +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1304,13 +1304,14 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1304
1304
|
};
|
|
1305
1305
|
|
|
1306
1306
|
// src/constants.ts
|
|
1307
|
-
var ApplePayEntryPoint = /* @__PURE__ */ ((
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
return
|
|
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
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1314
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1315
1316
|
CONTROL: "control",
|
|
1316
1317
|
TREATMENT: "treatment"
|
|
@@ -1353,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1353
1354
|
...extra
|
|
1354
1355
|
});
|
|
1355
1356
|
};
|
|
1356
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
1357
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1358
1359
|
if (!isActiveVariant) {
|
|
1359
1360
|
return;
|
|
@@ -1361,14 +1362,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
1361
1362
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
1362
1363
|
window.__applePayExperimentExposures = exposures;
|
|
1363
1364
|
const pathname = window.location?.pathname ?? "";
|
|
1364
|
-
const dedupeKey = `${pathname}:${
|
|
1365
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
1365
1366
|
if (exposures[dedupeKey]) {
|
|
1366
1367
|
return;
|
|
1367
1368
|
}
|
|
1368
1369
|
exposures[dedupeKey] = true;
|
|
1369
1370
|
emitTedlEvent({
|
|
1370
1371
|
name: "$exposure",
|
|
1371
|
-
flag_key:
|
|
1372
|
+
flag_key: flagKey,
|
|
1372
1373
|
variant,
|
|
1373
1374
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
1374
1375
|
});
|
|
@@ -2003,7 +2004,26 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2003
2004
|
return typeof experimentKey === "string" ? experimentKey : void 0;
|
|
2004
2005
|
};
|
|
2005
2006
|
|
|
2007
|
+
// src/utils/applePayExpressEligibility.ts
|
|
2008
|
+
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2009
|
+
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2010
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2011
|
+
|
|
2006
2012
|
// src/apple-pay-button.ts
|
|
2013
|
+
var ENTRY_POINT_CONFIG = {
|
|
2014
|
+
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2015
|
+
isEligible: isEligibleForApplePayExpressExperiment,
|
|
2016
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2017
|
+
},
|
|
2018
|
+
["article_paywall" /* PAYWALL */]: {
|
|
2019
|
+
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
2020
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY
|
|
2021
|
+
},
|
|
2022
|
+
["article_regwall" /* REGWALL */]: {
|
|
2023
|
+
isEligible: () => true,
|
|
2024
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2007
2027
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
2008
2028
|
var TOTAL_LABEL = "The Economist";
|
|
2009
2029
|
var DEFAULT_CURRENCY = "USD";
|
|
@@ -2022,9 +2042,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2022
2042
|
/**
|
|
2023
2043
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
2024
2044
|
*
|
|
2025
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
2026
|
-
* {@link
|
|
2027
|
-
*
|
|
2045
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
2046
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
2047
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
2048
|
+
*
|
|
2049
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
2050
|
+
* before calling this method.
|
|
2028
2051
|
*
|
|
2029
2052
|
* - `treatment` → button created and returned
|
|
2030
2053
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -2034,6 +2057,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2034
2057
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2035
2058
|
* fallback will be removed.
|
|
2036
2059
|
*
|
|
2060
|
+
* **Eligibility:**
|
|
2061
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
2062
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2063
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2064
|
+
*
|
|
2037
2065
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2038
2066
|
* @param country - The user's country code.
|
|
2039
2067
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -2045,19 +2073,35 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2045
2073
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
2046
2074
|
return null;
|
|
2047
2075
|
}
|
|
2076
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2077
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2078
|
+
);
|
|
2079
|
+
const resolvedEntryPoint = entryPoint || "dual_offer_banner" /* DUAL_OFFER_BANNER */;
|
|
2080
|
+
const config = ENTRY_POINT_CONFIG[resolvedEntryPoint];
|
|
2081
|
+
if (!config) {
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2084
|
+
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2085
|
+
const isEligible = eligibilityCheck();
|
|
2086
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2087
|
+
return null;
|
|
2088
|
+
}
|
|
2048
2089
|
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
2049
|
-
|
|
2090
|
+
experimentFlagKey
|
|
2050
2091
|
);
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2092
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2093
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2094
|
+
void isApplePayAvailable().then((available) => {
|
|
2095
|
+
if (available) {
|
|
2096
|
+
trackApplePayExperimentExposure(
|
|
2097
|
+
experimentValue,
|
|
2098
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2099
|
+
experimentFlagKey
|
|
2100
|
+
);
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2056
2103
|
}
|
|
2057
2104
|
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2058
|
-
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2059
|
-
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2060
|
-
);
|
|
2061
2105
|
if (!isTreatment && !hasUrlParamFlag) {
|
|
2062
2106
|
return null;
|
|
2063
2107
|
}
|
|
@@ -2373,6 +2417,9 @@ function defineApplePayElements() {
|
|
|
2373
2417
|
}
|
|
2374
2418
|
export {
|
|
2375
2419
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2420
|
+
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2421
|
+
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2422
|
+
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2376
2423
|
ApplePayButton,
|
|
2377
2424
|
ApplePayEntryPoint,
|
|
2378
2425
|
ApplePayModal,
|
|
@@ -8,9 +8,12 @@ export declare class ApplePayButton extends HTMLElement {
|
|
|
8
8
|
/**
|
|
9
9
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
10
10
|
*
|
|
11
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
12
|
-
* {@link
|
|
13
|
-
*
|
|
11
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
12
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
13
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
14
|
+
*
|
|
15
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
16
|
+
* before calling this method.
|
|
14
17
|
*
|
|
15
18
|
* - `treatment` → button created and returned
|
|
16
19
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -20,6 +23,11 @@ export declare class ApplePayButton extends HTMLElement {
|
|
|
20
23
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
21
24
|
* fallback will be removed.
|
|
22
25
|
*
|
|
26
|
+
* **Eligibility:**
|
|
27
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
28
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
29
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
30
|
+
*
|
|
23
31
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
24
32
|
* @param country - The user's country code.
|
|
25
33
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -1300,6 +1300,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1300
1300
|
|
|
1301
1301
|
// src/constants.ts
|
|
1302
1302
|
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1303
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1303
1304
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1304
1305
|
CONTROL: "control",
|
|
1305
1306
|
TREATMENT: "treatment"
|
|
@@ -1342,7 +1343,7 @@ var track = (action, extra) => {
|
|
|
1342
1343
|
...extra
|
|
1343
1344
|
});
|
|
1344
1345
|
};
|
|
1345
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
1346
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
1346
1347
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1347
1348
|
if (!isActiveVariant) {
|
|
1348
1349
|
return;
|
|
@@ -1350,14 +1351,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
1350
1351
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
1351
1352
|
window.__applePayExperimentExposures = exposures;
|
|
1352
1353
|
const pathname = window.location?.pathname ?? "";
|
|
1353
|
-
const dedupeKey = `${pathname}:${
|
|
1354
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
1354
1355
|
if (exposures[dedupeKey]) {
|
|
1355
1356
|
return;
|
|
1356
1357
|
}
|
|
1357
1358
|
exposures[dedupeKey] = true;
|
|
1358
1359
|
emitTedlEvent({
|
|
1359
1360
|
name: "$exposure",
|
|
1360
|
-
flag_key:
|
|
1361
|
+
flag_key: flagKey,
|
|
1361
1362
|
variant,
|
|
1362
1363
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
1363
1364
|
});
|
|
@@ -1992,7 +1993,26 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
1992
1993
|
return typeof experimentKey === "string" ? experimentKey : void 0;
|
|
1993
1994
|
};
|
|
1994
1995
|
|
|
1996
|
+
// src/utils/applePayExpressEligibility.ts
|
|
1997
|
+
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
1998
|
+
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
1999
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2000
|
+
|
|
1995
2001
|
// src/apple-pay-button.ts
|
|
2002
|
+
var ENTRY_POINT_CONFIG = {
|
|
2003
|
+
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2004
|
+
isEligible: isEligibleForApplePayExpressExperiment,
|
|
2005
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2006
|
+
},
|
|
2007
|
+
["article_paywall" /* PAYWALL */]: {
|
|
2008
|
+
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
2009
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY
|
|
2010
|
+
},
|
|
2011
|
+
["article_regwall" /* REGWALL */]: {
|
|
2012
|
+
isEligible: () => true,
|
|
2013
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
1996
2016
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
1997
2017
|
var TOTAL_LABEL = "The Economist";
|
|
1998
2018
|
var DEFAULT_CURRENCY = "USD";
|
|
@@ -2011,9 +2031,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2011
2031
|
/**
|
|
2012
2032
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
2013
2033
|
*
|
|
2014
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
2015
|
-
* {@link
|
|
2016
|
-
*
|
|
2034
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
2035
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
2036
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
2037
|
+
*
|
|
2038
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
2039
|
+
* before calling this method.
|
|
2017
2040
|
*
|
|
2018
2041
|
* - `treatment` → button created and returned
|
|
2019
2042
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -2023,6 +2046,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2023
2046
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2024
2047
|
* fallback will be removed.
|
|
2025
2048
|
*
|
|
2049
|
+
* **Eligibility:**
|
|
2050
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
2051
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2052
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2053
|
+
*
|
|
2026
2054
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2027
2055
|
* @param country - The user's country code.
|
|
2028
2056
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -2034,19 +2062,35 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2034
2062
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
2035
2063
|
return null;
|
|
2036
2064
|
}
|
|
2065
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2066
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2067
|
+
);
|
|
2068
|
+
const resolvedEntryPoint = entryPoint || "dual_offer_banner" /* DUAL_OFFER_BANNER */;
|
|
2069
|
+
const config = ENTRY_POINT_CONFIG[resolvedEntryPoint];
|
|
2070
|
+
if (!config) {
|
|
2071
|
+
return null;
|
|
2072
|
+
}
|
|
2073
|
+
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2074
|
+
const isEligible = eligibilityCheck();
|
|
2075
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2076
|
+
return null;
|
|
2077
|
+
}
|
|
2037
2078
|
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
2038
|
-
|
|
2079
|
+
experimentFlagKey
|
|
2039
2080
|
);
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2081
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2082
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2083
|
+
void isApplePayAvailable().then((available) => {
|
|
2084
|
+
if (available) {
|
|
2085
|
+
trackApplePayExperimentExposure(
|
|
2086
|
+
experimentValue,
|
|
2087
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2088
|
+
experimentFlagKey
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2045
2092
|
}
|
|
2046
2093
|
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
2094
|
if (!isTreatment && !hasUrlParamFlag) {
|
|
2051
2095
|
return null;
|
|
2052
2096
|
}
|
|
@@ -1308,6 +1308,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1308
1308
|
|
|
1309
1309
|
// src/constants.ts
|
|
1310
1310
|
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1311
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1311
1312
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1312
1313
|
CONTROL: "control",
|
|
1313
1314
|
TREATMENT: "treatment"
|
|
@@ -1350,7 +1351,7 @@ var track = (action, extra) => {
|
|
|
1350
1351
|
...extra
|
|
1351
1352
|
});
|
|
1352
1353
|
};
|
|
1353
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
1354
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
1354
1355
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1355
1356
|
if (!isActiveVariant) {
|
|
1356
1357
|
return;
|
|
@@ -1358,14 +1359,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
1358
1359
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
1359
1360
|
window.__applePayExperimentExposures = exposures;
|
|
1360
1361
|
const pathname = window.location?.pathname ?? "";
|
|
1361
|
-
const dedupeKey = `${pathname}:${
|
|
1362
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
1362
1363
|
if (exposures[dedupeKey]) {
|
|
1363
1364
|
return;
|
|
1364
1365
|
}
|
|
1365
1366
|
exposures[dedupeKey] = true;
|
|
1366
1367
|
emitTedlEvent({
|
|
1367
1368
|
name: "$exposure",
|
|
1368
|
-
flag_key:
|
|
1369
|
+
flag_key: flagKey,
|
|
1369
1370
|
variant,
|
|
1370
1371
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
1371
1372
|
});
|
|
@@ -2000,7 +2001,26 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2000
2001
|
return typeof experimentKey === "string" ? experimentKey : void 0;
|
|
2001
2002
|
};
|
|
2002
2003
|
|
|
2004
|
+
// src/utils/applePayExpressEligibility.ts
|
|
2005
|
+
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2006
|
+
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2007
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2008
|
+
|
|
2003
2009
|
// src/apple-pay-button.ts
|
|
2010
|
+
var ENTRY_POINT_CONFIG = {
|
|
2011
|
+
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2012
|
+
isEligible: isEligibleForApplePayExpressExperiment,
|
|
2013
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2014
|
+
},
|
|
2015
|
+
["article_paywall" /* PAYWALL */]: {
|
|
2016
|
+
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
2017
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY
|
|
2018
|
+
},
|
|
2019
|
+
["article_regwall" /* REGWALL */]: {
|
|
2020
|
+
isEligible: () => true,
|
|
2021
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2022
|
+
}
|
|
2023
|
+
};
|
|
2004
2024
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
2005
2025
|
var TOTAL_LABEL = "The Economist";
|
|
2006
2026
|
var DEFAULT_CURRENCY = "USD";
|
|
@@ -2019,9 +2039,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2019
2039
|
/**
|
|
2020
2040
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
2021
2041
|
*
|
|
2022
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
2023
|
-
* {@link
|
|
2024
|
-
*
|
|
2042
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
2043
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
2044
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
2045
|
+
*
|
|
2046
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
2047
|
+
* before calling this method.
|
|
2025
2048
|
*
|
|
2026
2049
|
* - `treatment` → button created and returned
|
|
2027
2050
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -2031,6 +2054,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2031
2054
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2032
2055
|
* fallback will be removed.
|
|
2033
2056
|
*
|
|
2057
|
+
* **Eligibility:**
|
|
2058
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
2059
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2060
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2061
|
+
*
|
|
2034
2062
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2035
2063
|
* @param country - The user's country code.
|
|
2036
2064
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -2042,19 +2070,35 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2042
2070
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
2043
2071
|
return null;
|
|
2044
2072
|
}
|
|
2073
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2074
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2075
|
+
);
|
|
2076
|
+
const resolvedEntryPoint = entryPoint || "dual_offer_banner" /* DUAL_OFFER_BANNER */;
|
|
2077
|
+
const config = ENTRY_POINT_CONFIG[resolvedEntryPoint];
|
|
2078
|
+
if (!config) {
|
|
2079
|
+
return null;
|
|
2080
|
+
}
|
|
2081
|
+
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2082
|
+
const isEligible = eligibilityCheck();
|
|
2083
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2084
|
+
return null;
|
|
2085
|
+
}
|
|
2045
2086
|
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
2046
|
-
|
|
2087
|
+
experimentFlagKey
|
|
2047
2088
|
);
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2089
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2090
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2091
|
+
void isApplePayAvailable().then((available) => {
|
|
2092
|
+
if (available) {
|
|
2093
|
+
trackApplePayExperimentExposure(
|
|
2094
|
+
experimentValue,
|
|
2095
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2096
|
+
experimentFlagKey
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
2099
|
+
});
|
|
2053
2100
|
}
|
|
2054
2101
|
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2055
|
-
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2056
|
-
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2057
|
-
);
|
|
2058
2102
|
if (!isTreatment && !hasUrlParamFlag) {
|
|
2059
2103
|
return null;
|
|
2060
2104
|
}
|
|
@@ -1300,6 +1300,7 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1300
1300
|
|
|
1301
1301
|
// src/constants.ts
|
|
1302
1302
|
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1303
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1303
1304
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1304
1305
|
CONTROL: "control",
|
|
1305
1306
|
TREATMENT: "treatment"
|
|
@@ -1342,7 +1343,7 @@ var track = (action, extra) => {
|
|
|
1342
1343
|
...extra
|
|
1343
1344
|
});
|
|
1344
1345
|
};
|
|
1345
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
1346
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
1346
1347
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1347
1348
|
if (!isActiveVariant) {
|
|
1348
1349
|
return;
|
|
@@ -1350,14 +1351,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
1350
1351
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
1351
1352
|
window.__applePayExperimentExposures = exposures;
|
|
1352
1353
|
const pathname = window.location?.pathname ?? "";
|
|
1353
|
-
const dedupeKey = `${pathname}:${
|
|
1354
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
1354
1355
|
if (exposures[dedupeKey]) {
|
|
1355
1356
|
return;
|
|
1356
1357
|
}
|
|
1357
1358
|
exposures[dedupeKey] = true;
|
|
1358
1359
|
emitTedlEvent({
|
|
1359
1360
|
name: "$exposure",
|
|
1360
|
-
flag_key:
|
|
1361
|
+
flag_key: flagKey,
|
|
1361
1362
|
variant,
|
|
1362
1363
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
1363
1364
|
});
|
|
@@ -1992,7 +1993,26 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
1992
1993
|
return typeof experimentKey === "string" ? experimentKey : void 0;
|
|
1993
1994
|
};
|
|
1994
1995
|
|
|
1996
|
+
// src/utils/applePayExpressEligibility.ts
|
|
1997
|
+
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
1998
|
+
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
1999
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2000
|
+
|
|
1995
2001
|
// src/apple-pay-button.ts
|
|
2002
|
+
var ENTRY_POINT_CONFIG = {
|
|
2003
|
+
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2004
|
+
isEligible: isEligibleForApplePayExpressExperiment,
|
|
2005
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2006
|
+
},
|
|
2007
|
+
["article_paywall" /* PAYWALL */]: {
|
|
2008
|
+
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
2009
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY
|
|
2010
|
+
},
|
|
2011
|
+
["article_regwall" /* REGWALL */]: {
|
|
2012
|
+
isEligible: () => true,
|
|
2013
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
1996
2016
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
1997
2017
|
var TOTAL_LABEL = "The Economist";
|
|
1998
2018
|
var DEFAULT_CURRENCY = "USD";
|
|
@@ -2011,9 +2031,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2011
2031
|
/**
|
|
2012
2032
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
2013
2033
|
*
|
|
2014
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
2015
|
-
* {@link
|
|
2016
|
-
*
|
|
2034
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
2035
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
2036
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
2037
|
+
*
|
|
2038
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
2039
|
+
* before calling this method.
|
|
2017
2040
|
*
|
|
2018
2041
|
* - `treatment` → button created and returned
|
|
2019
2042
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -2023,6 +2046,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2023
2046
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2024
2047
|
* fallback will be removed.
|
|
2025
2048
|
*
|
|
2049
|
+
* **Eligibility:**
|
|
2050
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
2051
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2052
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2053
|
+
*
|
|
2026
2054
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2027
2055
|
* @param country - The user's country code.
|
|
2028
2056
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -2034,19 +2062,35 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2034
2062
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
2035
2063
|
return null;
|
|
2036
2064
|
}
|
|
2065
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2066
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2067
|
+
);
|
|
2068
|
+
const resolvedEntryPoint = entryPoint || "dual_offer_banner" /* DUAL_OFFER_BANNER */;
|
|
2069
|
+
const config = ENTRY_POINT_CONFIG[resolvedEntryPoint];
|
|
2070
|
+
if (!config) {
|
|
2071
|
+
return null;
|
|
2072
|
+
}
|
|
2073
|
+
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2074
|
+
const isEligible = eligibilityCheck();
|
|
2075
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2076
|
+
return null;
|
|
2077
|
+
}
|
|
2037
2078
|
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
2038
|
-
|
|
2079
|
+
experimentFlagKey
|
|
2039
2080
|
);
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2081
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2082
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2083
|
+
void isApplePayAvailable().then((available) => {
|
|
2084
|
+
if (available) {
|
|
2085
|
+
trackApplePayExperimentExposure(
|
|
2086
|
+
experimentValue,
|
|
2087
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2088
|
+
experimentFlagKey
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2045
2092
|
}
|
|
2046
2093
|
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
2094
|
if (!isTreatment && !hasUrlParamFlag) {
|
|
2051
2095
|
return null;
|
|
2052
2096
|
}
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ export declare enum ApplePayEntryPoint {
|
|
|
4
4
|
DUAL_OFFER_BANNER = "dual_offer_banner"
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
* Amplitude experiment key for Apple Pay Express Checkout on banners
|
|
7
|
+
* Amplitude experiment key for Apple Pay Express Checkout on homepage banners
|
|
8
|
+
* (dual-offer banner) and article banner regwalls.
|
|
9
|
+
*
|
|
8
10
|
* This package reads the variant for this key internally via
|
|
9
11
|
* `window.experimentIntegration.getVariant()` — set up by the host page
|
|
10
|
-
* before `createIfEnabled` is called.
|
|
12
|
+
* before `createIfEnabled` is called.
|
|
11
13
|
*
|
|
12
14
|
* Fail-closed: missing integration, missing key, `control`, or Amplitude fetch
|
|
13
15
|
* failure on the host → button is hidden (unless QA URL param is present).
|
|
@@ -16,6 +18,20 @@ export declare enum ApplePayEntryPoint {
|
|
|
16
18
|
* (Engagement / Insider / Podcasts).
|
|
17
19
|
*/
|
|
18
20
|
export declare const APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
21
|
+
/**
|
|
22
|
+
* Amplitude experiment key for Apple Pay Express Checkout on article paywalls
|
|
23
|
+
* (`ApplePayEntryPoint.PAYWALL`, e.g. single-offer-paywall / multi-offer paywall).
|
|
24
|
+
*
|
|
25
|
+
* Same fail-closed / QA-param behaviour as {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY}.
|
|
26
|
+
* Eligibility for this flag ignores homepage and requires Safari/Apple device
|
|
27
|
+
* (plus `isApplePayAvailable` before `$exposure`).
|
|
28
|
+
*/
|
|
29
|
+
export declare const APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
30
|
+
/**
|
|
31
|
+
* Known Amplitude experiment flag keys for Apple Pay Express Checkout.
|
|
32
|
+
* Narrowed so callers cannot pass an arbitrary typo'd string.
|
|
33
|
+
*/
|
|
34
|
+
export type ApplePayExperimentFlagKey = typeof APPLE_PAY_EXPRESS_EXPERIMENT_KEY | typeof APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY;
|
|
19
35
|
/**
|
|
20
36
|
* Amplitude variant values for the Apple Pay Express Checkout experiment.
|
|
21
37
|
* CONTROL → button hidden (baseline)
|
package/dist/src/constants.js
CHANGED
|
@@ -6,12 +6,14 @@ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
|
|
|
6
6
|
return ApplePayEntryPoint2;
|
|
7
7
|
})(ApplePayEntryPoint || {});
|
|
8
8
|
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
9
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
9
10
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
10
11
|
CONTROL: "control",
|
|
11
12
|
TREATMENT: "treatment"
|
|
12
13
|
};
|
|
13
14
|
export {
|
|
14
15
|
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
16
|
+
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
15
17
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
16
18
|
ApplePayEntryPoint
|
|
17
19
|
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ export { ApplePayButton, APPLE_PAY_EXCLUDED_VARIANTS, } from './apple-pay-button
|
|
|
2
2
|
export { ApplePayModal } from './apple-pay-modal';
|
|
3
3
|
export { ensureApplePayLogoSymbol } from './apple-pay-logo';
|
|
4
4
|
export { configureApplePay } from './clients/payment-checkout/config';
|
|
5
|
-
export { ApplePayEntryPoint } from './constants';
|
|
5
|
+
export { ApplePayEntryPoint, APPLE_PAY_EXPRESS_EXPERIMENT_KEY, APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY, APPLE_PAY_EXPRESS_VARIANTS, } from './constants';
|
|
6
|
+
export type { ApplePayExperimentFlagKey } from './constants';
|
|
6
7
|
export type { ApplePayRuntimeConfig } from './clients/payment-checkout/config';
|
|
7
8
|
export type { Offer } from './types/offer.types';
|
|
8
9
|
export declare function defineApplePayElements(): void;
|
package/dist/src/index.js
CHANGED
|
@@ -1304,13 +1304,14 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1304
1304
|
};
|
|
1305
1305
|
|
|
1306
1306
|
// src/constants.ts
|
|
1307
|
-
var ApplePayEntryPoint = /* @__PURE__ */ ((
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
return
|
|
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
|
+
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1314
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1315
1316
|
CONTROL: "control",
|
|
1316
1317
|
TREATMENT: "treatment"
|
|
@@ -1353,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1353
1354
|
...extra
|
|
1354
1355
|
});
|
|
1355
1356
|
};
|
|
1356
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
1357
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1358
1359
|
if (!isActiveVariant) {
|
|
1359
1360
|
return;
|
|
@@ -1361,14 +1362,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
1361
1362
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
1362
1363
|
window.__applePayExperimentExposures = exposures;
|
|
1363
1364
|
const pathname = window.location?.pathname ?? "";
|
|
1364
|
-
const dedupeKey = `${pathname}:${
|
|
1365
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
1365
1366
|
if (exposures[dedupeKey]) {
|
|
1366
1367
|
return;
|
|
1367
1368
|
}
|
|
1368
1369
|
exposures[dedupeKey] = true;
|
|
1369
1370
|
emitTedlEvent({
|
|
1370
1371
|
name: "$exposure",
|
|
1371
|
-
flag_key:
|
|
1372
|
+
flag_key: flagKey,
|
|
1372
1373
|
variant,
|
|
1373
1374
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
1374
1375
|
});
|
|
@@ -2003,7 +2004,26 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2003
2004
|
return typeof experimentKey === "string" ? experimentKey : void 0;
|
|
2004
2005
|
};
|
|
2005
2006
|
|
|
2007
|
+
// src/utils/applePayExpressEligibility.ts
|
|
2008
|
+
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2009
|
+
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2010
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2011
|
+
|
|
2006
2012
|
// src/apple-pay-button.ts
|
|
2013
|
+
var ENTRY_POINT_CONFIG = {
|
|
2014
|
+
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2015
|
+
isEligible: isEligibleForApplePayExpressExperiment,
|
|
2016
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2017
|
+
},
|
|
2018
|
+
["article_paywall" /* PAYWALL */]: {
|
|
2019
|
+
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
2020
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY
|
|
2021
|
+
},
|
|
2022
|
+
["article_regwall" /* REGWALL */]: {
|
|
2023
|
+
isEligible: () => true,
|
|
2024
|
+
experimentFlagKey: APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2007
2027
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
2008
2028
|
var TOTAL_LABEL = "The Economist";
|
|
2009
2029
|
var DEFAULT_CURRENCY = "USD";
|
|
@@ -2022,9 +2042,12 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2022
2042
|
/**
|
|
2023
2043
|
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
2024
2044
|
*
|
|
2025
|
-
* Reads the experiment variant from `window.experimentIntegration.getVariant
|
|
2026
|
-
* {@link
|
|
2027
|
-
*
|
|
2045
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant`:
|
|
2046
|
+
* - {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY} for `PAYWALL`
|
|
2047
|
+
* - {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY} for `REGWALL` / `DUAL_OFFER_BANNER`
|
|
2048
|
+
*
|
|
2049
|
+
* The host page is responsible for setting up `window.experimentIntegration`
|
|
2050
|
+
* before calling this method.
|
|
2028
2051
|
*
|
|
2029
2052
|
* - `treatment` → button created and returned
|
|
2030
2053
|
* - `control` / missing / anything else → returns null (button suppressed)
|
|
@@ -2034,6 +2057,11 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2034
2057
|
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2035
2058
|
* fallback will be removed.
|
|
2036
2059
|
*
|
|
2060
|
+
* **Eligibility:**
|
|
2061
|
+
* - `DUAL_OFFER_BANNER` (or omitted): homepage + Safari/iPhone (SMA-3301)
|
|
2062
|
+
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2063
|
+
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2064
|
+
*
|
|
2037
2065
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2038
2066
|
* @param country - The user's country code.
|
|
2039
2067
|
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
@@ -2045,19 +2073,35 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2045
2073
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
2046
2074
|
return null;
|
|
2047
2075
|
}
|
|
2076
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2077
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2078
|
+
);
|
|
2079
|
+
const resolvedEntryPoint = entryPoint || "dual_offer_banner" /* DUAL_OFFER_BANNER */;
|
|
2080
|
+
const config = ENTRY_POINT_CONFIG[resolvedEntryPoint];
|
|
2081
|
+
if (!config) {
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2084
|
+
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2085
|
+
const isEligible = eligibilityCheck();
|
|
2086
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2087
|
+
return null;
|
|
2088
|
+
}
|
|
2048
2089
|
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
2049
|
-
|
|
2090
|
+
experimentFlagKey
|
|
2050
2091
|
);
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2092
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2093
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2094
|
+
void isApplePayAvailable().then((available) => {
|
|
2095
|
+
if (available) {
|
|
2096
|
+
trackApplePayExperimentExposure(
|
|
2097
|
+
experimentValue,
|
|
2098
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2099
|
+
experimentFlagKey
|
|
2100
|
+
);
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2056
2103
|
}
|
|
2057
2104
|
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2058
|
-
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2059
|
-
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2060
|
-
);
|
|
2061
2105
|
if (!isTreatment && !hasUrlParamFlag) {
|
|
2062
2106
|
return null;
|
|
2063
2107
|
}
|
|
@@ -2373,6 +2417,9 @@ function defineApplePayElements() {
|
|
|
2373
2417
|
}
|
|
2374
2418
|
export {
|
|
2375
2419
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2420
|
+
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2421
|
+
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2422
|
+
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2376
2423
|
ApplePayButton,
|
|
2377
2424
|
ApplePayEntryPoint,
|
|
2378
2425
|
ApplePayModal,
|
|
@@ -0,0 +1,20 @@
|
|
|
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 participates. Exposure is further gated on isApplePayAvailable()
|
|
6
|
+
* (BYPASS_APPLE_PAY_CHECKS respected). Amplitude audience targeting uses
|
|
7
|
+
* generic user_properties from Engagement.
|
|
8
|
+
*/
|
|
9
|
+
export declare const isApplePayExpressHomepage: (pathname?: string) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Dual-offer homepage banner: homepage + Safari/iPhone.
|
|
12
|
+
* Anonymous is assumed because the dual-offer banner is only mounted for
|
|
13
|
+
* anonymous visitors.
|
|
14
|
+
*/
|
|
15
|
+
export declare const isEligibleForApplePayExpressExperiment: () => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Article paywalls (`ApplePayEntryPoint.PAYWALL`): Safari/Apple device only.
|
|
18
|
+
* Homepage targeting does not apply — paywalls render on article pages.
|
|
19
|
+
*/
|
|
20
|
+
export declare const isEligibleForApplePayExpressPaywallExperiment: () => boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
12
|
+
export {
|
|
13
|
+
isApplePayExpressHomepage,
|
|
14
|
+
isEligibleForApplePayExpressExperiment,
|
|
15
|
+
isEligibleForApplePayExpressPaywallExperiment
|
|
16
|
+
};
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Event names are aligned to the PRD spec (section 10 — Tracking & Analytics).
|
|
13
13
|
*/
|
|
14
|
+
import { type ApplePayExperimentFlagKey } from '../constants';
|
|
14
15
|
declare global {
|
|
15
16
|
interface Window {
|
|
16
17
|
tedl?: {
|
|
@@ -50,12 +51,16 @@ export type ImpressionMetadata = {
|
|
|
50
51
|
/**
|
|
51
52
|
* Amplitude Experiment exposure for Apple Pay Express (SMA-3301).
|
|
52
53
|
*
|
|
53
|
-
* Fired
|
|
54
|
-
* treatment). Deduped per pathname + variant so
|
|
55
|
-
* the same page do not over-count. Includes
|
|
56
|
-
* SSR (__NEXT_DATA__) when present for
|
|
54
|
+
* Fired from createIfEnabled only after isApplePayAvailable() succeeds
|
|
55
|
+
* (control or treatment). Deduped per pathname + flag_key + variant so
|
|
56
|
+
* repeated renders on the same page do not over-count. Includes
|
|
57
|
+
* experiment_key from Engagement SSR (__NEXT_DATA__) when present for run
|
|
58
|
+
* attribution.
|
|
59
|
+
*
|
|
60
|
+
* @param flagKey - Amplitude flag_key. Defaults to the banners experiment;
|
|
61
|
+
* paywalls pass {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}.
|
|
57
62
|
*/
|
|
58
|
-
export declare const trackApplePayExperimentExposure: (variant: string, experimentKey?: string) => void;
|
|
63
|
+
export declare const trackApplePayExperimentExposure: (variant: string, experimentKey?: string, flagKey?: ApplePayExperimentFlagKey) => void;
|
|
59
64
|
/** Wallet button displayed — emits all 5 required analytics dimensions. */
|
|
60
65
|
export declare const trackExpressWalletImpression: (skuId: string, { entryPoint, country }: ImpressionMetadata) => void;
|
|
61
66
|
/** Wallet button clicked */
|
|
@@ -42,7 +42,7 @@ var track = (action, extra) => {
|
|
|
42
42
|
...extra
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
-
var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
45
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey = APPLE_PAY_EXPRESS_EXPERIMENT_KEY) => {
|
|
46
46
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
47
47
|
if (!isActiveVariant) {
|
|
48
48
|
return;
|
|
@@ -50,14 +50,14 @@ var trackApplePayExperimentExposure = (variant, experimentKey) => {
|
|
|
50
50
|
const exposures = window.__applePayExperimentExposures ?? {};
|
|
51
51
|
window.__applePayExperimentExposures = exposures;
|
|
52
52
|
const pathname = window.location?.pathname ?? "";
|
|
53
|
-
const dedupeKey = `${pathname}:${
|
|
53
|
+
const dedupeKey = `${pathname}:${flagKey}:${variant}`;
|
|
54
54
|
if (exposures[dedupeKey]) {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
exposures[dedupeKey] = true;
|
|
58
58
|
emitTedlEvent({
|
|
59
59
|
name: "$exposure",
|
|
60
|
-
flag_key:
|
|
60
|
+
flag_key: flagKey,
|
|
61
61
|
variant,
|
|
62
62
|
...experimentKey ? { experiment_key: experimentKey } : {}
|
|
63
63
|
});
|