@economist/web-apple-pay 0.1.3-beta.47 → 0.1.3-beta.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +105 -41
- package/dist/src/apple-pay-button.d.ts +17 -1
- package/dist/src/apple-pay-button.js +99 -33
- package/dist/src/apple-pay-button.stories.js +99 -33
- package/dist/src/apple-pay-modal.d.ts +2 -2
- package/dist/src/apple-pay-modal.js +5 -5
- package/dist/src/apple-pay-modal.stories.js +99 -33
- package/dist/src/constants.d.ts +20 -0
- package/dist/src/constants.js +7 -0
- package/dist/src/index.js +105 -41
- package/dist/src/types/experiment-integration.d.js +0 -0
- package/dist/src/utils/recaptcha.d.ts +2 -4
- package/dist/src/utils/recaptcha.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -605,7 +605,7 @@ var getRecaptchaToken = async (action) => {
|
|
|
605
605
|
});
|
|
606
606
|
});
|
|
607
607
|
};
|
|
608
|
-
var
|
|
608
|
+
var getPurchaseRecaptchaToken = () => {
|
|
609
609
|
return getRecaptchaToken("walletPurchase");
|
|
610
610
|
};
|
|
611
611
|
|
|
@@ -834,7 +834,7 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
834
834
|
#isClosed = false;
|
|
835
835
|
/**
|
|
836
836
|
* Callback invoked synchronously from the CTA click handler.
|
|
837
|
-
* Receives a Promise of reCAPTCHA
|
|
837
|
+
* Receives a Promise of a reCAPTCHA token — the promise is already in-flight
|
|
838
838
|
* by the time this is called. The caller (ApplePayButton) must call
|
|
839
839
|
* new ApplePaySession() synchronously inside this callback to stay within
|
|
840
840
|
* Safari's user-gesture window. The token promise resolves before
|
|
@@ -946,12 +946,12 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
946
946
|
this.querySelector('[role="alert"]:not(#apple-pay-modal-error)')?.remove();
|
|
947
947
|
cta.disabled = true;
|
|
948
948
|
cta.setAttribute("aria-busy", "true");
|
|
949
|
-
const
|
|
949
|
+
const recaptchaTokenPromise = getPurchaseRecaptchaToken();
|
|
950
950
|
if (!this.#isClosed && this.onConfirm) {
|
|
951
|
-
this.onConfirm(
|
|
951
|
+
this.onConfirm(recaptchaTokenPromise);
|
|
952
952
|
this.close();
|
|
953
953
|
}
|
|
954
|
-
|
|
954
|
+
recaptchaTokenPromise.catch(() => {
|
|
955
955
|
if (this.#isClosed) return;
|
|
956
956
|
cta.disabled = false;
|
|
957
957
|
cta.removeAttribute("aria-busy");
|
|
@@ -1006,7 +1006,10 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
1006
1006
|
|
|
1007
1007
|
// src/templates/apple-pay-button.template.html
|
|
1008
1008
|
var apple_pay_button_template_default = `<style>
|
|
1009
|
-
/*
|
|
1009
|
+
/*
|
|
1010
|
+
* Entry CTA: \u201CSubscribe with\u201D + Apple Pay wordmark (Figma 1118:14088).
|
|
1011
|
+
* \u201CSubscribe with\u201D matches Continue to checkout typography (EconomistSans Regular / 17 / 24 / 400).
|
|
1012
|
+
*/
|
|
1010
1013
|
teg-apple-pay-button {
|
|
1011
1014
|
display: block;
|
|
1012
1015
|
margin: var(--apple-pay-margin, 0);
|
|
@@ -1026,25 +1029,50 @@ var apple_pay_button_template_default = `<style>
|
|
|
1026
1029
|
display: flex;
|
|
1027
1030
|
align-items: center;
|
|
1028
1031
|
justify-content: center;
|
|
1029
|
-
gap: 0.375rem;
|
|
1030
1032
|
width: 100%;
|
|
1031
1033
|
min-width: 0;
|
|
1032
1034
|
height: 100%;
|
|
1033
|
-
min-height: var(--apple-pay-height, 2.
|
|
1034
|
-
|
|
1035
|
+
min-height: var(--apple-pay-height, 2.5rem);
|
|
1036
|
+
padding: 0;
|
|
1037
|
+
box-sizing: border-box;
|
|
1038
|
+
background-color: var(--apple-pay-background-color, #1a1a1a);
|
|
1035
1039
|
color: var(--apple-pay-foreground-color, #fff);
|
|
1036
1040
|
border: none;
|
|
1037
|
-
border-radius: var(--apple-pay-border-radius,
|
|
1041
|
+
border-radius: var(--apple-pay-border-radius, 0.25rem);
|
|
1038
1042
|
cursor: pointer;
|
|
1039
|
-
|
|
1040
|
-
font-
|
|
1041
|
-
|
|
1043
|
+
/* Same as wall Continue to checkout / Marber button large */
|
|
1044
|
+
font-family: var(
|
|
1045
|
+
--mb-typeface-sans,
|
|
1046
|
+
var(--wall-type-system-sans, 'EconomistSans', system-ui, sans-serif)
|
|
1047
|
+
);
|
|
1048
|
+
font-size: var(--mb-button-font-size, 1.0625rem);
|
|
1049
|
+
font-weight: var(--mb-font-weight-regular, 400);
|
|
1050
|
+
line-height: 1;
|
|
1042
1051
|
}
|
|
1043
1052
|
|
|
1044
|
-
teg-apple-pay-button .apple-pay-
|
|
1053
|
+
teg-apple-pay-button .apple-pay-btn__label {
|
|
1054
|
+
display: inline-flex;
|
|
1055
|
+
align-items: center;
|
|
1056
|
+
/* No flex gap \u2014 spacing after \u201Cwith\u201D uses the same word-space as \u201CSubscribe with\u201D */
|
|
1057
|
+
gap: 0;
|
|
1058
|
+
white-space: nowrap;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
teg-apple-pay-button .apple-pay-btn__caption {
|
|
1062
|
+
/* One typographic word space after \u201Cwith\u201D, matching Subscribe\u2194with */
|
|
1063
|
+
padding-right: 0.25em;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
teg-apple-pay-button .apple-pay-btn__logo {
|
|
1045
1067
|
flex-shrink: 0;
|
|
1046
1068
|
display: block;
|
|
1069
|
+
/* Match caption font-size so mark aligns with text metrics */
|
|
1070
|
+
height: 1.05em;
|
|
1071
|
+
width: auto;
|
|
1072
|
+
aspect-ratio: 51 / 22;
|
|
1047
1073
|
color: currentColor;
|
|
1074
|
+
/* Optical nudge \u2014 SVG viewBox sits slightly high vs EconomistSans caps */
|
|
1075
|
+
transform: translateY(0.06em);
|
|
1048
1076
|
}
|
|
1049
1077
|
|
|
1050
1078
|
teg-apple-pay-button .apple-pay-btn.wap-loading {
|
|
@@ -1052,6 +1080,10 @@ var apple_pay_button_template_default = `<style>
|
|
|
1052
1080
|
cursor: default;
|
|
1053
1081
|
}
|
|
1054
1082
|
|
|
1083
|
+
teg-apple-pay-button .apple-pay-btn.wap-loading .apple-pay-btn__label {
|
|
1084
|
+
visibility: hidden;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1055
1087
|
teg-apple-pay-button .apple-pay-btn.wap-loading::before {
|
|
1056
1088
|
content: '';
|
|
1057
1089
|
position: absolute;
|
|
@@ -1065,11 +1097,6 @@ var apple_pay_button_template_default = `<style>
|
|
|
1065
1097
|
animation: wap-button-spinner 0.8s linear infinite;
|
|
1066
1098
|
}
|
|
1067
1099
|
|
|
1068
|
-
teg-apple-pay-button .apple-pay-btn__logo {
|
|
1069
|
-
display: inline-flex;
|
|
1070
|
-
align-items: center;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
1100
|
teg-apple-pay-button .apple-pay-btn__loading {
|
|
1074
1101
|
display: none;
|
|
1075
1102
|
}
|
|
@@ -1084,18 +1111,26 @@ var apple_pay_button_template_default = `<style>
|
|
|
1084
1111
|
}
|
|
1085
1112
|
</style>
|
|
1086
1113
|
|
|
1087
|
-
<div class="apple-pay-container" aria-label="
|
|
1114
|
+
<div class="apple-pay-container" aria-label="Subscribe with Apple Pay">
|
|
1088
1115
|
<button
|
|
1089
1116
|
class="apple-pay-btn"
|
|
1090
1117
|
type="button"
|
|
1091
|
-
aria-label="
|
|
1118
|
+
aria-label="Subscribe with Apple Pay"
|
|
1092
1119
|
data-analytics="paywall:apple-pay-checkout"
|
|
1093
1120
|
>
|
|
1094
|
-
<span class="apple-pay-
|
|
1095
|
-
|
|
1121
|
+
<span class="apple-pay-btn__label"
|
|
1122
|
+
><span class="apple-pay-btn__caption">Subscribe with</span
|
|
1123
|
+
><svg
|
|
1124
|
+
class="apple-pay-btn__logo"
|
|
1125
|
+
width="42"
|
|
1126
|
+
height="18"
|
|
1127
|
+
viewBox="0 0 51 22"
|
|
1128
|
+
aria-hidden="true"
|
|
1129
|
+
role="img"
|
|
1130
|
+
>
|
|
1096
1131
|
<use href="#apple-pay-logo" />
|
|
1097
|
-
</svg
|
|
1098
|
-
|
|
1132
|
+
</svg
|
|
1133
|
+
></span>
|
|
1099
1134
|
<span class="apple-pay-btn__loading" aria-hidden="true">Loading...</span>
|
|
1100
1135
|
</button>
|
|
1101
1136
|
</div>
|
|
@@ -1902,8 +1937,22 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
|
|
|
1902
1937
|
return [...zoneCountries];
|
|
1903
1938
|
};
|
|
1904
1939
|
|
|
1940
|
+
// src/constants.ts
|
|
1941
|
+
var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint3) => {
|
|
1942
|
+
ApplePayEntryPoint3["PAYWALL"] = "article_paywall";
|
|
1943
|
+
ApplePayEntryPoint3["REGWALL"] = "article_regwall";
|
|
1944
|
+
ApplePayEntryPoint3["DUAL_OFFER_BANNER"] = "dual_offer_banner";
|
|
1945
|
+
return ApplePayEntryPoint3;
|
|
1946
|
+
})(ApplePayEntryPoint || {});
|
|
1947
|
+
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-feature-flag-placeholder";
|
|
1948
|
+
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1949
|
+
CONTROL: "control",
|
|
1950
|
+
TREATMENT: "treatment"
|
|
1951
|
+
};
|
|
1952
|
+
|
|
1905
1953
|
// src/apple-pay-button.ts
|
|
1906
1954
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
1955
|
+
var APPLE_PAY_EXPRESS_GATING_DISABLED = true;
|
|
1907
1956
|
var TOTAL_LABEL = "The Economist";
|
|
1908
1957
|
var DEFAULT_CURRENCY = "USD";
|
|
1909
1958
|
var DEFAULT_TOTAL = "0.00";
|
|
@@ -1919,7 +1968,23 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
1919
1968
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
1920
1969
|
}
|
|
1921
1970
|
/**
|
|
1922
|
-
* Creates and configures an ApplePayButton
|
|
1971
|
+
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
1972
|
+
*
|
|
1973
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant` using
|
|
1974
|
+
* {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY}. The host page is responsible
|
|
1975
|
+
* for setting up `window.experimentIntegration` before calling this method.
|
|
1976
|
+
*
|
|
1977
|
+
* - `treatment` → button created and returned
|
|
1978
|
+
* - `control` / missing / anything else → returns null (button suppressed)
|
|
1979
|
+
*
|
|
1980
|
+
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
1981
|
+
* gate is also evaluated as a fallback until all host apps have integrated
|
|
1982
|
+
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
1983
|
+
* fallback will be removed.
|
|
1984
|
+
*
|
|
1985
|
+
* @param offer - The offer to display in the Apple Pay flow.
|
|
1986
|
+
* @param country - The user's country code.
|
|
1987
|
+
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
1923
1988
|
*/
|
|
1924
1989
|
static createIfEnabled(offer, country, entryPoint) {
|
|
1925
1990
|
if (!offer) {
|
|
@@ -1928,7 +1993,14 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
1928
1993
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
1929
1994
|
return null;
|
|
1930
1995
|
}
|
|
1931
|
-
|
|
1996
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
1997
|
+
APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
1998
|
+
);
|
|
1999
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
2000
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
2001
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
2002
|
+
);
|
|
2003
|
+
if (!APPLE_PAY_EXPRESS_GATING_DISABLED && !isTreatment && !hasUrlParamFlag) {
|
|
1932
2004
|
return null;
|
|
1933
2005
|
}
|
|
1934
2006
|
_ApplePayButton.define();
|
|
@@ -2161,8 +2233,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2161
2233
|
}
|
|
2162
2234
|
const skuId = this.#offer.sku_id;
|
|
2163
2235
|
const country = this.#country;
|
|
2164
|
-
modal.onConfirm = (
|
|
2165
|
-
this.#initiateApplePay(skuId, country,
|
|
2236
|
+
modal.onConfirm = (recaptchaTokenPromise) => {
|
|
2237
|
+
this.#initiateApplePay(skuId, country, recaptchaTokenPromise);
|
|
2166
2238
|
};
|
|
2167
2239
|
modal.open();
|
|
2168
2240
|
}
|
|
@@ -2185,7 +2257,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2185
2257
|
return null;
|
|
2186
2258
|
}
|
|
2187
2259
|
}
|
|
2188
|
-
#buildSessionParams(skuId, country, sessionData, paymentOptions,
|
|
2260
|
+
#buildSessionParams(skuId, country, sessionData, paymentOptions, recaptchaTokenPromise) {
|
|
2189
2261
|
const offer = this.#offer;
|
|
2190
2262
|
const totalAmount = offer.price?.purchase ? `${offer.price.purchase}` : DEFAULT_TOTAL;
|
|
2191
2263
|
return {
|
|
@@ -2198,7 +2270,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2198
2270
|
returnUrl: this.#returnUrl,
|
|
2199
2271
|
userLoggedIn: sessionData.loggedIn,
|
|
2200
2272
|
onPaymentAuthorized: async (event, session) => {
|
|
2201
|
-
const recaptchaToken = await
|
|
2273
|
+
const recaptchaToken = await recaptchaTokenPromise;
|
|
2202
2274
|
return handlePaymentAuthorized(event, session, sessionData, {
|
|
2203
2275
|
skuId,
|
|
2204
2276
|
country,
|
|
@@ -2210,7 +2282,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2210
2282
|
}
|
|
2211
2283
|
};
|
|
2212
2284
|
}
|
|
2213
|
-
#initiateApplePay(skuId, country,
|
|
2285
|
+
#initiateApplePay(skuId, country, recaptchaTokenPromise) {
|
|
2214
2286
|
try {
|
|
2215
2287
|
const sessionData = this.#sessionData ?? _ApplePayButton.#ANONYMOUS_SESSION;
|
|
2216
2288
|
const paymentOptions = this.#paymentOptions;
|
|
@@ -2223,7 +2295,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2223
2295
|
country,
|
|
2224
2296
|
sessionData,
|
|
2225
2297
|
paymentOptions,
|
|
2226
|
-
|
|
2298
|
+
recaptchaTokenPromise
|
|
2227
2299
|
)
|
|
2228
2300
|
);
|
|
2229
2301
|
} catch {
|
|
@@ -2236,14 +2308,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2236
2308
|
}
|
|
2237
2309
|
};
|
|
2238
2310
|
|
|
2239
|
-
// src/constants.ts
|
|
2240
|
-
var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
|
|
2241
|
-
ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
|
|
2242
|
-
ApplePayEntryPoint2["REGWALL"] = "article_regwall";
|
|
2243
|
-
ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
|
|
2244
|
-
return ApplePayEntryPoint2;
|
|
2245
|
-
})(ApplePayEntryPoint || {});
|
|
2246
|
-
|
|
2247
2311
|
// src/index.ts
|
|
2248
2312
|
function defineApplePayElements() {
|
|
2249
2313
|
ApplePayButton.define();
|
|
@@ -6,7 +6,23 @@ 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
|
|
9
|
+
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
10
|
+
*
|
|
11
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant` using
|
|
12
|
+
* {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY}. The host page is responsible
|
|
13
|
+
* for setting up `window.experimentIntegration` before calling this method.
|
|
14
|
+
*
|
|
15
|
+
* - `treatment` → button created and returned
|
|
16
|
+
* - `control` / missing / anything else → returns null (button suppressed)
|
|
17
|
+
*
|
|
18
|
+
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
19
|
+
* gate is also evaluated as a fallback until all host apps have integrated
|
|
20
|
+
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
21
|
+
* fallback will be removed.
|
|
22
|
+
*
|
|
23
|
+
* @param offer - The offer to display in the Apple Pay flow.
|
|
24
|
+
* @param country - The user's country code.
|
|
25
|
+
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
10
26
|
*/
|
|
11
27
|
static createIfEnabled(offer: Offer | undefined, country: string, entryPoint?: ApplePayEntryPoint): ApplePayButton | null;
|
|
12
28
|
get offer(): Offer | null;
|
|
@@ -600,7 +600,7 @@ var getRecaptchaToken = async (action) => {
|
|
|
600
600
|
});
|
|
601
601
|
});
|
|
602
602
|
};
|
|
603
|
-
var
|
|
603
|
+
var getPurchaseRecaptchaToken = () => {
|
|
604
604
|
return getRecaptchaToken("walletPurchase");
|
|
605
605
|
};
|
|
606
606
|
|
|
@@ -829,7 +829,7 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
829
829
|
#isClosed = false;
|
|
830
830
|
/**
|
|
831
831
|
* Callback invoked synchronously from the CTA click handler.
|
|
832
|
-
* Receives a Promise of reCAPTCHA
|
|
832
|
+
* Receives a Promise of a reCAPTCHA token — the promise is already in-flight
|
|
833
833
|
* by the time this is called. The caller (ApplePayButton) must call
|
|
834
834
|
* new ApplePaySession() synchronously inside this callback to stay within
|
|
835
835
|
* Safari's user-gesture window. The token promise resolves before
|
|
@@ -941,12 +941,12 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
941
941
|
this.querySelector('[role="alert"]:not(#apple-pay-modal-error)')?.remove();
|
|
942
942
|
cta.disabled = true;
|
|
943
943
|
cta.setAttribute("aria-busy", "true");
|
|
944
|
-
const
|
|
944
|
+
const recaptchaTokenPromise = getPurchaseRecaptchaToken();
|
|
945
945
|
if (!this.#isClosed && this.onConfirm) {
|
|
946
|
-
this.onConfirm(
|
|
946
|
+
this.onConfirm(recaptchaTokenPromise);
|
|
947
947
|
this.close();
|
|
948
948
|
}
|
|
949
|
-
|
|
949
|
+
recaptchaTokenPromise.catch(() => {
|
|
950
950
|
if (this.#isClosed) return;
|
|
951
951
|
cta.disabled = false;
|
|
952
952
|
cta.removeAttribute("aria-busy");
|
|
@@ -1001,7 +1001,10 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
|
|
|
1001
1001
|
|
|
1002
1002
|
// src/templates/apple-pay-button.template.html
|
|
1003
1003
|
var apple_pay_button_template_default = `<style>
|
|
1004
|
-
/*
|
|
1004
|
+
/*
|
|
1005
|
+
* Entry CTA: \u201CSubscribe with\u201D + Apple Pay wordmark (Figma 1118:14088).
|
|
1006
|
+
* \u201CSubscribe with\u201D matches Continue to checkout typography (EconomistSans Regular / 17 / 24 / 400).
|
|
1007
|
+
*/
|
|
1005
1008
|
teg-apple-pay-button {
|
|
1006
1009
|
display: block;
|
|
1007
1010
|
margin: var(--apple-pay-margin, 0);
|
|
@@ -1021,25 +1024,50 @@ var apple_pay_button_template_default = `<style>
|
|
|
1021
1024
|
display: flex;
|
|
1022
1025
|
align-items: center;
|
|
1023
1026
|
justify-content: center;
|
|
1024
|
-
gap: 0.375rem;
|
|
1025
1027
|
width: 100%;
|
|
1026
1028
|
min-width: 0;
|
|
1027
1029
|
height: 100%;
|
|
1028
|
-
min-height: var(--apple-pay-height, 2.
|
|
1029
|
-
|
|
1030
|
+
min-height: var(--apple-pay-height, 2.5rem);
|
|
1031
|
+
padding: 0;
|
|
1032
|
+
box-sizing: border-box;
|
|
1033
|
+
background-color: var(--apple-pay-background-color, #1a1a1a);
|
|
1030
1034
|
color: var(--apple-pay-foreground-color, #fff);
|
|
1031
1035
|
border: none;
|
|
1032
|
-
border-radius: var(--apple-pay-border-radius,
|
|
1036
|
+
border-radius: var(--apple-pay-border-radius, 0.25rem);
|
|
1033
1037
|
cursor: pointer;
|
|
1034
|
-
|
|
1035
|
-
font-
|
|
1036
|
-
|
|
1038
|
+
/* Same as wall Continue to checkout / Marber button large */
|
|
1039
|
+
font-family: var(
|
|
1040
|
+
--mb-typeface-sans,
|
|
1041
|
+
var(--wall-type-system-sans, 'EconomistSans', system-ui, sans-serif)
|
|
1042
|
+
);
|
|
1043
|
+
font-size: var(--mb-button-font-size, 1.0625rem);
|
|
1044
|
+
font-weight: var(--mb-font-weight-regular, 400);
|
|
1045
|
+
line-height: 1;
|
|
1037
1046
|
}
|
|
1038
1047
|
|
|
1039
|
-
teg-apple-pay-button .apple-pay-
|
|
1048
|
+
teg-apple-pay-button .apple-pay-btn__label {
|
|
1049
|
+
display: inline-flex;
|
|
1050
|
+
align-items: center;
|
|
1051
|
+
/* No flex gap \u2014 spacing after \u201Cwith\u201D uses the same word-space as \u201CSubscribe with\u201D */
|
|
1052
|
+
gap: 0;
|
|
1053
|
+
white-space: nowrap;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
teg-apple-pay-button .apple-pay-btn__caption {
|
|
1057
|
+
/* One typographic word space after \u201Cwith\u201D, matching Subscribe\u2194with */
|
|
1058
|
+
padding-right: 0.25em;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
teg-apple-pay-button .apple-pay-btn__logo {
|
|
1040
1062
|
flex-shrink: 0;
|
|
1041
1063
|
display: block;
|
|
1064
|
+
/* Match caption font-size so mark aligns with text metrics */
|
|
1065
|
+
height: 1.05em;
|
|
1066
|
+
width: auto;
|
|
1067
|
+
aspect-ratio: 51 / 22;
|
|
1042
1068
|
color: currentColor;
|
|
1069
|
+
/* Optical nudge \u2014 SVG viewBox sits slightly high vs EconomistSans caps */
|
|
1070
|
+
transform: translateY(0.06em);
|
|
1043
1071
|
}
|
|
1044
1072
|
|
|
1045
1073
|
teg-apple-pay-button .apple-pay-btn.wap-loading {
|
|
@@ -1047,6 +1075,10 @@ var apple_pay_button_template_default = `<style>
|
|
|
1047
1075
|
cursor: default;
|
|
1048
1076
|
}
|
|
1049
1077
|
|
|
1078
|
+
teg-apple-pay-button .apple-pay-btn.wap-loading .apple-pay-btn__label {
|
|
1079
|
+
visibility: hidden;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1050
1082
|
teg-apple-pay-button .apple-pay-btn.wap-loading::before {
|
|
1051
1083
|
content: '';
|
|
1052
1084
|
position: absolute;
|
|
@@ -1060,11 +1092,6 @@ var apple_pay_button_template_default = `<style>
|
|
|
1060
1092
|
animation: wap-button-spinner 0.8s linear infinite;
|
|
1061
1093
|
}
|
|
1062
1094
|
|
|
1063
|
-
teg-apple-pay-button .apple-pay-btn__logo {
|
|
1064
|
-
display: inline-flex;
|
|
1065
|
-
align-items: center;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
1095
|
teg-apple-pay-button .apple-pay-btn__loading {
|
|
1069
1096
|
display: none;
|
|
1070
1097
|
}
|
|
@@ -1079,18 +1106,26 @@ var apple_pay_button_template_default = `<style>
|
|
|
1079
1106
|
}
|
|
1080
1107
|
</style>
|
|
1081
1108
|
|
|
1082
|
-
<div class="apple-pay-container" aria-label="
|
|
1109
|
+
<div class="apple-pay-container" aria-label="Subscribe with Apple Pay">
|
|
1083
1110
|
<button
|
|
1084
1111
|
class="apple-pay-btn"
|
|
1085
1112
|
type="button"
|
|
1086
|
-
aria-label="
|
|
1113
|
+
aria-label="Subscribe with Apple Pay"
|
|
1087
1114
|
data-analytics="paywall:apple-pay-checkout"
|
|
1088
1115
|
>
|
|
1089
|
-
<span class="apple-pay-
|
|
1090
|
-
|
|
1116
|
+
<span class="apple-pay-btn__label"
|
|
1117
|
+
><span class="apple-pay-btn__caption">Subscribe with</span
|
|
1118
|
+
><svg
|
|
1119
|
+
class="apple-pay-btn__logo"
|
|
1120
|
+
width="42"
|
|
1121
|
+
height="18"
|
|
1122
|
+
viewBox="0 0 51 22"
|
|
1123
|
+
aria-hidden="true"
|
|
1124
|
+
role="img"
|
|
1125
|
+
>
|
|
1091
1126
|
<use href="#apple-pay-logo" />
|
|
1092
|
-
</svg
|
|
1093
|
-
|
|
1127
|
+
</svg
|
|
1128
|
+
></span>
|
|
1094
1129
|
<span class="apple-pay-btn__loading" aria-hidden="true">Loading...</span>
|
|
1095
1130
|
</button>
|
|
1096
1131
|
</div>
|
|
@@ -1897,8 +1932,16 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
|
|
|
1897
1932
|
return [...zoneCountries];
|
|
1898
1933
|
};
|
|
1899
1934
|
|
|
1935
|
+
// src/constants.ts
|
|
1936
|
+
var APPLE_PAY_EXPRESS_EXPERIMENT_KEY = "apple-pay-express-feature-flag-placeholder";
|
|
1937
|
+
var APPLE_PAY_EXPRESS_VARIANTS = {
|
|
1938
|
+
CONTROL: "control",
|
|
1939
|
+
TREATMENT: "treatment"
|
|
1940
|
+
};
|
|
1941
|
+
|
|
1900
1942
|
// src/apple-pay-button.ts
|
|
1901
1943
|
var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
|
|
1944
|
+
var APPLE_PAY_EXPRESS_GATING_DISABLED = true;
|
|
1902
1945
|
var TOTAL_LABEL = "The Economist";
|
|
1903
1946
|
var DEFAULT_CURRENCY = "USD";
|
|
1904
1947
|
var DEFAULT_TOTAL = "0.00";
|
|
@@ -1914,7 +1957,23 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
1914
1957
|
define(_ApplePayButton.tag, _ApplePayButton);
|
|
1915
1958
|
}
|
|
1916
1959
|
/**
|
|
1917
|
-
* Creates and configures an ApplePayButton
|
|
1960
|
+
* Creates and configures an ApplePayButton when the Amplitude experiment is enabled.
|
|
1961
|
+
*
|
|
1962
|
+
* Reads the experiment variant from `window.experimentIntegration.getVariant` using
|
|
1963
|
+
* {@link APPLE_PAY_EXPRESS_EXPERIMENT_KEY}. The host page is responsible
|
|
1964
|
+
* for setting up `window.experimentIntegration` before calling this method.
|
|
1965
|
+
*
|
|
1966
|
+
* - `treatment` → button created and returned
|
|
1967
|
+
* - `control` / missing / anything else → returns null (button suppressed)
|
|
1968
|
+
*
|
|
1969
|
+
* **Transition period:** the legacy `FEATURE_APPLE_PAY_EXPRESS_CHECKOUT` URL param
|
|
1970
|
+
* gate is also evaluated as a fallback until all host apps have integrated
|
|
1971
|
+
* `window.experimentIntegration`. Once all consumers are migrated, the URL param
|
|
1972
|
+
* fallback will be removed.
|
|
1973
|
+
*
|
|
1974
|
+
* @param offer - The offer to display in the Apple Pay flow.
|
|
1975
|
+
* @param country - The user's country code.
|
|
1976
|
+
* @param entryPoint - Where the button is being rendered (e.g. paywall, banner).
|
|
1918
1977
|
*/
|
|
1919
1978
|
static createIfEnabled(offer, country, entryPoint) {
|
|
1920
1979
|
if (!offer) {
|
|
@@ -1923,7 +1982,14 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
1923
1982
|
if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
|
|
1924
1983
|
return null;
|
|
1925
1984
|
}
|
|
1926
|
-
|
|
1985
|
+
const experimentValue = window.experimentIntegration?.getVariant?.(
|
|
1986
|
+
APPLE_PAY_EXPRESS_EXPERIMENT_KEY
|
|
1987
|
+
);
|
|
1988
|
+
const isTreatment = experimentValue === APPLE_PAY_EXPRESS_VARIANTS.TREATMENT;
|
|
1989
|
+
const hasUrlParamFlag = new URLSearchParams(window.location.search).has(
|
|
1990
|
+
FEATURE_APPLE_PAY_EXPRESS_CHECKOUT
|
|
1991
|
+
);
|
|
1992
|
+
if (!APPLE_PAY_EXPRESS_GATING_DISABLED && !isTreatment && !hasUrlParamFlag) {
|
|
1927
1993
|
return null;
|
|
1928
1994
|
}
|
|
1929
1995
|
_ApplePayButton.define();
|
|
@@ -2156,8 +2222,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2156
2222
|
}
|
|
2157
2223
|
const skuId = this.#offer.sku_id;
|
|
2158
2224
|
const country = this.#country;
|
|
2159
|
-
modal.onConfirm = (
|
|
2160
|
-
this.#initiateApplePay(skuId, country,
|
|
2225
|
+
modal.onConfirm = (recaptchaTokenPromise) => {
|
|
2226
|
+
this.#initiateApplePay(skuId, country, recaptchaTokenPromise);
|
|
2161
2227
|
};
|
|
2162
2228
|
modal.open();
|
|
2163
2229
|
}
|
|
@@ -2180,7 +2246,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2180
2246
|
return null;
|
|
2181
2247
|
}
|
|
2182
2248
|
}
|
|
2183
|
-
#buildSessionParams(skuId, country, sessionData, paymentOptions,
|
|
2249
|
+
#buildSessionParams(skuId, country, sessionData, paymentOptions, recaptchaTokenPromise) {
|
|
2184
2250
|
const offer = this.#offer;
|
|
2185
2251
|
const totalAmount = offer.price?.purchase ? `${offer.price.purchase}` : DEFAULT_TOTAL;
|
|
2186
2252
|
return {
|
|
@@ -2193,7 +2259,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2193
2259
|
returnUrl: this.#returnUrl,
|
|
2194
2260
|
userLoggedIn: sessionData.loggedIn,
|
|
2195
2261
|
onPaymentAuthorized: async (event, session) => {
|
|
2196
|
-
const recaptchaToken = await
|
|
2262
|
+
const recaptchaToken = await recaptchaTokenPromise;
|
|
2197
2263
|
return handlePaymentAuthorized(event, session, sessionData, {
|
|
2198
2264
|
skuId,
|
|
2199
2265
|
country,
|
|
@@ -2205,7 +2271,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2205
2271
|
}
|
|
2206
2272
|
};
|
|
2207
2273
|
}
|
|
2208
|
-
#initiateApplePay(skuId, country,
|
|
2274
|
+
#initiateApplePay(skuId, country, recaptchaTokenPromise) {
|
|
2209
2275
|
try {
|
|
2210
2276
|
const sessionData = this.#sessionData ?? _ApplePayButton.#ANONYMOUS_SESSION;
|
|
2211
2277
|
const paymentOptions = this.#paymentOptions;
|
|
@@ -2218,7 +2284,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
|
|
|
2218
2284
|
country,
|
|
2219
2285
|
sessionData,
|
|
2220
2286
|
paymentOptions,
|
|
2221
|
-
|
|
2287
|
+
recaptchaTokenPromise
|
|
2222
2288
|
)
|
|
2223
2289
|
);
|
|
2224
2290
|
} catch {
|