@economist/web-apple-pay 1.10.0 → 2.0.0-beta.2
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/README.md +19 -5
- package/dist/index.js +57 -45
- package/dist/src/apple-pay-button.d.ts +18 -16
- package/dist/src/apple-pay-button.js +56 -44
- package/dist/src/apple-pay-button.stories.js +56 -44
- package/dist/src/apple-pay-modal.stories.js +56 -44
- package/dist/src/constants.d.ts +8 -18
- package/dist/src/constants.js +1 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +57 -45
- package/dist/src/utils/applePayExpressEligibility.d.ts +10 -9
- package/dist/src/utils/applePayExpressEligibility.js +2 -2
- package/dist/src/utils/expressCheckoutTracking.d.ts +13 -4
- package/dist/src/utils/expressCheckoutTracking.js +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,10 @@ npm install --save @economist/web-apple-pay
|
|
|
27
27
|
Call `configureApplePay(...)` once during app startup, before rendering Apple Pay UI:
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
configureApplePay,
|
|
32
|
+
defineApplePayElements,
|
|
33
|
+
} from '@economist/web-apple-pay';
|
|
31
34
|
|
|
32
35
|
configureApplePay({
|
|
33
36
|
merchantId: 'merchant.com.economist.your-app',
|
|
@@ -85,8 +88,8 @@ to the DOM. This is the supported, stable way to know whether Apple Pay is
|
|
|
85
88
|
available without touching lifecycle internals.
|
|
86
89
|
|
|
87
90
|
```ts
|
|
88
|
-
container.appendChild(btn);
|
|
89
|
-
await btn.whenReady();
|
|
91
|
+
container.appendChild(btn); // spec-compliant — browser fires connectedCallback naturally
|
|
92
|
+
await btn.whenReady(); // resolves when rendering is complete
|
|
90
93
|
if (btn.style.display !== 'none') {
|
|
91
94
|
// Apple Pay rendered successfully
|
|
92
95
|
} else {
|
|
@@ -121,10 +124,20 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
121
124
|
- `configureApplePay(config)`: sets required runtime config (merchant ID and wallet API base URL, with optional debug bypass).
|
|
122
125
|
- `ApplePayButton`: button component class.
|
|
123
126
|
- `whenReady(): Promise<void>` — resolves when the current render lifecycle completes (available or hidden). Resolves immediately if called before the element is connected.
|
|
127
|
+
- `createIfEnabled(offer, country, entryPoint?)`: returns a configured button or `null`.
|
|
128
|
+
- `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions — no homepage/Safari gate at `createIfEnabled` (device gating via `isApplePayAvailable` on mount); no banners Amplitude experiment / `$exposure`.
|
|
129
|
+
- `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; wallet impression `entry_point` is `free_trial_banner`.
|
|
130
|
+
- `PAYWALL`: experiment-gated via `apple-pay-express-checkout-on-paywalls` (`treatment` or QA URL).
|
|
131
|
+
- `REGWALL`: inert — always returns `null`.
|
|
124
132
|
- `ApplePayModal`: modal component class.
|
|
125
133
|
- `ensureApplePayLogoSymbol()`: logo symbol injection helper.
|
|
134
|
+
- `APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY`: Amplitude flag key for paywalls experiment gating / `$exposure`.
|
|
126
135
|
- `Offer`: offer contract type used by component props.
|
|
127
136
|
|
|
137
|
+
### Breaking changes
|
|
138
|
+
|
|
139
|
+
- `APPLE_PAY_EXPRESS_EXPERIMENT_KEY` (banners experiment flag) is no longer exported. Use `APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY` for paywalls, or drop the import if you only needed the retired banners key.
|
|
140
|
+
|
|
128
141
|
## Troubleshooting
|
|
129
142
|
|
|
130
143
|
### Button does not appear
|
|
@@ -132,8 +145,9 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
132
145
|
Check:
|
|
133
146
|
|
|
134
147
|
- `configureApplePay(...)` was called before rendering (with a valid `merchantId` and `walletApiBaseUrl`)
|
|
135
|
-
- device/browser supports Apple Pay (Safari on Apple device required)
|
|
136
|
-
-
|
|
148
|
+
- device/browser supports Apple Pay (Safari on Apple device required — enforced by `isApplePayAvailable` on mount)
|
|
149
|
+
- for paywalls: Amplitude treatment (or `?FEATURE_APPLE_PAY_EXPRESS_CHECKOUT`) is satisfied, plus Safari/Apple placement eligibility
|
|
150
|
+
- for banners: consumer kill switch off (no homepage/Safari gate at `createIfEnabled`)
|
|
137
151
|
- offer variant is not excluded (`bundle`, `insider_print`)
|
|
138
152
|
|
|
139
153
|
### Logged-in checkbox copy looks wrong
|
package/dist/index.js
CHANGED
|
@@ -1308,9 +1308,9 @@ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
|
|
|
1308
1308
|
ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
|
|
1309
1309
|
ApplePayEntryPoint2["REGWALL"] = "article_regwall";
|
|
1310
1310
|
ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
|
|
1311
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
1311
1312
|
return ApplePayEntryPoint2;
|
|
1312
1313
|
})(ApplePayEntryPoint || {});
|
|
1313
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1314
1314
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1315
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1316
1316
|
CONTROL: "control",
|
|
@@ -1354,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1354
1354
|
...extra
|
|
1355
1355
|
});
|
|
1356
1356
|
};
|
|
1357
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1358
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1359
1359
|
if (!isActiveVariant) {
|
|
1360
1360
|
return;
|
|
@@ -1383,8 +1383,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1383
1383
|
device: getDevice()
|
|
1384
1384
|
});
|
|
1385
1385
|
};
|
|
1386
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1387
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1386
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
1387
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1388
|
+
sku_id: skuId,
|
|
1389
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
1390
|
+
});
|
|
1388
1391
|
};
|
|
1389
1392
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1390
1393
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -2005,15 +2008,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2005
2008
|
};
|
|
2006
2009
|
|
|
2007
2010
|
// src/utils/applePayExpressEligibility.ts
|
|
2008
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2009
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2010
2011
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2011
2012
|
|
|
2012
2013
|
// src/apple-pay-button.ts
|
|
2013
2014
|
var ENTRY_POINT_CONFIG = {
|
|
2014
2015
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2015
|
-
isEligible:
|
|
2016
|
-
experimentFlagKey
|
|
2016
|
+
isEligible: () => true
|
|
2017
|
+
// no experimentFlagKey → always-on after offer exclusions
|
|
2018
|
+
},
|
|
2019
|
+
["free_trial_banner" /* FREE_TRIAL_BANNER */]: {
|
|
2020
|
+
isEligible: () => true
|
|
2021
|
+
// Dual parity — no experimentFlagKey, no homepage gate here
|
|
2017
2022
|
},
|
|
2018
2023
|
["article_paywall" /* PAYWALL */]: {
|
|
2019
2024
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2021,7 +2026,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2021
2026
|
},
|
|
2022
2027
|
["article_regwall" /* REGWALL */]: {
|
|
2023
2028
|
isEligible: () => true,
|
|
2024
|
-
|
|
2029
|
+
enabled: false
|
|
2025
2030
|
}
|
|
2026
2031
|
};
|
|
2027
2032
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2040,27 +2045,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2040
2045
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2041
2046
|
}
|
|
2042
2047
|
/**
|
|
2043
|
-
* Creates and configures an ApplePayButton when the
|
|
2044
|
-
*
|
|
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
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2048
2049
|
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2050
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
2051
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
2052
|
+
* `$exposure`.
|
|
2053
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
2054
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
2055
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
2056
|
+
* (`treatment` or QA URL param). The host must set up
|
|
2057
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
2058
|
+
* - `REGWALL`: inert — always returns null.
|
|
2051
2059
|
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2058
|
-
* fallback will be removed.
|
|
2060
|
+
* **PAYWALL only — transition period:** the legacy
|
|
2061
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
2062
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
2063
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
2064
|
+
* `isApplePayAvailable()` on mount.
|
|
2059
2065
|
*
|
|
2060
2066
|
* **Eligibility:**
|
|
2061
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
2067
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
2068
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
2069
|
+
* later by `isApplePayAvailable()` on mount)
|
|
2062
2070
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2063
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2064
2071
|
*
|
|
2065
2072
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2066
2073
|
* @param country - The user's country code.
|
|
@@ -2083,28 +2090,31 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2083
2090
|
}
|
|
2084
2091
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2085
2092
|
const isEligible = eligibilityCheck();
|
|
2086
|
-
if (
|
|
2093
|
+
if (config.enabled === false) {
|
|
2087
2094
|
return null;
|
|
2088
2095
|
}
|
|
2089
|
-
|
|
2090
|
-
experimentFlagKey
|
|
2091
|
-
);
|
|
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
|
-
});
|
|
2103
|
-
}
|
|
2104
|
-
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2105
|
-
if (!isTreatment && !hasUrlParamFlag) {
|
|
2096
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2106
2097
|
return null;
|
|
2107
2098
|
}
|
|
2099
|
+
if (experimentFlagKey) {
|
|
2100
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(experimentFlagKey);
|
|
2101
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2102
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2103
|
+
void isApplePayAvailable().then((available) => {
|
|
2104
|
+
if (available) {
|
|
2105
|
+
trackApplePayExperimentExposure(
|
|
2106
|
+
experimentValue,
|
|
2107
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2108
|
+
experimentFlagKey
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2114
|
+
if (!isTreatment && !hasUrlParamFlag) {
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2108
2118
|
_ApplePayButton.define();
|
|
2109
2119
|
const button = document.createElement(_ApplePayButton.tag);
|
|
2110
2120
|
button.offer = offer;
|
|
@@ -2325,7 +2335,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2325
2335
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2326
2336
|
return;
|
|
2327
2337
|
}
|
|
2328
|
-
trackExpressWalletClick(
|
|
2338
|
+
trackExpressWalletClick(
|
|
2339
|
+
this.#offer.sku_id,
|
|
2340
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2341
|
+
);
|
|
2329
2342
|
ApplePayModal.define();
|
|
2330
2343
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2331
2344
|
modal.offer = this.#offer;
|
|
@@ -2417,7 +2430,6 @@ function defineApplePayElements() {
|
|
|
2417
2430
|
}
|
|
2418
2431
|
export {
|
|
2419
2432
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2420
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2421
2433
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2422
2434
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2423
2435
|
ApplePayButton,
|
|
@@ -6,27 +6,29 @@ export declare class ApplePayButton extends HTMLElement {
|
|
|
6
6
|
static readonly tag = "teg-apple-pay-button";
|
|
7
7
|
static define(): void;
|
|
8
8
|
/**
|
|
9
|
-
* Creates and configures an ApplePayButton when the
|
|
9
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
12
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
13
|
+
* `$exposure`.
|
|
14
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
15
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
16
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
17
|
+
* (`treatment` or QA URL param). The host must set up
|
|
18
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
19
|
+
* - `REGWALL`: inert — always returns null.
|
|
14
20
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
22
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
23
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
24
|
-
* fallback will be removed.
|
|
21
|
+
* **PAYWALL only — transition period:** the legacy
|
|
22
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
23
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
24
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
25
|
+
* `isApplePayAvailable()` on mount.
|
|
25
26
|
*
|
|
26
27
|
* **Eligibility:**
|
|
27
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
28
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
29
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
30
|
+
* later by `isApplePayAvailable()` on mount)
|
|
28
31
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
29
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
30
32
|
*
|
|
31
33
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
32
34
|
* @param country - The user's country code.
|
|
@@ -1299,7 +1299,6 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1299
1299
|
};
|
|
1300
1300
|
|
|
1301
1301
|
// src/constants.ts
|
|
1302
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1303
1302
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1304
1303
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1305
1304
|
CONTROL: "control",
|
|
@@ -1343,7 +1342,7 @@ var track = (action, extra) => {
|
|
|
1343
1342
|
...extra
|
|
1344
1343
|
});
|
|
1345
1344
|
};
|
|
1346
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1345
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1347
1346
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1348
1347
|
if (!isActiveVariant) {
|
|
1349
1348
|
return;
|
|
@@ -1372,8 +1371,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1372
1371
|
device: getDevice()
|
|
1373
1372
|
});
|
|
1374
1373
|
};
|
|
1375
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1376
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1374
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
1375
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1376
|
+
sku_id: skuId,
|
|
1377
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
1378
|
+
});
|
|
1377
1379
|
};
|
|
1378
1380
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1379
1381
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -1994,15 +1996,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
1994
1996
|
};
|
|
1995
1997
|
|
|
1996
1998
|
// src/utils/applePayExpressEligibility.ts
|
|
1997
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
1998
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
1999
1999
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2000
2000
|
|
|
2001
2001
|
// src/apple-pay-button.ts
|
|
2002
2002
|
var ENTRY_POINT_CONFIG = {
|
|
2003
2003
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2004
|
-
isEligible:
|
|
2005
|
-
experimentFlagKey
|
|
2004
|
+
isEligible: () => true
|
|
2005
|
+
// no experimentFlagKey → always-on after offer exclusions
|
|
2006
|
+
},
|
|
2007
|
+
["free_trial_banner" /* FREE_TRIAL_BANNER */]: {
|
|
2008
|
+
isEligible: () => true
|
|
2009
|
+
// Dual parity — no experimentFlagKey, no homepage gate here
|
|
2006
2010
|
},
|
|
2007
2011
|
["article_paywall" /* PAYWALL */]: {
|
|
2008
2012
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2010,7 +2014,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2010
2014
|
},
|
|
2011
2015
|
["article_regwall" /* REGWALL */]: {
|
|
2012
2016
|
isEligible: () => true,
|
|
2013
|
-
|
|
2017
|
+
enabled: false
|
|
2014
2018
|
}
|
|
2015
2019
|
};
|
|
2016
2020
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2029,27 +2033,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2029
2033
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2030
2034
|
}
|
|
2031
2035
|
/**
|
|
2032
|
-
* Creates and configures an ApplePayButton when the
|
|
2033
|
-
*
|
|
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`
|
|
2036
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2037
2037
|
*
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2038
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
2039
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
2040
|
+
* `$exposure`.
|
|
2041
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
2042
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
2043
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
2044
|
+
* (`treatment` or QA URL param). The host must set up
|
|
2045
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
2046
|
+
* - `REGWALL`: inert — always returns null.
|
|
2040
2047
|
*
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2047
|
-
* fallback will be removed.
|
|
2048
|
+
* **PAYWALL only — transition period:** the legacy
|
|
2049
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
2050
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
2051
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
2052
|
+
* `isApplePayAvailable()` on mount.
|
|
2048
2053
|
*
|
|
2049
2054
|
* **Eligibility:**
|
|
2050
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
2055
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
2056
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
2057
|
+
* later by `isApplePayAvailable()` on mount)
|
|
2051
2058
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2052
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2053
2059
|
*
|
|
2054
2060
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2055
2061
|
* @param country - The user's country code.
|
|
@@ -2072,28 +2078,31 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2072
2078
|
}
|
|
2073
2079
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2074
2080
|
const isEligible = eligibilityCheck();
|
|
2075
|
-
if (
|
|
2081
|
+
if (config.enabled === false) {
|
|
2076
2082
|
return null;
|
|
2077
2083
|
}
|
|
2078
|
-
|
|
2079
|
-
experimentFlagKey
|
|
2080
|
-
);
|
|
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
|
-
});
|
|
2092
|
-
}
|
|
2093
|
-
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2094
|
-
if (!isTreatment && !hasUrlParamFlag) {
|
|
2084
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2095
2085
|
return null;
|
|
2096
2086
|
}
|
|
2087
|
+
if (experimentFlagKey) {
|
|
2088
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(experimentFlagKey);
|
|
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
|
+
});
|
|
2100
|
+
}
|
|
2101
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2102
|
+
if (!isTreatment && !hasUrlParamFlag) {
|
|
2103
|
+
return null;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2097
2106
|
_ApplePayButton.define();
|
|
2098
2107
|
const button = document.createElement(_ApplePayButton.tag);
|
|
2099
2108
|
button.offer = offer;
|
|
@@ -2314,7 +2323,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2314
2323
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2315
2324
|
return;
|
|
2316
2325
|
}
|
|
2317
|
-
trackExpressWalletClick(
|
|
2326
|
+
trackExpressWalletClick(
|
|
2327
|
+
this.#offer.sku_id,
|
|
2328
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2329
|
+
);
|
|
2318
2330
|
ApplePayModal.define();
|
|
2319
2331
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2320
2332
|
modal.offer = this.#offer;
|
|
@@ -1307,7 +1307,6 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1307
1307
|
};
|
|
1308
1308
|
|
|
1309
1309
|
// src/constants.ts
|
|
1310
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1311
1310
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1312
1311
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1313
1312
|
CONTROL: "control",
|
|
@@ -1351,7 +1350,7 @@ var track = (action, extra) => {
|
|
|
1351
1350
|
...extra
|
|
1352
1351
|
});
|
|
1353
1352
|
};
|
|
1354
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1353
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1355
1354
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1356
1355
|
if (!isActiveVariant) {
|
|
1357
1356
|
return;
|
|
@@ -1380,8 +1379,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1380
1379
|
device: getDevice()
|
|
1381
1380
|
});
|
|
1382
1381
|
};
|
|
1383
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1384
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1382
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
1383
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1384
|
+
sku_id: skuId,
|
|
1385
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
1386
|
+
});
|
|
1385
1387
|
};
|
|
1386
1388
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1387
1389
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -2002,15 +2004,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2002
2004
|
};
|
|
2003
2005
|
|
|
2004
2006
|
// src/utils/applePayExpressEligibility.ts
|
|
2005
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2006
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2007
2007
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2008
2008
|
|
|
2009
2009
|
// src/apple-pay-button.ts
|
|
2010
2010
|
var ENTRY_POINT_CONFIG = {
|
|
2011
2011
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2012
|
-
isEligible:
|
|
2013
|
-
experimentFlagKey
|
|
2012
|
+
isEligible: () => true
|
|
2013
|
+
// no experimentFlagKey → always-on after offer exclusions
|
|
2014
|
+
},
|
|
2015
|
+
["free_trial_banner" /* FREE_TRIAL_BANNER */]: {
|
|
2016
|
+
isEligible: () => true
|
|
2017
|
+
// Dual parity — no experimentFlagKey, no homepage gate here
|
|
2014
2018
|
},
|
|
2015
2019
|
["article_paywall" /* PAYWALL */]: {
|
|
2016
2020
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2018,7 +2022,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2018
2022
|
},
|
|
2019
2023
|
["article_regwall" /* REGWALL */]: {
|
|
2020
2024
|
isEligible: () => true,
|
|
2021
|
-
|
|
2025
|
+
enabled: false
|
|
2022
2026
|
}
|
|
2023
2027
|
};
|
|
2024
2028
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2037,27 +2041,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2037
2041
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2038
2042
|
}
|
|
2039
2043
|
/**
|
|
2040
|
-
* Creates and configures an ApplePayButton when the
|
|
2041
|
-
*
|
|
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.
|
|
2044
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2048
2045
|
*
|
|
2049
|
-
* - `
|
|
2050
|
-
*
|
|
2046
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
2047
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
2048
|
+
* `$exposure`.
|
|
2049
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
2050
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
2051
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
2052
|
+
* (`treatment` or QA URL param). The host must set up
|
|
2053
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
2054
|
+
* - `REGWALL`: inert — always returns null.
|
|
2051
2055
|
*
|
|
2052
|
-
* **
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
+
* **PAYWALL only — transition period:** the legacy
|
|
2057
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
2058
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
2059
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
2060
|
+
* `isApplePayAvailable()` on mount.
|
|
2056
2061
|
*
|
|
2057
2062
|
* **Eligibility:**
|
|
2058
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
2063
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
2064
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
2065
|
+
* later by `isApplePayAvailable()` on mount)
|
|
2059
2066
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2060
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2061
2067
|
*
|
|
2062
2068
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2063
2069
|
* @param country - The user's country code.
|
|
@@ -2080,28 +2086,31 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2080
2086
|
}
|
|
2081
2087
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2082
2088
|
const isEligible = eligibilityCheck();
|
|
2083
|
-
if (
|
|
2089
|
+
if (config.enabled === false) {
|
|
2084
2090
|
return null;
|
|
2085
2091
|
}
|
|
2086
|
-
|
|
2087
|
-
experimentFlagKey
|
|
2088
|
-
);
|
|
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
|
-
});
|
|
2100
|
-
}
|
|
2101
|
-
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2102
|
-
if (!isTreatment && !hasUrlParamFlag) {
|
|
2092
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2103
2093
|
return null;
|
|
2104
2094
|
}
|
|
2095
|
+
if (experimentFlagKey) {
|
|
2096
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(experimentFlagKey);
|
|
2097
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2098
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2099
|
+
void isApplePayAvailable().then((available) => {
|
|
2100
|
+
if (available) {
|
|
2101
|
+
trackApplePayExperimentExposure(
|
|
2102
|
+
experimentValue,
|
|
2103
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2104
|
+
experimentFlagKey
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2110
|
+
if (!isTreatment && !hasUrlParamFlag) {
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2105
2114
|
_ApplePayButton.define();
|
|
2106
2115
|
const button = document.createElement(_ApplePayButton.tag);
|
|
2107
2116
|
button.offer = offer;
|
|
@@ -2322,7 +2331,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2322
2331
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2323
2332
|
return;
|
|
2324
2333
|
}
|
|
2325
|
-
trackExpressWalletClick(
|
|
2334
|
+
trackExpressWalletClick(
|
|
2335
|
+
this.#offer.sku_id,
|
|
2336
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2337
|
+
);
|
|
2326
2338
|
ApplePayModal.define();
|
|
2327
2339
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2328
2340
|
modal.offer = this.#offer;
|
|
@@ -1299,7 +1299,6 @@ var redirectToCheckoutFallback = (params) => {
|
|
|
1299
1299
|
};
|
|
1300
1300
|
|
|
1301
1301
|
// src/constants.ts
|
|
1302
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1303
1302
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1304
1303
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1305
1304
|
CONTROL: "control",
|
|
@@ -1343,7 +1342,7 @@ var track = (action, extra) => {
|
|
|
1343
1342
|
...extra
|
|
1344
1343
|
});
|
|
1345
1344
|
};
|
|
1346
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1345
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1347
1346
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1348
1347
|
if (!isActiveVariant) {
|
|
1349
1348
|
return;
|
|
@@ -1372,8 +1371,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1372
1371
|
device: getDevice()
|
|
1373
1372
|
});
|
|
1374
1373
|
};
|
|
1375
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1376
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1374
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
1375
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1376
|
+
sku_id: skuId,
|
|
1377
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
1378
|
+
});
|
|
1377
1379
|
};
|
|
1378
1380
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1379
1381
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -1994,15 +1996,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
1994
1996
|
};
|
|
1995
1997
|
|
|
1996
1998
|
// src/utils/applePayExpressEligibility.ts
|
|
1997
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
1998
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
1999
1999
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2000
2000
|
|
|
2001
2001
|
// src/apple-pay-button.ts
|
|
2002
2002
|
var ENTRY_POINT_CONFIG = {
|
|
2003
2003
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2004
|
-
isEligible:
|
|
2005
|
-
experimentFlagKey
|
|
2004
|
+
isEligible: () => true
|
|
2005
|
+
// no experimentFlagKey → always-on after offer exclusions
|
|
2006
|
+
},
|
|
2007
|
+
["free_trial_banner" /* FREE_TRIAL_BANNER */]: {
|
|
2008
|
+
isEligible: () => true
|
|
2009
|
+
// Dual parity — no experimentFlagKey, no homepage gate here
|
|
2006
2010
|
},
|
|
2007
2011
|
["article_paywall" /* PAYWALL */]: {
|
|
2008
2012
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2010,7 +2014,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2010
2014
|
},
|
|
2011
2015
|
["article_regwall" /* REGWALL */]: {
|
|
2012
2016
|
isEligible: () => true,
|
|
2013
|
-
|
|
2017
|
+
enabled: false
|
|
2014
2018
|
}
|
|
2015
2019
|
};
|
|
2016
2020
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2029,27 +2033,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2029
2033
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2030
2034
|
}
|
|
2031
2035
|
/**
|
|
2032
|
-
* Creates and configures an ApplePayButton when the
|
|
2033
|
-
*
|
|
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`
|
|
2036
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2037
2037
|
*
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2038
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
2039
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
2040
|
+
* `$exposure`.
|
|
2041
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
2042
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
2043
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
2044
|
+
* (`treatment` or QA URL param). The host must set up
|
|
2045
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
2046
|
+
* - `REGWALL`: inert — always returns null.
|
|
2040
2047
|
*
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2047
|
-
* fallback will be removed.
|
|
2048
|
+
* **PAYWALL only — transition period:** the legacy
|
|
2049
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
2050
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
2051
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
2052
|
+
* `isApplePayAvailable()` on mount.
|
|
2048
2053
|
*
|
|
2049
2054
|
* **Eligibility:**
|
|
2050
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
2055
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
2056
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
2057
|
+
* later by `isApplePayAvailable()` on mount)
|
|
2051
2058
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2052
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2053
2059
|
*
|
|
2054
2060
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2055
2061
|
* @param country - The user's country code.
|
|
@@ -2072,28 +2078,31 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2072
2078
|
}
|
|
2073
2079
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2074
2080
|
const isEligible = eligibilityCheck();
|
|
2075
|
-
if (
|
|
2081
|
+
if (config.enabled === false) {
|
|
2076
2082
|
return null;
|
|
2077
2083
|
}
|
|
2078
|
-
|
|
2079
|
-
experimentFlagKey
|
|
2080
|
-
);
|
|
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
|
-
});
|
|
2092
|
-
}
|
|
2093
|
-
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2094
|
-
if (!isTreatment && !hasUrlParamFlag) {
|
|
2084
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2095
2085
|
return null;
|
|
2096
2086
|
}
|
|
2087
|
+
if (experimentFlagKey) {
|
|
2088
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(experimentFlagKey);
|
|
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
|
+
});
|
|
2100
|
+
}
|
|
2101
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2102
|
+
if (!isTreatment && !hasUrlParamFlag) {
|
|
2103
|
+
return null;
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2097
2106
|
_ApplePayButton.define();
|
|
2098
2107
|
const button = document.createElement(_ApplePayButton.tag);
|
|
2099
2108
|
button.offer = offer;
|
|
@@ -2314,7 +2323,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2314
2323
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2315
2324
|
return;
|
|
2316
2325
|
}
|
|
2317
|
-
trackExpressWalletClick(
|
|
2326
|
+
trackExpressWalletClick(
|
|
2327
|
+
this.#offer.sku_id,
|
|
2328
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2329
|
+
);
|
|
2318
2330
|
ApplePayModal.define();
|
|
2319
2331
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2320
2332
|
modal.offer = this.#offer;
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
1
|
export declare enum ApplePayEntryPoint {
|
|
2
2
|
PAYWALL = "article_paywall",
|
|
3
3
|
REGWALL = "article_regwall",
|
|
4
|
-
DUAL_OFFER_BANNER = "dual_offer_banner"
|
|
4
|
+
DUAL_OFFER_BANNER = "dual_offer_banner",
|
|
5
|
+
FREE_TRIAL_BANNER = "free_trial_banner"
|
|
5
6
|
}
|
|
6
|
-
/**
|
|
7
|
-
* Amplitude experiment key for Apple Pay Express Checkout on homepage banners
|
|
8
|
-
* (dual-offer banner) and article banner regwalls.
|
|
9
|
-
*
|
|
10
|
-
* This package reads the variant for this key internally via
|
|
11
|
-
* `window.experimentIntegration.getVariant()` — set up by the host page
|
|
12
|
-
* before `createIfEnabled` is called.
|
|
13
|
-
*
|
|
14
|
-
* Fail-closed: missing integration, missing key, `control`, or Amplitude fetch
|
|
15
|
-
* failure on the host → button is hidden (unless QA URL param is present).
|
|
16
|
-
*
|
|
17
|
-
* Must match the Feature experiment key in Amplitude and host app constants
|
|
18
|
-
* (Engagement / Insider / Podcasts).
|
|
19
|
-
*/
|
|
20
|
-
export declare const APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
21
7
|
/**
|
|
22
8
|
* Amplitude experiment key for Apple Pay Express Checkout on article paywalls
|
|
23
9
|
* (`ApplePayEntryPoint.PAYWALL`, e.g. single-offer-paywall / multi-offer paywall).
|
|
24
10
|
*
|
|
25
|
-
*
|
|
11
|
+
* Fail-closed when the variant is missing or not `treatment`; the QA URL param
|
|
12
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` can show the button without treatment.
|
|
26
13
|
* Eligibility for this flag ignores homepage and requires Safari/Apple device
|
|
27
14
|
* (plus `isApplePayAvailable` before `$exposure`).
|
|
15
|
+
*
|
|
16
|
+
* Must match the Feature experiment key in Amplitude and host app constants
|
|
17
|
+
* (Engagement / Insider / Podcasts) while those still bridge the experiment.
|
|
28
18
|
*/
|
|
29
19
|
export declare const APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
30
20
|
/**
|
|
31
21
|
* Known Amplitude experiment flag keys for Apple Pay Express Checkout.
|
|
32
22
|
* Narrowed so callers cannot pass an arbitrary typo'd string.
|
|
33
23
|
*/
|
|
34
|
-
export type ApplePayExperimentFlagKey = typeof
|
|
24
|
+
export type ApplePayExperimentFlagKey = typeof APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY;
|
|
35
25
|
/**
|
|
36
26
|
* Amplitude variant values for the Apple Pay Express Checkout experiment.
|
|
37
27
|
* CONTROL → button hidden (baseline)
|
package/dist/src/constants.js
CHANGED
|
@@ -3,16 +3,15 @@ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
|
|
|
3
3
|
ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
|
|
4
4
|
ApplePayEntryPoint2["REGWALL"] = "article_regwall";
|
|
5
5
|
ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
|
|
6
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
6
7
|
return ApplePayEntryPoint2;
|
|
7
8
|
})(ApplePayEntryPoint || {});
|
|
8
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
9
9
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
10
10
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
11
11
|
CONTROL: "control",
|
|
12
12
|
TREATMENT: "treatment"
|
|
13
13
|
};
|
|
14
14
|
export {
|
|
15
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
16
15
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
17
16
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
18
17
|
ApplePayEntryPoint
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ 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,
|
|
5
|
+
export { ApplePayEntryPoint, APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY, APPLE_PAY_EXPRESS_VARIANTS, } from './constants';
|
|
6
6
|
export type { ApplePayExperimentFlagKey } from './constants';
|
|
7
7
|
export type { ApplePayRuntimeConfig } from './clients/payment-checkout/config';
|
|
8
8
|
export type { Offer } from './types/offer.types';
|
package/dist/src/index.js
CHANGED
|
@@ -1308,9 +1308,9 @@ var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
|
|
|
1308
1308
|
ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
|
|
1309
1309
|
ApplePayEntryPoint2["REGWALL"] = "article_regwall";
|
|
1310
1310
|
ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
|
|
1311
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
1311
1312
|
return ApplePayEntryPoint2;
|
|
1312
1313
|
})(ApplePayEntryPoint || {});
|
|
1313
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1314
1314
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1315
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1316
1316
|
CONTROL: "control",
|
|
@@ -1354,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1354
1354
|
...extra
|
|
1355
1355
|
});
|
|
1356
1356
|
};
|
|
1357
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1358
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1359
1359
|
if (!isActiveVariant) {
|
|
1360
1360
|
return;
|
|
@@ -1383,8 +1383,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1383
1383
|
device: getDevice()
|
|
1384
1384
|
});
|
|
1385
1385
|
};
|
|
1386
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1387
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1386
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
1387
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
1388
|
+
sku_id: skuId,
|
|
1389
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
1390
|
+
});
|
|
1388
1391
|
};
|
|
1389
1392
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1390
1393
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -2005,15 +2008,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2005
2008
|
};
|
|
2006
2009
|
|
|
2007
2010
|
// src/utils/applePayExpressEligibility.ts
|
|
2008
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2009
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2010
2011
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2011
2012
|
|
|
2012
2013
|
// src/apple-pay-button.ts
|
|
2013
2014
|
var ENTRY_POINT_CONFIG = {
|
|
2014
2015
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2015
|
-
isEligible:
|
|
2016
|
-
experimentFlagKey
|
|
2016
|
+
isEligible: () => true
|
|
2017
|
+
// no experimentFlagKey → always-on after offer exclusions
|
|
2018
|
+
},
|
|
2019
|
+
["free_trial_banner" /* FREE_TRIAL_BANNER */]: {
|
|
2020
|
+
isEligible: () => true
|
|
2021
|
+
// Dual parity — no experimentFlagKey, no homepage gate here
|
|
2017
2022
|
},
|
|
2018
2023
|
["article_paywall" /* PAYWALL */]: {
|
|
2019
2024
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2021,7 +2026,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2021
2026
|
},
|
|
2022
2027
|
["article_regwall" /* REGWALL */]: {
|
|
2023
2028
|
isEligible: () => true,
|
|
2024
|
-
|
|
2029
|
+
enabled: false
|
|
2025
2030
|
}
|
|
2026
2031
|
};
|
|
2027
2032
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2040,27 +2045,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2040
2045
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2041
2046
|
}
|
|
2042
2047
|
/**
|
|
2043
|
-
* Creates and configures an ApplePayButton when the
|
|
2044
|
-
*
|
|
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
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2048
2049
|
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2050
|
+
* - `DUAL_OFFER_BANNER` (or omitted): always-on after offer exclusions —
|
|
2051
|
+
* no homepage/Safari gate here, no banners experiment read, and no banners
|
|
2052
|
+
* `$exposure`.
|
|
2053
|
+
* - `FREE_TRIAL_BANNER`: same always-on-after-exclusions gate as Dual; distinct
|
|
2054
|
+
* TEDL `entry_point` string (`free_trial_banner`) for wallet impression attribution.
|
|
2055
|
+
* - `PAYWALL`: experiment-gated via {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}
|
|
2056
|
+
* (`treatment` or QA URL param). The host must set up
|
|
2057
|
+
* `window.experimentIntegration` before calling for this entry point.
|
|
2058
|
+
* - `REGWALL`: inert — always returns null.
|
|
2051
2059
|
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2058
|
-
* fallback will be removed.
|
|
2060
|
+
* **PAYWALL only — transition period:** the legacy
|
|
2061
|
+
* `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param can show the button without
|
|
2062
|
+
* treatment (and without inflating `$exposure`). For banners there is no
|
|
2063
|
+
* experiment gate; `BYPASS_APPLE_PAY_CHECKS` only skips device checks in
|
|
2064
|
+
* `isApplePayAvailable()` on mount.
|
|
2059
2065
|
*
|
|
2060
2066
|
* **Eligibility:**
|
|
2061
|
-
* - `DUAL_OFFER_BANNER` (or omitted):
|
|
2067
|
+
* - `DUAL_OFFER_BANNER` / `FREE_TRIAL_BANNER` (or omitted): always eligible at
|
|
2068
|
+
* this gate (homepage placement is host-owned; Safari/Apple is enforced
|
|
2069
|
+
* later by `isApplePayAvailable()` on mount)
|
|
2062
2070
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2063
|
-
* - `REGWALL`: no host-side placement gate (pre-SMA-3301 article behaviour)
|
|
2064
2071
|
*
|
|
2065
2072
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2066
2073
|
* @param country - The user's country code.
|
|
@@ -2083,28 +2090,31 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2083
2090
|
}
|
|
2084
2091
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2085
2092
|
const isEligible = eligibilityCheck();
|
|
2086
|
-
if (
|
|
2093
|
+
if (config.enabled === false) {
|
|
2087
2094
|
return null;
|
|
2088
2095
|
}
|
|
2089
|
-
|
|
2090
|
-
experimentFlagKey
|
|
2091
|
-
);
|
|
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
|
-
});
|
|
2103
|
-
}
|
|
2104
|
-
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2105
|
-
if (!isTreatment && !hasUrlParamFlag) {
|
|
2096
|
+
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2106
2097
|
return null;
|
|
2107
2098
|
}
|
|
2099
|
+
if (experimentFlagKey) {
|
|
2100
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(experimentFlagKey);
|
|
2101
|
+
const isExperimentVariant = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2102
|
+
if (isExperimentVariant && isEligible && !bypassApplePayChecks() && !hasUrlParamFlag) {
|
|
2103
|
+
void isApplePayAvailable().then((available) => {
|
|
2104
|
+
if (available) {
|
|
2105
|
+
trackApplePayExperimentExposure(
|
|
2106
|
+
experimentValue,
|
|
2107
|
+
getExperimentKeyFromNextData(experimentFlagKey),
|
|
2108
|
+
experimentFlagKey
|
|
2109
|
+
);
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2114
|
+
if (!isTreatment && !hasUrlParamFlag) {
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2108
2118
|
_ApplePayButton.define();
|
|
2109
2119
|
const button = document.createElement(_ApplePayButton.tag);
|
|
2110
2120
|
button.offer = offer;
|
|
@@ -2325,7 +2335,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2325
2335
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2326
2336
|
return;
|
|
2327
2337
|
}
|
|
2328
|
-
trackExpressWalletClick(
|
|
2338
|
+
trackExpressWalletClick(
|
|
2339
|
+
this.#offer.sku_id,
|
|
2340
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2341
|
+
);
|
|
2329
2342
|
ApplePayModal.define();
|
|
2330
2343
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2331
2344
|
modal.offer = this.#offer;
|
|
@@ -2417,7 +2430,6 @@ function defineApplePayElements() {
|
|
|
2417
2430
|
}
|
|
2418
2431
|
export {
|
|
2419
2432
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2420
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2421
2433
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2422
2434
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2423
2435
|
ApplePayButton,
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Host-side eligibility for Apple Pay Express
|
|
2
|
+
* Host-side placement eligibility helpers for Apple Pay Express.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* (
|
|
7
|
-
*
|
|
4
|
+
* Paywalls: used by createIfEnabled after offer exclusions so experiment
|
|
5
|
+
* $exposure is Safari/Apple-gated. Banners: createIfEnabled does not call
|
|
6
|
+
* the banner helper (always-on after offer exclusions); Safari/Apple still
|
|
7
|
+
* runs later via isApplePayAvailable() on mount. Exposure (paywalls) is
|
|
8
|
+
* further gated on isApplePayAvailable() (BYPASS_APPLE_PAY_CHECKS respected).
|
|
8
9
|
*/
|
|
9
10
|
export declare const isApplePayExpressHomepage: (pathname?: string) => boolean;
|
|
10
11
|
/**
|
|
11
|
-
* Dual-offer homepage
|
|
12
|
-
* Anonymous is assumed because
|
|
13
|
-
* anonymous visitors.
|
|
12
|
+
* Dual-offer / Free Trial homepage banners: homepage + Safari/iPhone.
|
|
13
|
+
* Anonymous is assumed because these banners are only mounted for
|
|
14
|
+
* anonymous visitors. Not wired into createIfEnabled ENTRY_POINT_CONFIG.
|
|
14
15
|
*/
|
|
15
|
-
export declare const
|
|
16
|
+
export declare const isEligibleForApplePayExpressBanner: () => boolean;
|
|
16
17
|
/**
|
|
17
18
|
* Article paywalls (`ApplePayEntryPoint.PAYWALL`): Safari/Apple device only.
|
|
18
19
|
* Homepage targeting does not apply — paywalls render on article pages.
|
|
@@ -7,10 +7,10 @@ var isAppleDeviceOrSafari = () => {
|
|
|
7
7
|
|
|
8
8
|
// src/utils/applePayExpressEligibility.ts
|
|
9
9
|
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
10
|
-
var
|
|
10
|
+
var isEligibleForApplePayExpressBanner = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
11
11
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
12
12
|
export {
|
|
13
13
|
isApplePayExpressHomepage,
|
|
14
|
-
|
|
14
|
+
isEligibleForApplePayExpressBanner,
|
|
15
15
|
isEligibleForApplePayExpressPaywallExperiment
|
|
16
16
|
};
|
|
@@ -57,14 +57,23 @@ export type ImpressionMetadata = {
|
|
|
57
57
|
* experiment_key from Engagement SSR (__NEXT_DATA__) when present for run
|
|
58
58
|
* attribution.
|
|
59
59
|
*
|
|
60
|
-
* @param flagKey - Amplitude flag_key.
|
|
61
|
-
*
|
|
60
|
+
* @param flagKey - Amplitude flag_key (required). Callers must pass an
|
|
61
|
+
* explicit key such as {@link APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY}.
|
|
62
62
|
*/
|
|
63
|
-
export declare const trackApplePayExperimentExposure: (variant: string, experimentKey
|
|
63
|
+
export declare const trackApplePayExperimentExposure: (variant: string, experimentKey: string | undefined, flagKey: ApplePayExperimentFlagKey) => void;
|
|
64
64
|
/** Wallet button displayed — emits all 5 required analytics dimensions. */
|
|
65
65
|
export declare const trackExpressWalletImpression: (skuId: string, { entryPoint, country }: ImpressionMetadata) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Optional metadata for the wallet click event.
|
|
68
|
+
* `entry_point` is included only when provided so existing one-arg callers stay
|
|
69
|
+
* payload-compatible.
|
|
70
|
+
*/
|
|
71
|
+
export type ClickMetadata = {
|
|
72
|
+
/** Entry point where the Apple Pay button was clicked — e.g. 'free_trial_banner'. */
|
|
73
|
+
entryPoint?: string;
|
|
74
|
+
};
|
|
66
75
|
/** Wallet button clicked */
|
|
67
|
-
export declare const trackExpressWalletClick: (skuId: string) => void;
|
|
76
|
+
export declare const trackExpressWalletClick: (skuId: string, { entryPoint }?: ClickMetadata) => void;
|
|
68
77
|
/** Apple Pay sheet opened (session.begin() called) */
|
|
69
78
|
export declare const trackWalletPaymentSheetOpen: (skuId: string) => void;
|
|
70
79
|
/** Payment authorised by the user in the Apple Pay sheet */
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
3
2
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
4
3
|
CONTROL: "control",
|
|
5
4
|
TREATMENT: "treatment"
|
|
@@ -42,7 +41,7 @@ var track = (action, extra) => {
|
|
|
42
41
|
...extra
|
|
43
42
|
});
|
|
44
43
|
};
|
|
45
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
44
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
46
45
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
47
46
|
if (!isActiveVariant) {
|
|
48
47
|
return;
|
|
@@ -71,8 +70,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
71
70
|
device: getDevice()
|
|
72
71
|
});
|
|
73
72
|
};
|
|
74
|
-
var trackExpressWalletClick = (skuId) => {
|
|
75
|
-
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
73
|
+
var trackExpressWalletClick = (skuId, { entryPoint } = {}) => {
|
|
74
|
+
track(EXPRESS_CHECKOUT_EVENTS.BUTTON_CLICK, {
|
|
75
|
+
sku_id: skuId,
|
|
76
|
+
...entryPoint ? { entry_point: entryPoint } : {}
|
|
77
|
+
});
|
|
76
78
|
};
|
|
77
79
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
78
80
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|