@amos.com/amos-js 0.6.1 → 0.7.1
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/apple-pay-waiting-overlay.d.ts +9 -0
- package/dist/apple-pay.d.ts +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +178 -143
- package/dist/messaging.d.ts +0 -13
- package/dist/types.d.ts +7 -16
- package/package.json +1 -1
- package/src/apple-pay-waiting-overlay.ts +103 -0
- package/src/apple-pay.ts +26 -69
- package/src/index.ts +0 -2
- package/src/messaging.ts +0 -28
- package/src/types.ts +8 -17
|
@@ -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;
|
package/dist/apple-pay.d.ts
CHANGED
|
@@ -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
|
|
78
|
-
*
|
|
79
|
-
*
|
|
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.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { attachApplePayButtonListeners, getApplePayButtonInitialHeight, getApple
|
|
|
4
4
|
export type { FormattedGooglePayPaymentData, GooglePayButtonController, GooglePayButtonListenerOptions, } from './google-pay';
|
|
5
5
|
export { attachGooglePayButtonListeners, formatGooglePayPaymentData, getGooglePayButtonInitialHeight, getGooglePayButtonSrc, } from './google-pay';
|
|
6
6
|
export { decodeJwt, getEmbedOrigin } from './jwt';
|
|
7
|
-
export { confirmPaymentIntent, confirmSetupIntent,
|
|
7
|
+
export { confirmPaymentIntent, confirmSetupIntent, sendConfirmationFailed, sendParentReadyMessage, updateAmount, updateAppearance, updateMerchantName, validateForm, } from './messaging';
|
|
8
8
|
export type { AmosApplePayButtonMountController, AmosApplePayButtonOptions, AmosBankAccountPaymentMethodFormOptions, AmosCreditCardPaymentMethodFormOptions, AmosGooglePayButtonMountController, AmosGooglePayButtonOptions, AmosPaymentMethodFormMountController, } from './mount';
|
|
9
9
|
export { mountAmosApplePayButton, mountAmosBankAccountPaymentMethodForm, mountAmosCreditCardPaymentMethodForm, mountAmosGooglePayButton, } from './mount';
|
|
10
10
|
export type { BillingAddressRequirement, CreditCardAdditionalFields, PaymentMethodFormController, PaymentMethodFormListenerOptions, } from './payment-method-form';
|
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(){return`ApplePaySession`in globalThis}function c({iframe:e,hasNativeApplePaySession:t}){e?.contentWindow?.postMessage(n({type:`UPDATE_NATIVE_APPLE_PAY_SESSION`,hasNativeApplePaySession:t}),`*`)}function l({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 u({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 d({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 f({iframe:e,errorMessage:t}){e?.contentWindow?.postMessage(n({type:`CONFIRMATION_FAILED`,errorMessage:t}),`*`)}function p(e){return`${t(e)}/iframe/apple-pay?token=${e}`}function m(){return`40px`}function h(e){let t={cssText:e.style.cssText,bodyOverflow:document.body.style.overflow};return document.body.style.overflow=`hidden`,Object.assign(e.style,{position:`fixed`,inset:`0px`,width:`100vw`,height:`100vh`,maxWidth:`none`,maxHeight:`none`,margin:`0`,border:`0`,zIndex:`2147483647`,opacity:`1`,background:`#ffffff`}),t}function g(e,t){t&&(document.body.style.overflow=t.bodyOverflow,e.style.cssText=t.cssText)}function _(e,t){let n={...t},l=null;function d(){a({iframe:e,amount:n.amount})}function p(){o({iframe:e,merchantName:n.merchantName})}function m(){c({iframe:e,hasNativeApplePaySession:s()})}function _(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:r(e),i({iframe:e,appearance:n.appearance}),m(),d(),p();break;case`UPDATE_HEIGHT`:l||n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:i({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`EXPAND_IFRAME`:l||=h(e);break;case`COLLAPSE_IFRAME`:g(e,l),l=null;break;case`CREATE_PAYMENT_INTENT`:n.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{u({iframe:e,token:t})}).catch(t=>{f({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`,_),{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&&d(),o&&p()},destroy(){window.removeEventListener(`message`,_),g(e,l),l=null}}}function v(e){return`${t(e)}/iframe/google-pay?token=${e}`}function y(){return`40px`}function b(e,t){let n={...t};function s(){a({iframe:e,amount:n.amount})}function c(){o({iframe:e,merchantName:n.merchantName})}function l(t){switch(t.data.type){case`IFRAME_READY`:r(e),i({iframe:e,appearance:n.appearance}),s(),c();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=>{u({iframe:e,token:t})}).catch(t=>{f({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`,l),{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&&c()},destroy(){window.removeEventListener(`message`,l)}}}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,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 E(e,n=`country`){let r=new URLSearchParams({token:e,billingAddressRequirement:n});return`${t(e)}/iframe/bank?${r}`}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 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 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:p(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:m(),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=u,exports.confirmSetupIntent=d,exports.createMessage=n,exports.decodeJwt=e,exports.formatGooglePayPaymentData=x,exports.getApplePayButtonInitialHeight=m,exports.getApplePayButtonSrc=p,exports.getBankAccountFormInitialHeight=O,exports.getBankAccountFormSrc=E,exports.getCreditCardFormInitialHeight=D,exports.getCreditCardFormSrc=T,exports.getEmbedOrigin=t,exports.getGooglePayButtonInitialHeight=y,exports.getGooglePayButtonSrc=v,exports.hasNativeApplePaySession=s,exports.mountAmosApplePayButton=I,exports.mountAmosBankAccountPaymentMethodForm=P,exports.mountAmosCreditCardPaymentMethodForm=N,exports.mountAmosGooglePayButton=F,exports.sendConfirmationFailed=f,exports.sendParentReadyMessage=r,exports.updateAmount=a,exports.updateAppearance=i,exports.updateMerchantName=o,exports.updateNativeApplePaySession=c,exports.validateForm=l;
|
|
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
|
|
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
|
|
11
|
-
let { env:
|
|
12
|
-
switch (
|
|
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,230 +84,198 @@ function t(t) {
|
|
|
17
84
|
}
|
|
18
85
|
//#endregion
|
|
19
86
|
//#region src/types.ts
|
|
20
|
-
function
|
|
87
|
+
function a(e) {
|
|
21
88
|
return e;
|
|
22
89
|
}
|
|
23
90
|
//#endregion
|
|
24
91
|
//#region src/messaging.ts
|
|
25
|
-
function
|
|
26
|
-
e?.contentWindow?.postMessage(
|
|
92
|
+
function o(e) {
|
|
93
|
+
e?.contentWindow?.postMessage(a({ type: "PARENT_ACKNOWLEDGED_IFRAME_READY" }), "*");
|
|
27
94
|
}
|
|
28
|
-
function
|
|
29
|
-
e?.contentWindow?.postMessage(
|
|
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
|
|
35
|
-
e?.contentWindow?.postMessage(
|
|
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
|
|
41
|
-
e?.contentWindow?.postMessage(
|
|
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
|
|
47
|
-
return "ApplePaySession" in globalThis;
|
|
48
|
-
}
|
|
49
|
-
function c({ iframe: e, hasNativeApplePaySession: t }) {
|
|
50
|
-
e?.contentWindow?.postMessage(n({
|
|
51
|
-
type: "UPDATE_NATIVE_APPLE_PAY_SESSION",
|
|
52
|
-
hasNativeApplePaySession: t
|
|
53
|
-
}), "*");
|
|
54
|
-
}
|
|
55
|
-
function l({ iframe: e }) {
|
|
113
|
+
function u({ iframe: e }) {
|
|
56
114
|
let t = crypto.randomUUID();
|
|
57
|
-
return new Promise((
|
|
58
|
-
e?.contentWindow?.postMessage(
|
|
115
|
+
return new Promise((n) => {
|
|
116
|
+
e?.contentWindow?.postMessage(a({
|
|
59
117
|
type: "VALIDATE_FORM",
|
|
60
118
|
requestId: t
|
|
61
119
|
}), "*");
|
|
62
|
-
let
|
|
63
|
-
window.removeEventListener("message",
|
|
120
|
+
let r = setTimeout(() => {
|
|
121
|
+
window.removeEventListener("message", i), n(!1);
|
|
64
122
|
}, 5e3);
|
|
65
|
-
function
|
|
66
|
-
e.data.type === "VALIDATE_FORM" && e.data.requestId === t && (window.removeEventListener("message",
|
|
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));
|
|
67
125
|
}
|
|
68
|
-
window.addEventListener("message",
|
|
126
|
+
window.addEventListener("message", i);
|
|
69
127
|
});
|
|
70
128
|
}
|
|
71
|
-
function
|
|
72
|
-
let { payment_intent_id:
|
|
73
|
-
|
|
129
|
+
function d({ iframe: e, token: t }) {
|
|
130
|
+
let { payment_intent_id: n } = r(t).payload;
|
|
131
|
+
e?.contentWindow?.postMessage(a({
|
|
74
132
|
type: "CONFIRM_PAYMENT_INTENT",
|
|
75
|
-
token:
|
|
76
|
-
id:
|
|
133
|
+
token: t,
|
|
134
|
+
id: n ?? void 0
|
|
77
135
|
}), "*");
|
|
78
136
|
}
|
|
79
|
-
function
|
|
80
|
-
let { setup_intent_id:
|
|
81
|
-
|
|
137
|
+
function f({ iframe: e, token: t }) {
|
|
138
|
+
let { setup_intent_id: n } = r(t).payload;
|
|
139
|
+
e?.contentWindow?.postMessage(a({
|
|
82
140
|
type: "CONFIRM_SETUP_INTENT",
|
|
83
|
-
token:
|
|
84
|
-
id:
|
|
141
|
+
token: t,
|
|
142
|
+
id: n ?? void 0
|
|
85
143
|
}), "*");
|
|
86
144
|
}
|
|
87
|
-
function
|
|
88
|
-
e?.contentWindow?.postMessage(
|
|
145
|
+
function p({ iframe: e, errorMessage: t }) {
|
|
146
|
+
e?.contentWindow?.postMessage(a({
|
|
89
147
|
type: "CONFIRMATION_FAILED",
|
|
90
148
|
errorMessage: t
|
|
91
149
|
}), "*");
|
|
92
150
|
}
|
|
93
151
|
//#endregion
|
|
94
152
|
//#region src/apple-pay.ts
|
|
95
|
-
function
|
|
96
|
-
return `${
|
|
153
|
+
function m(e) {
|
|
154
|
+
return `${i(e)}/iframe/apple-pay?token=${e}`;
|
|
97
155
|
}
|
|
98
|
-
function
|
|
156
|
+
function h() {
|
|
99
157
|
return "40px";
|
|
100
158
|
}
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
inset: "0px",
|
|
109
|
-
width: "100vw",
|
|
110
|
-
height: "100vh",
|
|
111
|
-
maxWidth: "none",
|
|
112
|
-
maxHeight: "none",
|
|
113
|
-
margin: "0",
|
|
114
|
-
border: "0",
|
|
115
|
-
zIndex: "2147483647",
|
|
116
|
-
opacity: "1",
|
|
117
|
-
background: "#ffffff"
|
|
118
|
-
}), t;
|
|
119
|
-
}
|
|
120
|
-
function g(e, t) {
|
|
121
|
-
t && (document.body.style.overflow = t.bodyOverflow, e.style.cssText = t.cssText);
|
|
122
|
-
}
|
|
123
|
-
function _(e, t) {
|
|
124
|
-
let n = { ...t }, l = null;
|
|
125
|
-
function d() {
|
|
126
|
-
a({
|
|
127
|
-
iframe: e,
|
|
128
|
-
amount: n.amount
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
function p() {
|
|
132
|
-
o({
|
|
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({
|
|
133
166
|
iframe: e,
|
|
134
|
-
|
|
167
|
+
amount: i.amount
|
|
135
168
|
});
|
|
136
169
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
170
|
+
function u() {
|
|
171
|
+
l({
|
|
139
172
|
iframe: e,
|
|
140
|
-
|
|
173
|
+
merchantName: i.merchantName
|
|
141
174
|
});
|
|
142
175
|
}
|
|
143
|
-
function
|
|
144
|
-
if (
|
|
176
|
+
function f(r) {
|
|
177
|
+
if (r.source === e.contentWindow) switch (r.data.type) {
|
|
145
178
|
case "IFRAME_READY":
|
|
146
|
-
|
|
179
|
+
o(e), s({
|
|
147
180
|
iframe: e,
|
|
148
|
-
appearance:
|
|
149
|
-
}),
|
|
181
|
+
appearance: i.appearance
|
|
182
|
+
}), a(), u();
|
|
150
183
|
break;
|
|
151
184
|
case "UPDATE_HEIGHT":
|
|
152
|
-
|
|
185
|
+
i.onHeightChange?.(r.data.height);
|
|
153
186
|
break;
|
|
154
187
|
case "UPDATE_APPEARANCE":
|
|
155
|
-
|
|
188
|
+
s({
|
|
156
189
|
iframe: e,
|
|
157
|
-
appearance:
|
|
190
|
+
appearance: r.data.appearance
|
|
158
191
|
});
|
|
159
192
|
break;
|
|
160
193
|
case "UPDATED_APPEARANCE":
|
|
161
|
-
|
|
194
|
+
i.onAppearanceReady?.();
|
|
162
195
|
break;
|
|
163
|
-
case "
|
|
164
|
-
|
|
196
|
+
case "APPLE_PAY_WINDOW_OPEN":
|
|
197
|
+
t({ onCancel: () => {
|
|
198
|
+
g(e), n();
|
|
199
|
+
} });
|
|
165
200
|
break;
|
|
166
|
-
case "
|
|
167
|
-
|
|
201
|
+
case "APPLE_PAY_WINDOW_CLOSE":
|
|
202
|
+
n();
|
|
168
203
|
break;
|
|
169
204
|
case "CREATE_PAYMENT_INTENT":
|
|
170
|
-
|
|
171
|
-
paymentIntentCreateAttributes:
|
|
172
|
-
customerCreateAttributes:
|
|
205
|
+
i.onInitiatePaymentIntentRequest({
|
|
206
|
+
paymentIntentCreateAttributes: r.data.paymentIntentCreateAttributes,
|
|
207
|
+
customerCreateAttributes: r.data.customerCreateAttributes
|
|
173
208
|
}).then((t) => {
|
|
174
|
-
|
|
209
|
+
d({
|
|
175
210
|
iframe: e,
|
|
176
211
|
token: t
|
|
177
212
|
});
|
|
178
213
|
}).catch((t) => {
|
|
179
|
-
|
|
214
|
+
p({
|
|
180
215
|
iframe: e,
|
|
181
216
|
errorMessage: t instanceof Error ? t.message : "Unknown error"
|
|
182
217
|
});
|
|
183
218
|
});
|
|
184
219
|
break;
|
|
185
220
|
case "PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":
|
|
186
|
-
n.onPaymentIntentConfirmationSucceeded(
|
|
221
|
+
n(), i.onPaymentIntentConfirmationSucceeded(r.data.paymentIntent);
|
|
187
222
|
break;
|
|
188
223
|
case "CONFIRMATION_FAILED":
|
|
189
|
-
n.onConfirmationFailed(
|
|
224
|
+
n(), i.onConfirmationFailed(r.data.errorMessage);
|
|
190
225
|
break;
|
|
191
226
|
}
|
|
192
227
|
}
|
|
193
|
-
return window.addEventListener("message",
|
|
228
|
+
return window.addEventListener("message", f), {
|
|
194
229
|
update(t) {
|
|
195
|
-
let
|
|
196
|
-
|
|
197
|
-
...
|
|
230
|
+
let n = "appearance" in t, r = "amount" in t, o = "merchantName" in t;
|
|
231
|
+
i = {
|
|
232
|
+
...i,
|
|
198
233
|
...t
|
|
199
|
-
},
|
|
234
|
+
}, n && s({
|
|
200
235
|
iframe: e,
|
|
201
|
-
appearance:
|
|
202
|
-
}),
|
|
236
|
+
appearance: i.appearance
|
|
237
|
+
}), r && a(), o && u();
|
|
203
238
|
},
|
|
204
239
|
destroy() {
|
|
205
|
-
window.removeEventListener("message",
|
|
240
|
+
window.removeEventListener("message", f), n();
|
|
206
241
|
}
|
|
207
242
|
};
|
|
208
243
|
}
|
|
209
244
|
//#endregion
|
|
210
245
|
//#region src/google-pay.ts
|
|
211
246
|
function v(e) {
|
|
212
|
-
return `${
|
|
247
|
+
return `${i(e)}/iframe/google-pay?token=${e}`;
|
|
213
248
|
}
|
|
214
249
|
function y() {
|
|
215
250
|
return "40px";
|
|
216
251
|
}
|
|
217
252
|
function b(e, t) {
|
|
218
253
|
let n = { ...t };
|
|
219
|
-
function
|
|
220
|
-
|
|
254
|
+
function r() {
|
|
255
|
+
c({
|
|
221
256
|
iframe: e,
|
|
222
257
|
amount: n.amount
|
|
223
258
|
});
|
|
224
259
|
}
|
|
225
|
-
function
|
|
226
|
-
|
|
260
|
+
function i() {
|
|
261
|
+
l({
|
|
227
262
|
iframe: e,
|
|
228
263
|
merchantName: n.merchantName
|
|
229
264
|
});
|
|
230
265
|
}
|
|
231
|
-
function
|
|
266
|
+
function a(t) {
|
|
232
267
|
switch (t.data.type) {
|
|
233
268
|
case "IFRAME_READY":
|
|
234
|
-
|
|
269
|
+
o(e), s({
|
|
235
270
|
iframe: e,
|
|
236
271
|
appearance: n.appearance
|
|
237
|
-
}),
|
|
272
|
+
}), r(), i();
|
|
238
273
|
break;
|
|
239
274
|
case "UPDATE_HEIGHT":
|
|
240
275
|
n.onHeightChange?.(t.data.height);
|
|
241
276
|
break;
|
|
242
277
|
case "UPDATE_APPEARANCE":
|
|
243
|
-
|
|
278
|
+
s({
|
|
244
279
|
iframe: e,
|
|
245
280
|
appearance: t.data.appearance
|
|
246
281
|
});
|
|
@@ -253,12 +288,12 @@ function b(e, t) {
|
|
|
253
288
|
paymentIntentCreateAttributes: t.data.paymentIntentCreateAttributes,
|
|
254
289
|
customerCreateAttributes: t.data.customerCreateAttributes
|
|
255
290
|
}).then((t) => {
|
|
256
|
-
|
|
291
|
+
d({
|
|
257
292
|
iframe: e,
|
|
258
293
|
token: t
|
|
259
294
|
});
|
|
260
295
|
}).catch((t) => {
|
|
261
|
-
|
|
296
|
+
p({
|
|
262
297
|
iframe: e,
|
|
263
298
|
errorMessage: t instanceof Error ? t.message : "Unknown error"
|
|
264
299
|
});
|
|
@@ -272,19 +307,19 @@ function b(e, t) {
|
|
|
272
307
|
break;
|
|
273
308
|
}
|
|
274
309
|
}
|
|
275
|
-
return window.addEventListener("message",
|
|
310
|
+
return window.addEventListener("message", a), {
|
|
276
311
|
update(t) {
|
|
277
|
-
let
|
|
312
|
+
let a = "appearance" in t, o = "amount" in t, c = "merchantName" in t;
|
|
278
313
|
n = {
|
|
279
314
|
...n,
|
|
280
315
|
...t
|
|
281
|
-
},
|
|
316
|
+
}, a && s({
|
|
282
317
|
iframe: e,
|
|
283
318
|
appearance: n.appearance
|
|
284
|
-
}),
|
|
319
|
+
}), o && r(), c && i();
|
|
285
320
|
},
|
|
286
321
|
destroy() {
|
|
287
|
-
window.removeEventListener("message",
|
|
322
|
+
window.removeEventListener("message", a);
|
|
288
323
|
}
|
|
289
324
|
};
|
|
290
325
|
}
|
|
@@ -327,20 +362,20 @@ var S = {
|
|
|
327
362
|
country: 400,
|
|
328
363
|
full: 640
|
|
329
364
|
};
|
|
330
|
-
function T(e,
|
|
331
|
-
let
|
|
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({
|
|
332
367
|
token: e,
|
|
333
|
-
additionalFields:
|
|
334
|
-
billingAddressRequirement:
|
|
368
|
+
additionalFields: r,
|
|
369
|
+
billingAddressRequirement: n
|
|
335
370
|
});
|
|
336
|
-
return `${
|
|
371
|
+
return `${i(e)}/iframe/card?${a}`;
|
|
337
372
|
}
|
|
338
|
-
function E(e,
|
|
339
|
-
let
|
|
373
|
+
function E(e, t = "country") {
|
|
374
|
+
let n = new URLSearchParams({
|
|
340
375
|
token: e,
|
|
341
|
-
billingAddressRequirement:
|
|
376
|
+
billingAddressRequirement: t
|
|
342
377
|
});
|
|
343
|
-
return `${
|
|
378
|
+
return `${i(e)}/iframe/bank?${n}`;
|
|
344
379
|
}
|
|
345
380
|
function D(e = { cardholderName: !1 }, t = "country") {
|
|
346
381
|
return `${(S[t] ?? S.country) + (e.cardholderName ? C : 0)}px`;
|
|
@@ -350,10 +385,10 @@ function O(e = "country") {
|
|
|
350
385
|
}
|
|
351
386
|
function k(e, t) {
|
|
352
387
|
let n = { ...t };
|
|
353
|
-
function
|
|
388
|
+
function r(t) {
|
|
354
389
|
switch (t.data.type) {
|
|
355
390
|
case "IFRAME_READY":
|
|
356
|
-
|
|
391
|
+
o(e), s({
|
|
357
392
|
iframe: e,
|
|
358
393
|
appearance: n.appearance
|
|
359
394
|
});
|
|
@@ -362,7 +397,7 @@ function k(e, t) {
|
|
|
362
397
|
n.onHeightChange?.(t.data.height);
|
|
363
398
|
break;
|
|
364
399
|
case "UPDATE_APPEARANCE":
|
|
365
|
-
|
|
400
|
+
s({
|
|
366
401
|
iframe: e,
|
|
367
402
|
appearance: t.data.appearance
|
|
368
403
|
});
|
|
@@ -381,19 +416,19 @@ function k(e, t) {
|
|
|
381
416
|
break;
|
|
382
417
|
}
|
|
383
418
|
}
|
|
384
|
-
return window.addEventListener("message",
|
|
419
|
+
return window.addEventListener("message", r), {
|
|
385
420
|
update(t) {
|
|
386
421
|
let r = "appearance" in t;
|
|
387
422
|
n = {
|
|
388
423
|
...n,
|
|
389
424
|
...t
|
|
390
|
-
}, r &&
|
|
425
|
+
}, r && s({
|
|
391
426
|
iframe: e,
|
|
392
427
|
appearance: n.appearance
|
|
393
428
|
});
|
|
394
429
|
},
|
|
395
430
|
destroy() {
|
|
396
|
-
window.removeEventListener("message",
|
|
431
|
+
window.removeEventListener("message", r);
|
|
397
432
|
}
|
|
398
433
|
};
|
|
399
434
|
}
|
|
@@ -496,10 +531,10 @@ function F(e, t) {
|
|
|
496
531
|
}
|
|
497
532
|
function I(e, t) {
|
|
498
533
|
let n = A(e), { renderToken: r, ...i } = t, a = M({
|
|
499
|
-
src:
|
|
534
|
+
src: m(r),
|
|
500
535
|
title: "Secure Apple Pay button powered by Amos",
|
|
501
536
|
name: "amos-apple-pay-button",
|
|
502
|
-
height:
|
|
537
|
+
height: h(),
|
|
503
538
|
allow: "payment"
|
|
504
539
|
});
|
|
505
540
|
n.appendChild(a);
|
|
@@ -521,4 +556,4 @@ function I(e, t) {
|
|
|
521
556
|
};
|
|
522
557
|
}
|
|
523
558
|
//#endregion
|
|
524
|
-
export { _ as attachApplePayButtonListeners, b as attachGooglePayButtonListeners, k as attachPaymentMethodFormListeners,
|
|
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/messaging.d.ts
CHANGED
|
@@ -34,19 +34,6 @@ export declare function updateMerchantName({ iframe, merchantName, }: {
|
|
|
34
34
|
iframe: Iframe;
|
|
35
35
|
merchantName: string;
|
|
36
36
|
}): void;
|
|
37
|
-
/**
|
|
38
|
-
* Whether the host page exposes a native `ApplePaySession` (Safari).
|
|
39
|
-
* Non-Safari browsers load Apple's SDK inside the embed iframe instead.
|
|
40
|
-
*/
|
|
41
|
-
export declare function hasNativeApplePaySession(): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* Tell the Apple Pay iframe whether the parent has a native
|
|
44
|
-
* `ApplePaySession`. Sent during the `IFRAME_READY` handshake.
|
|
45
|
-
*/
|
|
46
|
-
export declare function updateNativeApplePaySession({ iframe, hasNativeApplePaySession, }: {
|
|
47
|
-
iframe: Iframe;
|
|
48
|
-
hasNativeApplePaySession: boolean;
|
|
49
|
-
}): void;
|
|
50
37
|
/**
|
|
51
38
|
* Ask the embedded credit-card or bank-account iframe form to validate
|
|
52
39
|
* its inputs.
|
package/dist/types.d.ts
CHANGED
|
@@ -42,14 +42,6 @@ export type Message = {
|
|
|
42
42
|
} | {
|
|
43
43
|
type: "UPDATE_MERCHANT_NAME";
|
|
44
44
|
merchantName: string;
|
|
45
|
-
} | {
|
|
46
|
-
/**
|
|
47
|
-
* Parent → iframe: whether the host page has a native
|
|
48
|
-
* `ApplePaySession` (Safari). When `false`, the iframe should
|
|
49
|
-
* expand for Chrome's in-iframe QR handoff UI.
|
|
50
|
-
*/
|
|
51
|
-
type: "UPDATE_NATIVE_APPLE_PAY_SESSION";
|
|
52
|
-
hasNativeApplePaySession: boolean;
|
|
53
45
|
} | {
|
|
54
46
|
type: "UPDATE_APPEARANCE";
|
|
55
47
|
appearance: Appearance;
|
|
@@ -77,15 +69,14 @@ export type Message = {
|
|
|
77
69
|
} | {
|
|
78
70
|
type: "UPDATED_APPEARANCE";
|
|
79
71
|
} | {
|
|
80
|
-
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
type: "EXPAND_IFRAME";
|
|
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";
|
|
86
77
|
} | {
|
|
87
|
-
/**
|
|
88
|
-
type: "
|
|
78
|
+
/** Parent → embed: user cancelled from the host-page waiting overlay. */
|
|
79
|
+
type: "APPLE_PAY_CANCEL";
|
|
89
80
|
};
|
|
90
81
|
/**
|
|
91
82
|
* Identity helper that brands an object as a typed `Message`.
|
package/package.json
CHANGED
|
@@ -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,16 +1,18 @@
|
|
|
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,
|
|
5
|
-
hasNativeApplePaySession,
|
|
6
9
|
sendConfirmationFailed,
|
|
7
10
|
sendParentReadyMessage,
|
|
8
11
|
updateAmount as sendUpdateAmount,
|
|
9
12
|
updateAppearance as sendUpdateAppearance,
|
|
10
13
|
updateMerchantName as sendUpdateMerchantName,
|
|
11
|
-
updateNativeApplePaySession as sendUpdateNativeApplePaySession,
|
|
12
14
|
} from "./messaging";
|
|
13
|
-
import type
|
|
15
|
+
import { type Appearance, createMessage, type Message } from "./types";
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Build the iframe `src` URL for the embedded Apple Pay button.
|
|
@@ -90,47 +92,11 @@ export type ApplePayButtonController = {
|
|
|
90
92
|
destroy: () => void;
|
|
91
93
|
};
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Expand the Apple Pay iframe to a full-viewport overlay so Chrome's QR
|
|
100
|
-
* handoff UI (rendered inside the iframe) is not clipped to the button
|
|
101
|
-
* height. Safari's native sheet is OS-level and unaffected.
|
|
102
|
-
*/
|
|
103
|
-
function expandApplePayIframe(iframe: HTMLIFrameElement): SavedIframeLayout {
|
|
104
|
-
const saved: SavedIframeLayout = {
|
|
105
|
-
cssText: iframe.style.cssText,
|
|
106
|
-
bodyOverflow: document.body.style.overflow,
|
|
107
|
-
};
|
|
108
|
-
document.body.style.overflow = "hidden";
|
|
109
|
-
Object.assign(iframe.style, {
|
|
110
|
-
position: "fixed",
|
|
111
|
-
inset: "0px",
|
|
112
|
-
width: "100vw",
|
|
113
|
-
height: "100vh",
|
|
114
|
-
maxWidth: "none",
|
|
115
|
-
maxHeight: "none",
|
|
116
|
-
margin: "0",
|
|
117
|
-
border: "0",
|
|
118
|
-
zIndex: "2147483647",
|
|
119
|
-
opacity: "1",
|
|
120
|
-
background: "#ffffff",
|
|
121
|
-
});
|
|
122
|
-
return saved;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function collapseApplePayIframe(
|
|
126
|
-
iframe: HTMLIFrameElement,
|
|
127
|
-
saved: SavedIframeLayout | null,
|
|
128
|
-
): void {
|
|
129
|
-
if (!saved) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
document.body.style.overflow = saved.bodyOverflow;
|
|
133
|
-
iframe.style.cssText = saved.cssText;
|
|
95
|
+
function sendApplePayCancel(iframe: HTMLIFrameElement): void {
|
|
96
|
+
iframe.contentWindow?.postMessage(
|
|
97
|
+
createMessage({ type: "APPLE_PAY_CANCEL" }),
|
|
98
|
+
"*",
|
|
99
|
+
);
|
|
134
100
|
}
|
|
135
101
|
|
|
136
102
|
/**
|
|
@@ -142,16 +108,15 @@ function collapseApplePayIframe(
|
|
|
142
108
|
* correct `src` (see {@link getApplePayButtonSrc}).
|
|
143
109
|
*
|
|
144
110
|
* The Apple Pay button and `ApplePaySession` run inside the Amos embed
|
|
145
|
-
* iframe
|
|
146
|
-
*
|
|
147
|
-
*
|
|
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`.
|
|
148
114
|
*/
|
|
149
115
|
export function attachApplePayButtonListeners(
|
|
150
116
|
iframe: HTMLIFrameElement,
|
|
151
117
|
options: ApplePayButtonListenerOptions,
|
|
152
118
|
): ApplePayButtonController {
|
|
153
119
|
let current = { ...options };
|
|
154
|
-
let savedLayout: SavedIframeLayout | null = null;
|
|
155
120
|
|
|
156
121
|
function pushAmount() {
|
|
157
122
|
sendUpdateAmount({ iframe, amount: current.amount });
|
|
@@ -161,13 +126,6 @@ export function attachApplePayButtonListeners(
|
|
|
161
126
|
sendUpdateMerchantName({ iframe, merchantName: current.merchantName });
|
|
162
127
|
}
|
|
163
128
|
|
|
164
|
-
function pushNativeApplePaySession() {
|
|
165
|
-
sendUpdateNativeApplePaySession({
|
|
166
|
-
iframe,
|
|
167
|
-
hasNativeApplePaySession: hasNativeApplePaySession(),
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
129
|
function handleMessage(event: MessageEvent<Message>) {
|
|
172
130
|
// Ignore messages from other frames / windows.
|
|
173
131
|
if (event.source !== iframe.contentWindow) {
|
|
@@ -178,16 +136,12 @@ export function attachApplePayButtonListeners(
|
|
|
178
136
|
case "IFRAME_READY":
|
|
179
137
|
sendParentReadyMessage(iframe);
|
|
180
138
|
sendUpdateAppearance({ iframe, appearance: current.appearance });
|
|
181
|
-
pushNativeApplePaySession();
|
|
182
139
|
pushAmount();
|
|
183
140
|
pushMerchantName();
|
|
184
141
|
break;
|
|
185
142
|
|
|
186
143
|
case "UPDATE_HEIGHT":
|
|
187
|
-
|
|
188
|
-
if (!savedLayout) {
|
|
189
|
-
current.onHeightChange?.(event.data.height);
|
|
190
|
-
}
|
|
144
|
+
current.onHeightChange?.(event.data.height);
|
|
191
145
|
break;
|
|
192
146
|
|
|
193
147
|
case "UPDATE_APPEARANCE":
|
|
@@ -198,15 +152,17 @@ export function attachApplePayButtonListeners(
|
|
|
198
152
|
current.onAppearanceReady?.();
|
|
199
153
|
break;
|
|
200
154
|
|
|
201
|
-
case "
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
155
|
+
case "APPLE_PAY_WINDOW_OPEN":
|
|
156
|
+
showApplePayWaitingOverlay({
|
|
157
|
+
onCancel: () => {
|
|
158
|
+
sendApplePayCancel(iframe);
|
|
159
|
+
hideApplePayWaitingOverlay();
|
|
160
|
+
},
|
|
161
|
+
});
|
|
205
162
|
break;
|
|
206
163
|
|
|
207
|
-
case "
|
|
208
|
-
|
|
209
|
-
savedLayout = null;
|
|
164
|
+
case "APPLE_PAY_WINDOW_CLOSE":
|
|
165
|
+
hideApplePayWaitingOverlay();
|
|
210
166
|
break;
|
|
211
167
|
|
|
212
168
|
case "CREATE_PAYMENT_INTENT":
|
|
@@ -229,10 +185,12 @@ export function attachApplePayButtonListeners(
|
|
|
229
185
|
break;
|
|
230
186
|
|
|
231
187
|
case "PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":
|
|
188
|
+
hideApplePayWaitingOverlay();
|
|
232
189
|
current.onPaymentIntentConfirmationSucceeded(event.data.paymentIntent);
|
|
233
190
|
break;
|
|
234
191
|
|
|
235
192
|
case "CONFIRMATION_FAILED":
|
|
193
|
+
hideApplePayWaitingOverlay();
|
|
236
194
|
current.onConfirmationFailed(event.data.errorMessage);
|
|
237
195
|
break;
|
|
238
196
|
}
|
|
@@ -258,8 +216,7 @@ export function attachApplePayButtonListeners(
|
|
|
258
216
|
},
|
|
259
217
|
destroy() {
|
|
260
218
|
window.removeEventListener("message", handleMessage);
|
|
261
|
-
|
|
262
|
-
savedLayout = null;
|
|
219
|
+
hideApplePayWaitingOverlay();
|
|
263
220
|
},
|
|
264
221
|
};
|
|
265
222
|
}
|
package/src/index.ts
CHANGED
|
@@ -27,13 +27,11 @@ export { decodeJwt, getEmbedOrigin } from "./jwt";
|
|
|
27
27
|
export {
|
|
28
28
|
confirmPaymentIntent,
|
|
29
29
|
confirmSetupIntent,
|
|
30
|
-
hasNativeApplePaySession,
|
|
31
30
|
sendConfirmationFailed,
|
|
32
31
|
sendParentReadyMessage,
|
|
33
32
|
updateAmount,
|
|
34
33
|
updateAppearance,
|
|
35
34
|
updateMerchantName,
|
|
36
|
-
updateNativeApplePaySession,
|
|
37
35
|
validateForm,
|
|
38
36
|
} from "./messaging";
|
|
39
37
|
export type {
|
package/src/messaging.ts
CHANGED
|
@@ -70,34 +70,6 @@ export function updateMerchantName({
|
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
/**
|
|
74
|
-
* Whether the host page exposes a native `ApplePaySession` (Safari).
|
|
75
|
-
* Non-Safari browsers load Apple's SDK inside the embed iframe instead.
|
|
76
|
-
*/
|
|
77
|
-
export function hasNativeApplePaySession(): boolean {
|
|
78
|
-
return "ApplePaySession" in globalThis;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Tell the Apple Pay iframe whether the parent has a native
|
|
83
|
-
* `ApplePaySession`. Sent during the `IFRAME_READY` handshake.
|
|
84
|
-
*/
|
|
85
|
-
export function updateNativeApplePaySession({
|
|
86
|
-
iframe,
|
|
87
|
-
hasNativeApplePaySession,
|
|
88
|
-
}: {
|
|
89
|
-
iframe: Iframe;
|
|
90
|
-
hasNativeApplePaySession: boolean;
|
|
91
|
-
}): void {
|
|
92
|
-
iframe?.contentWindow?.postMessage(
|
|
93
|
-
createMessage({
|
|
94
|
-
type: "UPDATE_NATIVE_APPLE_PAY_SESSION",
|
|
95
|
-
hasNativeApplePaySession,
|
|
96
|
-
}),
|
|
97
|
-
"*",
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
73
|
/**
|
|
102
74
|
* Ask the embedded credit-card or bank-account iframe form to validate
|
|
103
75
|
* its inputs.
|
package/src/types.ts
CHANGED
|
@@ -155,15 +155,6 @@ export type Message =
|
|
|
155
155
|
type: "UPDATE_MERCHANT_NAME";
|
|
156
156
|
merchantName: string;
|
|
157
157
|
}
|
|
158
|
-
| {
|
|
159
|
-
/**
|
|
160
|
-
* Parent → iframe: whether the host page has a native
|
|
161
|
-
* `ApplePaySession` (Safari). When `false`, the iframe should
|
|
162
|
-
* expand for Chrome's in-iframe QR handoff UI.
|
|
163
|
-
*/
|
|
164
|
-
type: "UPDATE_NATIVE_APPLE_PAY_SESSION";
|
|
165
|
-
hasNativeApplePaySession: boolean;
|
|
166
|
-
}
|
|
167
158
|
| {
|
|
168
159
|
type: "UPDATE_APPEARANCE";
|
|
169
160
|
appearance: Appearance;
|
|
@@ -202,16 +193,16 @@ export type Message =
|
|
|
202
193
|
type: "UPDATED_APPEARANCE";
|
|
203
194
|
}
|
|
204
195
|
| {
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
type: "
|
|
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";
|
|
211
202
|
}
|
|
212
203
|
| {
|
|
213
|
-
/**
|
|
214
|
-
type: "
|
|
204
|
+
/** Parent → embed: user cancelled from the host-page waiting overlay. */
|
|
205
|
+
type: "APPLE_PAY_CANCEL";
|
|
215
206
|
};
|
|
216
207
|
|
|
217
208
|
/**
|