@economist/web-apple-pay 1.7.6 → 1.7.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -71,7 +71,7 @@ function ensureApplePayLogoSymbol() {
71
71
  return;
72
72
  }
73
73
  const tmp = document.createElement("div");
74
- tmp.innerHTML = `<svg aria-hidden="true" style="display:none" id="${LOGO_DEFS_ID}"><defs><symbol id="apple-pay-logo" viewBox="0 0 51 22"><path d="${LOGO_PATH}" fill="white"/></symbol></defs></svg>`;
74
+ tmp.innerHTML = `<svg aria-hidden="true" style="display:none" id="${LOGO_DEFS_ID}"><defs><symbol id="apple-pay-logo" viewBox="0 0 51 22"><path d="${LOGO_PATH}" fill="currentColor"/></symbol></defs></svg>`;
75
75
  document.body.prepend(tmp.firstElementChild);
76
76
  }
77
77
 
@@ -109,16 +109,32 @@ var apple_pay_modal_template_default = `<style>
109
109
  position: absolute;
110
110
  top: 1.5rem;
111
111
  right: 1.3125rem;
112
- background: none;
112
+ background: transparent;
113
113
  border: none;
114
114
  cursor: pointer;
115
115
  padding: 0;
116
+ width: 1.5rem;
117
+ height: 1.5rem;
116
118
  display: flex;
117
119
  align-items: center;
118
120
  justify-content: center;
121
+ color: var(--mb-colour-greyscale-london-20, #1a1a1a);
122
+ transition:
123
+ background-color ease-in-out 0.2s,
124
+ color ease-in-out 0.2s;
125
+ }
126
+
127
+ .apm__close:hover {
128
+ color: var(--mb-colour-base-chicago-30, #333333);
129
+ }
130
+
131
+ .apm__close:active {
132
+ background-color: var(--mb-colour-base-chicago-90, #e6e6e6);
133
+ color: var(--mb-colour-base-chicago-30, #333333);
119
134
  }
120
135
 
121
136
  .apm__close:focus {
137
+ background-color: var(--mb-colour-base-chicago-90, #e6e6e6);
122
138
  outline: solid 0.125rem var(--focus-border-color, #121212);
123
139
  border-radius: 0.25rem;
124
140
  }
@@ -301,10 +317,6 @@ var apple_pay_modal_template_default = `<style>
301
317
  cursor: pointer;
302
318
  color: #fff;
303
319
  text-align: center;
304
- font-family: var(
305
- --mb-typeface-sans,
306
- var(--wall-type-system-sans, system-ui, sans-serif)
307
- );
308
320
  font-size: 1.25rem;
309
321
  font-style: normal;
310
322
  font-weight: 500;
