@economist/web-apple-pay 0.1.3-beta.41 → 0.1.3-beta.43

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
@@ -835,17 +835,12 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
835
835
  #country = "";
836
836
  #triggerElement = null;
837
837
  #keyHandler = null;
838
- #recaptchaTokens = null;
839
- #recaptchaTokensPromise = null;
838
+ #isClosed = false;
840
839
  /**
841
- * Synchronous callback invoked directly from the CTA click handler once the
842
- * user confirms. The caller (ApplePayButton) must call startApplePaySession
843
- * inside this callback to preserve the browser's user-gesture chain — Safari
844
- * requires new ApplePaySession() to execute within the original click stack.
845
- *
846
- * reCAPTCHA tokens are guaranteed non-null here: the CTA remains disabled
847
- * until the token pre-fetch resolves, so this callback is never reached
848
- * without valid tokens.
840
+ * Callback invoked from the CTA click handler once the user confirms.
841
+ * The caller (ApplePayButton) must call startApplePaySession inside this
842
+ * callback to preserve the browser's user-gesture chain — Safari requires
843
+ * new ApplePaySession() to execute within the original click stack.
849
844
  */
850
845
  onConfirm = null;
851
846
  set offer(value) {
@@ -942,28 +937,29 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
942
937
  }
943
938
  });
944
939
  }
