@amos.com/amos-js 0.7.0 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Create (or return existing) full-viewport waiting UI on the host page while
3
+ * Apple Pay Code runs in a separate window. Cancel invokes `onCancel`.
4
+ */
5
+ export declare function showApplePayWaitingOverlay({ onCancel, }: {
6
+ onCancel: () => void;
7
+ }): HTMLElement;
8
+ /** Remove the host-page Apple Pay waiting overlay if present. */
9
+ export declare function hideApplePayWaitingOverlay(): void;
@@ -74,8 +74,8 @@ export type ApplePayButtonController = {
74
74
  * correct `src` (see {@link getApplePayButtonSrc}).
75
75
  *
76
76
  * The Apple Pay button and `ApplePaySession` run inside the Amos embed
77
- * iframe (so only Amos domains need Apple merchant registration). On
78
- * non-Safari browsers, the embed opens Apple's QR handoff in a popup
79
- * (`pay.apple.com`) rather than expanding this iframe.
77
+ * iframe so only Amos domains need Apple merchant registration. While
78
+ * Apple Pay Code is open in a separate window, this host paints a
79
+ * waiting overlay and can cancel via {@link Message} `APPLE_PAY_CANCEL`.
80
80
  */
81
81
  export declare function attachApplePayButtonListeners(iframe: HTMLIFrameElement, options: ApplePayButtonListenerOptions): ApplePayButtonController;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){let[t=``,n=``,r=``]=e?.split(`.`)??[],i=typeof atob==`function`?atob:e=>Buffer.from(e,`base64`).toString(`utf8`);return{header:JSON.parse(i(t)),payload:JSON.parse(i(n)),signature:r}}function t(t){let{env:n=`sandbox`}=e(t).payload;switch(n){case`production`:return`https://embed.amos.com`;case`sandbox`:return`https://embed-sandbox.amos.com`;default:return`https://embed-sandbox.amos.com`}}function n(e){return e}function r(e){e?.contentWindow?.postMessage(n({type:`PARENT_ACKNOWLEDGED_IFRAME_READY`}),`*`)}function i({iframe:e,appearance:t={}}){e?.contentWindow?.postMessage(n({type:`UPDATE_APPEARANCE`,appearance:t}),`*`)}function a({iframe:e,amount:t}){e?.contentWindow?.postMessage(n({type:`UPDATE_AMOUNT`,amount:t}),`*`)}function o({iframe:e,merchantName:t}){e?.contentWindow?.postMessage(n({type:`UPDATE_MERCHANT_NAME`,merchantName:t}),`*`)}function s({iframe:e}){let t=crypto.randomUUID();return new Promise(r=>{e?.contentWindow?.postMessage(n({type:`VALIDATE_FORM`,requestId:t}),`*`);let i=setTimeout(()=>{window.removeEventListener(`message`,a),r(!1)},5e3);function a(e){e.data.type===`VALIDATE_FORM`&&e.data.requestId===t&&(window.removeEventListener(`message`,a),clearTimeout(i),r(e.data.isValid??!1))}window.addEventListener(`message`,a)})}function c({iframe:t,token:r}){let{payment_intent_id:i}=e(r).payload;t?.contentWindow?.postMessage(n({type:`CONFIRM_PAYMENT_INTENT`,token:r,id:i??void 0}),`*`)}function l({iframe:t,token:r}){let{setup_intent_id:i}=e(r).payload;t?.contentWindow?.postMessage(n({type:`CONFIRM_SETUP_INTENT`,token:r,id:i??void 0}),`*`)}function u({iframe:e,errorMessage:t}){e?.contentWindow?.postMessage(n({type:`CONFIRMATION_FAILED`,errorMessage:t}),`*`)}function d(e){return`${t(e)}/iframe/apple-pay?token=${e}`}function f(){return`40px`}function p(e,t){let n={...t};function s(){a({iframe:e,amount:n.amount})}function l(){o({iframe:e,merchantName:n.merchantName})}function d(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:r(e),i({iframe:e,appearance:n.appearance}),s(),l();break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:i({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`CREATE_PAYMENT_INTENT`:n.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{c({iframe:e,token:t})}).catch(t=>{u({iframe:e,errorMessage:t instanceof Error?t.message:`Unknown error`})});break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n.onPaymentIntentConfirmationSucceeded(t.data.paymentIntent);break;case`CONFIRMATION_FAILED`:n.onConfirmationFailed(t.data.errorMessage);break}}return window.addEventListener(`message`,d),{update(t){let r=`appearance`in t,a=`amount`in t,o=`merchantName`in t;n={...n,...t},r&&i({iframe:e,appearance:n.appearance}),a&&s(),o&&l()},destroy(){window.removeEventListener(`message`,d)}}}function m(e){return`${t(e)}/iframe/google-pay?token=${e}`}function h(){return`40px`}function g(e,t){let n={...t};function s(){a({iframe:e,amount:n.amount})}function l(){o({iframe:e,merchantName:n.merchantName})}function d(t){switch(t.data.type){case`IFRAME_READY`:r(e),i({iframe:e,appearance:n.appearance}),s(),l();break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:i({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`CREATE_PAYMENT_INTENT`:n.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{c({iframe:e,token:t})}).catch(t=>{u({iframe:e,errorMessage:t instanceof Error?t.message:`Unknown error`})});break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n.onPaymentIntentConfirmationSucceeded(t.data.paymentIntent);break;case`CONFIRMATION_FAILED`:n.onConfirmationFailed(t.data.errorMessage);break}}return window.addEventListener(`message`,d),{update(t){let r=`appearance`in t,a=`amount`in t,o=`merchantName`in t;n={...n,...t},r&&i({iframe:e,appearance:n.appearance}),a&&s(),o&&l()},destroy(){window.removeEventListener(`message`,d)}}}function _({paymentData:e}){return{paymentMethod:{type:`googlepay`,billing_address_attributes:{name:e.shippingAddress?.name,address_line1:e.shippingAddress?.address1,address_line2:e.shippingAddress?.address2,city:e.shippingAddress?.locality,state:e.shippingAddress?.administrativeArea,postal_code:e.shippingAddress?.postalCode,country:e.shippingAddress?.countryCode,email:e.email,phone:e.shippingAddress?.phoneNumber},card_profile_attributes:{wallet_provider:`googlepay`,wallet_payload:e.paymentMethodData.tokenizationData.token,wallet_last4:e.paymentMethodData.info?.cardDetails,wallet_brand:(()=>{switch(e.paymentMethodData.info?.cardNetwork){case`AMEX`:return`american_express`;case`VISA`:return`visa`;case`MASTERCARD`:return`master`;case`DISCOVER`:return`discover`;default:return}})()}}}}var v={country:212,full:452},y=80,b={country:400,full:640};function x(e,n={cardholderName:!1},r=`country`){let i=Object.entries(n).filter(([,e])=>e).map(([e])=>e).join(`,`),a=new URLSearchParams({token:e,additionalFields:i,billingAddressRequirement:r});return`${t(e)}/iframe/card?${a}`}function S(e,n=`country`){let r=new URLSearchParams({token:e,billingAddressRequirement:n});return`${t(e)}/iframe/bank?${r}`}function C(e={cardholderName:!1},t=`country`){return`${(v[t]??v.country)+(e.cardholderName?y:0)}px`}function w(e=`country`){return`${b[e]??b.country}px`}function T(e,t){let n={...t};function a(t){switch(t.data.type){case`IFRAME_READY`:r(e),i({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:i({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n.onPaymentIntentConfirmationSucceeded?.(t.data.paymentIntent);break;case`SETUP_INTENT_CONFIRMATION_SUCCEEDED`:n.onSetupIntentConfirmationSucceeded?.(t.data.setupIntent);break;case`CONFIRMATION_FAILED`:n.onConfirmationFailed(t.data.errorMessage);break}}return window.addEventListener(`message`,a),{update(t){let r=`appearance`in t;n={...n,...t},r&&i({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,a)}}}function E(e){if(typeof e==`string`){let t=document.querySelector(e);if(!(t instanceof HTMLElement))throw Error(`[amos-js] Container "${e}" did not match any HTMLElement.`);return t}return e}var D={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`};function O({src:e,title:t,name:n,height:r,allow:i}){let a=document.createElement(`iframe`);return a.src=e,a.title=t,a.name=n,a.setAttribute(`role`,`presentation`),a.scrolling=`no`,i&&(a.allow=i),Object.assign(a.style,D,{height:r}),a}function k(e,t){let n=E(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t,s=O({src:x(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:C(i,a)});n.appendChild(s);let c=T(s,{...o,onHeightChange:e=>{s.style.height=e,o.onHeightChange?.(e)},onAppearanceReady:()=>{s.style.opacity=`1`,o.onAppearanceReady?.()}});return{iframe:s,update:c.update,destroy(){c.destroy(),s.remove()}}}function A(e,t){let n=E(e),{renderToken:r,billingAddressRequirement:i=`country`,...a}=t,o=O({src:S(r,i),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:w(i)});n.appendChild(o);let s=T(o,{...a,onHeightChange:e=>{o.style.height=e,a.onHeightChange?.(e)},onAppearanceReady:()=>{o.style.opacity=`1`,a.onAppearanceReady?.()}});return{iframe:o,update:s.update,destroy(){s.destroy(),o.remove()}}}function j(e,t){let n=E(e),{renderToken:r,...i}=t,a=O({src:m(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:h(),allow:`payment`});n.appendChild(a);let o=g(a,{...i,onHeightChange:e=>{a.style.height=e,i.onHeightChange?.(e)},onAppearanceReady:()=>{a.style.opacity=`1`,i.onAppearanceReady?.()}});return{iframe:a,update:o.update,destroy(){o.destroy(),a.remove()}}}function M(e,t){let n=E(e),{renderToken:r,...i}=t,a=O({src:d(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:f(),allow:`payment`});n.appendChild(a);let o=p(a,{...i,onHeightChange:e=>{a.style.height=e,i.onHeightChange?.(e)},onAppearanceReady:()=>{a.style.opacity=`1`,i.onAppearanceReady?.()}});return{iframe:a,update:o.update,destroy(){o.destroy(),a.remove()}}}exports.attachApplePayButtonListeners=p,exports.attachGooglePayButtonListeners=g,exports.attachPaymentMethodFormListeners=T,exports.confirmPaymentIntent=c,exports.confirmSetupIntent=l,exports.createMessage=n,exports.decodeJwt=e,exports.formatGooglePayPaymentData=_,exports.getApplePayButtonInitialHeight=f,exports.getApplePayButtonSrc=d,exports.getBankAccountFormInitialHeight=w,exports.getBankAccountFormSrc=S,exports.getCreditCardFormInitialHeight=C,exports.getCreditCardFormSrc=x,exports.getEmbedOrigin=t,exports.getGooglePayButtonInitialHeight=h,exports.getGooglePayButtonSrc=m,exports.mountAmosApplePayButton=M,exports.mountAmosBankAccountPaymentMethodForm=A,exports.mountAmosCreditCardPaymentMethodForm=k,exports.mountAmosGooglePayButton=j,exports.sendConfirmationFailed=u,exports.sendParentReadyMessage=r,exports.updateAmount=a,exports.updateAppearance=i,exports.updateMerchantName=o,exports.validateForm=s;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`data-amos-apple-pay-waiting`;function t({onCancel:t}){let n=document.querySelector(`[${e}]`);if(n)return n;let r=document.createElement(`div`);r.setAttribute(e,`true`),r.setAttribute(`role`,`dialog`),r.setAttribute(`aria-modal`,`true`),r.setAttribute(`aria-labelledby`,`amos-apple-pay-waiting-title`),Object.assign(r.style,{position:`fixed`,inset:`0`,zIndex:`2147483646`,display:`flex`,alignItems:`center`,justifyContent:`center`,padding:`24px`,boxSizing:`border-box`,background:`rgba(0, 0, 0, 0.55)`,fontFamily:`-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`});let i=document.createElement(`div`);Object.assign(i.style,{width:`100%`,maxWidth:`360px`,borderRadius:`12px`,background:`#fff`,padding:`28px 24px 20px`,boxSizing:`border-box`,textAlign:`center`,boxShadow:`0 12px 40px rgba(0, 0, 0, 0.25)`});let a=document.createElement(`div`);a.setAttribute(`aria-hidden`,`true`),Object.assign(a.style,{display:`inline-flex`,alignItems:`center`,justifyContent:`center`,gap:`6px`,marginBottom:`16px`,fontSize:`28px`,fontWeight:`600`,letterSpacing:`-0.02em`,color:`#000`,lineHeight:`1`}),a.innerHTML=`<svg width="22" height="26" viewBox="0 0 14 17" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M13.072 5.846c-.1.08-1.873 1.09-1.873 3.34 0 2.61 2.29 3.53 2.36 3.55-.04.1-.368 1.27-.766 2.52-.35 1.09-.72 2.18-1.28 2.18-.55 0-.73-.36-1.43-.36-.71 0-.93.37-1.48.37-.55 0-.93-.99-1.35-2.01-.5-1.2-.88-2.43-.88-3.85 0-2.26 1.47-3.46 2.91-3.46.57 0 1.11.38 1.49.38.37 0 .98-.45 1.7-.45.28 0 1.27.03 1.97 1.01ZM9.52 3.37c.3-.36.52-.86.52-1.36 0-.07 0-.14-.01-.2-.5.02-1.1.33-1.46.75-.28.32-.55.84-.55 1.35 0 .07.01.15.02.17.04.01.1.02.16.02.45 0 1.02-.3 1.32-.73Z"/></svg><span>Pay</span>`;let o=document.createElement(`p`);o.id=`amos-apple-pay-waiting-title`,Object.assign(o.style,{margin:`0 0 20px`,fontSize:`15px`,lineHeight:`1.45`,color:`#1a1a1a`}),o.textContent=`Complete your payment in the open Apple Pay window, or close Apple Pay to continue paying another way.`;let s=document.createElement(`button`);return s.type=`button`,s.textContent=`Cancel payment`,Object.assign(s.style,{display:`block`,width:`100%`,border:`none`,borderRadius:`8px`,padding:`12px 16px`,background:`#2c2c2e`,color:`#fff`,fontSize:`15px`,fontWeight:`500`,cursor:`pointer`}),s.addEventListener(`click`,t),i.append(a,o,s),r.append(i),document.body.append(r),r}function n(){document.querySelector(`[${e}]`)?.remove()}function r(e){let[t=``,n=``,r=``]=e?.split(`.`)??[],i=typeof atob==`function`?atob:e=>Buffer.from(e,`base64`).toString(`utf8`);return{header:JSON.parse(i(t)),payload:JSON.parse(i(n)),signature:r}}function i(e){let{env:t=`sandbox`}=r(e).payload;switch(t){case`production`:return`https://embed.amos.com`;case`sandbox`:return`https://embed-sandbox.amos.com`;default:return`https://embed-sandbox.amos.com`}}function a(e){return e}function o(e){e?.contentWindow?.postMessage(a({type:`PARENT_ACKNOWLEDGED_IFRAME_READY`}),`*`)}function s({iframe:e,appearance:t={}}){e?.contentWindow?.postMessage(a({type:`UPDATE_APPEARANCE`,appearance:t}),`*`)}function c({iframe:e,amount:t}){e?.contentWindow?.postMessage(a({type:`UPDATE_AMOUNT`,amount:t}),`*`)}function l({iframe:e,merchantName:t}){e?.contentWindow?.postMessage(a({type:`UPDATE_MERCHANT_NAME`,merchantName:t}),`*`)}function u({iframe:e}){let t=crypto.randomUUID();return new Promise(n=>{e?.contentWindow?.postMessage(a({type:`VALIDATE_FORM`,requestId:t}),`*`);let r=setTimeout(()=>{window.removeEventListener(`message`,i),n(!1)},5e3);function i(e){e.data.type===`VALIDATE_FORM`&&e.data.requestId===t&&(window.removeEventListener(`message`,i),clearTimeout(r),n(e.data.isValid??!1))}window.addEventListener(`message`,i)})}function d({iframe:e,token:t}){let{payment_intent_id:n}=r(t).payload;e?.contentWindow?.postMessage(a({type:`CONFIRM_PAYMENT_INTENT`,token:t,id:n??void 0}),`*`)}function f({iframe:e,token:t}){let{setup_intent_id:n}=r(t).payload;e?.contentWindow?.postMessage(a({type:`CONFIRM_SETUP_INTENT`,token:t,id:n??void 0}),`*`)}function p({iframe:e,errorMessage:t}){e?.contentWindow?.postMessage(a({type:`CONFIRMATION_FAILED`,errorMessage:t}),`*`)}function m(e){return`${i(e)}/iframe/apple-pay?token=${e}`}function h(){return`40px`}function g(e){e.contentWindow?.postMessage(a({type:`APPLE_PAY_CANCEL`}),`*`)}function _(e,r){let i={...r};function a(){c({iframe:e,amount:i.amount})}function u(){l({iframe:e,merchantName:i.merchantName})}function f(r){if(r.source===e.contentWindow)switch(r.data.type){case`IFRAME_READY`:o(e),s({iframe:e,appearance:i.appearance}),a(),u();break;case`UPDATE_HEIGHT`:i.onHeightChange?.(r.data.height);break;case`UPDATE_APPEARANCE`:s({iframe:e,appearance:r.data.appearance});break;case`UPDATED_APPEARANCE`:i.onAppearanceReady?.();break;case`APPLE_PAY_WINDOW_OPEN`:t({onCancel:()=>{g(e),n()}});break;case`APPLE_PAY_WINDOW_CLOSE`:n();break;case`CREATE_PAYMENT_INTENT`:i.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:r.data.paymentIntentCreateAttributes,customerCreateAttributes:r.data.customerCreateAttributes}).then(t=>{d({iframe:e,token:t})}).catch(t=>{p({iframe:e,errorMessage:t instanceof Error?t.message:`Unknown error`})});break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n(),i.onPaymentIntentConfirmationSucceeded(r.data.paymentIntent);break;case`CONFIRMATION_FAILED`:n(),i.onConfirmationFailed(r.data.errorMessage);break}}return window.addEventListener(`message`,f),{update(t){let n=`appearance`in t,r=`amount`in t,o=`merchantName`in t;i={...i,...t},n&&s({iframe:e,appearance:i.appearance}),r&&a(),o&&u()},destroy(){window.removeEventListener(`message`,f),n()}}}function v(e){return`${i(e)}/iframe/google-pay?token=${e}`}function y(){return`40px`}function b(e,t){let n={...t};function r(){c({iframe:e,amount:n.amount})}function i(){l({iframe:e,merchantName:n.merchantName})}function a(t){switch(t.data.type){case`IFRAME_READY`:o(e),s({iframe:e,appearance:n.appearance}),r(),i();break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:s({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`CREATE_PAYMENT_INTENT`:n.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{d({iframe:e,token:t})}).catch(t=>{p({iframe:e,errorMessage:t instanceof Error?t.message:`Unknown error`})});break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n.onPaymentIntentConfirmationSucceeded(t.data.paymentIntent);break;case`CONFIRMATION_FAILED`:n.onConfirmationFailed(t.data.errorMessage);break}}return window.addEventListener(`message`,a),{update(t){let a=`appearance`in t,o=`amount`in t,c=`merchantName`in t;n={...n,...t},a&&s({iframe:e,appearance:n.appearance}),o&&r(),c&&i()},destroy(){window.removeEventListener(`message`,a)}}}function x({paymentData:e}){return{paymentMethod:{type:`googlepay`,billing_address_attributes:{name:e.shippingAddress?.name,address_line1:e.shippingAddress?.address1,address_line2:e.shippingAddress?.address2,city:e.shippingAddress?.locality,state:e.shippingAddress?.administrativeArea,postal_code:e.shippingAddress?.postalCode,country:e.shippingAddress?.countryCode,email:e.email,phone:e.shippingAddress?.phoneNumber},card_profile_attributes:{wallet_provider:`googlepay`,wallet_payload:e.paymentMethodData.tokenizationData.token,wallet_last4:e.paymentMethodData.info?.cardDetails,wallet_brand:(()=>{switch(e.paymentMethodData.info?.cardNetwork){case`AMEX`:return`american_express`;case`VISA`:return`visa`;case`MASTERCARD`:return`master`;case`DISCOVER`:return`discover`;default:return}})()}}}}var S={country:212,full:452},C=80,w={country:400,full:640};function T(e,t={cardholderName:!1},n=`country`){let r=Object.entries(t).filter(([,e])=>e).map(([e])=>e).join(`,`),a=new URLSearchParams({token:e,additionalFields:r,billingAddressRequirement:n});return`${i(e)}/iframe/card?${a}`}function E(e,t=`country`){let n=new URLSearchParams({token:e,billingAddressRequirement:t});return`${i(e)}/iframe/bank?${n}`}function D(e={cardholderName:!1},t=`country`){return`${(S[t]??S.country)+(e.cardholderName?C:0)}px`}function O(e=`country`){return`${w[e]??w.country}px`}function k(e,t){let n={...t};function r(t){switch(t.data.type){case`IFRAME_READY`:o(e),s({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:s({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`PAYMENT_INTENT_CONFIRMATION_SUCCEEDED`:n.onPaymentIntentConfirmationSucceeded?.(t.data.paymentIntent);break;case`SETUP_INTENT_CONFIRMATION_SUCCEEDED`:n.onSetupIntentConfirmationSucceeded?.(t.data.setupIntent);break;case`CONFIRMATION_FAILED`:n.onConfirmationFailed(t.data.errorMessage);break}}return window.addEventListener(`message`,r),{update(t){let r=`appearance`in t;n={...n,...t},r&&s({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,r)}}}function A(e){if(typeof e==`string`){let t=document.querySelector(e);if(!(t instanceof HTMLElement))throw Error(`[amos-js] Container "${e}" did not match any HTMLElement.`);return t}return e}var j={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`};function M({src:e,title:t,name:n,height:r,allow:i}){let a=document.createElement(`iframe`);return a.src=e,a.title=t,a.name=n,a.setAttribute(`role`,`presentation`),a.scrolling=`no`,i&&(a.allow=i),Object.assign(a.style,j,{height:r}),a}function N(e,t){let n=A(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t,s=M({src:T(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:D(i,a)});n.appendChild(s);let c=k(s,{...o,onHeightChange:e=>{s.style.height=e,o.onHeightChange?.(e)},onAppearanceReady:()=>{s.style.opacity=`1`,o.onAppearanceReady?.()}});return{iframe:s,update:c.update,destroy(){c.destroy(),s.remove()}}}function P(e,t){let n=A(e),{renderToken:r,billingAddressRequirement:i=`country`,...a}=t,o=M({src:E(r,i),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:O(i)});n.appendChild(o);let s=k(o,{...a,onHeightChange:e=>{o.style.height=e,a.onHeightChange?.(e)},onAppearanceReady:()=>{o.style.opacity=`1`,a.onAppearanceReady?.()}});return{iframe:o,update:s.update,destroy(){s.destroy(),o.remove()}}}function F(e,t){let n=A(e),{renderToken:r,...i}=t,a=M({src:v(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:y(),allow:`payment`});n.appendChild(a);let o=b(a,{...i,onHeightChange:e=>{a.style.height=e,i.onHeightChange?.(e)},onAppearanceReady:()=>{a.style.opacity=`1`,i.onAppearanceReady?.()}});return{iframe:a,update:o.update,destroy(){o.destroy(),a.remove()}}}function I(e,t){let n=A(e),{renderToken:r,...i}=t,a=M({src:m(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:h(),allow:`payment`});n.appendChild(a);let o=_(a,{...i,onHeightChange:e=>{a.style.height=e,i.onHeightChange?.(e)},onAppearanceReady:()=>{a.style.opacity=`1`,i.onAppearanceReady?.()}});return{iframe:a,update:o.update,destroy(){o.destroy(),a.remove()}}}exports.attachApplePayButtonListeners=_,exports.attachGooglePayButtonListeners=b,exports.attachPaymentMethodFormListeners=k,exports.confirmPaymentIntent=d,exports.confirmSetupIntent=f,exports.createMessage=a,exports.decodeJwt=r,exports.formatGooglePayPaymentData=x,exports.getApplePayButtonInitialHeight=h,exports.getApplePayButtonSrc=m,exports.getBankAccountFormInitialHeight=O,exports.getBankAccountFormSrc=E,exports.getCreditCardFormInitialHeight=D,exports.getCreditCardFormSrc=T,exports.getEmbedOrigin=i,exports.getGooglePayButtonInitialHeight=y,exports.getGooglePayButtonSrc=v,exports.mountAmosApplePayButton=I,exports.mountAmosBankAccountPaymentMethodForm=P,exports.mountAmosCreditCardPaymentMethodForm=N,exports.mountAmosGooglePayButton=F,exports.sendConfirmationFailed=p,exports.sendParentReadyMessage=o,exports.updateAmount=c,exports.updateAppearance=s,exports.updateMerchantName=l,exports.validateForm=u;
package/dist/index.mjs CHANGED
@@ -1,5 +1,72 @@
1
+ //#region src/apple-pay-waiting-overlay.ts
2
+ var e = "data-amos-apple-pay-waiting";
3
+ function t({ onCancel: t }) {
4
+ let n = document.querySelector(`[${e}]`);
5
+ if (n) return n;
6
+ let r = document.createElement("div");
7
+ r.setAttribute(e, "true"), r.setAttribute("role", "dialog"), r.setAttribute("aria-modal", "true"), r.setAttribute("aria-labelledby", "amos-apple-pay-waiting-title"), Object.assign(r.style, {
8
+ position: "fixed",
9
+ inset: "0",
10
+ zIndex: "2147483646",
11
+ display: "flex",
12
+ alignItems: "center",
13
+ justifyContent: "center",
14
+ padding: "24px",
15
+ boxSizing: "border-box",
16
+ background: "rgba(0, 0, 0, 0.55)",
17
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif"
18
+ });
19
+ let i = document.createElement("div");
20
+ Object.assign(i.style, {
21
+ width: "100%",
22
+ maxWidth: "360px",
23
+ borderRadius: "12px",
24
+ background: "#fff",
25
+ padding: "28px 24px 20px",
26
+ boxSizing: "border-box",
27
+ textAlign: "center",
28
+ boxShadow: "0 12px 40px rgba(0, 0, 0, 0.25)"
29
+ });
30
+ let a = document.createElement("div");
31
+ a.setAttribute("aria-hidden", "true"), Object.assign(a.style, {
32
+ display: "inline-flex",
33
+ alignItems: "center",
34
+ justifyContent: "center",
35
+ gap: "6px",
36
+ marginBottom: "16px",
37
+ fontSize: "28px",
38
+ fontWeight: "600",
39
+ letterSpacing: "-0.02em",
40
+ color: "#000",
41
+ lineHeight: "1"
42
+ }), a.innerHTML = "<svg width=\"22\" height=\"26\" viewBox=\"0 0 14 17\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.072 5.846c-.1.08-1.873 1.09-1.873 3.34 0 2.61 2.29 3.53 2.36 3.55-.04.1-.368 1.27-.766 2.52-.35 1.09-.72 2.18-1.28 2.18-.55 0-.73-.36-1.43-.36-.71 0-.93.37-1.48.37-.55 0-.93-.99-1.35-2.01-.5-1.2-.88-2.43-.88-3.85 0-2.26 1.47-3.46 2.91-3.46.57 0 1.11.38 1.49.38.37 0 .98-.45 1.7-.45.28 0 1.27.03 1.97 1.01ZM9.52 3.37c.3-.36.52-.86.52-1.36 0-.07 0-.14-.01-.2-.5.02-1.1.33-1.46.75-.28.32-.55.84-.55 1.35 0 .07.01.15.02.17.04.01.1.02.16.02.45 0 1.02-.3 1.32-.73Z\"/></svg><span>Pay</span>";
43
+ let o = document.createElement("p");
44
+ o.id = "amos-apple-pay-waiting-title", Object.assign(o.style, {
45
+ margin: "0 0 20px",
46
+ fontSize: "15px",
47
+ lineHeight: "1.45",
48
+ color: "#1a1a1a"
49
+ }), o.textContent = "Complete your payment in the open Apple Pay window, or close Apple Pay to continue paying another way.";
50
+ let s = document.createElement("button");
51
+ return s.type = "button", s.textContent = "Cancel payment", Object.assign(s.style, {
52
+ display: "block",
53
+ width: "100%",
54
+ border: "none",
55
+ borderRadius: "8px",
56
+ padding: "12px 16px",
57
+ background: "#2c2c2e",
58
+ color: "#fff",
59
+ fontSize: "15px",
60
+ fontWeight: "500",
61
+ cursor: "pointer"
62
+ }), s.addEventListener("click", t), i.append(a, o, s), r.append(i), document.body.append(r), r;
63
+ }
64
+ function n() {
65
+ document.querySelector(`[${e}]`)?.remove();
66
+ }
67
+ //#endregion
1
68
  //#region src/jwt.ts
2
- function e(e) {
69
+ function r(e) {
3
70
  let [t = "", n = "", r = ""] = e?.split(".") ?? [], i = typeof atob == "function" ? atob : (e) => Buffer.from(e, "base64").toString("utf8");
4
71
  return {
5
72
  header: JSON.parse(i(t)),
@@ -7,9 +74,9 @@ function e(e) {
7
74
  signature: r
8
75
  };
9
76
  }
10
- function t(t) {
11
- let { env: n = "sandbox" } = e(t).payload;
12
- switch (n) {
77
+ function i(e) {
78
+ let { env: t = "sandbox" } = r(e).payload;
79
+ switch (t) {
13
80
  case "production": return "https://embed.amos.com";
14
81
  case "sandbox": return "https://embed-sandbox.amos.com";
15
82
  default: return "https://embed-sandbox.amos.com";
@@ -17,187 +84,198 @@ function t(t) {
17
84
  }
18
85
  //#endregion
19
86
  //#region src/types.ts
20
- function n(e) {
87
+ function a(e) {
21
88
  return e;
22
89
  }
23
90
  //#endregion
24
91
  //#region src/messaging.ts
25
- function r(e) {
26
- e?.contentWindow?.postMessage(n({ type: "PARENT_ACKNOWLEDGED_IFRAME_READY" }), "*");
92
+ function o(e) {
93
+ e?.contentWindow?.postMessage(a({ type: "PARENT_ACKNOWLEDGED_IFRAME_READY" }), "*");
27
94
  }
28
- function i({ iframe: e, appearance: t = {} }) {
29
- e?.contentWindow?.postMessage(n({
95
+ function s({ iframe: e, appearance: t = {} }) {
96
+ e?.contentWindow?.postMessage(a({
30
97
  type: "UPDATE_APPEARANCE",
31
98
  appearance: t
32
99
  }), "*");
33
100
  }
34
- function a({ iframe: e, amount: t }) {
35
- e?.contentWindow?.postMessage(n({
101
+ function c({ iframe: e, amount: t }) {
102
+ e?.contentWindow?.postMessage(a({
36
103
  type: "UPDATE_AMOUNT",
37
104
  amount: t
38
105
  }), "*");
39
106
  }
40
- function o({ iframe: e, merchantName: t }) {
41
- e?.contentWindow?.postMessage(n({
107
+ function l({ iframe: e, merchantName: t }) {
108
+ e?.contentWindow?.postMessage(a({
42
109
  type: "UPDATE_MERCHANT_NAME",
43
110
  merchantName: t
44
111
  }), "*");
45
112
  }
46
- function s({ iframe: e }) {
113
+ function u({ iframe: e }) {
47
114
  let t = crypto.randomUUID();
48
- return new Promise((r) => {
49
- e?.contentWindow?.postMessage(n({
115
+ return new Promise((n) => {
116
+ e?.contentWindow?.postMessage(a({
50
117
  type: "VALIDATE_FORM",
51
118
  requestId: t
52
119
  }), "*");
53
- let i = setTimeout(() => {
54
- window.removeEventListener("message", a), r(!1);
120
+ let r = setTimeout(() => {
121
+ window.removeEventListener("message", i), n(!1);
55
122
  }, 5e3);
56
- function a(e) {
57
- e.data.type === "VALIDATE_FORM" && e.data.requestId === t && (window.removeEventListener("message", a), clearTimeout(i), r(e.data.isValid ?? !1));
123
+ function i(e) {
124
+ e.data.type === "VALIDATE_FORM" && e.data.requestId === t && (window.removeEventListener("message", i), clearTimeout(r), n(e.data.isValid ?? !1));
58
125
  }
59
- window.addEventListener("message", a);
126
+ window.addEventListener("message", i);
60
127
  });
61
128
  }
62
- function c({ iframe: t, token: r }) {
63
- let { payment_intent_id: i } = e(r).payload;
64
- t?.contentWindow?.postMessage(n({
129
+ function d({ iframe: e, token: t }) {
130
+ let { payment_intent_id: n } = r(t).payload;
131
+ e?.contentWindow?.postMessage(a({
65
132
  type: "CONFIRM_PAYMENT_INTENT",
66
- token: r,
67
- id: i ?? void 0
133
+ token: t,
134
+ id: n ?? void 0
68
135
  }), "*");
69
136
  }
70
- function l({ iframe: t, token: r }) {
71
- let { setup_intent_id: i } = e(r).payload;
72
- t?.contentWindow?.postMessage(n({
137
+ function f({ iframe: e, token: t }) {
138
+ let { setup_intent_id: n } = r(t).payload;
139
+ e?.contentWindow?.postMessage(a({
73
140
  type: "CONFIRM_SETUP_INTENT",
74
- token: r,
75
- id: i ?? void 0
141
+ token: t,
142
+ id: n ?? void 0
76
143
  }), "*");
77
144
  }
78
- function u({ iframe: e, errorMessage: t }) {
79
- e?.contentWindow?.postMessage(n({
145
+ function p({ iframe: e, errorMessage: t }) {
146
+ e?.contentWindow?.postMessage(a({
80
147
  type: "CONFIRMATION_FAILED",
81
148
  errorMessage: t
82
149
  }), "*");
83
150
  }
84
151
  //#endregion
85
152
  //#region src/apple-pay.ts
86
- function d(e) {
87
- return `${t(e)}/iframe/apple-pay?token=${e}`;
153
+ function m(e) {
154
+ return `${i(e)}/iframe/apple-pay?token=${e}`;
88
155
  }
89
- function f() {
156
+ function h() {
90
157
  return "40px";
91
158
  }
92
- function p(e, t) {
93
- let n = { ...t };
94
- function s() {
95
- a({
159
+ function g(e) {
160
+ e.contentWindow?.postMessage(a({ type: "APPLE_PAY_CANCEL" }), "*");
161
+ }
162
+ function _(e, r) {
163
+ let i = { ...r };
164
+ function a() {
165
+ c({
96
166
  iframe: e,
97
- amount: n.amount
167
+ amount: i.amount
98
168
  });
99
169
  }
100
- function l() {
101
- o({
170
+ function u() {
171
+ l({
102
172
  iframe: e,
103
- merchantName: n.merchantName
173
+ merchantName: i.merchantName
104
174
  });
105
175
  }
106
- function d(t) {
107
- if (t.source === e.contentWindow) switch (t.data.type) {
176
+ function f(r) {
177
+ if (r.source === e.contentWindow) switch (r.data.type) {
108
178
  case "IFRAME_READY":
109
- r(e), i({
179
+ o(e), s({
110
180
  iframe: e,
111
- appearance: n.appearance
112
- }), s(), l();
181
+ appearance: i.appearance
182
+ }), a(), u();
113
183
  break;
114
184
  case "UPDATE_HEIGHT":
115
- n.onHeightChange?.(t.data.height);
185
+ i.onHeightChange?.(r.data.height);
116
186
  break;
117
187
  case "UPDATE_APPEARANCE":
118
- i({
188
+ s({
119
189
  iframe: e,
120
- appearance: t.data.appearance
190
+ appearance: r.data.appearance
121
191
  });
122
192
  break;
123
193
  case "UPDATED_APPEARANCE":
124
- n.onAppearanceReady?.();
194
+ i.onAppearanceReady?.();
195
+ break;
196
+ case "APPLE_PAY_WINDOW_OPEN":
197
+ t({ onCancel: () => {
198
+ g(e), n();
199
+ } });
200
+ break;
201
+ case "APPLE_PAY_WINDOW_CLOSE":
202
+ n();
125
203
  break;
126
204
  case "CREATE_PAYMENT_INTENT":
127
- n.onInitiatePaymentIntentRequest({
128
- paymentIntentCreateAttributes: t.data.paymentIntentCreateAttributes,
129
- customerCreateAttributes: t.data.customerCreateAttributes
205
+ i.onInitiatePaymentIntentRequest({
206
+ paymentIntentCreateAttributes: r.data.paymentIntentCreateAttributes,
207
+ customerCreateAttributes: r.data.customerCreateAttributes
130
208
  }).then((t) => {
131
- c({
209
+ d({
132
210
  iframe: e,
133
211
  token: t
134
212
  });
135
213
  }).catch((t) => {
136
- u({
214
+ p({
137
215
  iframe: e,
138
216
  errorMessage: t instanceof Error ? t.message : "Unknown error"
139
217
  });
140
218
  });
141
219
  break;
142
220
  case "PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":
143
- n.onPaymentIntentConfirmationSucceeded(t.data.paymentIntent);
221
+ n(), i.onPaymentIntentConfirmationSucceeded(r.data.paymentIntent);
144
222
  break;
145
223
  case "CONFIRMATION_FAILED":
146
- n.onConfirmationFailed(t.data.errorMessage);
224
+ n(), i.onConfirmationFailed(r.data.errorMessage);
147
225
  break;
148
226
  }
149
227
  }
150
- return window.addEventListener("message", d), {
228
+ return window.addEventListener("message", f), {
151
229
  update(t) {
152
- let r = "appearance" in t, a = "amount" in t, o = "merchantName" in t;
153
- n = {
154
- ...n,
230
+ let n = "appearance" in t, r = "amount" in t, o = "merchantName" in t;
231
+ i = {
232
+ ...i,
155
233
  ...t
156
- }, r && i({
234
+ }, n && s({
157
235
  iframe: e,
158
- appearance: n.appearance
159
- }), a && s(), o && l();
236
+ appearance: i.appearance
237
+ }), r && a(), o && u();
160
238
  },
161
239
  destroy() {
162
- window.removeEventListener("message", d);
240
+ window.removeEventListener("message", f), n();
163
241
  }
164
242
  };
165
243
  }
166
244
  //#endregion
167
245
  //#region src/google-pay.ts
168
- function m(e) {
169
- return `${t(e)}/iframe/google-pay?token=${e}`;
246
+ function v(e) {
247
+ return `${i(e)}/iframe/google-pay?token=${e}`;
170
248
  }
171
- function h() {
249
+ function y() {
172
250
  return "40px";
173
251
  }
174
- function g(e, t) {
252
+ function b(e, t) {
175
253
  let n = { ...t };
176
- function s() {
177
- a({
254
+ function r() {
255
+ c({
178
256
  iframe: e,
179
257
  amount: n.amount
180
258
  });
181
259
  }
182
- function l() {
183
- o({
260
+ function i() {
261
+ l({
184
262
  iframe: e,
185
263
  merchantName: n.merchantName
186
264
  });
187
265
  }
188
- function d(t) {
266
+ function a(t) {
189
267
  switch (t.data.type) {
190
268
  case "IFRAME_READY":
191
- r(e), i({
269
+ o(e), s({
192
270
  iframe: e,
193
271
  appearance: n.appearance
194
- }), s(), l();
272
+ }), r(), i();
195
273
  break;
196
274
  case "UPDATE_HEIGHT":
197
275
  n.onHeightChange?.(t.data.height);
198
276
  break;
199
277
  case "UPDATE_APPEARANCE":
200
- i({
278
+ s({
201
279
  iframe: e,
202
280
  appearance: t.data.appearance
203
281
  });
@@ -210,12 +288,12 @@ function g(e, t) {
210
288
  paymentIntentCreateAttributes: t.data.paymentIntentCreateAttributes,
211
289
  customerCreateAttributes: t.data.customerCreateAttributes
212
290
  }).then((t) => {
213
- c({
291
+ d({
214
292
  iframe: e,
215
293
  token: t
216
294
  });
217
295
  }).catch((t) => {
218
- u({
296
+ p({
219
297
  iframe: e,
220
298
  errorMessage: t instanceof Error ? t.message : "Unknown error"
221
299
  });
@@ -229,23 +307,23 @@ function g(e, t) {
229
307
  break;
230
308
  }
231
309
  }
232
- return window.addEventListener("message", d), {
310
+ return window.addEventListener("message", a), {
233
311
  update(t) {
234
- let r = "appearance" in t, a = "amount" in t, o = "merchantName" in t;
312
+ let a = "appearance" in t, o = "amount" in t, c = "merchantName" in t;
235
313
  n = {
236
314
  ...n,
237
315
  ...t
238
- }, r && i({
316
+ }, a && s({
239
317
  iframe: e,
240
318
  appearance: n.appearance
241
- }), a && s(), o && l();
319
+ }), o && r(), c && i();
242
320
  },
243
321
  destroy() {
244
- window.removeEventListener("message", d);
322
+ window.removeEventListener("message", a);
245
323
  }
246
324
  };
247
325
  }
248
- function _({ paymentData: e }) {
326
+ function x({ paymentData: e }) {
249
327
  return { paymentMethod: {
250
328
  type: "googlepay",
251
329
  billing_address_attributes: {
@@ -277,40 +355,40 @@ function _({ paymentData: e }) {
277
355
  }
278
356
  //#endregion
279
357
  //#region src/payment-method-form.ts
280
- var v = {
358
+ var S = {
281
359
  country: 212,
282
360
  full: 452
283
- }, y = 80, b = {
361
+ }, C = 80, w = {
284
362
  country: 400,
285
363
  full: 640
286
364
  };
287
- function x(e, n = { cardholderName: !1 }, r = "country") {
288
- let i = Object.entries(n).filter(([, e]) => e).map(([e]) => e).join(","), a = new URLSearchParams({
365
+ function T(e, t = { cardholderName: !1 }, n = "country") {
366
+ let r = Object.entries(t).filter(([, e]) => e).map(([e]) => e).join(","), a = new URLSearchParams({
289
367
  token: e,
290
- additionalFields: i,
291
- billingAddressRequirement: r
368
+ additionalFields: r,
369
+ billingAddressRequirement: n
292
370
  });
293
- return `${t(e)}/iframe/card?${a}`;
371
+ return `${i(e)}/iframe/card?${a}`;
294
372
  }
295
- function S(e, n = "country") {
296
- let r = new URLSearchParams({
373
+ function E(e, t = "country") {
374
+ let n = new URLSearchParams({
297
375
  token: e,
298
- billingAddressRequirement: n
376
+ billingAddressRequirement: t
299
377
  });
300
- return `${t(e)}/iframe/bank?${r}`;
378
+ return `${i(e)}/iframe/bank?${n}`;
301
379
  }
302
- function C(e = { cardholderName: !1 }, t = "country") {
303
- return `${(v[t] ?? v.country) + (e.cardholderName ? y : 0)}px`;
380
+ function D(e = { cardholderName: !1 }, t = "country") {
381
+ return `${(S[t] ?? S.country) + (e.cardholderName ? C : 0)}px`;
304
382
  }
305
- function w(e = "country") {
306
- return `${b[e] ?? b.country}px`;
383
+ function O(e = "country") {
384
+ return `${w[e] ?? w.country}px`;
307
385
  }
308
- function T(e, t) {
386
+ function k(e, t) {
309
387
  let n = { ...t };
310
- function a(t) {
388
+ function r(t) {
311
389
  switch (t.data.type) {
312
390
  case "IFRAME_READY":
313
- r(e), i({
391
+ o(e), s({
314
392
  iframe: e,
315
393
  appearance: n.appearance
316
394
  });
@@ -319,7 +397,7 @@ function T(e, t) {
319
397
  n.onHeightChange?.(t.data.height);
320
398
  break;
321
399
  case "UPDATE_APPEARANCE":
322
- i({
400
+ s({
323
401
  iframe: e,
324
402
  appearance: t.data.appearance
325
403
  });
@@ -338,25 +416,25 @@ function T(e, t) {
338
416
  break;
339
417
  }
340
418
  }
341
- return window.addEventListener("message", a), {
419
+ return window.addEventListener("message", r), {
342
420
  update(t) {
343
421
  let r = "appearance" in t;
344
422
  n = {
345
423
  ...n,
346
424
  ...t
347
- }, r && i({
425
+ }, r && s({
348
426
  iframe: e,
349
427
  appearance: n.appearance
350
428
  });
351
429
  },
352
430
  destroy() {
353
- window.removeEventListener("message", a);
431
+ window.removeEventListener("message", r);
354
432
  }
355
433
  };
356
434
  }
357
435
  //#endregion
358
436
  //#region src/mount.ts
359
- function E(e) {
437
+ function A(e) {
360
438
  if (typeof e == "string") {
361
439
  let t = document.querySelector(e);
362
440
  if (!(t instanceof HTMLElement)) throw Error(`[amos-js] Container "${e}" did not match any HTMLElement.`);
@@ -364,26 +442,26 @@ function E(e) {
364
442
  }
365
443
  return e;
366
444
  }
367
- var D = {
445
+ var j = {
368
446
  width: "calc(100% + 8px)",
369
447
  transition: "opacity 150ms ease-in, height 200ms ease-in-out",
370
448
  margin: "0 -4px",
371
449
  opacity: "0",
372
450
  border: "0"
373
451
  };
374
- function O({ src: e, title: t, name: n, height: r, allow: i }) {
452
+ function M({ src: e, title: t, name: n, height: r, allow: i }) {
375
453
  let a = document.createElement("iframe");
376
- return a.src = e, a.title = t, a.name = n, a.setAttribute("role", "presentation"), a.scrolling = "no", i && (a.allow = i), Object.assign(a.style, D, { height: r }), a;
454
+ return a.src = e, a.title = t, a.name = n, a.setAttribute("role", "presentation"), a.scrolling = "no", i && (a.allow = i), Object.assign(a.style, j, { height: r }), a;
377
455
  }
378
- function k(e, t) {
379
- let n = E(e), { renderToken: r, additionalFields: i = { cardholderName: !1 }, billingAddressRequirement: a = "country", ...o } = t, s = O({
380
- src: x(r, i, a),
456
+ function N(e, t) {
457
+ let n = A(e), { renderToken: r, additionalFields: i = { cardholderName: !1 }, billingAddressRequirement: a = "country", ...o } = t, s = M({
458
+ src: T(r, i, a),
381
459
  title: "Secure credit card payment method form powered by Amos",
382
460
  name: "amos-credit-card-payment-method-form",
383
- height: C(i, a)
461
+ height: D(i, a)
384
462
  });
385
463
  n.appendChild(s);
386
- let c = T(s, {
464
+ let c = k(s, {
387
465
  ...o,
388
466
  onHeightChange: (e) => {
389
467
  s.style.height = e, o.onHeightChange?.(e);
@@ -400,15 +478,15 @@ function k(e, t) {
400
478
  }
401
479
  };
402
480
  }
403
- function A(e, t) {
404
- let n = E(e), { renderToken: r, billingAddressRequirement: i = "country", ...a } = t, o = O({
405
- src: S(r, i),
481
+ function P(e, t) {
482
+ let n = A(e), { renderToken: r, billingAddressRequirement: i = "country", ...a } = t, o = M({
483
+ src: E(r, i),
406
484
  title: "Secure bank account payment method form powered by Amos",
407
485
  name: "amos-bank-account-payment-method-form",
408
- height: w(i)
486
+ height: O(i)
409
487
  });
410
488
  n.appendChild(o);
411
- let s = T(o, {
489
+ let s = k(o, {
412
490
  ...a,
413
491
  onHeightChange: (e) => {
414
492
  o.style.height = e, a.onHeightChange?.(e);
@@ -425,16 +503,16 @@ function A(e, t) {
425
503
  }
426
504
  };
427
505
  }
428
- function j(e, t) {
429
- let n = E(e), { renderToken: r, ...i } = t, a = O({
430
- src: m(r),
506
+ function F(e, t) {
507
+ let n = A(e), { renderToken: r, ...i } = t, a = M({
508
+ src: v(r),
431
509
  title: "Secure Google Pay button powered by Amos",
432
510
  name: "amos-google-pay-button",
433
- height: h(),
511
+ height: y(),
434
512
  allow: "payment"
435
513
  });
436
514
  n.appendChild(a);
437
- let o = g(a, {
515
+ let o = b(a, {
438
516
  ...i,
439
517
  onHeightChange: (e) => {
440
518
  a.style.height = e, i.onHeightChange?.(e);
@@ -451,16 +529,16 @@ function j(e, t) {
451
529
  }
452
530
  };
453
531
  }
454
- function M(e, t) {
455
- let n = E(e), { renderToken: r, ...i } = t, a = O({
456
- src: d(r),
532
+ function I(e, t) {
533
+ let n = A(e), { renderToken: r, ...i } = t, a = M({
534
+ src: m(r),
457
535
  title: "Secure Apple Pay button powered by Amos",
458
536
  name: "amos-apple-pay-button",
459
- height: f(),
537
+ height: h(),
460
538
  allow: "payment"
461
539
  });
462
540
  n.appendChild(a);
463
- let o = p(a, {
541
+ let o = _(a, {
464
542
  ...i,
465
543
  onHeightChange: (e) => {
466
544
  a.style.height = e, i.onHeightChange?.(e);
@@ -478,4 +556,4 @@ function M(e, t) {
478
556
  };
479
557
  }
480
558
  //#endregion
481
- export { p as attachApplePayButtonListeners, g as attachGooglePayButtonListeners, T as attachPaymentMethodFormListeners, c as confirmPaymentIntent, l as confirmSetupIntent, n as createMessage, e as decodeJwt, _ as formatGooglePayPaymentData, f as getApplePayButtonInitialHeight, d as getApplePayButtonSrc, w as getBankAccountFormInitialHeight, S as getBankAccountFormSrc, C as getCreditCardFormInitialHeight, x as getCreditCardFormSrc, t as getEmbedOrigin, h as getGooglePayButtonInitialHeight, m as getGooglePayButtonSrc, M as mountAmosApplePayButton, A as mountAmosBankAccountPaymentMethodForm, k as mountAmosCreditCardPaymentMethodForm, j as mountAmosGooglePayButton, u as sendConfirmationFailed, r as sendParentReadyMessage, a as updateAmount, i as updateAppearance, o as updateMerchantName, s as validateForm };
559
+ export { _ as attachApplePayButtonListeners, b as attachGooglePayButtonListeners, k as attachPaymentMethodFormListeners, d as confirmPaymentIntent, f as confirmSetupIntent, a as createMessage, r as decodeJwt, x as formatGooglePayPaymentData, h as getApplePayButtonInitialHeight, m as getApplePayButtonSrc, O as getBankAccountFormInitialHeight, E as getBankAccountFormSrc, D as getCreditCardFormInitialHeight, T as getCreditCardFormSrc, i as getEmbedOrigin, y as getGooglePayButtonInitialHeight, v as getGooglePayButtonSrc, I as mountAmosApplePayButton, P as mountAmosBankAccountPaymentMethodForm, N as mountAmosCreditCardPaymentMethodForm, F as mountAmosGooglePayButton, p as sendConfirmationFailed, o as sendParentReadyMessage, c as updateAmount, s as updateAppearance, l as updateMerchantName, u as validateForm };
package/dist/types.d.ts CHANGED
@@ -68,6 +68,15 @@ export type Message = {
68
68
  errorMessage: string;
69
69
  } | {
70
70
  type: "UPDATED_APPEARANCE";
71
+ } | {
72
+ /** Embed → parent: Apple Pay Code window / waiting UI should show. */
73
+ type: "APPLE_PAY_WINDOW_OPEN";
74
+ } | {
75
+ /** Embed → parent: waiting UI should dismiss. */
76
+ type: "APPLE_PAY_WINDOW_CLOSE";
77
+ } | {
78
+ /** Parent → embed: user cancelled from the host-page waiting overlay. */
79
+ type: "APPLE_PAY_CANCEL";
71
80
  };
72
81
  /**
73
82
  * Identity helper that brands an object as a typed `Message`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amos.com/amos-js",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,7 +35,7 @@
35
35
  "license": "MIT",
36
36
  "description": "Amos JavaScript SDK for embedding payment methods via iframes.",
37
37
  "devDependencies": {
38
- "@biomejs/biome": "2.5.5",
38
+ "@biomejs/biome": "2.5.",
39
39
  "@changesets/cli": "2.31.1",
40
40
  "@types/node": "26.1.1",
41
41
  "@typescript/typescript6": "6.0.2",
@@ -44,7 +44,7 @@
44
44
  "vite-plugin-dts": "5.0.3"
45
45
  },
46
46
  "dependencies": {
47
- "@amos.com/node": "0.1.32",
47
+ "@amos.com/node": "0.1.33",
48
48
  "@types/googlepay": "0.7.11"
49
49
  }
50
50
  }
@@ -0,0 +1,103 @@
1
+ const OVERLAY_ATTRIBUTE = "data-amos-apple-pay-waiting";
2
+
3
+ /**
4
+ * Create (or return existing) full-viewport waiting UI on the host page while
5
+ * Apple Pay Code runs in a separate window. Cancel invokes `onCancel`.
6
+ */
7
+ export function showApplePayWaitingOverlay({
8
+ onCancel,
9
+ }: {
10
+ onCancel: () => void;
11
+ }): HTMLElement {
12
+ const existing = document.querySelector<HTMLElement>(
13
+ `[${OVERLAY_ATTRIBUTE}]`,
14
+ );
15
+ if (existing) {
16
+ return existing;
17
+ }
18
+
19
+ const root = document.createElement("div");
20
+ root.setAttribute(OVERLAY_ATTRIBUTE, "true");
21
+ root.setAttribute("role", "dialog");
22
+ root.setAttribute("aria-modal", "true");
23
+ root.setAttribute("aria-labelledby", "amos-apple-pay-waiting-title");
24
+ Object.assign(root.style, {
25
+ position: "fixed",
26
+ inset: "0",
27
+ zIndex: "2147483646",
28
+ display: "flex",
29
+ alignItems: "center",
30
+ justifyContent: "center",
31
+ padding: "24px",
32
+ boxSizing: "border-box",
33
+ background: "rgba(0, 0, 0, 0.55)",
34
+ fontFamily:
35
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
36
+ } satisfies Partial<CSSStyleDeclaration>);
37
+
38
+ const card = document.createElement("div");
39
+ Object.assign(card.style, {
40
+ width: "100%",
41
+ maxWidth: "360px",
42
+ borderRadius: "12px",
43
+ background: "#fff",
44
+ padding: "28px 24px 20px",
45
+ boxSizing: "border-box",
46
+ textAlign: "center",
47
+ boxShadow: "0 12px 40px rgba(0, 0, 0, 0.25)",
48
+ } satisfies Partial<CSSStyleDeclaration>);
49
+
50
+ const mark = document.createElement("div");
51
+ mark.setAttribute("aria-hidden", "true");
52
+ Object.assign(mark.style, {
53
+ display: "inline-flex",
54
+ alignItems: "center",
55
+ justifyContent: "center",
56
+ gap: "6px",
57
+ marginBottom: "16px",
58
+ fontSize: "28px",
59
+ fontWeight: "600",
60
+ letterSpacing: "-0.02em",
61
+ color: "#000",
62
+ lineHeight: "1",
63
+ } satisfies Partial<CSSStyleDeclaration>);
64
+ mark.innerHTML = `<svg width="22" height="26" viewBox="0 0 14 17" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M13.072 5.846c-.1.08-1.873 1.09-1.873 3.34 0 2.61 2.29 3.53 2.36 3.55-.04.1-.368 1.27-.766 2.52-.35 1.09-.72 2.18-1.28 2.18-.55 0-.73-.36-1.43-.36-.71 0-.93.37-1.48.37-.55 0-.93-.99-1.35-2.01-.5-1.2-.88-2.43-.88-3.85 0-2.26 1.47-3.46 2.91-3.46.57 0 1.11.38 1.49.38.37 0 .98-.45 1.7-.45.28 0 1.27.03 1.97 1.01ZM9.52 3.37c.3-.36.52-.86.52-1.36 0-.07 0-.14-.01-.2-.5.02-1.1.33-1.46.75-.28.32-.55.84-.55 1.35 0 .07.01.15.02.17.04.01.1.02.16.02.45 0 1.02-.3 1.32-.73Z"/></svg><span>Pay</span>`;
65
+
66
+ const title = document.createElement("p");
67
+ title.id = "amos-apple-pay-waiting-title";
68
+ Object.assign(title.style, {
69
+ margin: "0 0 20px",
70
+ fontSize: "15px",
71
+ lineHeight: "1.45",
72
+ color: "#1a1a1a",
73
+ } satisfies Partial<CSSStyleDeclaration>);
74
+ title.textContent =
75
+ "Complete your payment in the open Apple Pay window, or close Apple Pay to continue paying another way.";
76
+
77
+ const cancel = document.createElement("button");
78
+ cancel.type = "button";
79
+ cancel.textContent = "Cancel payment";
80
+ Object.assign(cancel.style, {
81
+ display: "block",
82
+ width: "100%",
83
+ border: "none",
84
+ borderRadius: "8px",
85
+ padding: "12px 16px",
86
+ background: "#2c2c2e",
87
+ color: "#fff",
88
+ fontSize: "15px",
89
+ fontWeight: "500",
90
+ cursor: "pointer",
91
+ } satisfies Partial<CSSStyleDeclaration>);
92
+ cancel.addEventListener("click", onCancel);
93
+
94
+ card.append(mark, title, cancel);
95
+ root.append(card);
96
+ document.body.append(root);
97
+ return root;
98
+ }
99
+
100
+ /** Remove the host-page Apple Pay waiting overlay if present. */
101
+ export function hideApplePayWaitingOverlay(): void {
102
+ document.querySelector(`[${OVERLAY_ATTRIBUTE}]`)?.remove();
103
+ }
package/src/apple-pay.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import type { components } from "@amos.com/node";
2
+ import {
3
+ hideApplePayWaitingOverlay,
4
+ showApplePayWaitingOverlay,
5
+ } from "./apple-pay-waiting-overlay";
2
6
  import { getEmbedOrigin } from "./jwt";
3
7
  import {
4
8
  confirmPaymentIntent,
@@ -8,7 +12,7 @@ import {
8
12
  updateAppearance as sendUpdateAppearance,
9
13
  updateMerchantName as sendUpdateMerchantName,
10
14
  } from "./messaging";
11
- import type { Appearance, Message } from "./types";
15
+ import { type Appearance, createMessage, type Message } from "./types";
12
16
 
13
17
  /**
14
18
  * Build the iframe `src` URL for the embedded Apple Pay button.
@@ -88,6 +92,13 @@ export type ApplePayButtonController = {
88
92
  destroy: () => void;
89
93
  };
90
94
 
95
+ function sendApplePayCancel(iframe: HTMLIFrameElement): void {
96
+ iframe.contentWindow?.postMessage(
97
+ createMessage({ type: "APPLE_PAY_CANCEL" }),
98
+ "*",
99
+ );
100
+ }
101
+
91
102
  /**
92
103
  * Wire up the host-page side of the Apple Pay iframe message protocol
93
104
  * on an existing `<iframe>` element. Returns a controller for updating
@@ -97,9 +108,9 @@ export type ApplePayButtonController = {
97
108
  * correct `src` (see {@link getApplePayButtonSrc}).
98
109
  *
99
110
  * The Apple Pay button and `ApplePaySession` run inside the Amos embed
100
- * iframe (so only Amos domains need Apple merchant registration). On
101
- * non-Safari browsers, the embed opens Apple's QR handoff in a popup
102
- * (`pay.apple.com`) rather than expanding this iframe.
111
+ * iframe so only Amos domains need Apple merchant registration. While
112
+ * Apple Pay Code is open in a separate window, this host paints a
113
+ * waiting overlay and can cancel via {@link Message} `APPLE_PAY_CANCEL`.
103
114
  */
104
115
  export function attachApplePayButtonListeners(
105
116
  iframe: HTMLIFrameElement,
@@ -141,6 +152,19 @@ export function attachApplePayButtonListeners(
141
152
  current.onAppearanceReady?.();
142
153
  break;
143
154
 
155
+ case "APPLE_PAY_WINDOW_OPEN":
156
+ showApplePayWaitingOverlay({
157
+ onCancel: () => {
158
+ sendApplePayCancel(iframe);
159
+ hideApplePayWaitingOverlay();
160
+ },
161
+ });
162
+ break;
163
+
164
+ case "APPLE_PAY_WINDOW_CLOSE":
165
+ hideApplePayWaitingOverlay();
166
+ break;
167
+
144
168
  case "CREATE_PAYMENT_INTENT":
145
169
  current
146
170
  .onInitiatePaymentIntentRequest({
@@ -161,10 +185,12 @@ export function attachApplePayButtonListeners(
161
185
  break;
162
186
 
163
187
  case "PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":
188
+ hideApplePayWaitingOverlay();
164
189
  current.onPaymentIntentConfirmationSucceeded(event.data.paymentIntent);
165
190
  break;
166
191
 
167
192
  case "CONFIRMATION_FAILED":
193
+ hideApplePayWaitingOverlay();
168
194
  current.onConfirmationFailed(event.data.errorMessage);
169
195
  break;
170
196
  }
@@ -190,6 +216,7 @@ export function attachApplePayButtonListeners(
190
216
  },
191
217
  destroy() {
192
218
  window.removeEventListener("message", handleMessage);
219
+ hideApplePayWaitingOverlay();
193
220
  },
194
221
  };
195
222
  }
package/src/types.ts CHANGED
@@ -191,6 +191,18 @@ export type Message =
191
191
  }
192
192
  | {
193
193
  type: "UPDATED_APPEARANCE";
194
+ }
195
+ | {
196
+ /** Embed → parent: Apple Pay Code window / waiting UI should show. */
197
+ type: "APPLE_PAY_WINDOW_OPEN";
198
+ }
199
+ | {
200
+ /** Embed → parent: waiting UI should dismiss. */
201
+ type: "APPLE_PAY_WINDOW_CLOSE";
202
+ }
203
+ | {
204
+ /** Parent → embed: user cancelled from the host-page waiting overlay. */
205
+ type: "APPLE_PAY_CANCEL";
194
206
  };
195
207
 
196
208
  /**