@amos.com/amos-js 0.9.10 → 0.9.11

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/README.md CHANGED
@@ -63,6 +63,9 @@ const form = mountAmosCreditCardPaymentMethodForm(
63
63
  console.log("Recoverable:", result.reason);
64
64
  }
65
65
  },
66
+ onValidityChange: ({ isValid }) => {
67
+ document.querySelector("#pay-now")!.disabled = !isValid;
68
+ },
66
69
  },
67
70
  );
68
71
 
@@ -264,6 +267,7 @@ Mount the secure credit-card payment method form into a container element (an `H
264
267
  - `billingAddressRequirement` (`"country" | "full"`, defaults to `"country"`) — how much billing address the iframe collects. `country` collects country / region and, for CA / PR / GB / US, a postal code (labeled ZIP for the United States). `full` shows a full street address form with Smarty autocomplete.
265
268
 
266
269
 
270
+ - `onValidityChange` (`(event: { isValid: boolean }) => void`) — called when form validity changes. `isValid` is true when all required fields are present and valid. Does not include PCI data. Use this to enable or disable your checkout button.
267
271
  - `onHeightChange`, `onAppearanceReady` (advanced — override the default iframe styling logic)
268
272
 
269
273
  **Returns** `AmosPaymentMethodFormMountController`:
@@ -363,7 +367,7 @@ Advanced helpers exposed for integrators that need to construct or inspect the m
363
367
 
364
368
  ### Exported types
365
369
 
366
- `Message`, `Appearance`, `ThemeVariable`, `FormattedGooglePayPaymentData`, plus the per-form `*Options` and `*Controller` types. For OpenAPI schema types, import `components` from `@amos.com/node`.
370
+ `Message`, `Appearance`, `ThemeVariable`, `FormattedGooglePayPaymentData`, `PaymentMethodFormValidityChangeEvent`, plus the per-form `*Options` and `*Controller` types. For OpenAPI schema types, import `components` from `@amos.com/node`.
367
371
 
368
372
  ## Notes and potential gotchas
369
373
 
package/dist/index.d.ts CHANGED
@@ -9,5 +9,5 @@ export type { AmosApplePayButtonMountController, AmosApplePayButtonOptions, Amos
9
9
  export { mountAmosApplePayButton, mountAmosBankAccountPaymentMethodForm, mountAmosCreditCardPaymentMethodForm, mountAmosGooglePayButton, } from './mount';
10
10
  export type { BillingAddressRequirement, CreditCardAdditionalFields, PaymentMethodFormController, PaymentMethodFormListenerOptions, } from './payment-method-form';
11
11
  export { attachPaymentMethodFormListeners, getBankAccountFormInitialHeight, getBankAccountFormSrc, getCreditCardFormInitialHeight, getCreditCardFormSrc, } from './payment-method-form';
12
- export type { Appearance, AppearanceLabels, ApplePayButtonElementProps, ApplePayButtonStyle, ApplePayButtonType, ConfirmationIncompleteReason, ConfirmationResult, GooglePayButtonElementProps, Message, ThemeVariable, WalletButtonStyle, } from './types';
12
+ export type { Appearance, AppearanceLabels, ApplePayButtonElementProps, ApplePayButtonStyle, ApplePayButtonType, ConfirmationIncompleteReason, ConfirmationResult, GooglePayButtonElementProps, Message, PaymentMethodFormValidityChangeEvent, ThemeVariable, WalletButtonStyle, } from './types';
13
13
  export { createMessage, pickApplePayButtonElementProps, pickGooglePayButtonElementProps, serializeWalletButtonStyle, } from './types';
package/dist/index.js CHANGED
@@ -1 +1 @@
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 814 1000" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/></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){if(!e||typeof e!=`object`)return;let t={};for(let[n,r]of Object.entries(e)){if(typeof r==`string`){if(r.length===0)continue;t[n]=r;continue}typeof r==`number`&&Number.isFinite(r)&&(t[n]=r)}return Object.keys(t).length>0?t:void 0}function o(e){let t={};if(e.buttonstyle!==void 0&&(t.buttonstyle=e.buttonstyle),e.type!==void 0&&(t.type=e.type),e.locale!==void 0&&(t.locale=e.locale),e.style!==void 0){let n=a(e.style);n&&(t.style=n)}return t}function s(e){let t={};if(e.buttonType!==void 0&&(t.buttonType=e.buttonType),e.buttonColor!==void 0&&(t.buttonColor=e.buttonColor),e.buttonRadius!==void 0&&(t.buttonRadius=e.buttonRadius),e.buttonSizeMode!==void 0&&(t.buttonSizeMode=e.buttonSizeMode),e.buttonLocale!==void 0&&(t.buttonLocale=e.buttonLocale),e.buttonBorderType!==void 0&&(t.buttonBorderType=e.buttonBorderType),e.style!==void 0){let n=a(e.style);n&&(t.style=n)}return t}function c(e){return e}function l(e){return new URL(e.src).origin}function u(e){e?.contentWindow&&e.contentWindow.postMessage(c({type:`PARENT_ACKNOWLEDGED_IFRAME_READY`}),l(e))}function d({iframe:e,appearance:t={}}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_APPEARANCE`,appearance:t}),l(e))}function f({iframe:e,props:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_APPLE_PAY_BUTTON`,props:o(t)}),l(e))}function p({iframe:e,props:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_GOOGLE_PAY_BUTTON`,props:s(t)}),l(e))}function m({iframe:e,amount:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_AMOUNT`,amount:t}),l(e))}function h({iframe:e,merchantName:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_MERCHANT_NAME`,merchantName:t}),l(e))}function g({iframe:e}){let t=crypto.randomUUID();return new Promise(n=>{e?.contentWindow&&e.contentWindow.postMessage(c({type:`VALIDATE_FORM`,requestId:t}),l(e));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 _({iframe:e}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`RESET_FORM`}),l(e))}function v({iframe:e,token:t}){if(!e?.contentWindow)return;let{payment_intent_id:n}=r(t).payload;e.contentWindow.postMessage(c({type:`CONFIRM_PAYMENT_INTENT`,token:t,id:n??void 0}),l(e))}function y({iframe:e,token:t}){if(!e?.contentWindow)return;let{setup_intent_id:n}=r(t).payload;e.contentWindow.postMessage(c({type:`CONFIRM_SETUP_INTENT`,token:t,id:n??void 0}),l(e))}function b({iframe:e,result:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`CONFIRMATION_RESULT`,result:t}),l(e))}function x(e){return`${i(e)}/iframe/apple-pay?token=${e}`}function S(){return`40px`}function C(e){e.contentWindow?.postMessage(c({type:`APPLE_PAY_CANCEL`}),l(e))}function w(e,r){let i={...r};function a(){m({iframe:e,amount:i.amount})}function o(){h({iframe:e,merchantName:i.merchantName})}function s(){f({iframe:e,props:i})}function c(r){if(r.source===e.contentWindow)switch(r.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:i.appearance}),a(),o(),s();break;case`UPDATE_HEIGHT`:i.onHeightChange?.(r.data.height);break;case`UPDATE_APPEARANCE`:d({iframe:e,appearance:r.data.appearance});break;case`UPDATED_APPEARANCE`:i.onAppearanceReady?.();break;case`APPLE_PAY_WINDOW_OPEN`:t({onCancel:()=>{C(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=>{v({iframe:e,token:t})}).catch(e=>{n(),i.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:n(),i.onResult(r.data.result)}}return window.addEventListener(`message`,c),{update(t){let n=`appearance`in t,r=`amount`in t,c=`merchantName`in t,l=`buttonstyle`in t||`type`in t||`locale`in t||`style`in t;i={...i,...t},n&&d({iframe:e,appearance:i.appearance}),r&&a(),c&&o(),l&&s()},destroy(){window.removeEventListener(`message`,c),n()}}}function T(e){return`${i(e)}/iframe/google-pay?token=${e}`}function E(){return`40px`}function D(e,t){let n={...t};function r(){m({iframe:e,amount:n.amount})}function i(){h({iframe:e,merchantName:n.merchantName})}function a(){p({iframe:e,props:n})}function o(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:n.appearance}),r(),i(),a();break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:d({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=>{v({iframe:e,token:t})}).catch(e=>{n.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:n.onResult(t.data.result)}}return window.addEventListener(`message`,o),{update(t){let o=`appearance`in t,s=`amount`in t,c=`merchantName`in t,l=`buttonType`in t||`buttonColor`in t||`buttonRadius`in t||`buttonSizeMode`in t||`buttonLocale`in t||`buttonBorderType`in t||`style`in t;n={...n,...t},o&&d({iframe:e,appearance:n.appearance}),s&&r(),c&&i(),l&&a()},destroy(){window.removeEventListener(`message`,o)}}}function O({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_payload:e.paymentMethodData.tokenizationData.token}}}}var k={country:212,full:452},A=80,j={country:400,full:640};function M(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 N(e,t=`country`){let n=new URLSearchParams({token:e,billingAddressRequirement:t});return`${i(e)}/iframe/bank?${n}`}function P(e={cardholderName:!1},t=`country`){return`${(k[t]??k.country)+(e.cardholderName?A:0)}px`}function F(e=`country`){return`${j[e]??j.country}px`}function I(e,t){let n={...t};function r(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:d({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`CONFIRMATION_RESULT`:n.onResult(t.data.result)}}return window.addEventListener(`message`,r),{update(t){let r=`appearance`in t;n={...n,...t},r&&d({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,r)}}}function L(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 R={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`};function z({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,R,{height:r}),a}function B(e,t){let n=L(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t,s=z({src:M(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:P(i,a)});n.appendChild(s);let c=I(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 V(e,t){let n=L(e),{renderToken:r,billingAddressRequirement:i=`country`,...a}=t,o=z({src:N(r,i),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:F(i)});n.appendChild(o);let s=I(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 H(e,t){let n=L(e),{renderToken:r,...i}=t,a=z({src:T(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:E(),allow:`payment`});n.appendChild(a);let o=D(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 U(e,t){let n=L(e),{renderToken:r,...i}=t,a=z({src:x(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:S(),allow:`payment`});n.appendChild(a);let o=w(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=w,exports.attachGooglePayButtonListeners=D,exports.attachPaymentMethodFormListeners=I,exports.confirmPaymentIntent=v,exports.confirmSetupIntent=y,exports.createMessage=c,exports.decodeJwt=r,exports.formatGooglePayPaymentData=O,exports.getApplePayButtonInitialHeight=S,exports.getApplePayButtonSrc=x,exports.getBankAccountFormInitialHeight=F,exports.getBankAccountFormSrc=N,exports.getCreditCardFormInitialHeight=P,exports.getCreditCardFormSrc=M,exports.getEmbedOrigin=i,exports.getGooglePayButtonInitialHeight=E,exports.getGooglePayButtonSrc=T,exports.mountAmosApplePayButton=U,exports.mountAmosBankAccountPaymentMethodForm=V,exports.mountAmosCreditCardPaymentMethodForm=B,exports.mountAmosGooglePayButton=H,exports.pickApplePayButtonElementProps=o,exports.pickGooglePayButtonElementProps=s,exports.resetForm=_,exports.sendConfirmationResult=b,exports.sendParentReadyMessage=u,exports.serializeWalletButtonStyle=a,exports.updateAmount=m,exports.updateAppearance=d,exports.updateApplePayButton=f,exports.updateGooglePayButton=p,exports.updateMerchantName=h,exports.validateForm=g;
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 814 1000" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/></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){if(!e||typeof e!=`object`)return;let t={};for(let[n,r]of Object.entries(e)){if(typeof r==`string`){if(r.length===0)continue;t[n]=r;continue}typeof r==`number`&&Number.isFinite(r)&&(t[n]=r)}return Object.keys(t).length>0?t:void 0}function o(e){let t={};if(e.buttonstyle!==void 0&&(t.buttonstyle=e.buttonstyle),e.type!==void 0&&(t.type=e.type),e.locale!==void 0&&(t.locale=e.locale),e.style!==void 0){let n=a(e.style);n&&(t.style=n)}return t}function s(e){let t={};if(e.buttonType!==void 0&&(t.buttonType=e.buttonType),e.buttonColor!==void 0&&(t.buttonColor=e.buttonColor),e.buttonRadius!==void 0&&(t.buttonRadius=e.buttonRadius),e.buttonSizeMode!==void 0&&(t.buttonSizeMode=e.buttonSizeMode),e.buttonLocale!==void 0&&(t.buttonLocale=e.buttonLocale),e.buttonBorderType!==void 0&&(t.buttonBorderType=e.buttonBorderType),e.style!==void 0){let n=a(e.style);n&&(t.style=n)}return t}function c(e){return e}function l(e){return new URL(e.src).origin}function u(e){e?.contentWindow&&e.contentWindow.postMessage(c({type:`PARENT_ACKNOWLEDGED_IFRAME_READY`}),l(e))}function d({iframe:e,appearance:t={}}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_APPEARANCE`,appearance:t}),l(e))}function f({iframe:e,props:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_APPLE_PAY_BUTTON`,props:o(t)}),l(e))}function p({iframe:e,props:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_GOOGLE_PAY_BUTTON`,props:s(t)}),l(e))}function m({iframe:e,amount:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_AMOUNT`,amount:t}),l(e))}function h({iframe:e,merchantName:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`UPDATE_MERCHANT_NAME`,merchantName:t}),l(e))}function g({iframe:e}){let t=crypto.randomUUID();return new Promise(n=>{e?.contentWindow&&e.contentWindow.postMessage(c({type:`VALIDATE_FORM`,requestId:t}),l(e));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 _({iframe:e}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`RESET_FORM`}),l(e))}function v({iframe:e,token:t}){if(!e?.contentWindow)return;let{payment_intent_id:n}=r(t).payload;e.contentWindow.postMessage(c({type:`CONFIRM_PAYMENT_INTENT`,token:t,id:n??void 0}),l(e))}function y({iframe:e,token:t}){if(!e?.contentWindow)return;let{setup_intent_id:n}=r(t).payload;e.contentWindow.postMessage(c({type:`CONFIRM_SETUP_INTENT`,token:t,id:n??void 0}),l(e))}function b({iframe:e,result:t}){e?.contentWindow&&e.contentWindow.postMessage(c({type:`CONFIRMATION_RESULT`,result:t}),l(e))}function x(e){return`${i(e)}/iframe/apple-pay?token=${e}`}function S(){return`40px`}function C(e){e.contentWindow?.postMessage(c({type:`APPLE_PAY_CANCEL`}),l(e))}function w(e,r){let i={...r};function a(){m({iframe:e,amount:i.amount})}function o(){h({iframe:e,merchantName:i.merchantName})}function s(){f({iframe:e,props:i})}function c(r){if(r.source===e.contentWindow)switch(r.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:i.appearance}),a(),o(),s();break;case`UPDATE_HEIGHT`:i.onHeightChange?.(r.data.height);break;case`UPDATE_APPEARANCE`:d({iframe:e,appearance:r.data.appearance});break;case`UPDATED_APPEARANCE`:i.onAppearanceReady?.();break;case`APPLE_PAY_WINDOW_OPEN`:t({onCancel:()=>{C(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=>{v({iframe:e,token:t})}).catch(e=>{n(),i.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:n(),i.onResult(r.data.result)}}return window.addEventListener(`message`,c),{update(t){let n=`appearance`in t,r=`amount`in t,c=`merchantName`in t,l=`buttonstyle`in t||`type`in t||`locale`in t||`style`in t;i={...i,...t},n&&d({iframe:e,appearance:i.appearance}),r&&a(),c&&o(),l&&s()},destroy(){window.removeEventListener(`message`,c),n()}}}function T(e){return`${i(e)}/iframe/google-pay?token=${e}`}function E(){return`40px`}function D(e,t){let n={...t};function r(){m({iframe:e,amount:n.amount})}function i(){h({iframe:e,merchantName:n.merchantName})}function a(){p({iframe:e,props:n})}function o(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:n.appearance}),r(),i(),a();break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:d({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=>{v({iframe:e,token:t})}).catch(e=>{n.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:n.onResult(t.data.result)}}return window.addEventListener(`message`,o),{update(t){let o=`appearance`in t,s=`amount`in t,c=`merchantName`in t,l=`buttonType`in t||`buttonColor`in t||`buttonRadius`in t||`buttonSizeMode`in t||`buttonLocale`in t||`buttonBorderType`in t||`style`in t;n={...n,...t},o&&d({iframe:e,appearance:n.appearance}),s&&r(),c&&i(),l&&a()},destroy(){window.removeEventListener(`message`,o)}}}function O({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_payload:e.paymentMethodData.tokenizationData.token}}}}var k={country:212,full:452},A=80,j={country:400,full:640};function M(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 N(e,t=`country`){let n=new URLSearchParams({token:e,billingAddressRequirement:t});return`${i(e)}/iframe/bank?${n}`}function P(e={cardholderName:!1},t=`country`){return`${(k[t]??k.country)+(e.cardholderName?A:0)}px`}function F(e=`country`){return`${j[e]??j.country}px`}function I(e,t){let n={...t};function r(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:u(e),d({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:d({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`FORM_VALIDITY_CHANGE`:n.onValidityChange?.({isValid:t.data.isValid});break;case`CONFIRMATION_RESULT`:n.onResult(t.data.result)}}return window.addEventListener(`message`,r),{update(t){let r=`appearance`in t;n={...n,...t},r&&d({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,r)}}}function L(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 R={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`};function z({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,R,{height:r}),a}function B(e,t){let n=L(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t,s=z({src:M(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:P(i,a)});n.appendChild(s);let c=I(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 V(e,t){let n=L(e),{renderToken:r,billingAddressRequirement:i=`country`,...a}=t,o=z({src:N(r,i),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:F(i)});n.appendChild(o);let s=I(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 H(e,t){let n=L(e),{renderToken:r,...i}=t,a=z({src:T(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:E(),allow:`payment`});n.appendChild(a);let o=D(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 U(e,t){let n=L(e),{renderToken:r,...i}=t,a=z({src:x(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:S(),allow:`payment`});n.appendChild(a);let o=w(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=w,exports.attachGooglePayButtonListeners=D,exports.attachPaymentMethodFormListeners=I,exports.confirmPaymentIntent=v,exports.confirmSetupIntent=y,exports.createMessage=c,exports.decodeJwt=r,exports.formatGooglePayPaymentData=O,exports.getApplePayButtonInitialHeight=S,exports.getApplePayButtonSrc=x,exports.getBankAccountFormInitialHeight=F,exports.getBankAccountFormSrc=N,exports.getCreditCardFormInitialHeight=P,exports.getCreditCardFormSrc=M,exports.getEmbedOrigin=i,exports.getGooglePayButtonInitialHeight=E,exports.getGooglePayButtonSrc=T,exports.mountAmosApplePayButton=U,exports.mountAmosBankAccountPaymentMethodForm=V,exports.mountAmosCreditCardPaymentMethodForm=B,exports.mountAmosGooglePayButton=H,exports.pickApplePayButtonElementProps=o,exports.pickGooglePayButtonElementProps=s,exports.resetForm=_,exports.sendConfirmationResult=b,exports.sendParentReadyMessage=u,exports.serializeWalletButtonStyle=a,exports.updateAmount=m,exports.updateAppearance=d,exports.updateApplePayButton=f,exports.updateGooglePayButton=p,exports.updateMerchantName=h,exports.validateForm=g;
package/dist/index.mjs CHANGED
@@ -443,6 +443,9 @@ function I(e, t) {
443
443
  case "UPDATED_APPEARANCE":
444
444
  n.onAppearanceReady?.();
445
445
  break;
446
+ case "FORM_VALIDITY_CHANGE":
447
+ n.onValidityChange?.({ isValid: t.data.isValid });
448
+ break;
446
449
  case "CONFIRMATION_RESULT": n.onResult(t.data.result);
447
450
  }
448
451
  }
@@ -1,4 +1,4 @@
1
- import { Appearance, ConfirmationResult } from './types';
1
+ import { Appearance, ConfirmationResult, PaymentMethodFormValidityChangeEvent } from './types';
2
2
  /**
3
3
  * The additional fields beyond the standard card number, expiration
4
4
  * date, CVV, and billing address fields that are required to be filled
@@ -59,6 +59,12 @@ export type PaymentMethodFormListenerOptions = {
59
59
  * iframe's opacity from `0` to `1` to fade it in.
60
60
  */
61
61
  onAppearanceReady?: () => void;
62
+ /**
63
+ * Called when card/bank form validity changes. `isValid` is true
64
+ * when all required fields are present and valid. Does not include
65
+ * PCI data. Use this to enable or disable a host checkout button.
66
+ */
67
+ onValidityChange?: (event: PaymentMethodFormValidityChangeEvent) => void;
62
68
  /**
63
69
  * Called when the interactive confirmation flow finishes (success or
64
70
  * terminal failure). Not settlement proof — verify via webhooks.
package/dist/types.d.ts CHANGED
@@ -1,4 +1,12 @@
1
1
  import { components } from '@amos.com/node';
2
+ /**
3
+ * PCI-safe snapshot of card/bank form validity, posted when HTML
4
+ * constraint validation changes. Use this to enable or disable a host
5
+ * checkout button.
6
+ */
7
+ export type PaymentMethodFormValidityChangeEvent = {
8
+ isValid: boolean;
9
+ };
2
10
  /**
3
11
  * Why an interactive confirmation attempt ended with `status: "incomplete"`.
4
12
  *
@@ -243,6 +251,14 @@ export type Message = {
243
251
  } | {
244
252
  /** Parent → embed: clear all form field values and API errors. */
245
253
  type: "RESET_FORM";
254
+ } | {
255
+ /**
256
+ * Embed → parent: card/bank form validity changed.
257
+ * `isValid` is true when all required fields are present and
258
+ * valid. Does not include PCI data.
259
+ */
260
+ type: "FORM_VALIDITY_CHANGE";
261
+ isValid: boolean;
246
262
  };
247
263
  /**
248
264
  * 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.9.10",
3
+ "version": "0.9.11",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.ts CHANGED
@@ -75,6 +75,7 @@ export type {
75
75
  ConfirmationResult,
76
76
  GooglePayButtonElementProps,
77
77
  Message,
78
+ PaymentMethodFormValidityChangeEvent,
78
79
  ThemeVariable,
79
80
  WalletButtonStyle,
80
81
  } from "./types";
@@ -3,7 +3,12 @@ import {
3
3
  sendParentReadyMessage,
4
4
  updateAppearance as sendUpdateAppearance,
5
5
  } from "./messaging";
6
- import type { Appearance, ConfirmationResult, Message } from "./types";
6
+ import type {
7
+ Appearance,
8
+ ConfirmationResult,
9
+ Message,
10
+ PaymentMethodFormValidityChangeEvent,
11
+ } from "./types";
7
12
 
8
13
  /**
9
14
  * The additional fields beyond the standard card number, expiration
@@ -126,6 +131,12 @@ export type PaymentMethodFormListenerOptions = {
126
131
  * iframe's opacity from `0` to `1` to fade it in.
127
132
  */
128
133
  onAppearanceReady?: () => void;
134
+ /**
135
+ * Called when card/bank form validity changes. `isValid` is true
136
+ * when all required fields are present and valid. Does not include
137
+ * PCI data. Use this to enable or disable a host checkout button.
138
+ */
139
+ onValidityChange?: (event: PaymentMethodFormValidityChangeEvent) => void;
129
140
  /**
130
141
  * Called when the interactive confirmation flow finishes (success or
131
142
  * terminal failure). Not settlement proof — verify via webhooks.
@@ -191,6 +202,10 @@ export function attachPaymentMethodFormListeners(
191
202
  current.onAppearanceReady?.();
192
203
  break;
193
204
 
205
+ case "FORM_VALIDITY_CHANGE":
206
+ current.onValidityChange?.({ isValid: event.data.isValid });
207
+ break;
208
+
194
209
  case "CONFIRMATION_RESULT":
195
210
  current.onResult(event.data.result);
196
211
  break;
package/src/types.ts CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  import type { components } from "@amos.com/node";
4
4
 
5
+ /**
6
+ * PCI-safe snapshot of card/bank form validity, posted when HTML
7
+ * constraint validation changes. Use this to enable or disable a host
8
+ * checkout button.
9
+ */
10
+ export type PaymentMethodFormValidityChangeEvent = {
11
+ isValid: boolean;
12
+ };
13
+
5
14
  /**
6
15
  * Why an interactive confirmation attempt ended with `status: "incomplete"`.
7
16
  *
@@ -593,6 +602,15 @@ export type Message =
593
602
  | {
594
603
  /** Parent → embed: clear all form field values and API errors. */
595
604
  type: "RESET_FORM";
605
+ }
606
+ | {
607
+ /**
608
+ * Embed → parent: card/bank form validity changed.
609
+ * `isValid` is true when all required fields are present and
610
+ * valid. Does not include PCI data.
611
+ */
612
+ type: "FORM_VALIDITY_CHANGE";
613
+ isValid: boolean;
596
614
  };
597
615
 
598
616
  /**