945
- if (this.#recaptchaTokensPromise) {
946
- if (cta) {
947
- cta.setAttribute("disabled", "");
948
- cta.setAttribute("aria-disabled", "true");
949
- cta.setAttribute("aria-busy", "true");
940
+ cta?.addEventListener("click", () => {
941
+ if (cta.disabled) return;
942
+ if (isUS && checkbox && !checkbox.checked) {
943
+ errorElement?.classList.add("apm__error--visible");
944
+ checkboxLabel?.classList.add("apm__checkbox-label--error");
945
+ return;
950
946
  }
951
- this.#recaptchaTokensPromise.then((tokens) => {
952
- this.#recaptchaTokens = tokens;
953
- if (cta) {
954
- cta.removeAttribute("disabled");
955
- cta.removeAttribute("aria-disabled");
956
- cta.removeAttribute("aria-busy");
957
- }
947
+ errorElement?.classList.remove("apm__error--visible");
948
+ cta.disabled = true;
949
+ cta.setAttribute("aria-busy", "true");
950
+ getPurchaseRecaptchaTokens().then((recaptchaTokens) => {
951
+ if (this.#isClosed) return;
952
+ this.onConfirm?.(recaptchaTokens);
953
+ this.close();
958
954
  }).catch(() => {
959
- if (cta) {
960
- cta.removeAttribute("aria-busy");
961
- }
955
+ cta.disabled = false;
956
+ cta.removeAttribute("aria-busy");
962
957
  const existingError = this.querySelector("#apple-pay-modal-error");
963
958
  if (existingError) {
964
959
  const icon = existingError.querySelector("svg");
965
960
  existingError.textContent = MSG_RECAPTCHA_LOAD_ERROR;
966
961
  if (icon) existingError.prepend(icon);
962
+ existingError.setAttribute("role", "alert");
967
963
  existingError.classList.add("apm__error--visible");
968
964
  } else {
969
965
  const errorNotice = document.createElement("div");
@@ -973,25 +969,13 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
973
969
  cta?.insertAdjacentElement("beforebegin", errorNotice);
974
970
  }
975
971
  });
976
- }
977
- cta?.addEventListener("click", () => {
978
- if (isUS && checkbox && !checkbox.checked) {
979
- errorElement?.classList.add("apm__error--visible");
980
- checkboxLabel?.classList.add("apm__checkbox-label--error");
981
- return;
982
- }
983
- if (this.#recaptchaTokens) {
984
- this.onConfirm?.(this.#recaptchaTokens);
985
- this.close();
986
- }
987
972
  });
988
973
  this.querySelector("#apple-pay-modal-close")?.addEventListener(
989
974
  "click",
990
975
  () => this.close()
991
976
  );
992
977
  }
993
- open(recaptchaTokensPromise) {
994
- this.#recaptchaTokensPromise = recaptchaTokensPromise ?? getPurchaseRecaptchaTokens();
978
+ open() {
995
979
  this.#triggerElement = document.activeElement;
996
980
  document.body.appendChild(this);
997
981
  this.#keyHandler = (event) => {
@@ -1006,6 +990,7 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
1006
990
  this.querySelector("#apple-pay-modal")?.focus();
1007
991
  }
1008
992
  close() {
993
+ this.#isClosed = true;
1009
994
  if (this.#keyHandler) {
1010
995
  document.removeEventListener("keydown", this.#keyHandler, {
1011
996
  capture: true
@@ -1913,6 +1898,7 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1913
1898
  };
1914
1899
 
1915
1900
  // src/apple-pay-button.ts
1901
+ var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1916
1902
  var TOTAL_LABEL = "The Economist";
1917
1903
  var DEFAULT_CURRENCY = "USD";
1918
1904
  var DEFAULT_TOTAL = "0.00";
@@ -1928,7 +1914,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1928
1914
  define(_ApplePayButton.tag, _ApplePayButton);
1929
1915
  }
1930
1916
  /**
1931
- * Creates and configures an ApplePayButton if the offer is eligible.
1917
+ * Creates and configures an ApplePayButton if the feature flag is present.
1932
1918
  */
1933
1919
  static createIfEnabled(offer, country, entryPoint) {
1934
1920
  if (!offer) {
@@ -1937,6 +1923,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1937
1923
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
1938
1924
  return null;
1939
1925
  }
1926
+ if (!new URLSearchParams(window.location.search).has(FEATURE_APPLE_PAY_EXPRESS_CHECKOUT)) {
1927
+ return null;
1928
+ }
1940
1929
  _ApplePayButton.define();
1941
1930
  const button = document.createElement(_ApplePayButton.tag);
1942
1931
  button.offer = offer;
@@ -1965,7 +1954,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1965
1954
  #returnUrl = "";
1966
1955
  #supportedBillingCountries = [];
1967
1956
  #entryPoint = "";
1968
- #recaptchaTokensPromise = null;
1969
1957
  // ─── Public API ─────────────────────────────────────────────────────────────
1970
1958
  get offer() {
1971
1959
  return this.#offer;
@@ -2030,7 +2018,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2030
2018
  this.#paymentOptions = null;
2031
2019
  this.#returnUrl = "";
2032
2020
  this.#supportedBillingCountries = [];
2033
- this.#recaptchaTokensPromise = null;
2034
2021
  this.querySelector(SEL_CONTAINER)?.remove();
2035
2022
  }
2036
2023
  // ─── Render pipeline ────────────────────────────────────────────────────────
@@ -2043,10 +2030,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2043
2030
  this.#captureReturnUrl();
2044
2031
  this.#computeBillingCountries();
2045
2032
  if (await this.#fetchAndCacheOptions()) return;
2046
- console.log("[web-apple-pay] button shown \u2014 reason: all checks passed, Apple Pay is available and offer is eligible");
2047
2033
  this.#finishLoading();
2048
- } catch (error) {
2049
- console.warn("[web-apple-pay] button hidden \u2014 reason: unexpected error in render pipeline", error);
2034
+ } catch {
2050
2035
  this.style.display = "none";
2051
2036
  this.querySelector(SEL_CONTAINER)?.remove();
2052
2037
  } finally {
@@ -2057,7 +2042,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2057
2042
  async #checkAvailability() {
2058
2043
  const available = await isApplePayAvailable();
2059
2044
  if (!available) {
2060
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: Apple Pay unavailable on this device/browser");
2061
2045
  this.style.display = "none";
2062
2046
  this.querySelector(SEL_CONTAINER)?.remove();
2063
2047
  return true;
@@ -2071,7 +2055,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2071
2055
  async #checkSession() {
2072
2056
  this.#sessionData = await this.#fetchSession();
2073
2057
  if (this.#sessionData?.loggedIn && (this.#sessionData.userType === "active-subscription" || this.#sessionData.userType === "b2b-user")) {
2074
- console.log(`[web-apple-pay] button removed from DOM \u2014 reason: session check failed, userType="${this.#sessionData.userType}"`);
2075
2058
  this.style.display = "none";
2076
2059
  this.querySelector(SEL_CONTAINER)?.remove();
2077
2060
  return true;
@@ -2081,7 +2064,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2081
2064
  /** Returns `true` (hide) when no offer has been set before mount. */
2082
2065
  #checkOffer() {
2083
2066
  if (!this.#offer) {
2084
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: no offer set on element before mount");
2085
2067
  this.style.display = "none";
2086
2068
  this.querySelector(SEL_CONTAINER)?.remove();
2087
2069
  return true;
@@ -2109,16 +2091,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2109
2091
  */
2110
2092
  async #fetchAndCacheOptions() {
2111
2093
  this.#paymentOptions = await this.#fetchPaymentOptions();
2112
- if (!this.#paymentOptions) {
2113
- console.warn("[web-apple-pay] button removed from DOM \u2014 reason: getPaymentOptions threw an error (see previous log for details)");
2114
- this.style.display = "none";
2115
- this.querySelector(SEL_CONTAINER)?.remove();
2116
- return true;
2117
- }
2118
- if (!this.#paymentOptions.options?.apple_pay) {
2119
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: BFF responded but apple_pay is absent from payment options", {
2120
- receivedOptions: this.#paymentOptions.options
2121
- });
2094
+ if (!this.#paymentOptions?.options?.apple_pay) {
2122
2095
  this.style.display = "none";
2123
2096
  this.querySelector(SEL_CONTAINER)?.remove();
2124
2097
  return true;
@@ -2127,7 +2100,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2127
2100
  }
2128
2101
  /** Injects the button template and wires click and confirm event listeners. */
2129
2102
  #renderTemplate() {
2130
- console.log("[web-apple-pay] button shown \u2014 reason: template injected into DOM (loading state), awaiting pipeline checks");
2131
2103
  this.style.removeProperty("display");
2132
2104
  ensureApplePayLogoSymbol();
2133
2105
  const template = document.createElement("template");
@@ -2148,7 +2120,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2148
2120
  if (button) {
2149
2121
  button.classList.remove("wap-loading");
2150
2122
  this.#updateDisabledState();
2151
- this.#scheduleRecaptchaTokens();
2152
2123
  trackExpressWalletImpression(this.#offer.sku_id, {
2153
2124
  entryPoint: this.#entryPoint,
2154
2125
  country: this.#country
@@ -2187,25 +2158,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2187
2158
  const country = this.#country;
2188
2159
  modal.onConfirm = (recaptchaTokens) => {
2189
2160
  this.#initiateApplePay(skuId, country, recaptchaTokens);
2190
- this.#scheduleRecaptchaTokens();
2191
2161
  };
2192
- modal.open(this.#recaptchaTokensPromise);
2193
- }
2194
- /**
2195
- * Starts a fresh reCAPTCHA token pre-fetch and stores its promise.
2196
- * If the fetch rejects, the field is cleared so the next `modal.open()` call
2197
- * falls back to a new attempt via the modal's own null-fallback path — preventing
2198
- * a single transient failure from permanently disabling the CTA on all retries.
2199
- * The identity guard prevents a late rejection from clobbering a newer attempt.
2200
- */
2201
- #scheduleRecaptchaTokens() {
2202
- const attempt = getPurchaseRecaptchaTokens();
2203
- attempt.catch(() => {
2204
- if (this.#recaptchaTokensPromise === attempt) {
2205
- this.#recaptchaTokensPromise = null;
2206
- }
2207
- });
2208
- this.#recaptchaTokensPromise = attempt;
2162
+ modal.open();
2209
2163
  }
2210
2164
  async #fetchSession() {
2211
2165
  try {
@@ -2216,16 +2170,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2216
2170
  }
2217
2171
  async #fetchPaymentOptions() {
2218
2172
  try {
2219
- const options = await getPaymentOptions({
2173
+ return await getPaymentOptions({
2220
2174
  sku: this.#offer.sku_id,
2221
2175
  countryCode: this.#country,
2222
2176
  currencyCode: this.#offer.price?.currency_code ?? DEFAULT_CURRENCY,
2223
2177
  checkoutUrl: this.#returnUrl
2224
2178
  });
2225
- console.log("[web-apple-pay] getPaymentOptions response received", options);
2226
- return options;
2227
- } catch (error) {
2228
- console.warn("[web-apple-pay] getPaymentOptions fetch failed \u2014 returning null", error);
2179
+ } catch {
2229
2180
  return null;
2230
2181
  }
2231
2182
  }
@@ -6,7 +6,7 @@ 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 if the offer is eligible.
9
+ * Creates and configures an ApplePayButton if the feature flag is present.
10
10
  */
11
11
  static createIfEnabled(offer: Offer | undefined, country: string, entryPoint?: ApplePayEntryPoint): ApplePayButton | null;
12
12
  get offer(): Offer | null;
@@ -830,17 +830,12 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
830
830
  #country = "";
831
831
  #triggerElement = null;
832
832
  #keyHandler = null;
833
- #recaptchaTokens = null;
834
- #recaptchaTokensPromise = null;
833
+ #isClosed = false;
835
834
  /**
836
- * Synchronous callback invoked directly from the CTA click handler once the
837
- * user confirms. The caller (ApplePayButton) must call startApplePaySession
838
- * inside this callback to preserve the browser's user-gesture chain — Safari
839
- * requires new ApplePaySession() to execute within the original click stack.
840
- *
841
- * reCAPTCHA tokens are guaranteed non-null here: the CTA remains disabled
842
- * until the token pre-fetch resolves, so this callback is never reached
843
- * without valid tokens.
835
+ * Callback invoked from the CTA click handler once the user confirms.
836
+ * The caller (ApplePayButton) must call startApplePaySession inside this
837
+ * callback to preserve the browser's user-gesture chain — Safari requires
838
+ * new ApplePaySession() to execute within the original click stack.
844
839
  */
845
840
  onConfirm = null;
846
841
  set offer(value) {
@@ -937,28 +932,29 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
937
932
  }
938
933
  });
939
934
  }
940
- if (this.#recaptchaTokensPromise) {
941
- if (cta) {
942
- cta.setAttribute("disabled", "");
943
- cta.setAttribute("aria-disabled", "true");
944
- cta.setAttribute("aria-busy", "true");
935
+ cta?.addEventListener("click", () => {
936
+ if (cta.disabled) return;
937
+ if (isUS && checkbox && !checkbox.checked) {
938
+ errorElement?.classList.add("apm__error--visible");
939
+ checkboxLabel?.classList.add("apm__checkbox-label--error");
940
+ return;
945
941
  }
946
- this.#recaptchaTokensPromise.then((tokens) => {
947
- this.#recaptchaTokens = tokens;
948
- if (cta) {
949
- cta.removeAttribute("disabled");
950
- cta.removeAttribute("aria-disabled");
951
- cta.removeAttribute("aria-busy");
952
- }
942
+ errorElement?.classList.remove("apm__error--visible");
943
+ cta.disabled = true;
944
+ cta.setAttribute("aria-busy", "true");
945
+ getPurchaseRecaptchaTokens().then((recaptchaTokens) => {
946
+ if (this.#isClosed) return;
947
+ this.onConfirm?.(recaptchaTokens);
948
+ this.close();
953
949
  }).catch(() => {
954
- if (cta) {
955
- cta.removeAttribute("aria-busy");
956
- }
950
+ cta.disabled = false;
951
+ cta.removeAttribute("aria-busy");
957
952
  const existingError = this.querySelector("#apple-pay-modal-error");
958
953
  if (existingError) {
959
954
  const icon = existingError.querySelector("svg");
960
955
  existingError.textContent = MSG_RECAPTCHA_LOAD_ERROR;
961
956
  if (icon) existingError.prepend(icon);
957
+ existingError.setAttribute("role", "alert");
962
958
  existingError.classList.add("apm__error--visible");
963
959
  } else {
964
960
  const errorNotice = document.createElement("div");
@@ -968,25 +964,13 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
968
964
  cta?.insertAdjacentElement("beforebegin", errorNotice);
969
965
  }
970
966
  });
971
- }
972
- cta?.addEventListener("click", () => {
973
- if (isUS && checkbox && !checkbox.checked) {
974
- errorElement?.classList.add("apm__error--visible");
975
- checkboxLabel?.classList.add("apm__checkbox-label--error");
976
- return;
977
- }
978
- if (this.#recaptchaTokens) {
979
- this.onConfirm?.(this.#recaptchaTokens);
980
- this.close();
981
- }
982
967
  });
983
968
  this.querySelector("#apple-pay-modal-close")?.addEventListener(
984
969
  "click",
985
970
  () => this.close()
986
971
  );
987
972
  }
988
- open(recaptchaTokensPromise) {
989
- this.#recaptchaTokensPromise = recaptchaTokensPromise ?? getPurchaseRecaptchaTokens();
973
+ open() {
990
974
  this.#triggerElement = document.activeElement;
991
975
  document.body.appendChild(this);
992
976
  this.#keyHandler = (event) => {
@@ -1001,6 +985,7 @@ var ApplePayModal = class _ApplePayModal extends HTMLElement {
1001
985
  this.querySelector("#apple-pay-modal")?.focus();
1002
986
  }
1003
987
  close() {
988
+ this.#isClosed = true;
1004
989
  if (this.#keyHandler) {
1005
990
  document.removeEventListener("keydown", this.#keyHandler, {
1006
991
  capture: true
@@ -1908,6 +1893,7 @@ var getSupportedBillingCountries = (offerCountry, offerVariant) => {
1908
1893
  };
1909
1894
 
1910
1895
  // src/apple-pay-button.ts
1896
+ var FEATURE_APPLE_PAY_EXPRESS_CHECKOUT = "FEATURE_APPLE_PAY_EXPRESS_CHECKOUT";
1911
1897
  var TOTAL_LABEL = "The Economist";
1912
1898
  var DEFAULT_CURRENCY = "USD";
1913
1899
  var DEFAULT_TOTAL = "0.00";
@@ -1923,7 +1909,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1923
1909
  define(_ApplePayButton.tag, _ApplePayButton);
1924
1910
  }
1925
1911
  /**
1926
- * Creates and configures an ApplePayButton if the offer is eligible.
1912
+ * Creates and configures an ApplePayButton if the feature flag is present.
1927
1913
  */
1928
1914
  static createIfEnabled(offer, country, entryPoint) {
1929
1915
  if (!offer) {
@@ -1932,6 +1918,9 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1932
1918
  if (APPLE_PAY_EXCLUDED_VARIANTS.includes(offer.product?.variant)) {
1933
1919
  return null;
1934
1920
  }
1921
+ if (!new URLSearchParams(window.location.search).has(FEATURE_APPLE_PAY_EXPRESS_CHECKOUT)) {
1922
+ return null;
1923
+ }
1935
1924
  _ApplePayButton.define();
1936
1925
  const button = document.createElement(_ApplePayButton.tag);
1937
1926
  button.offer = offer;
@@ -1960,7 +1949,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
1960
1949
  #returnUrl = "";
1961
1950
  #supportedBillingCountries = [];
1962
1951
  #entryPoint = "";
1963
- #recaptchaTokensPromise = null;
1964
1952
  // ─── Public API ─────────────────────────────────────────────────────────────
1965
1953
  get offer() {
1966
1954
  return this.#offer;
@@ -2025,7 +2013,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2025
2013
  this.#paymentOptions = null;
2026
2014
  this.#returnUrl = "";
2027
2015
  this.#supportedBillingCountries = [];
2028
- this.#recaptchaTokensPromise = null;
2029
2016
  this.querySelector(SEL_CONTAINER)?.remove();
2030
2017
  }
2031
2018
  // ─── Render pipeline ────────────────────────────────────────────────────────
@@ -2038,10 +2025,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2038
2025
  this.#captureReturnUrl();
2039
2026
  this.#computeBillingCountries();
2040
2027
  if (await this.#fetchAndCacheOptions()) return;
2041
- console.log("[web-apple-pay] button shown \u2014 reason: all checks passed, Apple Pay is available and offer is eligible");
2042
2028
  this.#finishLoading();
2043
- } catch (error) {
2044
- console.warn("[web-apple-pay] button hidden \u2014 reason: unexpected error in render pipeline", error);
2029
+ } catch {
2045
2030
  this.style.display = "none";
2046
2031
  this.querySelector(SEL_CONTAINER)?.remove();
2047
2032
  } finally {
@@ -2052,7 +2037,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2052
2037
  async #checkAvailability() {
2053
2038
  const available = await isApplePayAvailable();
2054
2039
  if (!available) {
2055
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: Apple Pay unavailable on this device/browser");
2056
2040
  this.style.display = "none";
2057
2041
  this.querySelector(SEL_CONTAINER)?.remove();
2058
2042
  return true;
@@ -2066,7 +2050,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2066
2050
  async #checkSession() {
2067
2051
  this.#sessionData = await this.#fetchSession();
2068
2052
  if (this.#sessionData?.loggedIn && (this.#sessionData.userType === "active-subscription" || this.#sessionData.userType === "b2b-user")) {
2069
- console.log(`[web-apple-pay] button removed from DOM \u2014 reason: session check failed, userType="${this.#sessionData.userType}"`);
2070
2053
  this.style.display = "none";
2071
2054
  this.querySelector(SEL_CONTAINER)?.remove();
2072
2055
  return true;
@@ -2076,7 +2059,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2076
2059
  /** Returns `true` (hide) when no offer has been set before mount. */
2077
2060
  #checkOffer() {
2078
2061
  if (!this.#offer) {
2079
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: no offer set on element before mount");
2080
2062
  this.style.display = "none";
2081
2063
  this.querySelector(SEL_CONTAINER)?.remove();
2082
2064
  return true;
@@ -2104,16 +2086,7 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2104
2086
  */
2105
2087
  async #fetchAndCacheOptions() {
2106
2088
  this.#paymentOptions = await this.#fetchPaymentOptions();
2107
- if (!this.#paymentOptions) {
2108
- console.warn("[web-apple-pay] button removed from DOM \u2014 reason: getPaymentOptions threw an error (see previous log for details)");
2109
- this.style.display = "none";
2110
- this.querySelector(SEL_CONTAINER)?.remove();
2111
- return true;
2112
- }
2113
- if (!this.#paymentOptions.options?.apple_pay) {
2114
- console.log("[web-apple-pay] button removed from DOM \u2014 reason: BFF responded but apple_pay is absent from payment options", {
2115
- receivedOptions: this.#paymentOptions.options
2116
- });
2089
+ if (!this.#paymentOptions?.options?.apple_pay) {
2117
2090
  this.style.display = "none";
2118
2091
  this.querySelector(SEL_CONTAINER)?.remove();
2119
2092
  return true;
@@ -2122,7 +2095,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2122
2095
  }
2123
2096
  /** Injects the button template and wires click and confirm event listeners. */
2124
2097
  #renderTemplate() {
2125
- console.log("[web-apple-pay] button shown \u2014 reason: template injected into DOM (loading state), awaiting pipeline checks");
2126
2098
  this.style.removeProperty("display");
2127
2099
  ensureApplePayLogoSymbol();
2128
2100
  const template = document.createElement("template");
@@ -2143,7 +2115,6 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2143
2115
  if (button) {
2144
2116
  button.classList.remove("wap-loading");
2145
2117
  this.#updateDisabledState();
2146
- this.#scheduleRecaptchaTokens();
2147
2118
  trackExpressWalletImpression(this.#offer.sku_id, {
2148
2119
  entryPoint: this.#entryPoint,
2149
2120
  country: this.#country
@@ -2182,25 +2153,8 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2182
2153
  const country = this.#country;
2183
2154
  modal.onConfirm = (recaptchaTokens) => {
2184
2155
  this.#initiateApplePay(skuId, country, recaptchaTokens);
2185
- this.#scheduleRecaptchaTokens();
2186
2156
  };
2187
- modal.open(this.#recaptchaTokensPromise);
2188
- }
2189
- /**
2190
- * Starts a fresh reCAPTCHA token pre-fetch and stores its promise.
2191
- * If the fetch rejects, the field is cleared so the next `modal.open()` call
2192
- * falls back to a new attempt via the modal's own null-fallback path — preventing
2193
- * a single transient failure from permanently disabling the CTA on all retries.
2194
- * The identity guard prevents a late rejection from clobbering a newer attempt.
2195
- */
2196
- #scheduleRecaptchaTokens() {
2197
- const attempt = getPurchaseRecaptchaTokens();
2198
- attempt.catch(() => {
2199
- if (this.#recaptchaTokensPromise === attempt) {
2200
- this.#recaptchaTokensPromise = null;
2201
- }
2202
- });
2203
- this.#recaptchaTokensPromise = attempt;
2157
+ modal.open();
2204
2158
  }
2205
2159
  async #fetchSession() {
2206
2160
  try {
@@ -2211,16 +2165,13 @@ var ApplePayButton = class _ApplePayButton extends HTMLElement {
2211
2165
  }
2212
2166
  async #fetchPaymentOptions() {
2213
2167
  try {
2214
- const options = await getPaymentOptions({
2168
+ return await getPaymentOptions({
2215
2169
  sku: this.#offer.sku_id,
2216
2170
  countryCode: this.#country,
2217
2171
  currencyCode: this.#offer.price?.currency_code ?? DEFAULT_CURRENCY,
2218
2172
  checkoutUrl: this.#returnUrl
2219
2173
  });
2220
- console.log("[web-apple-pay] getPaymentOptions response received", options);
2221
- return options;
2222
- } catch (error) {
2223
- console.warn("[web-apple-pay] getPaymentOptions fetch failed \u2014 returning null", error);
2174
+ } catch {
2224
2175
  return null;
2225
2176
  }
2226
2177
  }