@economist/web-apple-pay 1.10.2-beta.1 → 1.11.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/README.md +19 -59
- package/dist/index.js +40 -35
- package/dist/src/apple-pay-button.d.ts +18 -17
- package/dist/src/apple-pay-button.js +39 -33
- package/dist/src/apple-pay-button.stories.js +39 -33
- package/dist/src/apple-pay-modal.stories.js +39 -33
- package/dist/src/constants.d.ts +7 -19
- package/dist/src/constants.js +1 -3
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +40 -35
- 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',
|
|
@@ -54,56 +57,6 @@ container.appendChild(button);
|
|
|
54
57
|
|
|
55
58
|
When clicked, the button creates and opens `teg-apple-pay-modal` automatically.
|
|
56
59
|
|
|
57
|
-
### 3) Gated creation — `createIfEnabled`
|
|
58
|
-
|
|
59
|
-
Hosts that mount Apple Pay on a wall, banner, or popup should use
|
|
60
|
-
`ApplePayButton.createIfEnabled(offer, country, entryPoint)` instead of
|
|
61
|
-
`document.createElement`. It applies Amplitude experiment and placement rules
|
|
62
|
-
per entry point, then returns a configured button or `null`.
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
import {
|
|
66
|
-
ApplePayButton,
|
|
67
|
-
ApplePayEntryPoint,
|
|
68
|
-
} from '@economist/web-apple-pay';
|
|
69
|
-
|
|
70
|
-
const button = ApplePayButton.createIfEnabled(
|
|
71
|
-
offer,
|
|
72
|
-
'US',
|
|
73
|
-
ApplePayEntryPoint.FREE_TRIAL_POPUP,
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
if (button) {
|
|
77
|
-
container.appendChild(button);
|
|
78
|
-
await button.whenReady();
|
|
79
|
-
if (button.style.display === 'none') {
|
|
80
|
-
button.remove();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
#### Entry points
|
|
86
|
-
|
|
87
|
-
| `ApplePayEntryPoint` | Value | Amplitude flag | Placement eligibility |
|
|
88
|
-
| --- | --- | --- | --- |
|
|
89
|
-
| `PAYWALL` | `article_paywall` | `apple-pay-express-checkout-on-paywalls` | Safari / Apple device |
|
|
90
|
-
| `REGWALL` | `article_regwall` | `apple-pay-express-checkout-on-banners` | none |
|
|
91
|
-
| `DUAL_OFFER_BANNER` (default if omitted) | `dual_offer_banner` | `apple-pay-express-checkout-on-banners` | homepage + Safari / iPhone |
|
|
92
|
-
| `FREE_TRIAL_POPUP` | `free_trial_popup` | **none** — always shown | none |
|
|
93
|
-
|
|
94
|
-
`FREE_TRIAL_POPUP` does not read `window.experimentIntegration` and does not
|
|
95
|
-
emit `$exposure`. The button is created whenever the offer is valid (excluded
|
|
96
|
-
variants still suppress it). The component still hides itself after mount if
|
|
97
|
-
Apple Pay is unavailable on the device.
|
|
98
|
-
|
|
99
|
-
For every other entry point:
|
|
100
|
-
|
|
101
|
-
- Host must set `window.experimentIntegration.getVariant` before calling
|
|
102
|
-
`createIfEnabled`.
|
|
103
|
-
- `treatment` → button created; `control` / missing / anything else → `null`.
|
|
104
|
-
- QA override: `?FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` shows the button without
|
|
105
|
-
emitting `$exposure`.
|
|
106
|
-
|
|
107
60
|
## Runtime configuration
|
|
108
61
|
|
|
109
62
|
### `configureApplePay(config)`
|
|
@@ -135,8 +88,8 @@ to the DOM. This is the supported, stable way to know whether Apple Pay is
|
|
|
135
88
|
available without touching lifecycle internals.
|
|
136
89
|
|
|
137
90
|
```ts
|
|
138
|
-
container.appendChild(btn);
|
|
139
|
-
await btn.whenReady();
|
|
91
|
+
container.appendChild(btn); // spec-compliant — browser fires connectedCallback naturally
|
|
92
|
+
await btn.whenReady(); // resolves when rendering is complete
|
|
140
93
|
if (btn.style.display !== 'none') {
|
|
141
94
|
// Apple Pay rendered successfully
|
|
142
95
|
} else {
|
|
@@ -170,13 +123,21 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
170
123
|
- `defineApplePayElements()`: registers both custom elements.
|
|
171
124
|
- `configureApplePay(config)`: sets required runtime config (merchant ID and wallet API base URL, with optional debug bypass).
|
|
172
125
|
- `ApplePayButton`: button component class.
|
|
173
|
-
- `createIfEnabled(offer, country, entryPoint?)`: returns a configured button or `null` after applying Amplitude / placement rules for the entry point. `FREE_TRIAL_POPUP` is not experiment-gated.
|
|
174
126
|
- `whenReady(): Promise<void>` — resolves when the current render lifecycle completes (available or hidden). Resolves immediately if called before the element is connected.
|
|
175
|
-
- `
|
|
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`.
|
|
176
132
|
- `ApplePayModal`: modal component class.
|
|
177
133
|
- `ensureApplePayLogoSymbol()`: logo symbol injection helper.
|
|
134
|
+
- `APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY`: Amplitude flag key for paywalls experiment gating / `$exposure`.
|
|
178
135
|
- `Offer`: offer contract type used by component props.
|
|
179
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
|
+
|
|
180
141
|
## Troubleshooting
|
|
181
142
|
|
|
182
143
|
### Button does not appear
|
|
@@ -184,9 +145,9 @@ Consumers should listen for this event and continue payment orchestration.
|
|
|
184
145
|
Check:
|
|
185
146
|
|
|
186
147
|
- `configureApplePay(...)` was called before rendering (with a valid `merchantId` and `walletApiBaseUrl`)
|
|
187
|
-
- device/browser supports Apple Pay (Safari on Apple device required)
|
|
188
|
-
- for
|
|
189
|
-
-
|
|
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`)
|
|
190
151
|
- offer variant is not excluded (`bundle`, `insider_print`)
|
|
191
152
|
|
|
192
153
|
### Logged-in checkbox copy looks wrong
|
|
@@ -237,4 +198,3 @@ Story coverage matrix:
|
|
|
237
198
|
- `ApplePayButton` behavior and state variants are available as individual canvas stories in Storybook.
|
|
238
199
|
- `ApplePayModal` docs page shows the stable default example.
|
|
239
200
|
- `ApplePayModal` behavior and state variants are available as individual canvas stories in Storybook.
|
|
240
|
-
|
package/dist/index.js
CHANGED
|
@@ -1308,10 +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["
|
|
1311
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
1312
1312
|
return ApplePayEntryPoint2;
|
|
1313
1313
|
})(ApplePayEntryPoint || {});
|
|
1314
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1315
1314
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1316
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1317
1316
|
CONTROL: "control",
|
|
@@ -1355,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1355
1354
|
...extra
|
|
1356
1355
|
});
|
|
1357
1356
|
};
|
|
1358
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1359
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1360
1359
|
if (!isActiveVariant) {
|
|
1361
1360
|
return;
|
|
@@ -1384,8 +1383,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1384
1383
|
device: getDevice()
|
|
1385
1384
|
});
|
|
1386
1385
|
};
|
|
1387
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1388
|
-
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
|
+
});
|
|
1389
1391
|
};
|
|
1390
1392
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1391
1393
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -2006,15 +2008,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2006
2008
|
};
|
|
2007
2009
|
|
|
2008
2010
|
// src/utils/applePayExpressEligibility.ts
|
|
2009
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2010
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2011
2011
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2012
2012
|
|
|
2013
2013
|
// src/apple-pay-button.ts
|
|
2014
2014
|
var ENTRY_POINT_CONFIG = {
|
|
2015
2015
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2016
|
-
isEligible:
|
|
2017
|
-
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
|
|
2018
2022
|
},
|
|
2019
2023
|
["article_paywall" /* PAYWALL */]: {
|
|
2020
2024
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2022,10 +2026,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2022
2026
|
},
|
|
2023
2027
|
["article_regwall" /* REGWALL */]: {
|
|
2024
2028
|
isEligible: () => true,
|
|
2025
|
-
|
|
2026
|
-
},
|
|
2027
|
-
["free_trial_popup" /* FREE_TRIAL_POPUP */]: {
|
|
2028
|
-
isEligible: () => true
|
|
2029
|
+
enabled: false
|
|
2029
2030
|
}
|
|
2030
2031
|
};
|
|
2031
2032
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2044,28 +2045,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2044
2045
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2045
2046
|
}
|
|
2046
2047
|
/**
|
|
2047
|
-
* Creates and configures an ApplePayButton when the
|
|
2048
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2048
2049
|
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2052
|
-
* -
|
|
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.
|
|
2053
2059
|
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
*
|
|
2058
|
-
*
|
|
2059
|
-
*
|
|
2060
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
2061
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
2062
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2063
|
-
* 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.
|
|
2064
2065
|
*
|
|
2065
2066
|
* **Eligibility:**
|
|
2066
|
-
* - `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)
|
|
2067
2070
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2068
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
2069
2071
|
*
|
|
2070
2072
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2071
2073
|
* @param country - The user's country code.
|
|
@@ -2088,6 +2090,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2088
2090
|
}
|
|
2089
2091
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2090
2092
|
const isEligible = eligibilityCheck();
|
|
2093
|
+
if (config.enabled === false) {
|
|
2094
|
+
return null;
|
|
2095
|
+
}
|
|
2091
2096
|
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2092
2097
|
return null;
|
|
2093
2098
|
}
|
|
@@ -2232,9 +2237,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2232
2237
|
button.removeAttribute("aria-busy");
|
|
2233
2238
|
button.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2234
2239
|
}
|
|
2235
|
-
this.getAnimations?.({ subtree: true }).forEach(
|
|
2236
|
-
(animation) => animation.cancel()
|
|
2237
|
-
);
|
|
2240
|
+
this.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2238
2241
|
void this.offsetHeight;
|
|
2239
2242
|
this.style.display = "none";
|
|
2240
2243
|
this.querySelector(SEL_CONTAINER)?.remove();
|
|
@@ -2343,7 +2346,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2343
2346
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2344
2347
|
return;
|
|
2345
2348
|
}
|
|
2346
|
-
trackExpressWalletClick(
|
|
2349
|
+
trackExpressWalletClick(
|
|
2350
|
+
this.#offer.sku_id,
|
|
2351
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2352
|
+
);
|
|
2347
2353
|
ApplePayModal.define();
|
|
2348
2354
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2349
2355
|
modal.offer = this.#offer;
|
|
@@ -2435,7 +2441,6 @@ function defineApplePayElements() {
|
|
|
2435
2441
|
}
|
|
2436
2442
|
export {
|
|
2437
2443
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2438
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2439
2444
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2440
2445
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2441
2446
|
ApplePayButton,
|
|
@@ -6,28 +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
|
-
*
|
|
14
|
-
* -
|
|
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.
|
|
15
20
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
23
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
24
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
25
|
-
* 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.
|
|
26
26
|
*
|
|
27
27
|
* **Eligibility:**
|
|
28
|
-
* - `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)
|
|
29
31
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
30
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
31
32
|
*
|
|
32
33
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
33
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,10 +2014,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2010
2014
|
},
|
|
2011
2015
|
["article_regwall" /* REGWALL */]: {
|
|
2012
2016
|
isEligible: () => true,
|
|
2013
|
-
|
|
2014
|
-
},
|
|
2015
|
-
["free_trial_popup" /* FREE_TRIAL_POPUP */]: {
|
|
2016
|
-
isEligible: () => true
|
|
2017
|
+
enabled: false
|
|
2017
2018
|
}
|
|
2018
2019
|
};
|
|
2019
2020
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2032,28 +2033,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2032
2033
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2033
2034
|
}
|
|
2034
2035
|
/**
|
|
2035
|
-
* Creates and configures an ApplePayButton when the
|
|
2036
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2036
2037
|
*
|
|
2037
|
-
*
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
* -
|
|
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.
|
|
2041
2047
|
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
*
|
|
2047
|
-
*
|
|
2048
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
2049
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
2050
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2051
|
-
* 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.
|
|
2052
2053
|
*
|
|
2053
2054
|
* **Eligibility:**
|
|
2054
|
-
* - `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)
|
|
2055
2058
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2056
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
2057
2059
|
*
|
|
2058
2060
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2059
2061
|
* @param country - The user's country code.
|
|
@@ -2076,6 +2078,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2076
2078
|
}
|
|
2077
2079
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2078
2080
|
const isEligible = eligibilityCheck();
|
|
2081
|
+
if (config.enabled === false) {
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2079
2084
|
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2080
2085
|
return null;
|
|
2081
2086
|
}
|
|
@@ -2220,9 +2225,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2220
2225
|
button.removeAttribute("aria-busy");
|
|
2221
2226
|
button.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2222
2227
|
}
|
|
2223
|
-
this.getAnimations?.({ subtree: true }).forEach(
|
|
2224
|
-
(animation) => animation.cancel()
|
|
2225
|
-
);
|
|
2228
|
+
this.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2226
2229
|
void this.offsetHeight;
|
|
2227
2230
|
this.style.display = "none";
|
|
2228
2231
|
this.querySelector(SEL_CONTAINER)?.remove();
|
|
@@ -2331,7 +2334,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2331
2334
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2332
2335
|
return;
|
|
2333
2336
|
}
|
|
2334
|
-
trackExpressWalletClick(
|
|
2337
|
+
trackExpressWalletClick(
|
|
2338
|
+
this.#offer.sku_id,
|
|
2339
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2340
|
+
);
|
|
2335
2341
|
ApplePayModal.define();
|
|
2336
2342
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2337
2343
|
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,10 +2022,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2018
2022
|
},
|
|
2019
2023
|
["article_regwall" /* REGWALL */]: {
|
|
2020
2024
|
isEligible: () => true,
|
|
2021
|
-
|
|
2022
|
-
},
|
|
2023
|
-
["free_trial_popup" /* FREE_TRIAL_POPUP */]: {
|
|
2024
|
-
isEligible: () => true
|
|
2025
|
+
enabled: false
|
|
2025
2026
|
}
|
|
2026
2027
|
};
|
|
2027
2028
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2040,28 +2041,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2040
2041
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2041
2042
|
}
|
|
2042
2043
|
/**
|
|
2043
|
-
* Creates and configures an ApplePayButton when the
|
|
2044
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2044
2045
|
*
|
|
2045
|
-
*
|
|
2046
|
-
*
|
|
2047
|
-
*
|
|
2048
|
-
* -
|
|
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.
|
|
2049
2055
|
*
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
2057
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
2058
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2059
|
-
* fallback will be removed.
|
|
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.
|
|
2060
2061
|
*
|
|
2061
2062
|
* **Eligibility:**
|
|
2062
|
-
* - `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)
|
|
2063
2066
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2064
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
2065
2067
|
*
|
|
2066
2068
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2067
2069
|
* @param country - The user's country code.
|
|
@@ -2084,6 +2086,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2084
2086
|
}
|
|
2085
2087
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2086
2088
|
const isEligible = eligibilityCheck();
|
|
2089
|
+
if (config.enabled === false) {
|
|
2090
|
+
return null;
|
|
2091
|
+
}
|
|
2087
2092
|
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2088
2093
|
return null;
|
|
2089
2094
|
}
|
|
@@ -2228,9 +2233,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2228
2233
|
button.removeAttribute("aria-busy");
|
|
2229
2234
|
button.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2230
2235
|
}
|
|
2231
|
-
this.getAnimations?.({ subtree: true }).forEach(
|
|
2232
|
-
(animation) => animation.cancel()
|
|
2233
|
-
);
|
|
2236
|
+
this.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2234
2237
|
void this.offsetHeight;
|
|
2235
2238
|
this.style.display = "none";
|
|
2236
2239
|
this.querySelector(SEL_CONTAINER)?.remove();
|
|
@@ -2339,7 +2342,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2339
2342
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2340
2343
|
return;
|
|
2341
2344
|
}
|
|
2342
|
-
trackExpressWalletClick(
|
|
2345
|
+
trackExpressWalletClick(
|
|
2346
|
+
this.#offer.sku_id,
|
|
2347
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2348
|
+
);
|
|
2343
2349
|
ApplePayModal.define();
|
|
2344
2350
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2345
2351
|
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,10 +2014,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2010
2014
|
},
|
|
2011
2015
|
["article_regwall" /* REGWALL */]: {
|
|
2012
2016
|
isEligible: () => true,
|
|
2013
|
-
|
|
2014
|
-
},
|
|
2015
|
-
["free_trial_popup" /* FREE_TRIAL_POPUP */]: {
|
|
2016
|
-
isEligible: () => true
|
|
2017
|
+
enabled: false
|
|
2017
2018
|
}
|
|
2018
2019
|
};
|
|
2019
2020
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2032,28 +2033,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2032
2033
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2033
2034
|
}
|
|
2034
2035
|
/**
|
|
2035
|
-
* Creates and configures an ApplePayButton when the
|
|
2036
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2036
2037
|
*
|
|
2037
|
-
*
|
|
2038
|
-
*
|
|
2039
|
-
*
|
|
2040
|
-
* -
|
|
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.
|
|
2041
2047
|
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
*
|
|
2047
|
-
*
|
|
2048
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
2049
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
2050
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2051
|
-
* 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.
|
|
2052
2053
|
*
|
|
2053
2054
|
* **Eligibility:**
|
|
2054
|
-
* - `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)
|
|
2055
2058
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2056
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
2057
2059
|
*
|
|
2058
2060
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2059
2061
|
* @param country - The user's country code.
|
|
@@ -2076,6 +2078,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2076
2078
|
}
|
|
2077
2079
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2078
2080
|
const isEligible = eligibilityCheck();
|
|
2081
|
+
if (config.enabled === false) {
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2079
2084
|
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2080
2085
|
return null;
|
|
2081
2086
|
}
|
|
@@ -2220,9 +2225,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2220
2225
|
button.removeAttribute("aria-busy");
|
|
2221
2226
|
button.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2222
2227
|
}
|
|
2223
|
-
this.getAnimations?.({ subtree: true }).forEach(
|
|
2224
|
-
(animation) => animation.cancel()
|
|
2225
|
-
);
|
|
2228
|
+
this.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2226
2229
|
void this.offsetHeight;
|
|
2227
2230
|
this.style.display = "none";
|
|
2228
2231
|
this.querySelector(SEL_CONTAINER)?.remove();
|
|
@@ -2331,7 +2334,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2331
2334
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2332
2335
|
return;
|
|
2333
2336
|
}
|
|
2334
|
-
trackExpressWalletClick(
|
|
2337
|
+
trackExpressWalletClick(
|
|
2338
|
+
this.#offer.sku_id,
|
|
2339
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2340
|
+
);
|
|
2335
2341
|
ApplePayModal.define();
|
|
2336
2342
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2337
2343
|
modal.offer = this.#offer;
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -2,38 +2,26 @@ export declare enum ApplePayEntryPoint {
|
|
|
2
2
|
PAYWALL = "article_paywall",
|
|
3
3
|
REGWALL = "article_regwall",
|
|
4
4
|
DUAL_OFFER_BANNER = "dual_offer_banner",
|
|
5
|
-
|
|
6
|
-
FREE_TRIAL_POPUP = "free_trial_popup"
|
|
5
|
+
FREE_TRIAL_BANNER = "free_trial_banner"
|
|
7
6
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Amplitude experiment key for Apple Pay Express Checkout on homepage banners
|
|
10
|
-
* (dual-offer banner) and article banner regwalls.
|
|
11
|
-
*
|
|
12
|
-
* This package reads the variant for this key internally via
|
|
13
|
-
* `window.experimentIntegration.getVariant()` — set up by the host page
|
|
14
|
-
* before `createIfEnabled` is called.
|
|
15
|
-
*
|
|
16
|
-
* Fail-closed: missing integration, missing key, `control`, or Amplitude fetch
|
|
17
|
-
* failure on the host → button is hidden (unless QA URL param is present).
|
|
18
|
-
*
|
|
19
|
-
* Must match the Feature experiment key in Amplitude and host app constants
|
|
20
|
-
* (Engagement / Insider / Podcasts).
|
|
21
|
-
*/
|
|
22
|
-
export declare const APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
23
7
|
/**
|
|
24
8
|
* Amplitude experiment key for Apple Pay Express Checkout on article paywalls
|
|
25
9
|
* (`ApplePayEntryPoint.PAYWALL`, e.g. single-offer-paywall / multi-offer paywall).
|
|
26
10
|
*
|
|
27
|
-
*
|
|
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.
|
|
28
13
|
* Eligibility for this flag ignores homepage and requires Safari/Apple device
|
|
29
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.
|
|
30
18
|
*/
|
|
31
19
|
export declare const APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
32
20
|
/**
|
|
33
21
|
* Known Amplitude experiment flag keys for Apple Pay Express Checkout.
|
|
34
22
|
* Narrowed so callers cannot pass an arbitrary typo'd string.
|
|
35
23
|
*/
|
|
36
|
-
export type ApplePayExperimentFlagKey = typeof
|
|
24
|
+
export type ApplePayExperimentFlagKey = typeof APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY;
|
|
37
25
|
/**
|
|
38
26
|
* Amplitude variant values for the Apple Pay Express Checkout experiment.
|
|
39
27
|
* CONTROL → button hidden (baseline)
|
package/dist/src/constants.js
CHANGED
|
@@ -3,17 +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["
|
|
6
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
7
7
|
return ApplePayEntryPoint2;
|
|
8
8
|
})(ApplePayEntryPoint || {});
|
|
9
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
10
9
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
11
10
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
12
11
|
CONTROL: "control",
|
|
13
12
|
TREATMENT: "treatment"
|
|
14
13
|
};
|
|
15
14
|
export {
|
|
16
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
17
15
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
18
16
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
19
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,10 +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["
|
|
1311
|
+
ApplePayEntryPoint2["FREE_TRIAL_BANNER"] = "free_trial_banner";
|
|
1312
1312
|
return ApplePayEntryPoint2;
|
|
1313
1313
|
})(ApplePayEntryPoint || {});
|
|
1314
|
-
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-banners";
|
|
1315
1314
|
var APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY = "apple-pay-express-checkout-on-paywalls";
|
|
1316
1315
|
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1317
1316
|
CONTROL: "control",
|
|
@@ -1355,7 +1354,7 @@ var track = (action, extra) => {
|
|
|
1355
1354
|
...extra
|
|
1356
1355
|
});
|
|
1357
1356
|
};
|
|
1358
|
-
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey
|
|
1357
|
+
var trackApplePayExperimentExposure = (variant, experimentKey, flagKey) => {
|
|
1359
1358
|
const isActiveVariant = variant === APPLE_PAY_EXPRESS_VARIANTS.CONTROL || variant === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1360
1359
|
if (!isActiveVariant) {
|
|
1361
1360
|
return;
|
|
@@ -1384,8 +1383,11 @@ var trackExpressWalletImpression = (skuId, { entryPoint, country }) => {
|
|
|
1384
1383
|
device: getDevice()
|
|
1385
1384
|
});
|
|
1386
1385
|
};
|
|
1387
|
-
var trackExpressWalletClick = (skuId) => {
|
|
1388
|
-
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
|
+
});
|
|
1389
1391
|
};
|
|
1390
1392
|
var trackWalletPaymentSheetOpen = (skuId) => {
|
|
1391
1393
|
track(EXPRESS_CHECKOUT_EVENTS.SHEET_OPEN, { sku_id: skuId });
|
|
@@ -2006,15 +2008,17 @@ var getExperimentKeyFromNextData = (flagKey) => {
|
|
|
2006
2008
|
};
|
|
2007
2009
|
|
|
2008
2010
|
// src/utils/applePayExpressEligibility.ts
|
|
2009
|
-
var isApplePayExpressHomepage = (pathname = window.location.pathname) => pathname === "/";
|
|
2010
|
-
var isEligibleForApplePayExpressExperiment = () => isApplePayExpressHomepage() && isAppleDeviceOrSafari();
|
|
2011
2011
|
var isEligibleForApplePayExpressPaywallExperiment = () => isAppleDeviceOrSafari();
|
|
2012
2012
|
|
|
2013
2013
|
// src/apple-pay-button.ts
|
|
2014
2014
|
var ENTRY_POINT_CONFIG = {
|
|
2015
2015
|
["dual_offer_banner" /* DUAL_OFFER_BANNER */]: {
|
|
2016
|
-
isEligible:
|
|
2017
|
-
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
|
|
2018
2022
|
},
|
|
2019
2023
|
["article_paywall" /* PAYWALL */]: {
|
|
2020
2024
|
isEligible: isEligibleForApplePayExpressPaywallExperiment,
|
|
@@ -2022,10 +2026,7 @@ var ENTRY_POINT_CONFIG = {
|
|
|
2022
2026
|
},
|
|
2023
2027
|
["article_regwall" /* REGWALL */]: {
|
|
2024
2028
|
isEligible: () => true,
|
|
2025
|
-
|
|
2026
|
-
},
|
|
2027
|
-
["free_trial_popup" /* FREE_TRIAL_POPUP */]: {
|
|
2028
|
-
isEligible: () => true
|
|
2029
|
+
enabled: false
|
|
2029
2030
|
}
|
|
2030
2031
|
};
|
|
2031
2032
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
@@ -2044,28 +2045,29 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2044
2045
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
2045
2046
|
}
|
|
2046
2047
|
/**
|
|
2047
|
-
* Creates and configures an ApplePayButton when the
|
|
2048
|
+
* Creates and configures an ApplePayButton when the entry point allows it.
|
|
2048
2049
|
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2052
|
-
* -
|
|
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.
|
|
2053
2059
|
*
|
|
2054
|
-
*
|
|
2055
|
-
*
|
|
2056
|
-
*
|
|
2057
|
-
*
|
|
2058
|
-
*
|
|
2059
|
-
*
|
|
2060
|
-
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
2061
|
-
* gate is also evaluated as a fallback until all host apps have integrated
|
|
2062
|
-
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
2063
|
-
* 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.
|
|
2064
2065
|
*
|
|
2065
2066
|
* **Eligibility:**
|
|
2066
|
-
* - `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)
|
|
2067
2070
|
* - `PAYWALL`: Safari/Apple device only (no homepage) — article paywalls
|
|
2068
|
-
* - `REGWALL` / `FREE_TRIAL_POPUP`: no host-side placement gate
|
|
2069
2071
|
*
|
|
2070
2072
|
* @param offer - The offer to display in the Apple Pay flow.
|
|
2071
2073
|
* @param country - The user's country code.
|
|
@@ -2088,6 +2090,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2088
2090
|
}
|
|
2089
2091
|
const { isEligible: eligibilityCheck, experimentFlagKey } = config;
|
|
2090
2092
|
const isEligible = eligibilityCheck();
|
|
2093
|
+
if (config.enabled === false) {
|
|
2094
|
+
return null;
|
|
2095
|
+
}
|
|
2091
2096
|
if (!hasUrlParamFlag && !bypassApplePayChecks() && !isEligible) {
|
|
2092
2097
|
return null;
|
|
2093
2098
|
}
|
|
@@ -2232,9 +2237,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2232
2237
|
button.removeAttribute("aria-busy");
|
|
2233
2238
|
button.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2234
2239
|
}
|
|
2235
|
-
this.getAnimations?.({ subtree: true }).forEach(
|
|
2236
|
-
(animation) => animation.cancel()
|
|
2237
|
-
);
|
|
2240
|
+
this.getAnimations?.({ subtree: true }).forEach((animation) => animation.cancel());
|
|
2238
2241
|
void this.offsetHeight;
|
|
2239
2242
|
this.style.display = "none";
|
|
2240
2243
|
this.querySelector(SEL_CONTAINER)?.remove();
|
|
@@ -2343,7 +2346,10 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2343
2346
|
if (document.querySelector(ApplePayModal.tag)) {
|
|
2344
2347
|
return;
|
|
2345
2348
|
}
|
|
2346
|
-
trackExpressWalletClick(
|
|
2349
|
+
trackExpressWalletClick(
|
|
2350
|
+
this.#offer.sku_id,
|
|
2351
|
+
this.#entryPoint ? { entryPoint: this.#entryPoint } : void 0
|
|
2352
|
+
);
|
|
2347
2353
|
ApplePayModal.define();
|
|
2348
2354
|
const modal = document.createElement(ApplePayModal.tag);
|
|
2349
2355
|
modal.offer = this.#offer;
|
|
@@ -2435,7 +2441,6 @@ function defineApplePayElements() {
|
|
|
2435
2441
|
}
|
|
2436
2442
|
export {
|
|
2437
2443
|
APPLE_PAY_EXCLUDED_VARIANTS,
|
|
2438
|
-
APPLE_PAY_EXPRESS_EXPERIMENT_KEY,
|
|
2439
2444
|
APPLE_PAY_EXPRESS_PAYWALLS_EXPERIMENT_KEY,
|
|
2440
2445
|
APPLE_PAY_EXPRESS_VARIANTS,
|
|
2441
2446
|
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 });
|
package/package.json
CHANGED