@@ -421,7 +433,7 @@ var apple_pay_modal_template_default = `<style>
421
433
  fill-rule="evenodd"
422
434
  clip-rule="evenodd"
423
435
  d="M18.75 6.60964L17.3904 5.25L12 10.6404L6.60964 5.25L5.25 6.60964L10.6404 12L5.25 17.3904L6.60964 18.75L12 13.3596L17.3904 18.75L18.75 17.3904L13.3596 12L18.75 6.60964Z"
424
- fill="#333333"
436
+ fill="currentColor"
425
437
  />
426
438
  </g>
427
439
  <defs>
@@ -684,6 +696,8 @@ function renewalPeriodText(unit, duration) {
684
696
  return "";
685
697
  }
686
698
  }
699
+ var LI_SEPARATOR = "\0LI_SEP\0";
700
+ var P_SEPARATOR = "\0P_SEP\0";
687
701
  function buildTermsContext(offer, country) {
688
702
  const isUS = country === "US";
689
703
  const isCA = country === "CA";
@@ -720,19 +734,19 @@ function freeTrialTerms(offer, ctx) {
720
734
  const trialDuration = offer.subscription_options?.trial_period?.duration ?? 1;
721
735
  const trialDateStr = `on ${getRenewalDateText(trialUnit, trialDuration)}${ctx.verificationText}`;
722
736
  if (ctx.isUS) {
723
- return `Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${trialDateStr} when your free trial ends, until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}`;
737
+ return `Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${trialDateStr} when your free trial ends, until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}`;
724
738
  }
725
- return `Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${trialDateStr} when your free trial ends, until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
739
+ return `Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${trialDateStr} when your free trial ends, until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
726
740
  }
727
741
  function nytTerms(ctx) {
728
742
  const nytAccessText = "Your complimentary access to The New York Times is for one year only and does not auto-renew. We will send your instructions on how to redeem access to The New York Times by email.";
729
743
  if (ctx.isUS) {
730
- return `Your subscription to <em>The Economist</em> auto-renews ${ctx.periodText} until cancelled{{liSeparator}}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.renewalDateStr}{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}{{pSeparator}}${nytAccessText}`;
744
+ return `Your subscription to <em>The Economist</em> auto-renews ${ctx.periodText} until cancelled${LI_SEPARATOR}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.renewalDateStr}${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}${P_SEPARATOR}${nytAccessText}`;
731
745
  }
732
746
  if (ctx.isCA) {
733
- return `Your subscription to <em>The Economist</em> auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled.{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}{{pSeparator}}${nytAccessText}`;
747
+ return `Your subscription to <em>The Economist</em> auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled.${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}${P_SEPARATOR}${nytAccessText}`;
734
748
  }
735
- return `Your subscription to <em>The Economist</em> auto-renews at ${ctx.renewalPriceText} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime} ${nytAccessText}`;
749
+ return `Your subscription to <em>The Economist</em> auto-renews at ${ctx.renewalPriceText} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime} ${nytAccessText}`;
736
750
  }
737
751
  function minTermContractTerms(offer, ctx) {
738
752
  const duePrice = formatPrice(offer.price.purchase, offer.price.currency_code);
@@ -742,28 +756,28 @@ function minTermContractTerms(offer, ctx) {
742
756
  const contractLength = mtDuration && mtUnit ? `${mtDuration} ${mtUnit}` : "";
743
757
  const initialContractText = contractLength ? `your initial ${contractLength} contract` : "your initial contract";
744
758
  const mtRenewalDateText = mtUnit && mtDuration ? getRenewalDateText(mtUnit, Number(mtDuration)) : ctx.renewalDateText;
745
- return `You\u2019ll be charged ${duePrice} a month for the duration of ${initialContractText}{{liSeparator}}Your subscription auto-renews annually at ${ctx.renewalPriceText} a month on ${mtRenewalDateText} until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}`;
759
+ return `You\u2019ll be charged ${duePrice} a month for the duration of ${initialContractText}${LI_SEPARATOR}Your subscription auto-renews annually at ${ctx.renewalPriceText} a month on ${mtRenewalDateText} until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}`;
746
760
  }
747
761
  function paidTrialTerms(offer, ctx) {
748
762
  const trialUnit = offer.subscription_options?.trial_period?.unit ?? ctx.unit;
749
763
  const trialDuration = offer.subscription_options?.trial_period?.duration ?? ctx.duration;
750
764
  const trialDateText = getRenewalDateText(trialUnit, trialDuration);
751
765
  if (ctx.isUS) {
752
- return `Your subscription auto-renews ${ctx.periodText} until cancelled{{liSeparator}}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} on ${trialDateText} when your paid trial ends{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.usCancelNote}${ctx.taxFootnote}`;
766
+ return `Your subscription auto-renews ${ctx.periodText} until cancelled${LI_SEPARATOR}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} on ${trialDateText} when your paid trial ends${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.usCancelNote}${ctx.taxFootnote}`;
753
767
  }
754
- return `Your subscription auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} on ${trialDateText} when your paid trial ends, until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
768
+ return `Your subscription auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} on ${trialDateText} when your paid trial ends, until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
755
769
  }
756
770
  function autoRenewalTerms(ctx) {
757
771
  if (ctx.isUS) {
758
- return `Your subscription auto-renews ${ctx.periodText} until cancelled{{liSeparator}}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.renewalDateStr}{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}`;
772
+ return `Your subscription auto-renews ${ctx.periodText} until cancelled${LI_SEPARATOR}Your subscription renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.renewalDateStr}${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal until cancelled. ${ctx.usCancelNote}${ctx.taxFootnote}`;
759
773
  }
760
- return `Your subscription auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled{{liSeparator}}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
774
+ return `Your subscription auto-renews at ${ctx.renewalPriceText}${ctx.taxSuffix} ${ctx.periodText} ${ctx.renewalDateStr} until cancelled${LI_SEPARATOR}You\u2019ll be charged the rate in effect at each renewal. ${ctx.cancelAnytime}${ctx.taxFootnote}`;
761
775
  }
