@amos.com/amos-js 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -173,7 +173,7 @@ Setup intents are used to save payment methods for future use (e.g. recurring pa
173
173
  - On the client, call `confirmSetupIntent({ iframe, token })` instead of `confirmPaymentIntent({ iframe, token })`.
174
174
  - The same `onResult` callback is used; succeeded setup intents arrive as `{ status: "succeeded", intent: "setup", setupIntent }`.
175
175
 
176
- The same `mountAmosCreditCardPaymentMethodForm` / `mountAmosBankAccountPaymentMethodForm` controllers support both payment intents and setup intents — they are differentiated by which confirmation function you call.
176
+ The same `mountAmosCreditCardPaymentMethodForm` / `mountAmosBankAccountPaymentMethodForm` controllers support both payment intents and setup intents — they are differentiated by which confirmation function you call. For bank setup, pass `intent: "setup"` so Connect / Plaid is always shown (no merchant ACH threshold lookup).
177
177
 
178
178
  ## Understanding PCI DSS compliance requirements
179
179
 
@@ -298,9 +298,10 @@ When the charge meets the merchant’s ACH verification threshold, the SDK hides
298
298
 
299
299
  **Additional `options` (ACH verification):**
300
300
 
301
- - `amount` (`string`, major-currency decimal, e.g. `"50.00"`, **required**, defaults to `"0"`) — same format as Google Pay / Apple Pay. Compared to the threshold the iframe fetches (cents). Pass `"0"` (the default) on open-amount forms until the customer enters a charge — 0 is typically under the threshold, so Connect stays hidden. Pass `amount` and `update({ amount })` when it changes. For setup intents, pass an amount at or above the merchant ACH threshold (the expected future charge) to show Connect.
301
+ - `amount` (`string`, major-currency decimal, e.g. `"50.00"`, **required**, defaults to `"0"`) — same format as Google Pay / Apple Pay. Compared to the threshold the iframe fetches (cents). Pass `"0"` (the default) on open-amount forms until the customer enters a charge — 0 is typically under the threshold, so Connect stays hidden. Pass `amount` and `update({ amount })` when it changes.
302
+ - `intent` (`"payment" | "setup"`, defaults to `"payment"`) — `"setup"` always shows Connect / Plaid (no merchant ACH threshold lookup), unless the render token disables verification. Use this when saving a bank account for later charges.
302
303
 
303
- Compare locally once the iframe posts `ACH_THRESHOLD`: Plaid when the amount (converted to cents, default `0`) is `>= achThreshold`. No threshold (or `null`) keeps the manual bank form. If `amount` later drops under the threshold, Plaid credentials are dropped and the iframe form is shown again.
304
+ Compare locally once the iframe posts `ACH_THRESHOLD`: Plaid when `requireVerification` is true (setup intents), or when the amount (converted to cents, default `0`) is `>= achThreshold`. No threshold (or `null`) keeps the manual bank form. Render tokens with Plaid verification disabled never require Connect. If `amount` later drops under the threshold, Plaid credentials are dropped and the iframe form is shown again.
304
305
 
305
306
  ```ts
306
307
  import { mountAmosBankAccountPaymentMethodForm } from "@amos.com/amos-js";
@@ -316,6 +317,18 @@ const bank = mountAmosBankAccountPaymentMethodForm("#bank-form", {
316
317
  bank.update({ amount: "25.00" });
317
318
  ```
318
319
 
320
+ Setup (always Connect, no merchant lookup):
321
+
322
+ ```ts
323
+ mountAmosBankAccountPaymentMethodForm("#bank-form", {
324
+ renderToken,
325
+ intent: "setup",
326
+ onResult: (result) => {
327
+ /* … */
328
+ },
329
+ });
330
+ ```
331
+
319
332
  `validateForm` / `confirmPaymentIntent` / `confirmSetupIntent` stay iframe-based. When Plaid succeeded, confirm sends `payment_method.plaid` (`public_token`, `account_id`) and does not require typed account numbers.
320
333
 
321
334
  **CSP:** the parent page must allow Plaid’s script and frames, for example `script-src https://cdn.plaid.com` and `frame-src https://cdn.plaid.com https://*.plaid.com`. Amos never loads `PLAID_SECRET` / `PLAID_CLIENT_ID` in the SDK or embed iframe.
@@ -424,7 +437,7 @@ Advanced helpers exposed for integrators that need to construct or inspect the m
424
437
  - **`onResult` is not settlement proof**: `onResult` tells you when to stop waiting (e.g. dismiss a spinner). Verify payment or setup success on your backend via webhooks. On `status: "incomplete"`, unlock your UI — the customer can fix fields in the iframe and retry. Use `result.reason` (`"field_errors"` or `"validation_failed"`) to distinguish recoverable states.
425
438
  - **Same components for payment vs setup intents**: `mountAmosCreditCardPaymentMethodForm` and `mountAmosBankAccountPaymentMethodForm` support both payment intents and setup intents. The flow differs only by which server call you make and which confirmation function you use. Handle both outcomes via `onResult`.
426
439
  - **Amount format**: for `mountAmosGooglePayButton`, `mountAmosApplePayButton`, and `mountAmosBankAccountPaymentMethodForm`, `amount` is a major-currency decimal string (e.g. `"50.00"` for $50.00). For `components["schemas"]["CreatePaymentIntentInput"]` on the server (card/bank create, and the object the wallet iframe sends to `onInitiatePaymentIntentRequest`), `amount` is a number in cents (e.g. `5000`).
427
- - **Plaid Link (ACH verification)**: load `cdn.plaid.com` from the **parent** document (see CSP above). Merchants do not proxy Pay API; the bank iframe fetches the ACH threshold and mints link tokens. Confirm still goes through the bank iframe so Amos can attach `plaid` to the payment method.
440
+ - **Plaid Link (ACH verification)**: load `cdn.plaid.com` from the **parent** document (see CSP above). Merchants do not proxy Pay API; the bank iframe fetches the ACH threshold for payment intents and mints link tokens. Setup intents skip the merchant lookup and always require Plaid unless the render token disables verification. Confirm still goes through the bank iframe so Amos can attach `plaid` to the payment method.
428
441
  - **Apple Pay waiting overlay**: on browsers where Apple's QR handoff opens in a popup (non-Safari), `mountAmosApplePayButton` shows a fixed full-viewport overlay on the host page until payment completes, the popup closes, or the user clicks **Cancel payment**. Avoid stacking other fixed UI above it.
429
442
  - **Browser-only**: the mount and messaging helpers require `window` and the DOM. They are not safe to call during server-side rendering — call them from client-side code only (for example, inside a `useEffect`-like hook in your framework of choice).
430
443
 
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`data-a
65
65
  animation: none;
66
66
  }
67
67
  }
68
- `;function A(){if(document.getElementById(k))return;let e=document.createElement(`style`);e.id=k,e.textContent=ne,document.head.appendChild(e)}function j(e,t){for(let[t,n]of Object.entries(te))e.style.setProperty(t,n);let n=t?.themeVariables;if(n)for(let[t,r]of Object.entries(n))typeof r==`string`&&r.trim()!==``&&e.style.setProperty(t,r.trim())}function M(e,t){let n=document.createElement(`div`);if(n.className=e,t)for(let e of t)n.appendChild(e);return n}function N(e,t){let n=M(`amos-js-form-skeleton-field`);t!==void 0&&(n.style.flexGrow=String(t)),e===`above`&&n.appendChild(M(`amos-js-form-skeleton-label`));let r=M(`amos-js-form-skeleton-input`);return e===`floating`&&r.classList.add(`amos-js-form-skeleton-input-floating`),n.appendChild(r),n}function P(e,t){return M(t?`amos-js-form-skeleton-row-stack`:`amos-js-form-skeleton-row`,e)}function re({labels:e,requirement:t,wrapCountryZip:n}){return t===`full`?[N(e),N(e),P([N(e,1.4),N(e,.7),N(e,.8)],!1),N(e)]:[P([N(e),N(e)],n)]}function ie(e){let t=e.appearance?.labels??`above`,n=e.billingAddressRequirement??`country`;if(e.kind===`card`){let r=[N(t),P([N(t),N(t)],!1)];return e.additionalFields?.cardholderName&&r.push(N(t)),r.push(...re({labels:t,requirement:n,wrapCountryZip:!1})),r}return[N(t),P([N(t),N(t)],!0),N(t),P([N(`above`),N(`above`)],!0),...re({labels:t,requirement:n,wrapCountryZip:!0})]}function ae(e){A();let t=M(`amos-js-form-skeleton`);t.setAttribute(`aria-hidden`,`true`);function n(e){j(t,e.appearance),t.replaceChildren(...ie(e))}return n(e),{element:t,update:n}}function F(e){A();let t=M(`amos-js-form-skeleton-input amos-js-wallet-skeleton`);t.setAttribute(`aria-hidden`,`true`);function n(e){j(t,void 0),t.style.height=e.height,t.style.borderRadius=e.borderRadius??`4px`}return n(e),{element:t,update:n}}function I(e){if(typeof e==`number`&&Number.isFinite(e))return`${e}px`;if(typeof e==`string`&&e.trim()!==``)return e.trim()}function L({iframeStyle:e,buttonProps:t}){return I(e?.borderRadius)??I(t?.buttonRadius)??I(t?.style?.borderRadius)??I(t?.style?.[`--apple-pay-button-border-radius`])??`4px`}function R(e){return`${i(e)}/iframe/google-pay?token=${e}`}function z(){return`48px`}function B(e,{height:t=`48px`,...n}){let r={...n,height:t};function i(){h({iframe:e,amount:r.amount})}function a(){g({iframe:e,merchantName:r.merchantName})}function o(){m({iframe:e,height:r.height??`48px`,props:r.buttonProps??{}})}function s(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:d(e),f({iframe:e,appearance:{}}),i(),a(),o();break;case`UPDATE_HEIGHT`:r.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:f({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:r.onAppearanceReady?.();break;case`CREATE_PAYMENT_INTENT`:r.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{S({iframe:e,token:t})}).catch(e=>{r.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:r.onResult(t.data.result)}}return window.addEventListener(`message`,s),{update(e){let t=`amount`in e,n=`merchantName`in e,s=`height`in e||`buttonProps`in e;r={...r,...e},t&&i(),n&&a(),s&&o()},destroy(){window.removeEventListener(`message`,s)}}}function oe({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 V={country:212,full:452},se=80,H={country:400,full:640};function U(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 W(e,t=`country`){let n=new URLSearchParams({token:e,billingAddressRequirement:t});return`${i(e)}/iframe/bank?${n}`}function G(e={cardholderName:!1},t=`country`){return`${(V[t]??V.country)+(e.cardholderName?se:0)}px`}function K(e=`country`){return`${H[e]??H.country}px`}function q(e,t){let n={...t};function r(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:d(e),f({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:f({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`FORM_VALIDITY_CHANGE`:if(s(e)?.requiresVerification)break;n.onValidityChange?.({isValid:t.data.isValid});break;case`CARD_BRAND_CHANGE`:n.onCardBrandChanged?.({brand:t.data.brand});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&&f({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,r)}}}var J=`https://cdn.plaid.com/link/v2/stable/link-initialize.js`;function Y({amount:e,achThreshold:t}){return t!=null&&(e??0)>=t}function ce(e){if(e==null)return;let t=e.trim();if(t===``)return;let n=Number(t.replace(/[^\d.]/g,``));if(Number.isFinite(n))return Math.round(n*100)}function le(e){return e.account_id??e.account?.id??e.accounts?.[0]?.id}function ue(e){let t=e.account??e.accounts?.[0];return{bankName:e.institution?.name??`Bank account`,last4:t?.mask??``}}var X;function de(){for(let e of document.querySelectorAll(`script[src="${J}"]`))e.remove()}function fe(){return typeof window>`u`?Promise.reject(Error(`Plaid Link requires a browser`)):window.Plaid?Promise.resolve():X||(de(),X=new Promise((e,t)=>{let n=document.createElement(`script`);n.src=J,n.async=!0;let r=e=>{n.remove(),X=void 0,t(Error(e))};n.addEventListener(`load`,()=>{if(window.Plaid){e();return}r(`Plaid Link failed to initialize`)},{once:!0}),n.addEventListener(`error`,()=>r(`Failed to load Plaid Link`),{once:!0}),document.head.append(n)}),X)}async function pe({token:e,onSuccess:t,onExit:n,signal:r}){if(await fe(),r?.aborted)return()=>{};if(!window.Plaid)throw Error(`Plaid Link failed to initialize`);let i=window.Plaid.create({token:e,onSuccess:t,onExit:e=>{n?.(e)}});return r?.aborted?(i.destroy(),()=>{}):(i.open(),()=>{i.destroy()})}var me=`amos-js-plaid-bank-ui-styles`,he=`
68
+ `;function A(){if(document.getElementById(k))return;let e=document.createElement(`style`);e.id=k,e.textContent=ne,document.head.appendChild(e)}function j(e,t){for(let[t,n]of Object.entries(te))e.style.setProperty(t,n);let n=t?.themeVariables;if(n)for(let[t,r]of Object.entries(n))typeof r==`string`&&r.trim()!==``&&e.style.setProperty(t,r.trim())}function M(e,t){let n=document.createElement(`div`);if(n.className=e,t)for(let e of t)n.appendChild(e);return n}function N(e,t){let n=M(`amos-js-form-skeleton-field`);t!==void 0&&(n.style.flexGrow=String(t)),e===`above`&&n.appendChild(M(`amos-js-form-skeleton-label`));let r=M(`amos-js-form-skeleton-input`);return e===`floating`&&r.classList.add(`amos-js-form-skeleton-input-floating`),n.appendChild(r),n}function P(e,t){return M(t?`amos-js-form-skeleton-row-stack`:`amos-js-form-skeleton-row`,e)}function re({labels:e,requirement:t,wrapCountryZip:n}){return t===`full`?[N(e),N(e),P([N(e,1.4),N(e,.7),N(e,.8)],!1),N(e)]:[P([N(e),N(e)],n)]}function ie(e){let t=e.appearance?.labels??`above`,n=e.billingAddressRequirement??`country`;if(e.kind===`card`){let r=[N(t),P([N(t),N(t)],!1)];return e.additionalFields?.cardholderName&&r.push(N(t)),r.push(...re({labels:t,requirement:n,wrapCountryZip:!1})),r}return[N(t),P([N(t),N(t)],!0),N(t),P([N(`above`),N(`above`)],!0),...re({labels:t,requirement:n,wrapCountryZip:!0})]}function ae(e){A();let t=M(`amos-js-form-skeleton`);t.setAttribute(`aria-hidden`,`true`);function n(e){j(t,e.appearance),t.replaceChildren(...ie(e))}return n(e),{element:t,update:n}}function F(e){A();let t=M(`amos-js-form-skeleton-input amos-js-wallet-skeleton`);t.setAttribute(`aria-hidden`,`true`);function n(e){j(t,void 0),t.style.height=e.height,t.style.borderRadius=e.borderRadius??`4px`}return n(e),{element:t,update:n}}function I(e){if(typeof e==`number`&&Number.isFinite(e))return`${e}px`;if(typeof e==`string`&&e.trim()!==``)return e.trim()}function L({iframeStyle:e,buttonProps:t}){return I(e?.borderRadius)??I(t?.buttonRadius)??I(t?.style?.borderRadius)??I(t?.style?.[`--apple-pay-button-border-radius`])??`4px`}function R(e){return`${i(e)}/iframe/google-pay?token=${e}`}function z(){return`48px`}function B(e,{height:t=`48px`,...n}){let r={...n,height:t};function i(){h({iframe:e,amount:r.amount})}function a(){g({iframe:e,merchantName:r.merchantName})}function o(){m({iframe:e,height:r.height??`48px`,props:r.buttonProps??{}})}function s(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:d(e),f({iframe:e,appearance:{}}),i(),a(),o();break;case`UPDATE_HEIGHT`:r.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:f({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:r.onAppearanceReady?.();break;case`CREATE_PAYMENT_INTENT`:r.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:t.data.paymentIntentCreateAttributes,customerCreateAttributes:t.data.customerCreateAttributes}).then(t=>{S({iframe:e,token:t})}).catch(e=>{r.onResult({status:`failed`,errorMessage:e instanceof Error?e.message:`Unknown error`})});break;case`CONFIRMATION_RESULT`:r.onResult(t.data.result)}}return window.addEventListener(`message`,s),{update(e){let t=`amount`in e,n=`merchantName`in e,s=`height`in e||`buttonProps`in e;r={...r,...e},t&&i(),n&&a(),s&&o()},destroy(){window.removeEventListener(`message`,s)}}}function oe({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 V={country:212,full:452},se=80,H={country:400,full:640};function U(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 W(e,t=`country`,n=`payment`){let r=new URLSearchParams({token:e,billingAddressRequirement:t});return n===`setup`&&r.set(`intent`,`setup`),`${i(e)}/iframe/bank?${r}`}function G(e={cardholderName:!1},t=`country`){return`${(V[t]??V.country)+(e.cardholderName?se:0)}px`}function K(e=`country`){return`${H[e]??H.country}px`}function q(e,t){let n={...t};function r(t){if(t.source===e.contentWindow)switch(t.data.type){case`IFRAME_READY`:d(e),f({iframe:e,appearance:n.appearance});break;case`UPDATE_HEIGHT`:n.onHeightChange?.(t.data.height);break;case`UPDATE_APPEARANCE`:f({iframe:e,appearance:t.data.appearance});break;case`UPDATED_APPEARANCE`:n.onAppearanceReady?.();break;case`FORM_VALIDITY_CHANGE`:if(s(e)?.requiresVerification)break;n.onValidityChange?.({isValid:t.data.isValid});break;case`CARD_BRAND_CHANGE`:n.onCardBrandChanged?.({brand:t.data.brand});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&&f({iframe:e,appearance:n.appearance})},destroy(){window.removeEventListener(`message`,r)}}}var J=`https://cdn.plaid.com/link/v2/stable/link-initialize.js`;function Y({amount:e,achThreshold:t}){return t!=null&&(e??0)>=t}function ce(e){if(e==null)return;let t=e.trim();if(t===``)return;let n=Number(t.replace(/[^\d.]/g,``));if(Number.isFinite(n))return Math.round(n*100)}function le(e){return e.account_id??e.account?.id??e.accounts?.[0]?.id}function ue(e){let t=e.account??e.accounts?.[0];return{bankName:e.institution?.name??`Bank account`,last4:t?.mask??``}}var X;function de(){for(let e of document.querySelectorAll(`script[src="${J}"]`))e.remove()}function fe(){return typeof window>`u`?Promise.reject(Error(`Plaid Link requires a browser`)):window.Plaid?Promise.resolve():X||(de(),X=new Promise((e,t)=>{let n=document.createElement(`script`);n.src=J,n.async=!0;let r=e=>{n.remove(),X=void 0,t(Error(e))};n.addEventListener(`load`,()=>{if(window.Plaid){e();return}r(`Plaid Link failed to initialize`)},{once:!0}),n.addEventListener(`error`,()=>r(`Failed to load Plaid Link`),{once:!0}),document.head.append(n)}),X)}async function pe({token:e,onSuccess:t,onExit:n,signal:r}){if(await fe(),r?.aborted)return()=>{};if(!window.Plaid)throw Error(`Plaid Link failed to initialize`);let i=window.Plaid.create({token:e,onSuccess:t,onExit:e=>{n?.(e)}});return r?.aborted?(i.destroy(),()=>{}):(i.open(),()=>{i.destroy()})}var me=`amos-js-plaid-bank-ui-styles`,he=`
69
69
  .amos-js-plaid-panel {
70
70
  box-sizing: border-box;
71
71
  color: var(--foreground, oklch(0.145 0 0));
@@ -171,4 +171,4 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=`data-a
171
171
  transition: none;
172
172
  }
173
173
  }
174
- `;function ge(){if(document.getElementById(me))return;let e=document.createElement(`style`);e.id=me,e.textContent=he,document.head.append(e)}function _e(e,t,n){for(let t of n)e.style.removeProperty(t);n.length=0;let r=t?.themeVariables;if(r)for(let[t,i]of Object.entries(r))typeof i==`string`&&i.trim()!==``&&(e.style.setProperty(t,i.trim()),n.push(t))}function ve({host:e,iframe:t,options:n}){ge();let r={...n,amount:n.amount??`0`},i=[],a=!1,s,l=!1,u,d=!1,f,p,m=new AbortController,h,g=document.createElement(`div`);g.className=`amos-js-plaid-panel`,g.setAttribute(`data-amos-plaid-panel`,`true`),g.dataset.mode=`hidden`,_e(g,r.appearance,i);let _=document.createElement(`button`);_.type=`button`,_.className=`amos-js-plaid-connect`,_.textContent=`Connect bank account`,_.setAttribute(`data-testid`,`amos-plaid-connect`);let v=document.createElement(`div`);v.className=`amos-js-plaid-linked`;let y=document.createElement(`span`);y.className=`amos-js-plaid-linked-name`;let b=document.createElement(`span`);b.className=`amos-js-plaid-linked-meta`;let x=document.createElement(`button`);x.type=`button`,x.className=`amos-js-plaid-disconnect`,x.textContent=`Disconnect`,x.setAttribute(`aria-label`,`Disconnect bank account`);let S=document.createElement(`p`);S.className=`amos-js-plaid-error`,S.setAttribute(`role`,`alert`),v.append(y,b,x),g.append(_,v,S),e.append(g);let C=t.parentElement;function w(e){S.textContent=e??``}function T(){return a?l?!0:Y({amount:ce(r.amount),achThreshold:s}):!1}function E(){let e=!!h;f!==e&&(f=e,r.onValidityChange?.({isValid:e}))}function D(){let e=T();if(o(t,{requiresVerification:e,plaid:e?h?.credentials:void 0,clearLinked:O}),!e){g.dataset.mode=`hidden`,C&&(C.style.display=``),f=void 0;return}g.dataset.mode=h?`linked`:`connect`,C&&(C.style.display=`none`),h&&(y.textContent=h.bankName,b.textContent=h.last4?`****${h.last4}`:`Connected`),E()}function O(){h=void 0,u=void 0,p?.(),p=void 0,w(void 0),D()}function k(e){if(e.source===t.contentWindow&&e.data.type===`ACH_THRESHOLD`){if(a=!0,s=e.data.achThreshold??void 0,l=e.data.requireVerification===!0,h&&!T()){O();return}D()}}return window.addEventListener(`message`,k),D(),x.addEventListener(`click`,()=>{O()}),_.addEventListener(`click`,()=>{(async()=>{if(!(m.signal.aborted||d)){d=!0,_.disabled=!0,w(void 0);try{if(u||=await ee({iframe:t}),m.signal.aborted)return;let e=u;p?.(),p=await pe({token:e,signal:m.signal,onSuccess:(e,t)=>{if(m.signal.aborted)return;let n=le(t);if(!n){w(`Select a bank account to continue.`);return}let r=ue(t);h={credentials:{public_token:e,account_id:n},bankName:r.bankName,last4:r.last4},u=void 0,D()},onExit:e=>{m.signal.aborted||e?.error_code===`INVALID_LINK_TOKEN`&&(u=void 0)}}),m.signal.aborted&&(p(),p=void 0)}catch(e){if(u=void 0,m.signal.aborted)return;w(e instanceof Error?e.message:`Could not connect bank.`)}finally{d=!1,m.signal.aborted||(_.disabled=!1)}}})()}),{update(e){if(`amount`in e&&(r.amount=e.amount??`0`),`onValidityChange`in e&&(r.onValidityChange=e.onValidityChange),`appearance`in e&&(r.appearance=e.appearance,_e(g,r.appearance,i)),h&&!T()){O();return}D()},destroy(){m.abort(),window.removeEventListener(`message`,k),p?.(),p=void 0,c(t),g.remove()}}}function Z(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 ye={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`},be={width:`100%`,transition:`height 200ms ease-in-out`,margin:`0`,opacity:`0`,border:`0`},xe={position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,margin:`0`,opacity:`0`,transition:`none`,pointerEvents:`none`},Se={position:`absolute`,top:`0`,left:`-4px`,width:`calc(100% + 8px)`,height:`100%`,margin:`0`,transition:`none`,pointerEvents:`none`};function Q({src:e,title:t,name:n,height:r,allow:i,className:a,style:o=ye}){let s=document.createElement(`iframe`);return s.src=e,s.title=t,s.name=n,s.setAttribute(`role`,`presentation`),s.scrolling=`no`,i&&(s.allow=i),a!=null&&(s.className=a),Object.assign(s.style,o,{height:r}),s}function Ce({host:e,iframe:t,listenerOptions:n,skeletonOptions:r}){let i=document.createElement(`div`);i.style.position=`relative`,i.style.width=`100%`,i.setAttribute(`aria-busy`,`true`);let a=ae(r);Object.assign(t.style,Se),i.append(a.element,t),e.appendChild(i);let o=!1,s=!1,c,l=r.appearance,u,d;function f(){return i.getBoundingClientRect().height}function p(){return c?Number.parseFloat(c):NaN}function m(){if(o)return;o=!0,d!==void 0&&(clearTimeout(d),d=void 0);let e=f(),n=p(),r=Number.isFinite(n)?Math.max(n,e):e;t.style.transition=`none`,t.style.position=``,t.style.top=``,t.style.left=``,t.style.margin=ye.margin??``,t.style.height=`${r}px`,t.style.opacity=`1`,t.style.pointerEvents=``,a.element.remove(),i.removeAttribute(`aria-busy`),u=setTimeout(()=>{t.style.transition=`height 200ms ease-in-out`},400)}function h(){if(o||!s)return;let e=p(),t=f();Number.isFinite(e)&&e>=t-2&&m()}let g=q(t,{...n,onHeightChange:e=>{c=e,o?t.style.height=e:h(),n.onHeightChange?.(e)},onAppearanceReady:()=>{s=!0,h(),!o&&d===void 0&&(d=setTimeout(()=>{m()},1500)),n.onAppearanceReady?.()}});return{iframe:t,update(e){g.update(e),!o&&`appearance`in e&&(l=e.appearance,a.update({...r,appearance:l}))},destroy(){u!==void 0&&clearTimeout(u),d!==void 0&&clearTimeout(d),g.destroy(),i.remove()}}}function $({host:e,iframe:t,listenerOptions:n,iframeStyle:r,attachListeners:i}){let a={height:n.height??`48px`,borderRadius:L({iframeStyle:r,buttonProps:n.buttonProps})},o=F(a),s=document.createElement(`div`);s.style.position=`relative`,s.style.width=`100%`,s.style.height=a.height,s.style.overflow=`hidden`,s.setAttribute(`aria-busy`,`true`),Object.assign(t.style,xe),t.style.height=`100%`,s.append(o.element,t),e.appendChild(s);let c=!1,l=!1,u,d=n;function f(){c||(c=!0,u!==void 0&&(clearTimeout(u),u=void 0),t.style.opacity=`1`,t.style.pointerEvents=``,o.element.remove(),s.removeAttribute(`aria-busy`))}function p(){c||!l||f()}let m=i(t,{...n,onHeightChange:e=>{d.onHeightChange?.(e)},onAppearanceReady:()=>{l=!0,p(),d.onAppearanceReady?.()}});return u=setTimeout(()=>{f()},1500),{iframe:t,update(e){d={...d,...e};let t={...e};delete t.onAppearanceReady,delete t.onHeightChange,m.update(t),a={height:d.height??a.height,borderRadius:L({iframeStyle:r,buttonProps:d.buttonProps})},s.style.height=a.height,c||o.update(a)},destroy(){u!==void 0&&clearTimeout(u),m.destroy(),s.remove()}}}function we(e,t){let n=Z(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t;return Ce({host:n,iframe:Q({src:U(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:G(i,a)}),listenerOptions:o,skeletonOptions:{kind:`card`,appearance:o.appearance,additionalFields:i,billingAddressRequirement:a}})}function Te(e,t){let n=Z(e),{renderToken:r,billingAddressRequirement:i=`country`,amount:a=`0`,...o}=t,s=Q({src:W(r,i),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:K(i)}),c=Ce({host:n,iframe:s,listenerOptions:o,skeletonOptions:{kind:`bank`,appearance:o.appearance,billingAddressRequirement:i}}),l=ve({host:n,iframe:s,options:{amount:a,appearance:o.appearance,onValidityChange:o.onValidityChange}});return{iframe:s,update(e){c.update(e),l.update(e)},destroy(){l.destroy(),c.destroy()}}}function Ee(e,t){let n=Z(e),{renderToken:r,iframeClassName:i,iframeStyle:a,...o}=t,s=Q({src:R(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:o.height??z(),allow:`payment`,className:i,style:be});return Object.assign(s.style,a),$({host:n,iframe:s,listenerOptions:o,iframeStyle:a,attachListeners:B})}function De(e,t){let n=Z(e),{renderToken:r,iframeClassName:i,iframeStyle:a,...o}=t,s=Q({src:T(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:o.height??E(),allow:`payment`,className:i,style:be});return Object.assign(s.style,a),$({host:n,iframe:s,listenerOptions:o,iframeStyle:a,attachListeners:O})}exports.SKELETON_STYLES=ne,exports.attachApplePayButtonListeners=O,exports.attachGooglePayButtonListeners=B,exports.attachPaymentMethodFormListeners=q,exports.confirmPaymentIntent=S,exports.confirmSetupIntent=C,exports.createMessage=l,exports.createPaymentMethodFormSkeleton=ae,exports.createWalletButtonSkeleton=F,exports.decodeJwt=r,exports.ensureSkeletonStyles=A,exports.formatGooglePayPaymentData=oe,exports.getApplePayButtonInitialHeight=E,exports.getApplePayButtonSrc=T,exports.getBankAccountFormInitialHeight=K,exports.getBankAccountFormSrc=W,exports.getCreditCardFormInitialHeight=G,exports.getCreditCardFormSrc=U,exports.getEmbedOrigin=i,exports.getGooglePayButtonInitialHeight=z,exports.getGooglePayButtonSrc=R,exports.linkedBankLabelFromMetadata=ue,exports.loadPlaidScript=fe,exports.mountAmosApplePayButton=De,exports.mountAmosBankAccountPaymentMethodForm=Te,exports.mountAmosCreditCardPaymentMethodForm=we,exports.mountAmosGooglePayButton=Ee,exports.openPlaidLink=pe,exports.plaidAccountIdFromMetadata=le,exports.requiresAchVerification=Y,exports.resetForm=y,exports.resolveWalletButtonSkeletonBorderRadius=L,exports.sendConfirmationResult=w,exports.sendParentReadyMessage=d,exports.updateAmount=h,exports.updateAppearance=f,exports.updateApplePayButton=p,exports.updateGooglePayButton=m,exports.updateMerchantName=g,exports.validateForm=_;
174
+ `;function ge(){if(document.getElementById(me))return;let e=document.createElement(`style`);e.id=me,e.textContent=he,document.head.append(e)}function _e(e,t,n){for(let t of n)e.style.removeProperty(t);n.length=0;let r=t?.themeVariables;if(r)for(let[t,i]of Object.entries(r))typeof i==`string`&&i.trim()!==``&&(e.style.setProperty(t,i.trim()),n.push(t))}function ve({host:e,iframe:t,options:n}){ge();let r={...n,amount:n.amount??`0`},i=[],a=!1,s,l=!1,u,d=!1,f,p,m=new AbortController,h,g=document.createElement(`div`);g.className=`amos-js-plaid-panel`,g.setAttribute(`data-amos-plaid-panel`,`true`),g.dataset.mode=`hidden`,_e(g,r.appearance,i);let _=document.createElement(`button`);_.type=`button`,_.className=`amos-js-plaid-connect`,_.textContent=`Connect bank account`,_.setAttribute(`data-testid`,`amos-plaid-connect`);let v=document.createElement(`div`);v.className=`amos-js-plaid-linked`;let y=document.createElement(`span`);y.className=`amos-js-plaid-linked-name`;let b=document.createElement(`span`);b.className=`amos-js-plaid-linked-meta`;let x=document.createElement(`button`);x.type=`button`,x.className=`amos-js-plaid-disconnect`,x.textContent=`Disconnect`,x.setAttribute(`aria-label`,`Disconnect bank account`);let S=document.createElement(`p`);S.className=`amos-js-plaid-error`,S.setAttribute(`role`,`alert`),v.append(y,b,x),g.append(_,v,S),e.append(g);let C=t.parentElement;function w(e){S.textContent=e??``}function T(){return a?l?!0:Y({amount:ce(r.amount),achThreshold:s}):!1}function E(){let e=!!h;f!==e&&(f=e,r.onValidityChange?.({isValid:e}))}function D(){let e=T();if(o(t,{requiresVerification:e,plaid:e?h?.credentials:void 0,clearLinked:O}),!e){g.dataset.mode=`hidden`,C&&(C.style.display=``),f=void 0;return}g.dataset.mode=h?`linked`:`connect`,C&&(C.style.display=`none`),h&&(y.textContent=h.bankName,b.textContent=h.last4?`****${h.last4}`:`Connected`),E()}function O(){h=void 0,u=void 0,p?.(),p=void 0,w(void 0),D()}function k(e){if(e.source===t.contentWindow&&e.data.type===`ACH_THRESHOLD`){if(a=!0,s=e.data.achThreshold??void 0,l=e.data.requireVerification===!0,h&&!T()){O();return}D()}}return window.addEventListener(`message`,k),D(),x.addEventListener(`click`,()=>{O()}),_.addEventListener(`click`,()=>{(async()=>{if(!(m.signal.aborted||d)){d=!0,_.disabled=!0,w(void 0);try{if(u||=await ee({iframe:t}),m.signal.aborted)return;let e=u;p?.(),p=await pe({token:e,signal:m.signal,onSuccess:(e,t)=>{if(m.signal.aborted)return;let n=le(t);if(!n){w(`Select a bank account to continue.`);return}let r=ue(t);h={credentials:{public_token:e,account_id:n},bankName:r.bankName,last4:r.last4},u=void 0,D()},onExit:e=>{m.signal.aborted||e?.error_code===`INVALID_LINK_TOKEN`&&(u=void 0)}}),m.signal.aborted&&(p(),p=void 0)}catch(e){if(u=void 0,m.signal.aborted)return;w(e instanceof Error?e.message:`Could not connect bank.`)}finally{d=!1,m.signal.aborted||(_.disabled=!1)}}})()}),{update(e){if(`amount`in e&&(r.amount=e.amount??`0`),`onValidityChange`in e&&(r.onValidityChange=e.onValidityChange),`appearance`in e&&(r.appearance=e.appearance,_e(g,r.appearance,i)),h&&!T()){O();return}D()},destroy(){m.abort(),window.removeEventListener(`message`,k),p?.(),p=void 0,c(t),g.remove()}}}function Z(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 ye={width:`calc(100% + 8px)`,transition:`opacity 150ms ease-in, height 200ms ease-in-out`,margin:`0 -4px`,opacity:`0`,border:`0`},be={width:`100%`,transition:`height 200ms ease-in-out`,margin:`0`,opacity:`0`,border:`0`},xe={position:`absolute`,top:`0`,left:`0`,width:`100%`,height:`100%`,margin:`0`,opacity:`0`,transition:`none`,pointerEvents:`none`},Se={position:`absolute`,top:`0`,left:`-4px`,width:`calc(100% + 8px)`,height:`100%`,margin:`0`,transition:`none`,pointerEvents:`none`};function Q({src:e,title:t,name:n,height:r,allow:i,className:a,style:o=ye}){let s=document.createElement(`iframe`);return s.src=e,s.title=t,s.name=n,s.setAttribute(`role`,`presentation`),s.scrolling=`no`,i&&(s.allow=i),a!=null&&(s.className=a),Object.assign(s.style,o,{height:r}),s}function Ce({host:e,iframe:t,listenerOptions:n,skeletonOptions:r}){let i=document.createElement(`div`);i.style.position=`relative`,i.style.width=`100%`,i.setAttribute(`aria-busy`,`true`);let a=ae(r);Object.assign(t.style,Se),i.append(a.element,t),e.appendChild(i);let o=!1,s=!1,c,l=r.appearance,u,d;function f(){return i.getBoundingClientRect().height}function p(){return c?Number.parseFloat(c):NaN}function m(){if(o)return;o=!0,d!==void 0&&(clearTimeout(d),d=void 0);let e=f(),n=p(),r=Number.isFinite(n)?Math.max(n,e):e;t.style.transition=`none`,t.style.position=``,t.style.top=``,t.style.left=``,t.style.margin=ye.margin??``,t.style.height=`${r}px`,t.style.opacity=`1`,t.style.pointerEvents=``,a.element.remove(),i.removeAttribute(`aria-busy`),u=setTimeout(()=>{t.style.transition=`height 200ms ease-in-out`},400)}function h(){if(o||!s)return;let e=p(),t=f();Number.isFinite(e)&&e>=t-2&&m()}let g=q(t,{...n,onHeightChange:e=>{c=e,o?t.style.height=e:h(),n.onHeightChange?.(e)},onAppearanceReady:()=>{s=!0,h(),!o&&d===void 0&&(d=setTimeout(()=>{m()},1500)),n.onAppearanceReady?.()}});return{iframe:t,update(e){g.update(e),!o&&`appearance`in e&&(l=e.appearance,a.update({...r,appearance:l}))},destroy(){u!==void 0&&clearTimeout(u),d!==void 0&&clearTimeout(d),g.destroy(),i.remove()}}}function $({host:e,iframe:t,listenerOptions:n,iframeStyle:r,attachListeners:i}){let a={height:n.height??`48px`,borderRadius:L({iframeStyle:r,buttonProps:n.buttonProps})},o=F(a),s=document.createElement(`div`);s.style.position=`relative`,s.style.width=`100%`,s.style.height=a.height,s.style.overflow=`hidden`,s.setAttribute(`aria-busy`,`true`),Object.assign(t.style,xe),t.style.height=`100%`,s.append(o.element,t),e.appendChild(s);let c=!1,l=!1,u,d=n;function f(){c||(c=!0,u!==void 0&&(clearTimeout(u),u=void 0),t.style.opacity=`1`,t.style.pointerEvents=``,o.element.remove(),s.removeAttribute(`aria-busy`))}function p(){c||!l||f()}let m=i(t,{...n,onHeightChange:e=>{d.onHeightChange?.(e)},onAppearanceReady:()=>{l=!0,p(),d.onAppearanceReady?.()}});return u=setTimeout(()=>{f()},1500),{iframe:t,update(e){d={...d,...e};let t={...e};delete t.onAppearanceReady,delete t.onHeightChange,m.update(t),a={height:d.height??a.height,borderRadius:L({iframeStyle:r,buttonProps:d.buttonProps})},s.style.height=a.height,c||o.update(a)},destroy(){u!==void 0&&clearTimeout(u),m.destroy(),s.remove()}}}function we(e,t){let n=Z(e),{renderToken:r,additionalFields:i={cardholderName:!1},billingAddressRequirement:a=`country`,...o}=t;return Ce({host:n,iframe:Q({src:U(r,i,a),title:`Secure credit card payment method form powered by Amos`,name:`amos-credit-card-payment-method-form`,height:G(i,a)}),listenerOptions:o,skeletonOptions:{kind:`card`,appearance:o.appearance,additionalFields:i,billingAddressRequirement:a}})}function Te(e,t){let n=Z(e),{renderToken:r,billingAddressRequirement:i=`country`,amount:a=`0`,intent:o=`payment`,...s}=t,c=Q({src:W(r,i,o),title:`Secure bank account payment method form powered by Amos`,name:`amos-bank-account-payment-method-form`,height:K(i)}),l=Ce({host:n,iframe:c,listenerOptions:s,skeletonOptions:{kind:`bank`,appearance:s.appearance,billingAddressRequirement:i}}),u=ve({host:n,iframe:c,options:{amount:a,appearance:s.appearance,onValidityChange:s.onValidityChange}});return{iframe:c,update(e){l.update(e),u.update(e)},destroy(){u.destroy(),l.destroy()}}}function Ee(e,t){let n=Z(e),{renderToken:r,iframeClassName:i,iframeStyle:a,...o}=t,s=Q({src:R(r),title:`Secure Google Pay button powered by Amos`,name:`amos-google-pay-button`,height:o.height??z(),allow:`payment`,className:i,style:be});return Object.assign(s.style,a),$({host:n,iframe:s,listenerOptions:o,iframeStyle:a,attachListeners:B})}function De(e,t){let n=Z(e),{renderToken:r,iframeClassName:i,iframeStyle:a,...o}=t,s=Q({src:T(r),title:`Secure Apple Pay button powered by Amos`,name:`amos-apple-pay-button`,height:o.height??E(),allow:`payment`,className:i,style:be});return Object.assign(s.style,a),$({host:n,iframe:s,listenerOptions:o,iframeStyle:a,attachListeners:O})}exports.SKELETON_STYLES=ne,exports.attachApplePayButtonListeners=O,exports.attachGooglePayButtonListeners=B,exports.attachPaymentMethodFormListeners=q,exports.confirmPaymentIntent=S,exports.confirmSetupIntent=C,exports.createMessage=l,exports.createPaymentMethodFormSkeleton=ae,exports.createWalletButtonSkeleton=F,exports.decodeJwt=r,exports.ensureSkeletonStyles=A,exports.formatGooglePayPaymentData=oe,exports.getApplePayButtonInitialHeight=E,exports.getApplePayButtonSrc=T,exports.getBankAccountFormInitialHeight=K,exports.getBankAccountFormSrc=W,exports.getCreditCardFormInitialHeight=G,exports.getCreditCardFormSrc=U,exports.getEmbedOrigin=i,exports.getGooglePayButtonInitialHeight=z,exports.getGooglePayButtonSrc=R,exports.linkedBankLabelFromMetadata=ue,exports.loadPlaidScript=fe,exports.mountAmosApplePayButton=De,exports.mountAmosBankAccountPaymentMethodForm=Te,exports.mountAmosCreditCardPaymentMethodForm=we,exports.mountAmosGooglePayButton=Ee,exports.openPlaidLink=pe,exports.plaidAccountIdFromMetadata=le,exports.requiresAchVerification=Y,exports.resetForm=y,exports.resolveWalletButtonSkeletonBorderRadius=L,exports.sendConfirmationResult=w,exports.sendParentReadyMessage=d,exports.updateAmount=h,exports.updateAppearance=f,exports.updateApplePayButton=p,exports.updateGooglePayButton=m,exports.updateMerchantName=g,exports.validateForm=_;
package/dist/index.mjs CHANGED
@@ -539,12 +539,12 @@ function U(e, t = { cardholderName: !1 }, n = "country") {
539
539
  });
540
540
  return `${i(e)}/iframe/card?${a}`;
541
541
  }
542
- function W(e, t = "country") {
543
- let n = new URLSearchParams({
542
+ function W(e, t = "country", n = "payment") {
543
+ let r = new URLSearchParams({
544
544
  token: e,
545
545
  billingAddressRequirement: t
546
546
  });
547
- return `${i(e)}/iframe/bank?${n}`;
547
+ return n === "setup" && r.set("intent", "setup"), `${i(e)}/iframe/bank?${r}`;
548
548
  }
549
549
  function G(e = { cardholderName: !1 }, t = "country") {
550
550
  return `${(V[t] ?? V.country) + (e.cardholderName ? se : 0)}px`;
@@ -945,36 +945,36 @@ function we(e, t) {
945
945
  });
946
946
  }
947
947
  function Te(e, t) {
948
- let n = Z(e), { renderToken: r, billingAddressRequirement: i = "country", amount: a = "0", ...o } = t, s = Q({
949
- src: W(r, i),
948
+ let n = Z(e), { renderToken: r, billingAddressRequirement: i = "country", amount: a = "0", intent: o = "payment", ...s } = t, c = Q({
949
+ src: W(r, i, o),
950
950
  title: "Secure bank account payment method form powered by Amos",
951
951
  name: "amos-bank-account-payment-method-form",
952
952
  height: K(i)
953
- }), c = Ce({
953
+ }), l = Ce({
954
954
  host: n,
955
- iframe: s,
956
- listenerOptions: o,
955
+ iframe: c,
956
+ listenerOptions: s,
957
957
  skeletonOptions: {
958
958
  kind: "bank",
959
- appearance: o.appearance,
959
+ appearance: s.appearance,
960
960
  billingAddressRequirement: i
961
961
  }
962
- }), l = ve({
962
+ }), u = ve({
963
963
  host: n,
964
- iframe: s,
964
+ iframe: c,
965
965
  options: {
966
966
  amount: a,
967
- appearance: o.appearance,
968
- onValidityChange: o.onValidityChange
967
+ appearance: s.appearance,
968
+ onValidityChange: s.onValidityChange
969
969
  }
970
970
  });
971
971
  return {
972
- iframe: s,
972
+ iframe: c,
973
973
  update(e) {
974
- c.update(e), l.update(e);
974
+ l.update(e), u.update(e);
975
975
  },
976
976
  destroy() {
977
- l.destroy(), c.destroy();
977
+ u.destroy(), l.destroy();
978
978
  }
979
979
  };
980
980
  }
package/dist/mount.d.ts CHANGED
@@ -85,9 +85,22 @@ export type AmosBankAccountPaymentMethodFormOptions = PaymentMethodFormListenerO
85
85
  * `"0"`, which is typically under the threshold so Connect / Plaid
86
86
  * stays hidden until the host passes a real charge.
87
87
  *
88
+ * Ignored when {@link AmosBankAccountPaymentMethodFormOptions.intent}
89
+ * is `"setup"` — setup intents always show Connect (unless the render
90
+ * token disables Plaid verification).
91
+ *
88
92
  * @default "0"
89
93
  */
90
94
  amount?: string;
95
+ /**
96
+ * `"setup"` saves a bank account for later charges and always shows
97
+ * Connect / Plaid (no merchant threshold lookup). `"payment"`
98
+ * compares {@link AmosBankAccountPaymentMethodFormOptions.amount} to
99
+ * the merchant ACH threshold.
100
+ *
101
+ * @default "payment"
102
+ */
103
+ intent?: "payment" | "setup";
91
104
  };
92
105
  /**
93
106
  * Mount the secure bank-account payment method form into a container
@@ -98,7 +111,8 @@ export type AmosBankAccountPaymentMethodFormOptions = PaymentMethodFormListenerO
98
111
  * Connect bank button is rendered in the parent document and Plaid Link
99
112
  * is opened on click. `amount` defaults to `"0"`, which is typically
100
113
  * under the threshold so Connect stays hidden on open-amount forms
101
- * until the host passes a real charge. The button uses the same
114
+ * until the host passes a real charge. Pass `intent: "setup"` to always
115
+ * show Connect without a merchant lookup. The button uses the same
102
116
  * `appearance.themeVariables` as the iframe (and inherits host-page
103
117
  * tokens when those variables are unset). Otherwise a field-shaped
104
118
  * skeleton is shown and replaced by the iframe once appearance is applied.
@@ -22,8 +22,11 @@ export type BillingAddressRequirement = "country" | "full";
22
22
  export declare function getCreditCardFormSrc(renderToken: string, additionalFields?: CreditCardAdditionalFields, billingAddressRequirement?: BillingAddressRequirement): string;
23
23
  /**
24
24
  * Build the iframe `src` URL for the embedded bank-account form.
25
+ *
26
+ * Pass `intent: "setup"` so the iframe always requires Plaid (when the
27
+ * render token allows it) and does not `GET /merchants` for a threshold.
25
28
  */
26
- export declare function getBankAccountFormSrc(renderToken: string, billingAddressRequirement?: BillingAddressRequirement): string;
29
+ export declare function getBankAccountFormSrc(renderToken: string, billingAddressRequirement?: BillingAddressRequirement, intent?: "payment" | "setup"): string;
27
30
  /**
28
31
  * Default iframe pixel height for the credit-card form, taking the
29
32
  * configured `additionalFields` and `billingAddressRequirement` into
package/dist/types.d.ts CHANGED
@@ -248,10 +248,11 @@ export type Message = {
248
248
  brand: CardBrand | null;
249
249
  } | {
250
250
  /**
251
- * Embed → parent: merchant ACH verification threshold for this
252
- * render token. `achThreshold` is cents, or `null` when the
253
- * merchant has no threshold (manual ACH). `requireVerification`
254
- * is true when the fetch failed in production (fail closed).
251
+ * Embed → parent: ACH verification policy for this bank iframe.
252
+ * `achThreshold` is cents, or `null` when the merchant has no
253
+ * threshold (manual ACH). `requireVerification` is true for setup
254
+ * intents (always Plaid, no merchant lookup), and when a payment
255
+ * threshold fetch failed in production (fail closed).
255
256
  */
256
257
  type: "ACH_THRESHOLD";
257
258
  achThreshold?: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amos.com/amos-js",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -35,11 +35,8 @@
35
35
  "author": "Amos",
36
36
  "license": "MIT",
37
37
  "description": "Amos JavaScript SDK for embedding payment methods via iframes.",
38
- "peerDependencies": {
39
- "@amos.com/node": ">=0.1.39"
40
- },
41
38
  "devDependencies": {
42
- "@amos.com/node": "0.1.39",
39
+ "@amos.com/node": "0.1.50",
43
40
  "@biomejs/biome": "2.5.7",
44
41
  "@changesets/cli": "2.31.1",
45
42
  "@types/node": "26.1.2",
@@ -50,5 +47,8 @@
50
47
  },
51
48
  "dependencies": {
52
49
  "@types/googlepay": "0.7.11"
50
+ },
51
+ "peerDependencies": {
52
+ "@amos.com/node": ">=0.1.50"
53
53
  }
54
54
  }
package/src/mount.ts CHANGED
@@ -514,9 +514,22 @@ export type AmosBankAccountPaymentMethodFormOptions =
514
514
  * `"0"`, which is typically under the threshold so Connect / Plaid
515
515
  * stays hidden until the host passes a real charge.
516
516
  *
517
+ * Ignored when {@link AmosBankAccountPaymentMethodFormOptions.intent}
518
+ * is `"setup"` — setup intents always show Connect (unless the render
519
+ * token disables Plaid verification).
520
+ *
517
521
  * @default "0"
518
522
  */
519
523
  amount?: string;
524
+ /**
525
+ * `"setup"` saves a bank account for later charges and always shows
526
+ * Connect / Plaid (no merchant threshold lookup). `"payment"`
527
+ * compares {@link AmosBankAccountPaymentMethodFormOptions.amount} to
528
+ * the merchant ACH threshold.
529
+ *
530
+ * @default "payment"
531
+ */
532
+ intent?: "payment" | "setup";
520
533
  };
521
534
 
522
535
  /**
@@ -528,7 +541,8 @@ export type AmosBankAccountPaymentMethodFormOptions =
528
541
  * Connect bank button is rendered in the parent document and Plaid Link
529
542
  * is opened on click. `amount` defaults to `"0"`, which is typically
530
543
  * under the threshold so Connect stays hidden on open-amount forms
531
- * until the host passes a real charge. The button uses the same
544
+ * until the host passes a real charge. Pass `intent: "setup"` to always
545
+ * show Connect without a merchant lookup. The button uses the same
532
546
  * `appearance.themeVariables` as the iframe (and inherits host-page
533
547
  * tokens when those variables are unset). Otherwise a field-shaped
534
548
  * skeleton is shown and replaced by the iframe once appearance is applied.
@@ -546,11 +560,12 @@ export function mountAmosBankAccountPaymentMethodForm(
546
560
  renderToken,
547
561
  billingAddressRequirement = "country",
548
562
  amount = "0",
563
+ intent = "payment",
549
564
  ...listenerOptions
550
565
  } = options;
551
566
 
552
567
  const iframe = createIframe({
553
- src: getBankAccountFormSrc(renderToken, billingAddressRequirement),
568
+ src: getBankAccountFormSrc(renderToken, billingAddressRequirement, intent),
554
569
  title: "Secure bank account payment method form powered by Amos",
555
570
  name: "amos-bank-account-payment-method-form",
556
571
  height: getBankAccountFormInitialHeight(billingAddressRequirement),
@@ -68,15 +68,22 @@ export function getCreditCardFormSrc(
68
68
 
69
69
  /**
70
70
  * Build the iframe `src` URL for the embedded bank-account form.
71
+ *
72
+ * Pass `intent: "setup"` so the iframe always requires Plaid (when the
73
+ * render token allows it) and does not `GET /merchants` for a threshold.
71
74
  */
72
75
  export function getBankAccountFormSrc(
73
76
  renderToken: string,
74
77
  billingAddressRequirement: BillingAddressRequirement = "country",
78
+ intent: "payment" | "setup" = "payment",
75
79
  ): string {
76
80
  const params = new URLSearchParams({
77
81
  token: renderToken,
78
82
  billingAddressRequirement,
79
83
  });
84
+ if (intent === "setup") {
85
+ params.set("intent", "setup");
86
+ }
80
87
 
81
88
  return `${getEmbedOrigin(renderToken)}/iframe/bank?${params}`;
82
89
  }
package/src/types.ts CHANGED
@@ -536,10 +536,11 @@ export type Message =
536
536
  }
537
537
  | {
538
538
  /**
539
- * Embed → parent: merchant ACH verification threshold for this
540
- * render token. `achThreshold` is cents, or `null` when the
541
- * merchant has no threshold (manual ACH). `requireVerification`
542
- * is true when the fetch failed in production (fail closed).
539
+ * Embed → parent: ACH verification policy for this bank iframe.
540
+ * `achThreshold` is cents, or `null` when the merchant has no
541
+ * threshold (manual ACH). `requireVerification` is true for setup
542
+ * intents (always Plaid, no merchant lookup), and when a payment
543
+ * threshold fetch failed in production (fail closed).
543
544
  */
544
545
  type: "ACH_THRESHOLD";
545
546
  achThreshold?: number | null;