762
776
  function noAutoRenewalTerms(ctx) {
763
777
  if (ctx.isUS || ctx.isCA) {
764
- return `Your subscription does not renew automatically${ctx.taxFootnote}{{liSeparator}}`;
778
+ return `Your subscription does not renew automatically${ctx.taxFootnote}${LI_SEPARATOR}`;
765
779
  }
766
- return `Your subscription does not renew automatically{{liSeparator}}`;
780
+ return `Your subscription does not renew automatically${LI_SEPARATOR}`;
767
781
  }
768
782
  function generateApplePayModalTerms(offer, country) {
769
783
  const ctx = buildTermsContext(offer, country);
@@ -786,9 +800,9 @@ function generateApplePayModalTerms(offer, country) {
786
800
  return noAutoRenewalTerms(ctx);
787
801
  }
788
802
  function renderTermsHtml(termsText) {
789
- const renewalTextLists = termsText.split("{{liSeparator}}");
803
+ const renewalTextLists = termsText.split(LI_SEPARATOR);
790
804
  const lastPart = renewalTextLists.pop() || "";
791
- const renewalTextParagraphs = lastPart.split("{{pSeparator}}");
805
+ const renewalTextParagraphs = lastPart.split(P_SEPARATOR);
792
806
  const ulHtml = `<ul class="apm__terms-bullets">${renewalTextLists.map((value) => `<li>${value}</li>`).join("")}</ul>`;
793
807
  const paragraphHtml = renewalTextParagraphs.filter(Boolean).map((value) => `<p class="apm__terms-legal">${value}</p>`).join("");
794
808
  return ulHtml + paragraphHtml;
@@ -942,7 +956,6 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
942
956
  cta.removeAttribute("aria-busy");
943
957
  }
944
958
  }).catch(() => {
945
- console.error("[web-apple-pay] apple-pay-modal: failed to pre-fetch reCAPTCHA tokens; CTA remains disabled");
946
959
  if (cta) {
947
960
  cta.removeAttribute("aria-busy");
948
961
  }
@@ -1031,8 +1044,8 @@ var apple_pay_button_template_default = `<style>
1031
1044
  min-width: 0;
1032
1045
  height: 100%;
1033
1046
  min-height: var(--apple-pay-height, 2.75rem);
1034
- background-color: #000;
1035
- color: #fff;
1047
+ background-color: var(--apple-pay-background-color, #000);
1048
+ color: var(--apple-pay-foreground-color, #fff);
1036
1049
  border: none;
1037
1050
  border-radius: var(--apple-pay-border-radius, 1.375rem);
1038
1051
  cursor: pointer;
@@ -1044,6 +1057,7 @@ var apple_pay_button_template_default = `<style>
1044
1057
  teg-apple-pay-button .apple-pay-btn svg {
1045
1058
  flex-shrink: 0;
1046
1059
  display: block;
1060
+ color: currentColor;
1047
1061
  }
1048
1062
 
1049
1063
  teg-apple-pay-button .apple-pay-btn.wap-loading {
@@ -1058,8 +1072,8 @@ var apple_pay_button_template_default = `<style>
1058
1072
  left: 50%;
1059
1073
  width: 1.25rem;
1060
1074
  height: 1.25rem;
1061
- border: 2px solid rgba(255, 255, 255, 0.25);
1062
- border-top-color: #fff;
1075
+ border: 2px solid var(--apple-pay-spinner-track-color, rgba(255, 255, 255, 0.25));
1076
+ border-top-color: var(--apple-pay-spinner-head-color, currentColor);
1063
1077
  border-radius: 50%;
1064
1078
  animation: wap-button-spinner 0.8s linear infinite;
1065
1079
  }
@@ -1127,15 +1141,11 @@ var isApplePayAvailable = async () => {
1127
1141
  }
1128
1142
  const merchantId = getApplePayConfig()?.merchantId;
1129
1143
  if (!merchantId) {
1130
- console.warn(
1131
- "[web-apple-pay] Missing merchantId. Call configureApplePay({ merchantId, ... }) before rendering Apple Pay components."
1132
- );
1133
1144
  return false;
1134
1145
  }
1135
1146
  const hasActiveCard = await applePaySession.canMakePaymentsWithActiveCard(merchantId);
1136
1147
  return hasActiveCard;
1137
- } catch (error) {
1138
- console.error("Error checking Apple Pay active card status:", error);
1148
+ } catch {
1139
1149
  return false;
1140
1150
  }
1141
1151
  };
@@ -1223,13 +1233,25 @@ var getExpressCheckoutSession = () => {
1223
1233
  };
1224
1234
 
1225
1235
  // src/utils/expressCheckoutRedirect.ts
1226
- var captureOriginUrl = () => window.location.href;
1227
- var buildQueryString = () => {
1228
- const countryCode = new URLSearchParams(window.location.search).get(
1229
- "country"
1230
- );
1231
- return countryCode ? `&country=${encodeURIComponent(countryCode)}` : "";
1236
+ var CHECKOUT_REDIRECT_KEY = "checkout-redirect";
1237
+ var ALLOWED_REDIRECT_HOSTNAME = "economist.com";
1238
+ function isAllowedRedirectUrl(url) {
1239
+ if (url.startsWith("/")) return !url.startsWith("//");
1240
+ try {
1241
+ const { hostname } = new URL(url);
1242
+ return hostname === ALLOWED_REDIRECT_HOSTNAME || hostname.endsWith(`.${ALLOWED_REDIRECT_HOSTNAME}`);
1243
+ } catch {
1244
+ return false;
1245
+ }
1246
+ }
1247
+ var writeCheckoutRedirect = (originUrl) => {
1248
+ if (!isAllowedRedirectUrl(originUrl)) return;
1249
+ try {
1250
+ localStorage.setItem(CHECKOUT_REDIRECT_KEY, originUrl);
1251
+ } catch {
1252
+ }
1232
1253
  };
1254
+ var captureOriginUrl = () => window.location.href;
1233
1255
  var decodeSku = (sku) => {
1234
1256
  try {
1235
1257
  return atob(sku.substring(sku.indexOf("-") + 1));
@@ -1240,14 +1262,11 @@ var decodeSku = (sku) => {
1240
1262
  var redirectToCheckoutComplete = (params) => {
1241
1263
  const url = new URL("/checkout/complete", window.location.origin);
1242
1264
  url.searchParams.set("basketId", params.basketId);
1243
- if (params.queryString) {
1244
- const qs = params.queryString.startsWith("?") ? params.queryString.slice(1) : params.queryString;
1245
- new URLSearchParams(qs).forEach((v, k) => url.searchParams.set(k, v));
1246
- }
1247
1265
  url.searchParams.set("lmo_offer", params.skuId);
1248
1266
  url.searchParams.set("status", params.status);
1249
1267
  url.searchParams.set("redirectToCheckout", "true");
1250
- url.searchParams.set("returnUrl", params.returnUrl);
1268
+ if (params.email) url.searchParams.set("email", params.email);
1269
+ if (params.country) url.searchParams.set("country", params.country);
1251
1270
  return url.pathname + url.search;
1252
1271
  };
1253
1272
  var redirectToCheckoutFallback = (params) => {
@@ -1258,7 +1277,7 @@ var redirectToCheckoutFallback = (params) => {
1258
1277
  url.searchParams.set("inlineError", params.inlineError);
1259
1278
  if (params.email) url.searchParams.set("email", params.email);
1260
1279
  if (params.emailError) url.searchParams.set("emailError", params.emailError);
1261
- url.searchParams.set("returnUrl", params.returnUrl);
1280
+ if (params.country) url.searchParams.set("country", params.country);
1262
1281
  return url.pathname + url.search;
1263
1282
  };
1264
1283
 
@@ -1342,17 +1361,16 @@ var MSG_EMAIL_WRONG_FORMAT = "That email doesn\u2019t look right. Please enter a
1342
1361
  var MSG_EMAIL_TOO_LONG = "This field must be 80 characters or less.";
1343
1362
  var MSG_UNSUPPORTED_BILLING_COUNTRY = "Billing country does not match offer price zone";
1344
1363
  var MSG_PAYMENT_GENERIC_ERROR = "Something went wrong. Please check your payment and billing details and try again or contact us.";
1345
- var MSG_RECAPTCHA_VALIDATION_FAILED = "Security check failed. Please try again.";
1346
- var MSG_EMAIL_COLLISION = "This email address is already linked to an account. Please log in, or try a different email address.";
1347
1364
  var MSG_CONTACT_VALIDATION_INTERNAL = "Could not validate Apple Pay contact";
1348
1365
 
1349
1366
  // src/clients/payment-checkout/apple-session.ts
1350
1367
  function redirectToFallbackCheckout(config) {
1368
+ writeCheckoutRedirect(config.returnUrl);
1351
1369
  trackFallbackCheckout(config.skuId);
1352
1370
  window.location.href = redirectToCheckoutFallback({
1353
1371
  skuId: config.skuId,
1354
- returnUrl: config.returnUrl,
1355
- inlineError: MSG_PAYMENT_GENERIC_ERROR
1372
+ inlineError: MSG_PAYMENT_GENERIC_ERROR,
1373
+ country: config.countryCode
1356
1374
  });
1357
1375
  }
1358
1376
  async function handleMerchantValidation(event, session, config) {
@@ -1374,8 +1392,7 @@ async function handleMerchantValidation(event, session, config) {
1374
1392
  return;
1375
1393
  }
1376
1394
  session.completeMerchantValidation(response.merchantSession);
1377
- } catch (err) {
1378
- console.error("[web-apple-pay] onvalidatemerchant: error during validation", err);
1395
+ } catch {
1379
1396
  session.abort();
1380
1397
  redirectToFallbackCheckout(config);
1381
1398
  }
@@ -1408,8 +1425,7 @@ function startApplePaySession(config) {
1408
1425
  };
1409
1426
  trackWalletPaymentSheetOpen(config.skuId);
1410
1427
  session.begin();
1411
- } catch (err) {
1412
- console.error("[web-apple-pay] startApplePaySession: failed to create session", err);
1428
+ } catch {
1413
1429
  redirectToFallbackCheckout(config);
1414
1430
  }
1415
1431
  }
@@ -1531,8 +1547,6 @@ var shippingContactDetails = (shippingContact) => {
1531
1547
  };
1532
1548
 
1533
1549
  // src/clients/payment-checkout/payment-handler.ts
1534
- var MSG_ELIGIBILITY = "Something went wrong, please try again";
1535
- var MSG_REGISTRATION = "We couldn't create your account. Please enter your email or try a different login method.";
1536
1550
  var failApplePaySession = (session, errors = []) => {
1537
1551
  session.completePayment({
1538
1552
  status: ApplePaySession.STATUS_FAILURE,
@@ -1556,37 +1570,42 @@ function validateContacts(event, sessionData, supportedBillingCountries) {
1556
1570
  }
1557
1571
  return void 0;
1558
1572
  }
1559
- function redirectFallback(skuId, returnUrl, options) {
1573
+ function redirectFallback(skuId, returnUrl, country, options) {
1574
+ writeCheckoutRedirect(returnUrl);
1560
1575
  trackFallbackCheckout(skuId);
1561
1576
  window.location.href = redirectToCheckoutFallback({
1562
1577
  skuId,
1563
- returnUrl,
1578
+ country,
1564
1579
  ...options
1565
1580
  });
1566
1581
  }
1567
1582
  var ERROR_HANDLERS = {
1568
- EMAIL_COLLISION: ({ skuId, returnUrl, validatedEmail }) => redirectFallback(skuId, returnUrl, {
1569
- emailError: MSG_EMAIL_COLLISION,
1583
+ // emailError flows as an inline field error on the email input.
1584
+ // email pre-populates the input so the user doesn't have to retype it.
1585
+ EMAIL_COLLISION: ({ skuId, returnUrl, country, validatedEmail, walletError }) => redirectFallback(skuId, returnUrl, country, {
1586
+ emailError: walletError.message,
1570
1587
  email: validatedEmail
1571
1588
  }),
1572
- PAYMENT_DECLINED: ({ skuId, returnUrl }) => (
1573
- // Matches sma-checkout catch-all: always redirect with generic inlineError.
1574
- redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR })
1575
- ),
1576
- ELIGIBILITY_REJECTED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_ELIGIBILITY }),
1577
- REGISTRATION_FAILED: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_REGISTRATION }),
1578
- VALIDATION_ERROR: ({ skuId, returnUrl }) => redirectFallback(skuId, returnUrl, { inlineError: MSG_RECAPTCHA_VALIDATION_FAILED })
1589
+ PAYMENT_DECLINED: ({ skuId, returnUrl, country, walletError }) => redirectFallback(skuId, returnUrl, country, { inlineError: walletError.message }),
1590
+ ELIGIBILITY_REJECTED: ({ skuId, returnUrl, country, walletError }) => redirectFallback(skuId, returnUrl, country, { inlineError: walletError.message }),
1591
+ REGISTRATION_FAILED: ({ skuId, returnUrl, country, walletError }) => redirectFallback(skuId, returnUrl, country, { inlineError: walletError.message }),
1592
+ ACCOUNT_CREATION_FAILED: ({ skuId, returnUrl, country, validatedEmail, walletError }) => redirectFallback(skuId, returnUrl, country, {
1593
+ emailError: walletError.message,
1594
+ email: validatedEmail
1595
+ }),
1596
+ VALIDATION_ERROR: ({ skuId, returnUrl, country, walletError }) => redirectFallback(skuId, returnUrl, country, { inlineError: walletError.message }),
1597
+ RECAPTCHA_FAILED: ({ skuId, returnUrl, country, walletError }) => redirectFallback(skuId, returnUrl, country, { inlineError: walletError.message })
1579
1598
  };
1580
1599
  function handleStructuredError(ctx) {
1581
1600
  const handler = ERROR_HANDLERS[ctx.walletError.errorType];
1582
1601
  if (handler) {
1583
1602
  handler(ctx);
1584
1603
  } else {
1585
- redirectFallback(ctx.skuId, ctx.returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
1604
+ redirectFallback(ctx.skuId, ctx.returnUrl, ctx.country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
1586
1605
  }
1587
1606
  }
1588
1607
  async function handlePaymentAuthorized(event, session, sessionData, config) {
1589
- const { skuId, returnUrl, queryString } = config;
1608
+ const { skuId, returnUrl, country } = config;
1590
1609
  let validatedEmail;
1591
1610
  try {
1592
1611
  validatedEmail = validateContacts(
@@ -1606,28 +1625,29 @@ async function handlePaymentAuthorized(event, session, sessionData, config) {
1606
1625
  });
1607
1626
  trackWalletPaymentSuccess(skuId, result.basketId);
1608
1627
  session.completePayment({ status: ApplePaySession.STATUS_SUCCESS });
1628
+ const successEmail = sessionData.loggedIn ? sessionData.emailAddress : validatedEmail;
1609
1629
  const userStatus = sessionData.loggedIn ? "lex" : "nex";
1630
+ writeCheckoutRedirect(returnUrl);
1610
1631
  window.location.href = redirectToCheckoutComplete({
1611
1632
  basketId: result.basketId,
1612
1633
  status: userStatus,
1613
1634
  skuId: decodeSku(skuId),
1614
- returnUrl,
1615
- queryString
1635
+ email: successEmail,
1636
+ country
1616
1637
  });
1617
1638
  } catch (err) {
1618
1639
  if (err instanceof ContactValidationError) {
1619
1640
  failApplePaySession(session, err.errors);
1620
1641
  return;
1621
1642
  }
1622
- console.error("[web-apple-pay] onpaymentauthorized error", { skuId, err });
1623
1643
  const walletError = parseWalletApiError(err);
1624
1644
  trackWalletPaymentFailure(skuId, walletError?.errorType ?? "UNKNOWN");
1625
1645
  failApplePaySession(session);
1626
1646
  if (!walletError) {
1627
- redirectFallback(skuId, returnUrl, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
1647
+ redirectFallback(skuId, returnUrl, country, { inlineError: MSG_PAYMENT_GENERIC_ERROR });
1628
1648
  return;
1629
1649
  }
1630
- handleStructuredError({ skuId, returnUrl, validatedEmail, walletError });
1650
+ handleStructuredError({ skuId, returnUrl, country, validatedEmail, walletError });
1631
1651
  }
1632
1652
  }
1633
1653
 
@@ -1897,7 +1917,6 @@ var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1897
1917
  var TOTAL_LABEL = "The Economist";
1898
1918
  var DEFAULT_CURRENCY = "USD";
1899
1919
  var DEFAULT_TOTAL = "0.00";
1900
- var ERROR_INITIATE = "Failed to initiate Apple Pay session:";
1901
1920
  var SEL_CONTAINER = ".apple-pay-container";
1902
1921
  var SEL_BUTTON = ".apple-pay-btn";
1903
1922
  var APPLE_PAY_EXCLUDED_VARIANTS = [
@@ -2029,8 +2048,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2029
2048
  this.#computeBillingCountries();
2030
2049
  if (await this.#fetchAndCacheOptions()) return;
2031
2050
  this.#finishLoading();
2032
- } catch (err) {
2033
- console.error("[web-apple-pay] #run: unexpected error, hiding button", err);
2051
+ } catch {
2034
2052
  this.style.display = "none";
2035
2053
  this.querySelector(SEL_CONTAINER)?.remove();
2036
2054
  } finally {
@@ -2169,8 +2187,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2169
2187
  */
2170
2188
  #scheduleRecaptchaTokens() {
2171
2189
  const attempt = getPurchaseRecaptchaTokens();
2172
- attempt.catch((err) => {
2173
- console.error("[web-apple-pay] reCAPTCHA token pre-fetch failed; will retry on modal open", err);
2190
+ attempt.catch(() => {
2174
2191
  if (this.#recaptchaTokensPromise === attempt) {
2175
2192
  this.#recaptchaTokensPromise = null;
2176
2193
  }
@@ -2213,7 +2230,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2213
2230
  country,
2214
2231
  currency: offer.price?.currency_code ?? DEFAULT_CURRENCY,
2215
2232
  returnUrl: this.#returnUrl,
2216
- queryString: buildQueryString(),
2217
2233
  supportedBillingCountries: this.#supportedBillingCountries,
2218
2234
  recaptchaTokens
2219
2235
  })
@@ -2232,8 +2248,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2232
2248
  recaptchaTokens
2233
2249
  )
2234
2250
  );
2235
- } catch (error) {
2236
- console.error(ERROR_INITIATE, error);
2251
+ } catch {
2237
2252
  }
2238
2253
  }
2239
2254
  };
@@ -2242,6 +2257,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2242
2257
  var ApplePayEntryPoint = /* @__PURE__ */ ((ApplePayEntryPoint2) => {
2243
2258
  ApplePayEntryPoint2["PAYWALL"] = "article_paywall";
2244
2259
  ApplePayEntryPoint2["REGWALL"] = "article_regwall";
2260
+ ApplePayEntryPoint2["DUAL_OFFER_BANNER"] = "dual_offer_banner";
2245
2261
  return ApplePayEntryPoint2;
2246
2262
  })(ApplePayEntryPoint || {});
2247
2263