@movmo_app/payments 0.6.0 → 0.7.0

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
@@ -4,8 +4,8 @@ PCI-safe card capture for Movmo UIs (`accounts-ui`, `flights-ui`) and airline pa
4
4
 
5
5
  ## What's in the box
6
6
 
7
- - **`<MovmoCardForm />`** — drop-in card-capture form (PCI-safe number + CVV iframes, single cardholder-name input, combined `MM / YY` expiry). The Save button is gated on Spreedly field validity; opt into auto-save via the `autoSave` prop. Tokenizes the card, then calls the Movmo API to save the vaulted card to the user's profile. Renders the detected card brand inline (Visa / MC / Amex / Discover) as the user types.
8
- - **`<PaymentMethodsManager />`** — full saved-cards UI: lists existing cards, lets the user set default / remove, and embeds `<MovmoCardForm />` for adding a new one. Renders a payment-type selector (Credit card + disabled "Coming soon" rows for PayPal / GooglePay / Klarna / ACH) by default; pass `paymentTypeSelector={false}` to hide it. Auto-saves the first card by default (`autoSaveFirstCard={true}` — matches flights-ui UX). Optional selection mode (`selectedId` + `onSelect`) for checkout flows.
7
+ - **`<MovmoCardForm />`** — drop-in card-capture form (PCI-safe number + CVV iframes, single cardholder-name input, combined `MM / YY` expiry). The Save button is gated on Spreedly field validity; opt into auto-save via the `autoSave` prop. Tokenizes the card, then calls the Movmo API to save the vaulted card to the user's profile. Renders the detected card brand inline (Visa / MC / Amex / Discover) as the user types. A field is only marked invalid once the user has left it ("touched") — inline messages appear under the number shell, one shared message under the expiry/CVV/postal row (whichever of those is invalid first in visual order), and under the name field, each wired to its input via `aria-describedby`. While `autoSave` is on, a live-region status line reads "Saving card…" during the save and otherwise nudges with the form's built-in hint copy ("Your card saves automatically once all fields are complete.") while required fields are still missing. Postal-code validation is international-friendly (3–10 letters/digits/spaces/hyphens, not US-only); ZIP+4 auto-hyphenation only kicks in for a complete 9-digit numeric US ZIP or a hyphen the user typed themselves. Pass `onValidationChange?: (state: CardValidationState) => void` to observe live validity (`{ valid, missing, touchedInvalid }`, field keys only — no PII) without wiring your own field-by-field logic.
8
+ - **`<PaymentMethodsManager />`** — full saved-cards UI: lists existing cards, lets the user set default / remove, and embeds `<MovmoCardForm />` for adding a new one. Renders a payment-type selector (Credit card + disabled "Coming soon" rows for PayPal / GooglePay / Klarna / ACH) by default; pass `paymentTypeSelector={false}` to hide it. Auto-saves the first card by default (`autoSaveFirstCard={true}` — matches flights-ui UX). Optional selection mode (`selectedId` + `onSelect`) for checkout flows. `onEvent` now also fires `'validation_error'` (`{ field_count, fields }`) once per touched-invalid streak on the embedded card form, re-arming once the user clears it.
9
9
  - **`useMovmoCardFields()`** — lower-level hook for partners composing their own form layout. Exposes per-field `validity` + detected `brand` so the consumer can gate its own submit button and render its own brand icon.
10
10
  - **`useUserPaymentMethods(userId)`** — fetches the saved-cards list with `{ items, status, error, refetch }`. Useful standalone (e.g., showing the selected card's last4 in a checkout summary).
11
11
  - **`useDeletePaymentMethod(userId)`** — exposes `{ deletePaymentMethod, status, error }`. Resolves on success, rejects on failure so callers can roll back optimistic updates.
@@ -108,3 +108,11 @@ pnpm --filter @movmo_app/payments storybook # → http://localhost:6007
108
108
  ```
109
109
 
110
110
  Storybook is the primary way to exercise the components on a laptop: it mocks both the underlying vault SDK and the `monolith-api` calls, so no vault credentials, no live backend, and no real card data are required. See `src/MovmoCardForm/__docs__/MovmoCardForm.stories.tsx` and `src/PaymentMethodsManager/__docs__/PaymentMethodsManager.stories.tsx` for the full state matrices.
111
+
112
+ ## Screenshot review
113
+
114
+ ```bash
115
+ pnpm --filter @movmo_app/payments screenshots
116
+ ```
117
+
118
+ Boots Storybook on port 6007 and drives it with Playwright to capture PNGs of the auto-save/validation stories into `screenshots/out/` for visual review — not a CI suite, no pixel assertions. The whole `screenshots/` directory (including the spec itself) is local-only and gitignored — it isn't part of the published package or the repo's git history. The canonical copy of the spec lives at `brain/scripts/payments-screenshot-capture.spec.ts`; copy it into `screenshots/capture.spec.ts` before running the command above. See `playwright.screenshots.config.ts` for the harness config.
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Jt=Object.defineProperty;var Zt=(t,r,s)=>r in t?Jt(t,r,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[r]=s;var lt=(t,r,s)=>Zt(t,typeof r!="symbol"?r+"":r,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react");var pt={exports:{}},qe={};/**
1
+ "use strict";var er=Object.defineProperty;var tr=(t,r,n)=>r in t?er(t,r,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[r]=n;var ut=(t,r,n)=>tr(t,typeof r!="symbol"?r+"":r,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react");var yt={exports:{}},Qe={};/**
2
2
  * @license React
3
3
  * react-jsx-runtime.production.min.js
4
4
  *
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
- */var wt;function Xt(){if(wt)return qe;wt=1;var t=n,r=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,l=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function f(x,m,R){var w,p={},v=null,E=null;R!==void 0&&(v=""+R),m.key!==void 0&&(v=""+m.key),m.ref!==void 0&&(E=m.ref);for(w in m)o.call(m,w)&&!c.hasOwnProperty(w)&&(p[w]=m[w]);if(x&&x.defaultProps)for(w in m=x.defaultProps,m)p[w]===void 0&&(p[w]=m[w]);return{$$typeof:r,type:x,key:v,ref:E,props:p,_owner:l.current}}return qe.Fragment=s,qe.jsx=f,qe.jsxs=f,qe}var Ke={};/**
9
+ */var jt;function rr(){if(jt)return Qe;jt=1;var t=s,r=Symbol.for("react.element"),n=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,l=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function m(y,f,N){var E,x={},g=null,j=null;N!==void 0&&(g=""+N),f.key!==void 0&&(g=""+f.key),f.ref!==void 0&&(j=f.ref);for(E in f)o.call(f,E)&&!c.hasOwnProperty(E)&&(x[E]=f[E]);if(y&&y.defaultProps)for(E in f=y.defaultProps,f)x[E]===void 0&&(x[E]=f[E]);return{$$typeof:r,type:y,key:g,ref:j,props:x,_owner:l.current}}return Qe.Fragment=n,Qe.jsx=m,Qe.jsxs=m,Qe}var et={};/**
10
10
  * @license React
11
11
  * react-jsx-runtime.development.js
12
12
  *
@@ -14,18 +14,18 @@
14
14
  *
15
15
  * This source code is licensed under the MIT license found in the
16
16
  * LICENSE file in the root directory of this source tree.
17
- */var Et;function Qt(){return Et||(Et=1,process.env.NODE_ENV!=="production"&&function(){var t=n,r=Symbol.for("react.element"),s=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),x=Symbol.for("react.context"),m=Symbol.for("react.forward_ref"),R=Symbol.for("react.suspense"),w=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),E=Symbol.for("react.offscreen"),T=Symbol.iterator,se="@@iterator";function M(e){if(e===null||typeof e!="object")return null;var i=T&&e[T]||e[se];return typeof i=="function"?i:null}var C=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function b(e){{for(var i=arguments.length,d=new Array(i>1?i-1:0),y=1;y<i;y++)d[y-1]=arguments[y];Y("error",e,d)}}function Y(e,i,d){{var y=C.ReactDebugCurrentFrame,F=y.getStackAddendum();F!==""&&(i+="%s",d=d.concat([F]));var O=d.map(function(k){return String(k)});O.unshift("Warning: "+i),Function.prototype.apply.call(console[e],console,O)}}var ee=!1,ve=!1,ue=!1,te=!1,oe=!1,D;D=Symbol.for("react.module.reference");function j(e){return!!(typeof e=="string"||typeof e=="function"||e===o||e===c||oe||e===l||e===R||e===w||te||e===E||ee||ve||ue||typeof e=="object"&&e!==null&&(e.$$typeof===v||e.$$typeof===p||e.$$typeof===f||e.$$typeof===x||e.$$typeof===m||e.$$typeof===D||e.getModuleId!==void 0))}function fe(e,i,d){var y=e.displayName;if(y)return y;var F=i.displayName||i.name||"";return F!==""?d+"("+F+")":d}function Ee(e){return e.displayName||"Context"}function S(e){if(e==null)return null;if(typeof e.tag=="number"&&b("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case o:return"Fragment";case s:return"Portal";case c:return"Profiler";case l:return"StrictMode";case R:return"Suspense";case w:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case x:var i=e;return Ee(i)+".Consumer";case f:var d=e;return Ee(d._context)+".Provider";case m:return fe(e,e.render,"ForwardRef");case p:var y=e.displayName||null;return y!==null?y:S(e.type)||"Memo";case v:{var F=e,O=F._payload,k=F._init;try{return S(k(O))}catch{return null}}}return null}var g=Object.assign,h=0,N,U,K,me,G,re,H;function W(){}W.__reactDisabledLog=!0;function Z(){{if(h===0){N=console.log,U=console.info,K=console.warn,me=console.error,G=console.group,re=console.groupCollapsed,H=console.groupEnd;var e={configurable:!0,enumerable:!0,value:W,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}h++}}function je(){{if(h--,h===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:g({},e,{value:N}),info:g({},e,{value:U}),warn:g({},e,{value:K}),error:g({},e,{value:me}),group:g({},e,{value:G}),groupCollapsed:g({},e,{value:re}),groupEnd:g({},e,{value:H})})}h<0&&b("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var pe=C.ReactCurrentDispatcher,he;function ie(e,i,d){{if(he===void 0)try{throw Error()}catch(F){var y=F.stack.trim().match(/\n( *(at )?)/);he=y&&y[1]||""}return`
18
- `+he+e}}var ae=!1,_e;{var Fe=typeof WeakMap=="function"?WeakMap:Map;_e=new Fe}function le(e,i){if(!e||ae)return"";{var d=_e.get(e);if(d!==void 0)return d}var y;ae=!0;var F=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var O;O=pe.current,pe.current=null,Z();try{if(i){var k=function(){throw Error()};if(Object.defineProperty(k.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(k,[])}catch(ce){y=ce}Reflect.construct(e,[],k)}else{try{k.call()}catch(ce){y=ce}e.call(k.prototype)}}else{try{throw Error()}catch(ce){y=ce}e()}}catch(ce){if(ce&&y&&typeof ce.stack=="string"){for(var _=ce.stack.split(`
19
- `),ne=y.stack.split(`
20
- `),V=_.length-1,q=ne.length-1;V>=1&&q>=0&&_[V]!==ne[q];)q--;for(;V>=1&&q>=0;V--,q--)if(_[V]!==ne[q]){if(V!==1||q!==1)do if(V--,q--,q<0||_[V]!==ne[q]){var ye=`
21
- `+_[V].replace(" at new "," at ");return e.displayName&&ye.includes("<anonymous>")&&(ye=ye.replace("<anonymous>",e.displayName)),typeof e=="function"&&_e.set(e,ye),ye}while(V>=1&&q>=0);break}}}finally{ae=!1,pe.current=O,je(),Error.prepareStackTrace=F}var Oe=e?e.displayName||e.name:"",Pe=Oe?ie(Oe):"";return typeof e=="function"&&_e.set(e,Pe),Pe}function J(e,i,d){return le(e,!1)}function ge(e){var i=e.prototype;return!!(i&&i.isReactComponent)}function z(e,i,d){if(e==null)return"";if(typeof e=="function")return le(e,ge(e));if(typeof e=="string")return ie(e);switch(e){case R:return ie("Suspense");case w:return ie("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case m:return J(e.render);case p:return z(e.type,i,d);case v:{var y=e,F=y._payload,O=y._init;try{return z(O(F),i,d)}catch{}}}return""}var xe=Object.prototype.hasOwnProperty,Se={},we=C.ReactDebugCurrentFrame;function X(e){if(e){var i=e._owner,d=z(e.type,e._source,i?i.type:null);we.setExtraStackFrame(d)}else we.setExtraStackFrame(null)}function P(e,i,d,y,F){{var O=Function.call.bind(xe);for(var k in e)if(O(e,k)){var _=void 0;try{if(typeof e[k]!="function"){var ne=Error((y||"React class")+": "+d+" type `"+k+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[k]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw ne.name="Invariant Violation",ne}_=e[k](i,k,y,d,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(V){_=V}_&&!(_ instanceof Error)&&(X(F),b("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",y||"React class",d,k,typeof _),X(null)),_ instanceof Error&&!(_.message in Se)&&(Se[_.message]=!0,X(F),b("Failed %s type: %s",d,_.message),X(null))}}}var $=Array.isArray;function A(e){return $(e)}function de(e){{var i=typeof Symbol=="function"&&Symbol.toStringTag,d=i&&e[Symbol.toStringTag]||e.constructor.name||"Object";return d}}function ot(e){try{return Je(e),!1}catch{return!0}}function Je(e){return""+e}function We(e){if(ot(e))return b("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",de(e)),Je(e)}var Ze=C.ReactCurrentOwner,Xe={key:!0,ref:!0,__self:!0,__source:!0},Le,Qe;function ze(e){if(xe.call(e,"ref")){var i=Object.getOwnPropertyDescriptor(e,"ref").get;if(i&&i.isReactWarning)return!1}return e.ref!==void 0}function et(e){if(xe.call(e,"key")){var i=Object.getOwnPropertyDescriptor(e,"key").get;if(i&&i.isReactWarning)return!1}return e.key!==void 0}function tt(e,i){typeof e.ref=="string"&&Ze.current}function rt(e,i){{var d=function(){Le||(Le=!0,b("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",i))};d.isReactWarning=!0,Object.defineProperty(e,"key",{get:d,configurable:!0})}}function Me(e,i){{var d=function(){Qe||(Qe=!0,b("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",i))};d.isReactWarning=!0,Object.defineProperty(e,"ref",{get:d,configurable:!0})}}var Be=function(e,i,d,y,F,O,k){var _={$$typeof:r,type:e,key:i,ref:d,props:k,_owner:O};return _._store={},Object.defineProperty(_._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(_,"_self",{configurable:!1,enumerable:!1,writable:!1,value:y}),Object.defineProperty(_,"_source",{configurable:!1,enumerable:!1,writable:!1,value:F}),Object.freeze&&(Object.freeze(_.props),Object.freeze(_)),_};function Ye(e,i,d,y,F){{var O,k={},_=null,ne=null;d!==void 0&&(We(d),_=""+d),et(i)&&(We(i.key),_=""+i.key),ze(i)&&(ne=i.ref,tt(i,F));for(O in i)xe.call(i,O)&&!Xe.hasOwnProperty(O)&&(k[O]=i[O]);if(e&&e.defaultProps){var V=e.defaultProps;for(O in V)k[O]===void 0&&(k[O]=V[O])}if(_||ne){var q=typeof e=="function"?e.displayName||e.name||"Unknown":e;_&&rt(k,q),ne&&Me(k,q)}return Be(e,_,ne,F,y,Ze.current,k)}}var ke=C.ReactCurrentOwner,at=C.ReactDebugCurrentFrame;function Re(e){if(e){var i=e._owner,d=z(e.type,e._source,i?i.type:null);at.setExtraStackFrame(d)}else at.setExtraStackFrame(null)}var u;u=!1;function B(e){return typeof e=="object"&&e!==null&&e.$$typeof===r}function I(){{if(ke.current){var e=S(ke.current.type);if(e)return`
17
+ */var _t;function ar(){return _t||(_t=1,process.env.NODE_ENV!=="production"&&function(){var t=s,r=Symbol.for("react.element"),n=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),m=Symbol.for("react.provider"),y=Symbol.for("react.context"),f=Symbol.for("react.forward_ref"),N=Symbol.for("react.suspense"),E=Symbol.for("react.suspense_list"),x=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),j=Symbol.for("react.offscreen"),P=Symbol.iterator,re="@@iterator";function A(e){if(e===null||typeof e!="object")return null;var i=P&&e[P]||e[re];return typeof i=="function"?i:null}var _=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function k(e){{for(var i=arguments.length,d=new Array(i>1?i-1:0),b=1;b<i;b++)d[b-1]=arguments[b];D("error",e,d)}}function D(e,i,d){{var b=_.ReactDebugCurrentFrame,F=b.getStackAddendum();F!==""&&(i+="%s",d=d.concat([F]));var W=d.map(function(R){return String(R)});W.unshift("Warning: "+i),Function.prototype.apply.call(console[e],console,W)}}var pe=!1,de=!1,ge=!1,ue=!1,se=!1,X;X=Symbol.for("react.module.reference");function w(e){return!!(typeof e=="string"||typeof e=="function"||e===o||e===c||se||e===l||e===N||e===E||ue||e===j||pe||de||ge||typeof e=="object"&&e!==null&&(e.$$typeof===g||e.$$typeof===x||e.$$typeof===m||e.$$typeof===y||e.$$typeof===f||e.$$typeof===X||e.getModuleId!==void 0))}function ye(e,i,d){var b=e.displayName;if(b)return b;var F=i.displayName||i.name||"";return F!==""?d+"("+F+")":d}function _e(e){return e.displayName||"Context"}function z(e){if(e==null)return null;if(typeof e.tag=="number"&&k("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case o:return"Fragment";case n:return"Portal";case c:return"Profiler";case l:return"StrictMode";case N:return"Suspense";case E:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case y:var i=e;return _e(i)+".Consumer";case m:var d=e;return _e(d._context)+".Provider";case f:return ye(e,e.render,"ForwardRef");case x:var b=e.displayName||null;return b!==null?b:z(e.type)||"Memo";case g:{var F=e,W=F._payload,R=F._init;try{return z(R(W))}catch{return null}}}return null}var h=Object.assign,v=0,S,M,te,ae,H,G,Y;function T(){}T.__reactDisabledLog=!0;function K(){{if(v===0){S=console.log,M=console.info,te=console.warn,ae=console.error,H=console.group,G=console.groupCollapsed,Y=console.groupEnd;var e={configurable:!0,enumerable:!0,value:T,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}v++}}function Ce(){{if(v--,v===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:h({},e,{value:S}),info:h({},e,{value:M}),warn:h({},e,{value:te}),error:h({},e,{value:ae}),group:h({},e,{value:H}),groupCollapsed:h({},e,{value:G}),groupEnd:h({},e,{value:Y})})}v<0&&k("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var ve=_.ReactCurrentDispatcher,q;function we(e,i,d){{if(q===void 0)try{throw Error()}catch(F){var b=F.stack.trim().match(/\n( *(at )?)/);q=b&&b[1]||""}return`
18
+ `+q+e}}var J=!1,Pe;{var ke=typeof WeakMap=="function"?WeakMap:Map;Pe=new ke}function ne(e,i){if(!e||J)return"";{var d=Pe.get(e);if(d!==void 0)return d}var b;J=!0;var F=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var W;W=ve.current,ve.current=null,K();try{if(i){var R=function(){throw Error()};if(Object.defineProperty(R.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(R,[])}catch(fe){b=fe}Reflect.construct(e,[],R)}else{try{R.call()}catch(fe){b=fe}e.call(R.prototype)}}else{try{throw Error()}catch(fe){b=fe}e()}}catch(fe){if(fe&&b&&typeof fe.stack=="string"){for(var C=fe.stack.split(`
19
+ `),ce=b.stack.split(`
20
+ `),B=C.length-1,V=ce.length-1;B>=1&&V>=0&&C[B]!==ce[V];)V--;for(;B>=1&&V>=0;B--,V--)if(C[B]!==ce[V]){if(B!==1||V!==1)do if(B--,V--,V<0||C[B]!==ce[V]){var be=`
21
+ `+C[B].replace(" at new "," at ");return e.displayName&&be.includes("<anonymous>")&&(be=be.replace("<anonymous>",e.displayName)),typeof e=="function"&&Pe.set(e,be),be}while(B>=1&&V>=0);break}}}finally{J=!1,ve.current=W,Ce(),Error.prepareStackTrace=F}var He=e?e.displayName||e.name:"",Be=He?we(He):"";return typeof e=="function"&&Pe.set(e,Be),Be}function Q(e,i,d){return ne(e,!1)}function Te(e){var i=e.prototype;return!!(i&&i.isReactComponent)}function $(e,i,d){if(e==null)return"";if(typeof e=="function")return ne(e,Te(e));if(typeof e=="string")return we(e);switch(e){case N:return we("Suspense");case E:return we("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case f:return Q(e.render);case x:return $(e.type,i,d);case g:{var b=e,F=b._payload,W=b._init;try{return $(W(F),i,d)}catch{}}}return""}var oe=Object.prototype.hasOwnProperty,Re={},ee=_.ReactDebugCurrentFrame;function Ee(e){if(e){var i=e._owner,d=$(e.type,e._source,i?i.type:null);ee.setExtraStackFrame(d)}else ee.setExtraStackFrame(null)}function Fe(e,i,d,b,F){{var W=Function.call.bind(oe);for(var R in e)if(W(e,R)){var C=void 0;try{if(typeof e[R]!="function"){var ce=Error((b||"React class")+": "+d+" type `"+R+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[R]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw ce.name="Invariant Violation",ce}C=e[R](i,R,b,d,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(B){C=B}C&&!(C instanceof Error)&&(Ee(F),k("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",b||"React class",d,R,typeof C),Ee(null)),C instanceof Error&&!(C.message in Re)&&(Re[C.message]=!0,Ee(F),k("Failed %s type: %s",d,C.message),Ee(null))}}}var he=Array.isArray;function Ie(e){return he(e)}function xe(e){{var i=typeof Symbol=="function"&&Symbol.toStringTag,d=i&&e[Symbol.toStringTag]||e.constructor.name||"Object";return d}}function ie(e){try{return We(e),!1}catch{return!0}}function We(e){return""+e}function Me(e){if(ie(e))return k("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",xe(e)),We(e)}var Ae=_.ReactCurrentOwner,Le={key:!0,ref:!0,__self:!0,__source:!0},De,Ne;function p(e){if(oe.call(e,"ref")){var i=Object.getOwnPropertyDescriptor(e,"ref").get;if(i&&i.isReactWarning)return!1}return e.ref!==void 0}function O(e){if(oe.call(e,"key")){var i=Object.getOwnPropertyDescriptor(e,"key").get;if(i&&i.isReactWarning)return!1}return e.key!==void 0}function me(e,i){typeof e.ref=="string"&&Ae.current}function le(e,i){{var d=function(){De||(De=!0,k("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",i))};d.isReactWarning=!0,Object.defineProperty(e,"key",{get:d,configurable:!0})}}function at(e,i){{var d=function(){Ne||(Ne=!0,k("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",i))};d.isReactWarning=!0,Object.defineProperty(e,"ref",{get:d,configurable:!0})}}var st=function(e,i,d,b,F,W,R){var C={$$typeof:r,type:e,key:i,ref:d,props:R,_owner:W};return C._store={},Object.defineProperty(C._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(C,"_self",{configurable:!1,enumerable:!1,writable:!1,value:b}),Object.defineProperty(C,"_source",{configurable:!1,enumerable:!1,writable:!1,value:F}),Object.freeze&&(Object.freeze(C.props),Object.freeze(C)),C};function nt(e,i,d,b,F){{var W,R={},C=null,ce=null;d!==void 0&&(Me(d),C=""+d),O(i)&&(Me(i.key),C=""+i.key),p(i)&&(ce=i.ref,me(i,F));for(W in i)oe.call(i,W)&&!Le.hasOwnProperty(W)&&(R[W]=i[W]);if(e&&e.defaultProps){var B=e.defaultProps;for(W in B)R[W]===void 0&&(R[W]=B[W])}if(C||ce){var V=typeof e=="function"?e.displayName||e.name||"Unknown":e;C&&le(R,V),ce&&at(R,V)}return st(e,C,ce,F,b,Ae.current,R)}}var $e=_.ReactCurrentOwner,Ve=_.ReactDebugCurrentFrame;function Se(e){if(e){var i=e._owner,d=$(e.type,e._source,i?i.type:null);Ve.setExtraStackFrame(d)}else Ve.setExtraStackFrame(null)}var Ue;Ue=!1;function Xe(e){return typeof e=="object"&&e!==null&&e.$$typeof===r}function ot(){{if($e.current){var e=z($e.current.type);if(e)return`
22
22
 
23
- Check the render method of \``+e+"`."}return""}}function L(e){return""}var be={};function Ce(e){{var i=I();if(!i){var d=typeof e=="string"?e:e.displayName||e.name;d&&(i=`
23
+ Check the render method of \``+e+"`."}return""}}function u(e){return""}var L={};function I(e){{var i=ot();if(!i){var d=typeof e=="string"?e:e.displayName||e.name;d&&(i=`
24
24
 
25
- Check the top-level render call using <`+d+">.")}return i}}function Ve(e,i){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var d=Ce(i);if(be[d])return;be[d]=!0;var y="";e&&e._owner&&e._owner!==ke.current&&(y=" It was passed a child from "+S(e._owner.type)+"."),Re(e),b('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',d,y),Re(null)}}function gt(e,i){{if(typeof e!="object")return;if(A(e))for(var d=0;d<e.length;d++){var y=e[d];B(y)&&Ve(y,i)}else if(B(e))e._store&&(e._store.validated=!0);else if(e){var F=M(e);if(typeof F=="function"&&F!==e.entries)for(var O=F.call(e),k;!(k=O.next()).done;)B(k.value)&&Ve(k.value,i)}}}function zt(e){{var i=e.type;if(i==null||typeof i=="string")return;var d;if(typeof i=="function")d=i.propTypes;else if(typeof i=="object"&&(i.$$typeof===m||i.$$typeof===p))d=i.propTypes;else return;if(d){var y=S(i);P(d,e.props,"prop",y,e)}else if(i.PropTypes!==void 0&&!u){u=!0;var F=S(i);b("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",F||"Unknown")}typeof i.getDefaultProps=="function"&&!i.getDefaultProps.isReactClassApproved&&b("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function Bt(e){{for(var i=Object.keys(e.props),d=0;d<i.length;d++){var y=i[d];if(y!=="children"&&y!=="key"){Re(e),b("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",y),Re(null);break}}e.ref!==null&&(Re(e),b("Invalid attribute `ref` supplied to `React.Fragment`."),Re(null))}}var xt={};function bt(e,i,d,y,F,O){{var k=j(e);if(!k){var _="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(_+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var ne=L();ne?_+=ne:_+=I();var V;e===null?V="null":A(e)?V="array":e!==void 0&&e.$$typeof===r?(V="<"+(S(e.type)||"Unknown")+" />",_=" Did you accidentally export a JSX literal instead of a component?"):V=typeof e,b("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",V,_)}var q=Ye(e,i,d,F,O);if(q==null)return q;if(k){var ye=i.children;if(ye!==void 0)if(y)if(A(ye)){for(var Oe=0;Oe<ye.length;Oe++)gt(ye[Oe],e);Object.freeze&&Object.freeze(ye)}else b("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else gt(ye,e)}if(xe.call(i,"key")){var Pe=S(e),ce=Object.keys(i).filter(function(Ht){return Ht!=="key"}),it=ce.length>0?"{key: someKey, "+ce.join(": ..., ")+": ...}":"{key: someKey}";if(!xt[Pe+it]){var Gt=ce.length>0?"{"+ce.join(": ..., ")+": ...}":"{}";b(`A props object containing a "key" prop is being spread into JSX:
25
+ Check the top-level render call using <`+d+">.")}return i}}function U(e,i){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var d=I(i);if(L[d])return;L[d]=!0;var b="";e&&e._owner&&e._owner!==$e.current&&(b=" It was passed a child from "+z(e._owner.type)+"."),Se(e),k('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',d,b),Se(null)}}function je(e,i){{if(typeof e!="object")return;if(Ie(e))for(var d=0;d<e.length;d++){var b=e[d];Xe(b)&&U(b,i)}else if(Xe(e))e._store&&(e._store.validated=!0);else if(e){var F=A(e);if(typeof F=="function"&&F!==e.entries)for(var W=F.call(e),R;!(R=W.next()).done;)Xe(R.value)&&U(R.value,i)}}}function Oe(e){{var i=e.type;if(i==null||typeof i=="string")return;var d;if(typeof i=="function")d=i.propTypes;else if(typeof i=="object"&&(i.$$typeof===f||i.$$typeof===x))d=i.propTypes;else return;if(d){var b=z(i);Fe(d,e.props,"prop",b,e)}else if(i.PropTypes!==void 0&&!Ue){Ue=!0;var F=z(i);k("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",F||"Unknown")}typeof i.getDefaultProps=="function"&&!i.getDefaultProps.isReactClassApproved&&k("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function it(e){{for(var i=Object.keys(e.props),d=0;d<i.length;d++){var b=i[d];if(b!=="children"&&b!=="key"){Se(e),k("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",b),Se(null);break}}e.ref!==null&&(Se(e),k("Invalid attribute `ref` supplied to `React.Fragment`."),Se(null))}}var wt={};function Et(e,i,d,b,F,W){{var R=w(e);if(!R){var C="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(C+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var ce=u();ce?C+=ce:C+=ot();var B;e===null?B="null":Ie(e)?B="array":e!==void 0&&e.$$typeof===r?(B="<"+(z(e.type)||"Unknown")+" />",C=" Did you accidentally export a JSX literal instead of a component?"):B=typeof e,k("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",B,C)}var V=nt(e,i,d,F,W);if(V==null)return V;if(R){var be=i.children;if(be!==void 0)if(b)if(Ie(be)){for(var He=0;He<be.length;He++)je(be[He],e);Object.freeze&&Object.freeze(be)}else k("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else je(be,e)}if(oe.call(i,"key")){var Be=z(e),fe=Object.keys(i).filter(function(Qt){return Qt!=="key"}),dt=fe.length>0?"{key: someKey, "+fe.join(": ..., ")+": ...}":"{key: someKey}";if(!wt[Be+dt]){var Xt=fe.length>0?"{"+fe.join(": ..., ")+": ...}":"{}";k(`A props object containing a "key" prop is being spread into JSX:
26
26
  let props = %s;
27
27
  <%s {...props} />
28
28
  React keys must be passed directly to JSX without using spread:
29
29
  let props = %s;
30
- <%s key={someKey} {...props} />`,it,Pe,Gt,Pe),xt[Pe+it]=!0}}return e===o?Bt(q):zt(q),q}}function Yt(e,i,d){return bt(e,i,d,!0)}function Vt(e,i,d){return bt(e,i,d,!1)}var qt=Vt,Kt=Yt;Ke.Fragment=o,Ke.jsx=qt,Ke.jsxs=Kt}()),Ke}process.env.NODE_ENV==="production"?pt.exports=Xt():pt.exports=Qt();var a=pt.exports;function Tt(t){var r,s,o="";if(typeof t=="string"||typeof t=="number")o+=t;else if(typeof t=="object")if(Array.isArray(t)){var l=t.length;for(r=0;r<l;r++)t[r]&&(s=Tt(t[r]))&&(o&&(o+=" "),o+=s)}else for(s in t)t[s]&&(o&&(o+=" "),o+=s);return o}function Q(){for(var t,r,s=0,o="",l=arguments.length;s<l;s++)(t=arguments[s])&&(r=Tt(t))&&(o&&(o+=" "),o+=r);return o}const er="https://core.spreedly.com/iframe/iframe-v1.min.js",tr="https://cdn.e2e.movmo.io";let De={};const rr=t=>{De={...De,...t}},ct=t=>{var s;const r=globalThis.process;return(s=r==null?void 0:r.env)==null?void 0:s[t]},Te=()=>({baseUrl:De.baseUrl??ct("REACT_APP_MOVMO_API_URL")??"",spreedlyScriptUrl:De.spreedlyScriptUrl??ct("REACT_APP_SPREEDLY_SCRIPT_URL")??er,iconCdnBaseUrl:De.iconCdnBaseUrl??ct("REACT_APP_MOVMO_ICON_CDN_URL")??tr,fetch:De.fetch??(typeof globalThis<"u"&&typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):(()=>{throw new Error("@movmo_app/payments: no fetch available")})())}),ht=t=>({id:t.id,last4:t.last4,brand:t.brand,expMonth:t.expMonth,expYear:t.expYear,isDefault:t.isDefault,vault:t.vault,cardholderName:t.cardholderName,zip:t.zip}),$e={Accept:"application/json","Content-Type":"application/json"},Ae=t=>{const{baseUrl:r}=Te();if(!r)throw new Error("@movmo_app/payments: baseUrl is not configured. Call setPaymentsConfig({ baseUrl }) at app boot, or set REACT_APP_MOVMO_API_URL.");return`${r}${t}`},Ue=(t,r)=>{const{fetch:s}=Te();return s(t,r)},Ie=async(t,r)=>{try{return(await t.json()).message||r}catch{return r}};let Ge=null;const yt=()=>{if(Ge)return Ge;const t=(async()=>{const r=await Ue(Ae("/v1/payments/tokenization-session"),{method:"GET",headers:$e,credentials:"include"});if(!r.ok)throw new Error(await Ie(r,`Failed to fetch tokenization session (${r.status})`));return await r.json()})();return Ge=t,t.finally(()=>{Ge===t&&(Ge=null)}).catch(()=>{}),t},ar=t=>typeof t.brand=="string"&&typeof t.last4=="string"&&typeof t.expMonth=="number"&&typeof t.expYear=="number",nr=async(t,r,s)=>{const o=await Ue(Ae(`/v1/users/${encodeURIComponent(t)}/payment-methods/from-token`),{method:"POST",headers:$e,credentials:"include",body:JSON.stringify({tokenizedPaymentMethodId:r,isDefault:s})});if(!o.ok)throw new Error(await Ie(o,`Failed to save payment method (${o.status})`));const l=await o.json();if(ar(l))return ht(l);const c=await Ue(Ae(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(l.id)}`),{method:"GET",headers:$e,credentials:"include"});if(!c.ok)throw new Error(await Ie(c,`Failed to fetch saved payment method (${c.status})`));const f=await c.json();return ht(f)},sr=async(t,r)=>{if(!t)return[];const s=await Ue(Ae(`/v1/users/${encodeURIComponent(t)}/payment-methods`),{method:"GET",headers:$e,credentials:"include",signal:r});if(!s.ok)throw new Error(await Ie(s,`Failed to fetch payment methods (${s.status})`));return(await s.json()??[]).map(ht)},or=async(t,r)=>{const s=await Ue(Ae(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"DELETE",headers:$e,credentials:"include"});if(!s.ok)throw new Error(await Ie(s,`Failed to delete payment method (${s.status})`))},Ft=async(t,r,s)=>{const o=await Ue(Ae(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"PUT",headers:$e,credentials:"include",body:JSON.stringify(s)});if(!o.ok)throw new Error(await Ie(o,`Failed to update payment method (${o.status})`))},ir={visa:"visa",master:"mastercard",mastercard:"mastercard",american_express:"amex",amex:"amex",discover:"discover"},lr=28,Ne=({brand:t,className:r,width:s=46})=>{const o=t?ir[t.toLowerCase()]??"credit-card":"credit-card",l=Math.max(s,lr),c=Math.round(l*24/34),{iconCdnBaseUrl:f}=Te();return a.jsx("img",{src:`${f}/website/assets/icons/payments/${o}.svg`,alt:o==="credit-card"?"card":`${o} card`,"data-testid":`card-brand-${t.toLowerCase()}`,className:r,width:l,height:c,loading:"lazy"})};let He=null;const cr=()=>{if(typeof window>"u")return Promise.reject(new Error("Spreedly can only be loaded in a browser environment."));if(window.Spreedly)return Promise.resolve(window.Spreedly);if(He)return He;const{spreedlyScriptUrl:t}=Te();return He=new Promise((r,s)=>{const o=document.querySelector(`script[src="${t}"]`),l=()=>{window.Spreedly?r(window.Spreedly):s(new Error("Spreedly script loaded but window.Spreedly is undefined."))};if(o){if(window.Spreedly){l();return}o.addEventListener("load",l,{once:!0}),o.addEventListener("error",()=>{o.remove(),s(new Error("Failed to load Spreedly iframe script."))},{once:!0});return}const c=document.createElement("script");c.src=t,c.async=!0,c.onload=l,c.onerror=()=>{c.remove(),s(new Error("Failed to load Spreedly iframe script."))},document.head.appendChild(c)}).catch(r=>{throw He=null,r}),He};class nt extends Error{constructor(s,o){super(o instanceof Error?o.message:"Failed to initialize card form.");lt(this,"source");lt(this,"cause");this.name="InitError",this.source=s,this.cause=o}}const dr="movmo-card-number",ur="movmo-card-cvv",fr=t=>({first_name:t.firstName,last_name:t.lastName,month:t.month,year:t.year,...t.email?{email:t.email}:{},...t.zip?{zip:t.zip}:{}}),Wt=(t={})=>{const{numberEl:r=dr,cvvEl:s=ur,onCardTokenized:o,onFieldErrors:l,onValidityChange:c,onBrandChange:f}=t,[x,m]=n.useState("idle"),[R,w]=n.useState(null),[p,v]=n.useState(null),[E,T]=n.useState(null),[se,M]=n.useState({number:!1,cvv:!1}),[C,b]=n.useState(null),[Y,ee]=n.useState({number:!1,cvv:!1}),ve=n.useRef(null),ue=n.useRef(o),te=n.useRef(l),oe=n.useRef(c),D=n.useRef(f);n.useEffect(()=>{ue.current=o},[o]),n.useEffect(()=>{te.current=l},[l]),n.useEffect(()=>{oe.current=c},[c]),n.useEffect(()=>{D.current=f},[f]);const j=n.useRef({number:!1,cvv:!1});n.useEffect(()=>{let S=!1;return m("loading"),w(null),v(null),T(null),M({number:!1,cvv:!1}),b(null),j.current={number:!1,cvv:!1},(async()=>{try{const[g,h]=await Promise.all([yt().catch(N=>{throw new nt("tokenization-session",N)}),cr().catch(N=>{throw new nt("spreedly-script",N)})]);if(S)return;ve.current=h,h.on("ready",()=>{var N,U,K,me,G,re;if(!S){m("ready");try{(N=h.setFieldType)==null||N.call(h,"number","tel"),(U=h.setFieldType)==null||U.call(h,"cvv","tel")}catch(H){console.warn("@movmo_app/payments: setFieldType failed",H)}try{typeof h.setNumberFormat=="function"?h.setNumberFormat("prettyFormat"):console.warn("@movmo_app/payments: Spreedly.setNumberFormat is missing — card-number digits will not be space-grouped.")}catch(H){console.warn("@movmo_app/payments: setNumberFormat failed",H)}try{(K=h.setPlaceholder)==null||K.call(h,"number","Card number"),(me=h.setPlaceholder)==null||me.call(h,"cvv","CVV");const H='box-sizing: border-box;width: 100%;height: 100%;margin: 0;padding: 0;border: 0;background: transparent;outline: none;font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;font-size: 14px;font-weight: 400;line-height: 20px;color: rgb(28 25 23);letter-spacing: 0;vertical-align: middle;';(G=h.setStyle)==null||G.call(h,"number",H),(re=h.setStyle)==null||re.call(h,"cvv",H)}catch(H){console.warn("@movmo_app/payments: setPlaceholder/setStyle failed",H)}}}),h.on("paymentMethod",N=>{var U;(U=ue.current)==null||U.call(ue,N)}),h.on("errors",N=>{var U;(U=te.current)==null||U.call(te,N)}),h.on("fieldEvent",(N,U,K,me)=>{var H;if(S)return;if(U==="focus"){ee(W=>W[N]?W:{...W,[N]:!0});return}if(U==="blur"){ee(W=>W[N]?{...W,[N]:!1}:W);return}if(U!=="input")return;const G=me??{};if(N==="number"){if(G.numberLength===0)b(W=>{var Z;return W!==null&&((Z=D.current)==null||Z.call(D,null)),null});else if(G.cardType!==void 0){const W=G.cardType||null;b(Z=>{var je;return Z!==W&&((je=D.current)==null||je.call(D,W)),W})}}const re=N==="number"?typeof G.validNumber=="boolean"?G.validNumber:void 0:typeof G.validCvv=="boolean"?G.validCvv:void 0;if(typeof re=="boolean"){const W=j.current,Z=N==="number"?{...W,number:re}:{...W,cvv:re};(Z.number!==W.number||Z.cvv!==W.cvv)&&(j.current=Z,M(Z),(H=oe.current)==null||H.call(oe,Z))}}),h.on("consoleError",N=>{var K;const U=N instanceof Error?N.message:"An unexpected error occurred while securing your card.";(K=te.current)==null||K.call(te,[{message:U}])}),h.init(g.environmentKey,{numberEl:r,cvvEl:s,nonce:g.nonce,timestamp:String(g.timestamp),certificateToken:g.certificateToken,signature:g.signature})}catch(g){if(S)return;const h=g instanceof Error?g.message:"Failed to initialize card form.";w(h),v(g instanceof nt?g.source:"spreedly-script"),T(g instanceof nt?g.cause:g),m("error")}})(),()=>{var g,h;S=!0;try{(h=(g=ve.current)==null?void 0:g.removeHandlers)==null||h.call(g)}catch(N){console.warn("@movmo_app/payments: removeHandlers failed during cleanup",N)}ve.current=null}},[r,s]);const fe=n.useCallback(S=>{var g;(g=ve.current)==null||g.tokenizeCreditCard(fr(S))},[]),Ee=n.useCallback(S=>{var g,h;(h=(g=ve.current)==null?void 0:g.transferFocus)==null||h.call(g,S)},[]);return{status:x,error:R,errorSource:p,errorCause:E,tokenize:fe,validity:se,brand:C,focused:Y,focusField:Ee}},dt="h-11 w-full rounded-md border border-grayWarm-300 bg-white px-3 py-2 text-sm text-grayWarm-900 placeholder:text-grayWarm-400 outline-none focus:border-grayWarm-950 focus:shadow-[0_0_0_1px_#1c1917]",jt="flex h-11 w-full items-center gap-2 rounded-md border bg-white px-3 py-2 transition-shadow",_t="border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]",Ct="border-grayWarm-300",mr=t=>{const r=t.trim();if(!r)return{firstName:"",lastName:""};const s=r.lastIndexOf(" ");return s===-1?{firstName:r,lastName:""}:{firstName:r.slice(0,s).trim(),lastName:r.slice(s+1).trim()}},Mt=t=>{const r=t.replace(/\D/g,"");if(r.length<4)return{month:"",year:""};const s=r.slice(0,2),o=r.slice(2),l=o.length===2?`20${o}`:o.slice(0,4);return{month:s,year:l}},pr=t=>{const r=t.replace(/\D/g,"").slice(0,4);return r.length<=2?r:`${r.slice(0,2)} / ${r.slice(2)}`},ut=t=>{const{month:r,year:s}=Mt(t);if(!r||!s)return!1;const o=parseInt(r,10),l=parseInt(s,10);if(isNaN(o)||o<1||o>12)return!1;const c=new Date;return!(l<c.getFullYear()||l>c.getFullYear()+20||l===c.getFullYear()&&o<c.getMonth()+1)},ft=t=>/^\d{5}(-\d{4})?$/.test(t.trim()),hr=t=>{const r=t.replace(/[^\d]/g,"").slice(0,9);return r.length<=5?r:`${r.slice(0,5)}-${r.slice(5)}`},vt=({userId:t,onSuccess:r,onError:s,onErrorDetail:o,isDefault:l=!1,className:c,defaultCardholderName:f,defaultCardholderFirstName:x="",defaultCardholderLastName:m="",autoSave:R=!1,formId:w="movmo-card-form",hideInternalSaveButton:p=!1,onCanSubmitChange:v,onSavingChange:E,autoFocus:T})=>{const se=f??[x,m].filter(Boolean).join(" "),[M,C]=n.useState(se),[b,Y]=n.useState(""),[ee,ve]=n.useState(""),[ue,te]=n.useState("idle"),oe=n.useRef(!1),D=n.useRef(o);n.useEffect(()=>{D.current=o},[o]);const j=n.useCallback(async P=>{var $;te("saving");try{const A=await nr(t,P,l);te("ready"),r(A)}catch(A){const de=A instanceof Error?A.message:"Failed to save payment method.";te("ready"),oe.current=!1,s(de),($=D.current)==null||$.call(D,{source:"save-from-token",message:de,cause:A})}},[t,l,r,s]),fe=n.useCallback(P=>{var A;const $=P.map(de=>de.message).filter(Boolean).join("; ")||"Card validation failed.";te(de=>de==="tokenizing"?"ready":de),oe.current=!1,s($),(A=D.current)==null||A.call(D,{source:"card-tokenize",message:$})},[s]),Ee=n.useMemo(()=>({onCardTokenized:j,onFieldErrors:fe}),[j,fe]),{status:S,error:g,errorSource:h,errorCause:N,tokenize:U,validity:K,brand:me,focused:G,focusField:re}=Wt(Ee),H=n.useRef(!1);n.useEffect(()=>{!T||S!=="ready"||H.current||(H.current=!0,re(T))},[T,S,re]);const W=M.trim().split(/\s+/).length>=2,Z=ut(b),je=ft(ee),pe=n.useRef(!1),he=n.useRef(!1),ie=n.useRef(!1),ae=n.useRef(null),_e=n.useRef(null);n.useEffect(()=>{var P;K.cvv?he.current||(he.current=!0,(P=ae.current)==null||P.focus()):he.current=!1},[K.cvv]);const Fe=!W||!Z||!je||!K.number||!K.cvv,le=ue==="tokenizing"||ue==="saving",J=S==="ready"&&!le&&!Fe,ge=n.useRef(v);n.useEffect(()=>{ge.current=v},[v]),n.useEffect(()=>{var P;(P=ge.current)==null||P.call(ge,J)},[J]);const z=n.useRef(E);n.useEffect(()=>{z.current=E},[E]),n.useEffect(()=>{var P;(P=z.current)==null||P.call(z,le)},[le]);const xe=n.useCallback(()=>{const{firstName:P,lastName:$}=mr(M),{month:A,year:de}=Mt(b);te("tokenizing"),U({firstName:P,lastName:$,month:A,year:de,zip:ee.trim()})},[M,b,ee,U]);n.useEffect(()=>{if(!R||!J||oe.current)return;const P=setTimeout(()=>{oe.current=!0,xe()},1200);return()=>clearTimeout(P)},[R,J,xe]);const Se=P=>{P.preventDefault(),J&&xe()},we=S!=="ready"||le,X=n.useRef(s);return n.useEffect(()=>{X.current=s},[s]),n.useEffect(()=>{var P,$;g&&((P=X.current)==null||P.call(X,g),($=D.current)==null||$.call(D,{source:h??"spreedly-script",message:g,cause:N}))},[g,h,N]),a.jsxs("form",{id:w,onSubmit:Se,className:Q("flex w-full flex-col gap-3",c),"data-testid":"movmo-card-form",children:[a.jsxs("div",{children:[a.jsx("span",{id:"movmo-card-number-label",className:"sr-only",children:"Card number"}),a.jsxs("div",{className:Q(jt,G.number?_t:Ct),children:[a.jsx(Ne,{brand:me??"",width:32,className:"flex-shrink-0"}),a.jsxs("div",{className:"relative h-full flex-1",children:[a.jsx("div",{id:"movmo-card-number","aria-labelledby":"movmo-card-number-label","aria-busy":S!=="ready",className:"absolute inset-0","data-testid":"movmo-card-number-mount"}),S!=="ready"?a.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-y-2 left-0 right-2 animate-pulse rounded bg-grayWarm-200"}):null]})]})]}),a.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-expiry",className:"sr-only",children:"Expiry MM / YY"}),a.jsx("input",{id:"movmo-card-expiry",type:"text",inputMode:"numeric",autoComplete:"cc-exp",placeholder:"MM / YY",value:b,onChange:P=>{const $=pr(P.target.value);Y($),ut($)&&!pe.current?(pe.current=!0,re("cvv")):ut($)||(pe.current=!1)},className:Q(dt,b&&!Z&&"border-error-500"),disabled:we,required:!0,"data-testid":"movmo-card-expiry-input"})]}),a.jsxs("div",{className:"relative",children:[a.jsx("span",{id:"movmo-card-cvv-label",className:"sr-only",children:"CVV"}),a.jsxs("div",{className:Q(jt,G.cvv?_t:Ct),children:[a.jsxs("div",{className:"relative h-full flex-1",children:[a.jsx("div",{id:"movmo-card-cvv","aria-labelledby":"movmo-card-cvv-label","aria-busy":S!=="ready",className:"absolute inset-0","data-testid":"movmo-card-cvv-mount"}),S!=="ready"?a.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-y-2 left-0 right-2 animate-pulse rounded bg-grayWarm-200"}):null]}),a.jsx("button",{type:"button","aria-label":"CVV help",tabIndex:-1,className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full border border-grayWarm-300 text-xs text-grayWarm-500",title:me==="american_express"?"The 4 numbers on the front of your card.":"The 3 numbers on the back of your card.","data-testid":"movmo-cvv-help",children:"?"})]})]}),a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-zip",className:"sr-only",children:"ZIP code"}),a.jsx("input",{id:"movmo-card-zip",ref:ae,type:"text",inputMode:"numeric",autoComplete:"postal-code",placeholder:"ZIP code",value:ee,onChange:P=>{var A;const $=hr(P.target.value);ve($),ft($)&&!ie.current?(ie.current=!0,(A=_e.current)==null||A.focus()):ft($)||(ie.current=!1)},className:Q(dt,ee&&!je&&"border-error-500"),disabled:we,required:!0,"data-testid":"movmo-card-zip-input"})]})]}),a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-cardholder-name",className:"sr-only",children:"Cardholder name"}),a.jsx("input",{id:"movmo-card-cardholder-name",ref:_e,type:"text",autoComplete:"cc-name",placeholder:"Cardholder name",value:M,onChange:P=>C(P.target.value),className:dt,disabled:we,required:!0,"data-testid":"movmo-card-cardholder-name-input"})]}),!R&&!p?a.jsx("button",{type:"submit",disabled:!J,className:Q("inline-flex h-11 items-center justify-center rounded-md bg-brand-500 px-4 text-sm font-semibold text-white transition-colors hover:bg-brand-600","disabled:cursor-not-allowed disabled:bg-grayWarm-300 disabled:text-grayWarm-500"),"data-testid":"movmo-card-save",children:le?"Saving…":S==="loading"?"Loading…":"Save card"}):le&&R?a.jsx("p",{className:"text-center text-sm text-grayWarm-500","aria-live":"polite","data-testid":"movmo-card-autosaving",children:"Saving card…"}):null]})};vt.displayName="MovmoCardForm";const Ot=t=>{const[r,s]=n.useState("idle"),[o,l]=n.useState(null);return{deletePaymentMethod:n.useCallback(async f=>{s("pending"),l(null);try{await or(t,f),s("idle")}catch(x){const m=x instanceof Error?x.message:"Failed to delete payment method.";throw l(m),s("error"),x}},[t]),status:r,error:o}},Dt=t=>{const[r,s]=n.useState("idle"),[o,l]=n.useState(null);return{setDefault:n.useCallback(async f=>{s("pending"),l(null);try{await Ft(t,f,{isDefault:!0}),s("idle")}catch(x){const m=x instanceof Error?x.message:"Failed to set default payment method.";throw l(m),s("error"),x}},[t]),status:r,error:o}},$t=t=>{const[r,s]=n.useState("idle"),[o,l]=n.useState(null);return{updatePaymentMethod:n.useCallback(async(f,x)=>{s("pending"),l(null);try{await Ft(t,f,x),s("idle")}catch(m){const R=m instanceof Error?m.message:"Failed to update payment method.";throw l(R),s("error"),m}},[t]),status:r,error:o}},At=t=>{const[r,s]=n.useState([]),[o,l]=n.useState("idle"),[c,f]=n.useState(null),[x,m]=n.useState(0),R=n.useRef(null);n.useEffect(()=>{var v;if((v=R.current)==null||v.abort(),!t){R.current=null,s([]),f(null),l("ready");return}const p=new AbortController;return R.current=p,l("loading"),f(null),sr(t,p.signal).then(E=>{p.signal.aborted||(s(E),l("ready"))}).catch(E=>{if(p.signal.aborted||E instanceof DOMException&&E.name==="AbortError")return;const T=E instanceof Error?E.message:"Failed to fetch payment methods.";f(T),l("error")}),()=>{p.abort()}},[t,x]);const w=n.useCallback(()=>{m(p=>p+1)},[]);return{items:r,status:o,error:c,refetch:w}},Ut=({open:t,onClose:r,title:s,titleId:o,formId:l,saveDisabled:c,saveLabel:f="Save",isSaving:x=!1,testIdPrefix:m="payment-method",children:R})=>(n.useEffect(()=>{if(!t)return;const w=p=>{p.key==="Escape"&&r()};return document.addEventListener("keydown",w),()=>document.removeEventListener("keydown",w)},[t,r]),n.useEffect(()=>{if(!t)return;const w=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=w}},[t]),t?a.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":o,className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",onClick:w=>{w.target===w.currentTarget&&r()},"data-testid":`${m}-modal`,children:a.jsxs("div",{className:"flex max-h-full w-full max-w-md flex-col rounded-xl bg-white shadow-2xl",children:[a.jsxs("div",{className:"flex items-center gap-3 border-b border-grayWarm-200 px-4 py-3",children:[a.jsx("button",{type:"button",onClick:r,"aria-label":`Close ${s.toLowerCase()} dialog`,className:"flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg bg-grayWarm-100 p-2 text-grayWarm-950 transition-colors hover:bg-grayWarm-200","data-testid":`${m}-close`,children:a.jsx("svg",{viewBox:"0 0 20 20",width:"20",height:"20","aria-hidden":"true",children:a.jsx("path",{d:"M5 5L15 15M15 5L5 15",stroke:"currentColor",strokeWidth:"1.67",strokeLinecap:"round",strokeLinejoin:"round"})})}),a.jsx("h2",{id:o,className:"flex-1 text-center text-base font-semibold text-grayWarm-900",children:s}),a.jsx("span",{"aria-hidden":"true",className:"h-9 w-9 flex-shrink-0"})]}),a.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:R}),a.jsxs("div",{className:"flex gap-3 border-t border-grayWarm-200 p-4",children:[a.jsx("button",{type:"button",onClick:r,className:"inline-flex h-11 flex-1 items-center justify-center rounded-lg border border-grayWarm-300 px-4 text-sm font-semibold text-grayWarm-900 transition-colors hover:border-grayWarm-900 hover:shadow-[0_0_0_1px_#1c1917]","data-testid":`${m}-cancel`,children:"Cancel"}),a.jsx("button",{type:"submit",form:l,disabled:x?!1:c,"aria-disabled":x||c,"aria-busy":x,className:Q("inline-flex h-11 flex-1 items-center justify-center rounded-lg bg-brand-500 px-4 text-sm font-semibold text-white transition-colors",x?"cursor-not-allowed opacity-90 pointer-events-none":"hover:bg-brand-600 disabled:cursor-not-allowed disabled:bg-grayWarm-300 disabled:text-grayWarm-500"),"data-testid":`${m}-save`,children:x?a.jsxs(a.Fragment,{children:[a.jsxs("svg",{className:"h-[18px] w-[18px] animate-spin",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:[a.jsx("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3",strokeOpacity:"0.25"}),a.jsx("path",{d:"M22 12a10 10 0 0 1-10 10",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]}),a.jsx("span",{className:"sr-only",children:"Saving"})]}):f})]})]})}):null),yr=({open:t,onClose:r,formId:s,saveDisabled:o,saveLabel:l="Save",isSaving:c=!1,children:f})=>a.jsx(Ut,{open:t,onClose:r,title:"Add payment method",titleId:"movmo-add-payment-title",formId:s,saveDisabled:o,saveLabel:l,isSaving:c,testIdPrefix:"add-payment-method",children:f}),vr=(t,r)=>`${String(t).padStart(2,"0")}/${r}`,gr=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},xr=({open:t,method:r,onClose:s,onSave:o,isSaving:l=!1,error:c=null})=>{const f=n.useId(),[x,m]=n.useState(""),[R,w]=n.useState("");if(n.useEffect(()=>{t&&r&&(m(r.cardholderName??""),w(r.zip??""))},[t,r]),!r)return null;const p=x.trim(),v=R.trim(),E=p!==(r.cardholderName??"").trim(),T=v!==(r.zip??"").trim(),se=E||T,M=(!E||p.length>0)&&(!T||/^[A-Za-z0-9 -]{3,20}$/.test(v)),C=!se||!M,b=Y=>{if(Y.preventDefault(),C||l)return;const ee={};E&&(ee.cardholderName=p),T&&(ee.zip=v),o(ee).catch(()=>{})};return a.jsxs(Ut,{open:t,onClose:s,title:"Edit payment method",titleId:"movmo-edit-payment-title",formId:f,saveDisabled:C,isSaving:l,testIdPrefix:"edit-payment-method",children:[a.jsxs("div",{className:"mb-4 flex items-start gap-3 rounded-lg bg-grayWarm-50 p-3","data-testid":"edit-payment-method-context",children:[a.jsx(Ne,{brand:r.brand,className:"flex-shrink-0"}),a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsxs("div",{className:"text-lg font-semibold text-grayWarm-950",children:[gr(r.brand)," •••• ",r.last4]}),a.jsxs("div",{className:"text-sm text-grayWarm-600",children:["Exp. ",vr(r.expMonth,r.expYear)]})]})]}),a.jsxs("form",{id:f,onSubmit:b,className:"flex flex-col gap-4",noValidate:!0,children:[a.jsxs("label",{className:"flex flex-col gap-1.5 text-sm font-medium text-grayWarm-700",children:["Cardholder name",a.jsx("input",{type:"text",autoComplete:"cc-name",value:x,onChange:Y=>m(Y.target.value),disabled:l,maxLength:255,"data-testid":"edit-payment-method-cardholder",className:"h-11 rounded-lg border border-grayWarm-300 px-3 text-base font-normal text-grayWarm-950 focus:border-grayWarm-950 focus:outline-none focus:ring-1 focus:ring-grayWarm-950"})]}),a.jsxs("label",{className:"flex flex-col gap-1.5 text-sm font-medium text-grayWarm-700",children:["Billing ZIP",a.jsx("input",{type:"text",inputMode:"numeric",autoComplete:"postal-code",value:R,onChange:Y=>w(Y.target.value),disabled:l,maxLength:20,"data-testid":"edit-payment-method-zip",className:"h-11 rounded-lg border border-grayWarm-300 px-3 text-base font-normal text-grayWarm-950 focus:border-grayWarm-950 focus:outline-none focus:ring-1 focus:ring-grayWarm-950"})]}),c?a.jsx("p",{role:"alert",className:"text-sm text-error-700","data-testid":"edit-payment-method-error",children:c}):null]})]})},br=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},It=({method:t,trailing:r,onClick:s,cardLabelFormat:o="branded",className:l})=>a.jsxs("div",{className:Q("flex items-center gap-3",s&&"cursor-pointer",l),onClick:s,role:s?"button":void 0,tabIndex:s?0:void 0,onKeyDown:s?c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),s())}:void 0,"data-testid":`payment-method-preview-${t.id}`,children:[a.jsx(Ne,{brand:t.brand,width:34,className:"flex-shrink-0"}),a.jsx("span",{className:"flex-1 text-lg font-semibold text-grayWarm-950",children:o==="masked"?`•••• ${t.last4}`:`${br(t.brand)} ${t.last4}`}),r]}),wr=(t,r,s=new Date)=>r<s.getFullYear()||r===s.getFullYear()&&t<s.getMonth()+1,kt=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},Er=(t,r)=>`${String(t).padStart(2,"0")}/${r}`,jr=({method:t,selectable:r,selected:s,onSelect:o,onSetDefault:l,onRemove:c,onEdit:f,disabled:x,showDefaultBadge:m,hideSetDefaultMenuItem:R,cardLabelFormat:w="branded"})=>{const[p,v]=n.useState(!1),E=n.useRef(null),T=wr(t.expMonth,t.expYear);n.useEffect(()=>{if(!p)return;const M=C=>{var b;(b=E.current)!=null&&b.contains(C.target)||v(!1)};return document.addEventListener("mousedown",M),()=>document.removeEventListener("mousedown",M)},[p]);const se=()=>{r&&o&&!x&&o(t)};return a.jsxs("div",{className:Q("flex items-start gap-3 transition-colors",r?"rounded-lg border px-3 py-3":"py-4",r&&!x&&"cursor-pointer",r&&(s?"border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200 hover:border-grayWarm-300")),onClick:se,"data-testid":`payment-method-row-${t.id}`,children:[r?a.jsx("input",{type:"radio",name:"movmo-payment-method",checked:s,onChange:()=>o==null?void 0:o(t),onClick:M=>M.stopPropagation(),"aria-label":`Select ${kt(t.brand)} ending ${t.last4}`,className:"mr-1 h-4 w-4 mt-2 cursor-pointer appearance-none rounded-full border-2 border-grayWarm-300 checked:border-[5px] checked:border-grayWarm-950 bg-white checked:bg-white focus:ring-0 focus:ring-offset-0",disabled:x}):null,a.jsx(Ne,{brand:t.brand,className:"flex-shrink-0"}),a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[a.jsx("span",{className:"text-lg font-semibold text-grayWarm-950",children:w==="masked"?`•••• ${t.last4}`:`${kt(t.brand)} ${t.last4}`}),m&&t.isDefault?a.jsx("span",{className:"inline-flex items-center rounded-full bg-success-50 px-2 py-0.5 text-xs font-semibold text-success-700","data-testid":`badge-default-${t.id}`,children:"Default"}):null,T?a.jsx("span",{className:"inline-flex items-center rounded-full bg-error-50 px-2 py-0.5 text-xs font-semibold text-error-700","data-testid":`badge-expired-${t.id}`,children:"Expired"}):null]}),a.jsxs("div",{className:Q("text-base",T?"text-grayWarm-400":"text-grayWarm-600"),children:["Exp. ",Er(t.expMonth,t.expYear)]})]}),a.jsxs("div",{className:"relative flex-shrink-0",ref:E,children:[a.jsx("button",{type:"button","aria-label":`Open actions for card ending ${t.last4}`,"aria-haspopup":"menu","aria-expanded":p,className:"rounded-lg p-2 text-grayWarm-600 transition-colors hover:bg-grayWarm-100 disabled:cursor-not-allowed disabled:opacity-50",disabled:x,onClick:M=>{M.stopPropagation(),v(C=>!C)},"data-testid":`menu-trigger-${t.id}`,children:a.jsx("svg",{viewBox:"0 0 24 24",width:"20",height:"20",fill:"currentColor","aria-hidden":"true",children:a.jsx("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"})})}),p?a.jsxs("div",{role:"menu",className:Q("absolute z-10 whitespace-nowrap rounded-lg border border-grayWarm-200 bg-white py-1 shadow-lg",r?"bottom-full left-1/2 mb-2 -translate-x-1/2":"right-0 top-full mt-1"),onClick:M=>M.stopPropagation(),"data-testid":`menu-${t.id}`,children:[r?a.jsx("span",{"aria-hidden":"true",className:"absolute -bottom-1.5 left-1/2 h-3 w-3 -translate-x-1/2 rotate-45 border-b border-r border-grayWarm-200 bg-white"}):null,!t.isDefault&&!R?a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-grayWarm-950 hover:text-grayWarm-700",onClick:()=>{v(!1),l(t)},"data-testid":`menu-set-default-${t.id}`,children:"Set as default"}):null,f&&t.vault==="spreedly"?a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-grayWarm-950 hover:text-grayWarm-700",onClick:()=>{v(!1),f(t)},"data-testid":`menu-edit-${t.id}`,children:"Edit"}):null,a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-error-700 hover:text-error-500",onClick:()=>{v(!1),c(t)},"data-testid":`menu-remove-${t.id}`,children:"Delete"})]}):null]})]})},_r=t=>`${Te().iconCdnBaseUrl}/website/assets/icons/payments/${t}.svg`,mt=({slug:t,alt:r})=>a.jsx("img",{src:_r(t),alt:r,height:20,loading:"lazy",style:{height:20,width:"auto"}}),st=({type:t,label:r,iconNode:s,disabled:o=!1})=>a.jsxs("label",{className:"flex cursor-pointer items-center gap-3 rounded-lg border border-grayWarm-200 px-4 py-3 transition-colors hover:border-grayWarm-300","data-testid":`payment-type-${t}`,children:[a.jsx("input",{type:"radio",name:"movmo-payment-type",value:t,disabled:o,onChange:()=>{},className:Q("h-4 w-4 accent-grayWarm-900",o?"cursor-not-allowed":"cursor-pointer"),"aria-label":r}),a.jsxs("span",{className:"flex flex-1 items-center gap-2 text-sm font-semibold text-grayWarm-900",children:[r,s]})]}),Rt=({selected:t,onSelect:r,creditCardBody:s,disabled:o=!1,className:l})=>{const c=t==="credit_card";return a.jsxs("div",{className:Q("flex w-full flex-col gap-3",l),children:[a.jsxs("label",{className:Q("flex cursor-pointer flex-col gap-3 rounded-lg border px-4 py-3 transition-colors",c?"border-grayWarm-900 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200"),"data-testid":"payment-type-credit_card",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx("input",{type:"radio",name:"movmo-payment-type",value:"credit_card",checked:c,disabled:o,onChange:()=>{o||r("credit_card")},className:Q("h-4 w-4 accent-grayWarm-900",o?"cursor-not-allowed":"cursor-pointer"),"aria-label":"Credit card"}),a.jsx("span",{className:"flex-1 text-sm font-semibold text-grayWarm-900",children:"Credit card"}),a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx(Ne,{brand:"mastercard",width:28}),a.jsx(Ne,{brand:"visa",width:28}),a.jsx(Ne,{brand:"amex",width:28}),a.jsx(Ne,{brand:"discover",width:28})]})]}),c?a.jsx("div",{"data-testid":"payment-type-credit_card-body",children:s}):null]}),c?a.jsx("p",{className:"mt-2 text-sm font-semibold text-grayWarm-900","data-testid":"payment-type-other-options-header",children:"Other options"}):null,a.jsx(st,{type:"paypal",label:"PayPal",iconNode:a.jsx(mt,{slug:"paypal",alt:"PayPal"}),disabled:o}),a.jsx(st,{type:"googlepay",label:"GooglePay",iconNode:a.jsx(mt,{slug:"google-pay",alt:"GooglePay"}),disabled:o}),a.jsx(st,{type:"klarna",label:"Klarna",iconNode:a.jsx(mt,{slug:"klarna",alt:"Klarna"}),disabled:o}),a.jsx(st,{type:"ach",label:"Bank account (ACH)",iconNode:a.jsx("span",{className:"text-xs font-medium text-grayWarm-500",children:"Direct debit"}),disabled:o})]})},Nt="movmo-add-payment-form",Cr=t=>{console.error("@movmo_app/payments: failed to update payment method",t);const r=t instanceof Error?t.message.trim():"";return/spreedly-backed cards/i.test(r)?"This card's details can't be edited.":r||"Failed to update payment method."},St=t=>{const r=t.filter(o=>o.isDefault),s=t.filter(o=>!o.isDefault);return[...r,...s]},Pt=({withDefaultBadge:t=!1})=>a.jsxs("div",{className:"flex items-start justify-between py-4","data-testid":"payment-method-skeleton",children:[a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx("div",{className:"h-8 w-[46px] flex-shrink-0 animate-pulse rounded bg-grayWarm-200"}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"h-5 w-[120px] animate-pulse rounded bg-grayWarm-200"}),t?a.jsx("div",{className:"h-5 w-[56px] animate-pulse rounded-full bg-grayWarm-200"}):null]}),a.jsx("div",{className:"h-4 w-[100px] animate-pulse rounded bg-grayWarm-200"})]})]}),a.jsx("div",{className:"h-5 w-5 flex-shrink-0 animate-pulse rounded-full bg-grayWarm-200"})]}),Lt=({userId:t,defaultCardholderName:r,defaultCardholderFirstName:s,defaultCardholderLastName:o,selectedId:l,onSelect:c,onChange:f,onError:x,onEvent:m,paymentTypeSelector:R=!0,autoSaveFirstCard:w=!0,selectionSetsDefault:p=!1,showDefaultBadge:v=!0,collapsible:E=!1,cardLabelFormat:T="branded",className:se})=>{const{items:M,status:C,error:b,refetch:Y}=At(t),{deletePaymentMethod:ee,status:ve}=Ot(t),{setDefault:ue,status:te}=Dt(t),{updatePaymentMethod:oe,status:D}=$t(t),[j,fe]=n.useState([]),Ee=n.useRef(j);n.useEffect(()=>{Ee.current=j},[j]);const[S,g]=n.useState(null),[h,N]=n.useState(!1),[U,K]=n.useState(null),[me,G]=n.useState(!1),[re,H]=n.useState(!1),[W,Z]=n.useState(null),[je,pe]=n.useState(null),[he,ie]=n.useState(null),[ae,_e]=n.useState(!1),Fe=n.useRef(!1),le=n.useRef(x);n.useEffect(()=>{le.current=x},[x]);const J=n.useCallback(u=>{var B;(B=le.current)==null||B.call(le,u)},[]),ge=n.useRef(m);n.useEffect(()=>{ge.current=m},[m]);const z=n.useCallback((u,B)=>{var I;(I=ge.current)==null||I.call(ge,u,B)},[]),xe=n.useCallback(()=>{N(!1),K(null),ie(null)},[]),Se=r??([s,o].filter(Boolean).join(" ")||void 0);n.useEffect(()=>{C==="ready"&&fe(St(M))},[M,C]);const we=n.useRef(null);n.useEffect(()=>{if(C==="error"&&b){if(we.current===b)return;we.current=b,J({source:"list",message:b})}else C!=="error"&&(we.current=null)},[C,b,J]),n.useEffect(()=>{if(!c||Fe.current||C!=="ready"||j.length===0||l)return;Fe.current=!0,z("autoselected",{had_saved_methods:!0});const u=j.find(B=>B.isDefault)??j[0];c(u)},[c,C,j,l,z]);const X=n.useCallback(u=>{fe(B=>{const I=typeof u=="function"?u(B):u,L=St(I);return queueMicrotask(()=>f==null?void 0:f(L)),L})},[f]),P=ve==="pending"||te==="pending"||D==="pending",$=n.useCallback(async u=>{const B=j;g(null),X(I=>I.map(L=>({...L,isDefault:L.id===u.id})));try{await ue(u.id),Y(),z("set_default")}catch(I){fe(B),f==null||f(B);const L=I instanceof Error?I.message:"Failed to set default payment method.";g(L),J({source:"set-default",message:L,cause:I})}},[j,X,ue,Y,f,J,z]),A=n.useCallback(u=>{c==null||c(u),p&&(u.isDefault||$(u))},[c,p,$]),de=n.useCallback(u=>{z("selected",{method_count:j.length}),A(u)},[z,j,A]),ot=n.useCallback(async u=>{const B=j;g(null);const I=j.filter(Ce=>Ce.id!==u.id);X(()=>I);const L=u.id===l&&c?I.find(Ce=>Ce.isDefault)??I[0]??null:null;L&&A(L);const be=!!L&&p&&L!==null&&!L.isDefault;try{await ee(u.id),be||Y(),z("deleted",{remaining_count:I.length})}catch(Ce){fe(B),f==null||f(B);const Ve=Ce instanceof Error?Ce.message:"Failed to delete payment method.";g(Ve),J({source:"delete",message:Ve,cause:Ce})}},[j,X,ee,Y,f,l,c,A,p,J,z]),Je=n.useCallback(u=>{pe(null),Z(u)},[]),We=n.useCallback(()=>{Z(null),pe(null)},[]),Ze=n.useCallback(async u=>{if(!W)return;const B=W,I=j;pe(null),X(L=>L.map(be=>be.id===B.id?{...be,...u.cardholderName!==void 0?{cardholderName:u.cardholderName}:{},...u.zip!==void 0?{zip:u.zip}:{}}:be));try{await oe(B.id,u),We(),Y(),z("edited",{fields:Object.keys(u)})}catch(L){fe(I),f==null||f(I);const be=Cr(L);pe(be),J({source:"update",message:be,cause:L})}},[W,j,X,oe,Y,f,We,J,z]),Xe=n.useCallback(u=>{K(null),N(!1),ie(null),X(I=>[u,...I.filter(L=>L.id!==u.id)]),A(u),!!c&&p&&!u.isDefault||Y(),z("added",{method_count:Ee.current.length+1})},[X,Y,A,c,p,z]),Le=n.useCallback(u=>{K(u)},[]),Qe=C==="ready"&&j.length===0,ze=typeof c=="function",et=!ze&&!E,tt=j.length===0,rt=w&&j.length===0,Me=n.useCallback(u=>a.jsx(vt,{userId:t,isDefault:tt,defaultCardholderName:Se,autoSave:!u&&rt,hideInternalSaveButton:u,formId:u?Nt:void 0,onCanSubmitChange:u?G:void 0,onSavingChange:u?H:void 0,autoFocus:u?"number":void 0,onSuccess:Xe,onError:Le,onErrorDetail:J}),[t,tt,Se,rt,Xe,Le,J]),Be=n.useMemo(()=>Me(!1),[Me]),Ye=n.useMemo(()=>Me(!0),[Me]),ke=!t,at=n.useMemo(()=>R?a.jsx(Rt,{selected:he,onSelect:u=>ie(u),creditCardBody:Be,disabled:ke}):Be,[R,he,Be,ke]),Re=n.useMemo(()=>R?a.jsx(Rt,{selected:he,onSelect:u=>ie(u),creditCardBody:Ye,disabled:ke}):Ye,[R,he,Ye,ke]);return a.jsxs("div",{className:Q("flex w-full flex-col gap-4",se),"data-testid":"payment-methods-manager",children:[C==="loading"&&j.length===0?a.jsxs("div",{className:Q(et?"flex flex-col divide-y divide-grayWarm-200 rounded-xl border border-grayWarm-200 px-4 md:px-6":"flex flex-col gap-2"),"data-testid":"payment-methods-loading",children:[a.jsx(Pt,{withDefaultBadge:!0}),a.jsx(Pt,{})]}):null,C==="error"?a.jsxs("div",{role:"alert","aria-live":"polite",className:"flex items-center justify-between gap-3 rounded-md bg-error-50 p-3 text-sm text-error-700","data-testid":"payment-methods-list-error",children:[a.jsx("span",{children:b??"Failed to load payment methods."}),a.jsx("button",{type:"button",onClick:Y,className:"rounded-md border border-error-700 px-3 py-1 text-xs font-semibold text-error-700 hover:bg-error-50",children:"Retry"})]}):null,S?a.jsx("div",{role:"alert","aria-live":"polite",className:"rounded-md bg-error-50 p-3 text-sm text-error-700","data-testid":"payment-methods-mutation-error",children:S}):null,E&&j.length>0?a.jsx("div",{className:"border-t border-grayWarm-200 pt-4",children:a.jsxs("div",{className:"flex items-center justify-between","data-testid":ae?"payment-methods-drawer-header":"payment-methods-collapsed-preview",children:[ae?a.jsx("h3",{className:"text-md font-semibold text-grayWarm-950",children:"Payment methods"}):a.jsx(It,{method:j.find(u=>u.id===l)??j.find(u=>u.isDefault)??j[0],cardLabelFormat:T,className:"flex-1"}),a.jsx("button",{type:"button","aria-label":ae?"Collapse payment methods":"Expand payment methods","aria-expanded":ae,className:"bg-grayWarm-100 p-2 rounded-lg hover:bg-grayWarm-200 transition-colors",onClick:()=>_e(u=>!u),"data-testid":ae?"payment-methods-drawer-close":"payment-methods-drawer-open",children:a.jsx("img",{src:`${Te().iconCdnBaseUrl}/website/assets/icons/chevron-${ae?"up":"down"}-double.svg`,alt:"",className:"w-5 h-5"})})]})}):null,j.length>0&&(!E||ae)?a.jsx("div",{className:Q("flex flex-col",et?"rounded-xl border border-grayWarm-200 px-4 md:px-6 divide-y divide-grayWarm-200":"space-y-3"),children:j.map(u=>a.jsx(jr,{method:u,selectable:ze,selected:ze&&u.id===l,onSelect:de,onSetDefault:$,onRemove:ot,onEdit:Je,disabled:P,showDefaultBadge:v,hideSetDefaultMenuItem:p,cardLabelFormat:T},u.id))}):null,Qe?a.jsx("div",{"data-testid":"payment-methods-empty",children:at}):j.length>0&&(!E||ae)?a.jsx("button",{type:"button",onClick:()=>{K(null),ie(null),G(!1),N(!0)},onMouseEnter:()=>{yt().catch(()=>{})},onFocus:()=>{yt().catch(()=>{})},className:"self-start rounded-lg bg-brand-50 px-6 py-3 text-md font-semibold text-brand-600 transition-colors hover:bg-brand-100","data-testid":"payment-methods-add-trigger",children:"Add payment method"}):null,a.jsxs(yr,{open:h,onClose:xe,formId:Nt,saveDisabled:!me,isSaving:re,children:[Re,U?a.jsx("p",{role:"alert","aria-live":"polite",className:"mt-3 rounded-md bg-error-50 px-3 py-2 text-sm text-error-700","data-testid":"payment-methods-modal-error",children:U}):null]}),a.jsx(xr,{open:W!==null,method:W,onClose:We,onSave:Ze,isSaving:D==="pending",error:je})]})};Lt.displayName="PaymentMethodsManager";const kr="/v1/auth/",Rr="movmo_csrf_token",Nr=t=>{if(typeof document>"u")return null;const r=document.cookie?document.cookie.split(";"):[];for(const s of r){const o=s.trim();if(o.startsWith(t+"="))return decodeURIComponent(o.substring(t.length+1))}return null},Sr=t=>typeof t=="string"?t:t instanceof URL?t.href:t.url,Pr=()=>{if(typeof globalThis<"u"&&typeof globalThis.fetch=="function")return globalThis.fetch.bind(globalThis);throw new Error("@movmo_app/payments: no global fetch available in this environment")},Tr=t=>{const{refreshSession:r,onRefreshFailed:s,csrfCookieName:o=Rr,extraHeaders:l,authPathFragment:c=kr,baseFetch:f=Pr(),readCookie:x=Nr}=t;let m=null;const R=()=>{if(m)return m;const p=(async()=>{await r()})();return m=p,p.finally(()=>{m===p&&(m=null)}).catch(()=>{}),p},w=(p,v)=>{const E=new Headers(v==null?void 0:v.headers),T=x(o);if(T&&!E.has("X-CSRF-Token")&&E.set("X-CSRF-Token",T),l){const se=l(p,v);for(const[M,C]of Object.entries(se))E.has(M)||E.set(M,C)}return{...v,headers:E,credentials:(v==null?void 0:v.credentials)??"include"}};return async function(v,E){const T=await f(v,w(v,E));if(Sr(v).includes(c)||T.status!==401&&T.status!==403)return T;try{await R()}catch(C){try{s(C)}catch(b){console.error("@movmo_app/payments: onRefreshFailed callback threw — auth retry path is misconfigured",b)}return T}try{return await f(v,w(v,E))}catch(C){return console.error("@movmo_app/payments: retry after token refresh failed — returning original response",C),T}}};exports.MovmoCardForm=vt;exports.PaymentMethodPreview=It;exports.PaymentMethodsManager=Lt;exports.createMovmoAuthFetch=Tr;exports.getPaymentsConfig=Te;exports.setPaymentsConfig=rr;exports.useDeletePaymentMethod=Ot;exports.useMovmoCardFields=Wt;exports.useSetDefaultPaymentMethod=Dt;exports.useUpdatePaymentMethod=$t;exports.useUserPaymentMethods=At;
30
+ <%s key={someKey} {...props} />`,dt,Be,Xt,Be),wt[Be+dt]=!0}}return e===o?it(V):Oe(V),V}}function Kt(e,i,d){return Et(e,i,d,!0)}function qt(e,i,d){return Et(e,i,d,!1)}var Jt=qt,Zt=Kt;et.Fragment=o,et.jsx=Jt,et.jsxs=Zt}()),et}process.env.NODE_ENV==="production"?yt.exports=rr():yt.exports=ar();var a=yt.exports;function Ot(t){var r,n,o="";if(typeof t=="string"||typeof t=="number")o+=t;else if(typeof t=="object")if(Array.isArray(t)){var l=t.length;for(r=0;r<l;r++)t[r]&&(n=Ot(t[r]))&&(o&&(o+=" "),o+=n)}else for(n in t)t[n]&&(o&&(o+=" "),o+=n);return o}function Z(){for(var t,r,n=0,o="",l=arguments.length;n<l;n++)(t=arguments[n])&&(r=Ot(t))&&(o&&(o+=" "),o+=r);return o}const sr="https://core.spreedly.com/iframe/iframe-v1.min.js",nr="https://cdn.e2e.movmo.io";let Ge={};const or=t=>{Ge={...Ge,...t}},mt=t=>{var n;const r=globalThis.process;return(n=r==null?void 0:r.env)==null?void 0:n[t]},Ye=()=>({baseUrl:Ge.baseUrl??mt("REACT_APP_MOVMO_API_URL")??"",spreedlyScriptUrl:Ge.spreedlyScriptUrl??mt("REACT_APP_SPREEDLY_SCRIPT_URL")??sr,iconCdnBaseUrl:Ge.iconCdnBaseUrl??mt("REACT_APP_MOVMO_ICON_CDN_URL")??nr,fetch:Ge.fetch??(typeof globalThis<"u"&&typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):(()=>{throw new Error("@movmo_app/payments: no fetch available")})())}),vt=t=>({id:t.id,last4:t.last4,brand:t.brand,expMonth:t.expMonth,expYear:t.expYear,isDefault:t.isDefault,vault:t.vault,cardholderName:t.cardholderName,zip:t.zip}),Ke={Accept:"application/json","Content-Type":"application/json"},qe=t=>{const{baseUrl:r}=Ye();if(!r)throw new Error("@movmo_app/payments: baseUrl is not configured. Call setPaymentsConfig({ baseUrl }) at app boot, or set REACT_APP_MOVMO_API_URL.");return`${r}${t}`},Je=(t,r)=>{const{fetch:n}=Ye();return n(t,r)},Ze=async(t,r)=>{try{return(await t.json()).message||r}catch{return r}};let tt=null;const xt=()=>{if(tt)return tt;const t=(async()=>{const r=await Je(qe("/v1/payments/tokenization-session"),{method:"GET",headers:Ke,credentials:"include"});if(!r.ok)throw new Error(await Ze(r,`Failed to fetch tokenization session (${r.status})`));return await r.json()})();return tt=t,t.finally(()=>{tt===t&&(tt=null)}).catch(()=>{}),t},ir=t=>typeof t.brand=="string"&&typeof t.last4=="string"&&typeof t.expMonth=="number"&&typeof t.expYear=="number",lr=async(t,r,n)=>{const o=await Je(qe(`/v1/users/${encodeURIComponent(t)}/payment-methods/from-token`),{method:"POST",headers:Ke,credentials:"include",body:JSON.stringify({tokenizedPaymentMethodId:r,isDefault:n})});if(!o.ok)throw new Error(await Ze(o,`Failed to save payment method (${o.status})`));const l=await o.json();if(ir(l))return vt(l);const c=await Je(qe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(l.id)}`),{method:"GET",headers:Ke,credentials:"include"});if(!c.ok)throw new Error(await Ze(c,`Failed to fetch saved payment method (${c.status})`));const m=await c.json();return vt(m)},cr=async(t,r)=>{if(!t)return[];const n=await Je(qe(`/v1/users/${encodeURIComponent(t)}/payment-methods`),{method:"GET",headers:Ke,credentials:"include",signal:r});if(!n.ok)throw new Error(await Ze(n,`Failed to fetch payment methods (${n.status})`));return(await n.json()??[]).map(vt)},dr=async(t,r)=>{const n=await Je(qe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"DELETE",headers:Ke,credentials:"include"});if(!n.ok)throw new Error(await Ze(n,`Failed to delete payment method (${n.status})`))},At=async(t,r,n)=>{const o=await Je(qe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"PUT",headers:Ke,credentials:"include",body:JSON.stringify(n)});if(!o.ok)throw new Error(await Ze(o,`Failed to update payment method (${o.status})`))},ur={visa:"visa",master:"mastercard",mastercard:"mastercard",american_express:"amex",amex:"amex",discover:"discover"},mr=28,ze=({brand:t,className:r,width:n=46})=>{const o=t?ur[t.toLowerCase()]??"credit-card":"credit-card",l=Math.max(n,mr),c=Math.round(l*24/34),{iconCdnBaseUrl:m}=Ye();return a.jsx("img",{src:`${m}/website/assets/icons/payments/${o}.svg`,alt:o==="credit-card"?"card":`${o} card`,"data-testid":`card-brand-${t.toLowerCase()}`,className:r,width:l,height:c,loading:"lazy"})};let rt=null;const fr=()=>{if(typeof window>"u")return Promise.reject(new Error("Spreedly can only be loaded in a browser environment."));if(window.Spreedly)return Promise.resolve(window.Spreedly);if(rt)return rt;const{spreedlyScriptUrl:t}=Ye();return rt=new Promise((r,n)=>{const o=document.querySelector(`script[src="${t}"]`),l=()=>{window.Spreedly?r(window.Spreedly):n(new Error("Spreedly script loaded but window.Spreedly is undefined."))};if(o){if(window.Spreedly){l();return}o.addEventListener("load",l,{once:!0}),o.addEventListener("error",()=>{o.remove(),n(new Error("Failed to load Spreedly iframe script."))},{once:!0});return}const c=document.createElement("script");c.src=t,c.async=!0,c.onload=l,c.onerror=()=>{c.remove(),n(new Error("Failed to load Spreedly iframe script."))},document.head.appendChild(c)}).catch(r=>{throw rt=null,r}),rt};class lt extends Error{constructor(n,o){super(o instanceof Error?o.message:"Failed to initialize card form.");ut(this,"source");ut(this,"cause");this.name="InitError",this.source=n,this.cause=o}}const pr="movmo-card-number",hr="movmo-card-cvv",yr=t=>({first_name:t.firstName,last_name:t.lastName,month:t.month,year:t.year,...t.email?{email:t.email}:{},...t.zip?{zip:t.zip}:{}}),Dt=(t={})=>{const{numberEl:r=pr,cvvEl:n=hr,onCardTokenized:o,onFieldErrors:l,onValidityChange:c,onBrandChange:m}=t,[y,f]=s.useState("idle"),[N,E]=s.useState(null),[x,g]=s.useState(null),[j,P]=s.useState(null),[re,A]=s.useState({number:!1,cvv:!1}),[_,k]=s.useState(null),[D,pe]=s.useState({number:!1,cvv:!1}),de=s.useRef(null),ge=s.useRef(o),ue=s.useRef(l),se=s.useRef(c),X=s.useRef(m);s.useEffect(()=>{ge.current=o},[o]),s.useEffect(()=>{ue.current=l},[l]),s.useEffect(()=>{se.current=c},[c]),s.useEffect(()=>{X.current=m},[m]);const w=s.useRef({number:!1,cvv:!1});s.useEffect(()=>{let z=!1;return f("loading"),E(null),g(null),P(null),A({number:!1,cvv:!1}),k(null),w.current={number:!1,cvv:!1},(async()=>{try{const[h,v]=await Promise.all([xt().catch(S=>{throw new lt("tokenization-session",S)}),fr().catch(S=>{throw new lt("spreedly-script",S)})]);if(z)return;de.current=v,v.on("ready",()=>{var S,M,te,ae,H,G;if(!z){f("ready");try{(S=v.setFieldType)==null||S.call(v,"number","tel"),(M=v.setFieldType)==null||M.call(v,"cvv","tel")}catch(Y){console.warn("@movmo_app/payments: setFieldType failed",Y)}try{typeof v.setNumberFormat=="function"?v.setNumberFormat("prettyFormat"):console.warn("@movmo_app/payments: Spreedly.setNumberFormat is missing — card-number digits will not be space-grouped.")}catch(Y){console.warn("@movmo_app/payments: setNumberFormat failed",Y)}try{(te=v.setPlaceholder)==null||te.call(v,"number","Card number"),(ae=v.setPlaceholder)==null||ae.call(v,"cvv","CVV");const Y='box-sizing: border-box;width: 100%;height: 100%;margin: 0;padding: 0;border: 0;background: transparent;outline: none;font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;font-size: 14px;font-weight: 400;line-height: 20px;color: rgb(28 25 23);letter-spacing: 0;vertical-align: middle;';(H=v.setStyle)==null||H.call(v,"number",Y),(G=v.setStyle)==null||G.call(v,"cvv",Y)}catch(Y){console.warn("@movmo_app/payments: setPlaceholder/setStyle failed",Y)}}}),v.on("paymentMethod",S=>{var M;(M=ge.current)==null||M.call(ge,S)}),v.on("errors",S=>{var M;(M=ue.current)==null||M.call(ue,S)}),v.on("fieldEvent",(S,M,te,ae)=>{var Y;if(z)return;if(M==="focus"){pe(T=>T[S]?T:{...T,[S]:!0});return}if(M==="blur"){pe(T=>T[S]?{...T,[S]:!1}:T);return}if(M!=="input")return;const H=ae??{};if(S==="number"){if(H.numberLength===0)k(T=>{var K;return T!==null&&((K=X.current)==null||K.call(X,null)),null});else if(H.cardType!==void 0){const T=H.cardType||null;k(K=>{var Ce;return K!==T&&((Ce=X.current)==null||Ce.call(X,T)),T})}}const G=S==="number"?typeof H.validNumber=="boolean"?H.validNumber:void 0:typeof H.validCvv=="boolean"?H.validCvv:void 0;if(typeof G=="boolean"){const T=w.current,K=S==="number"?{...T,number:G}:{...T,cvv:G};(K.number!==T.number||K.cvv!==T.cvv)&&(w.current=K,A(K),(Y=se.current)==null||Y.call(se,K))}}),v.on("consoleError",S=>{var te;const M=S instanceof Error?S.message:"An unexpected error occurred while securing your card.";(te=ue.current)==null||te.call(ue,[{message:M}])}),v.init(h.environmentKey,{numberEl:r,cvvEl:n,nonce:h.nonce,timestamp:String(h.timestamp),certificateToken:h.certificateToken,signature:h.signature})}catch(h){if(z)return;const v=h instanceof Error?h.message:"Failed to initialize card form.";E(v),g(h instanceof lt?h.source:"spreedly-script"),P(h instanceof lt?h.cause:h),f("error")}})(),()=>{var h,v;z=!0;try{(v=(h=de.current)==null?void 0:h.removeHandlers)==null||v.call(h)}catch(S){console.warn("@movmo_app/payments: removeHandlers failed during cleanup",S)}de.current=null}},[r,n]);const ye=s.useCallback(z=>{var h;(h=de.current)==null||h.tokenizeCreditCard(yr(z))},[]),_e=s.useCallback(z=>{var h,v;(v=(h=de.current)==null?void 0:h.transferFocus)==null||v.call(h,z)},[]);return{status:y,error:N,errorSource:x,errorCause:j,tokenize:ye,validity:re,brand:_,focused:D,focusField:_e}},bt={number:"Enter your card number",expiry:"Enter a valid expiry date",cvv:"Enter the security code",zip:"Enter your postal code",name:"Enter first and last name as printed on the card"},vr="Your card saves automatically once all fields are complete.",$t=t=>/^[A-Za-z0-9][A-Za-z0-9 -]{1,8}[A-Za-z0-9]$/.test(t.trim()),Ut=t=>{const r=t.replace(/[^A-Za-z0-9 -]/g,"").slice(0,10);if(!/^[\d-]*$/.test(r))return r;const n=r.replace(/-+/g,"-").replace(/^-/,"");return n.includes("-")?n:n.length===9?`${n.slice(0,5)}-${n.slice(5)}`:n},xr=({hookStatus:t,validity:r,nameValid:n,expiryValid:o,zipValid:l})=>{const c=t==="ready",m=[],y=f=>m.push({field:f,message:bt[f]});return c&&!r.number&&y("number"),o||y("expiry"),c&&!r.cvv&&y("cvv"),l||y("zip"),n||y("name"),m},ft="h-11 w-full rounded-md border bg-white px-3 py-2 text-sm text-grayWarm-900 placeholder:text-grayWarm-400 outline-none focus:border-grayWarm-950 focus:shadow-[0_0_0_1px_#1c1917]",Ct="flex h-11 w-full items-center gap-2 rounded-md border bg-white px-3 py-2 transition-shadow",kt="border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]",Rt="border-grayWarm-300",Nt="border-error-500",br={number:!1,expiry:!1,cvv:!1,zip:!1,name:!1},gr=t=>{const r=t.trim();if(!r)return{firstName:"",lastName:""};const n=r.lastIndexOf(" ");return n===-1?{firstName:r,lastName:""}:{firstName:r.slice(0,n).trim(),lastName:r.slice(n+1).trim()}},zt=t=>{const r=t.replace(/\D/g,"");if(r.length<4)return{month:"",year:""};const n=r.slice(0,2),o=r.slice(2),l=o.length===2?`20${o}`:o.slice(0,4);return{month:n,year:l}},wr=t=>{const r=t.replace(/\D/g,"").slice(0,4);return r.length<=2?r:`${r.slice(0,2)} / ${r.slice(2)}`},pt=t=>{const{month:r,year:n}=zt(t);if(!r||!n)return!1;const o=parseInt(r,10),l=parseInt(n,10);if(isNaN(o)||o<1||o>12)return!1;const c=new Date;return!(l<c.getFullYear()||l>c.getFullYear()+20||l===c.getFullYear()&&o<c.getMonth()+1)},gt=({userId:t,onSuccess:r,onError:n,onErrorDetail:o,isDefault:l=!1,className:c,defaultCardholderName:m,defaultCardholderFirstName:y="",defaultCardholderLastName:f="",autoSave:N=!1,formId:E="movmo-card-form",hideInternalSaveButton:x=!1,onCanSubmitChange:g,onSavingChange:j,autoFocus:P,onValidationChange:re})=>{const A=m??[y,f].filter(Boolean).join(" "),[_,k]=s.useState(A),[D,pe]=s.useState(""),[de,ge]=s.useState(""),[ue,se]=s.useState("idle"),X=s.useRef(!1),w=s.useRef(o);s.useEffect(()=>{w.current=o},[o]);const ye=s.useCallback(async p=>{var O;se("saving");try{const me=await lr(t,p,l);se("ready"),r(me)}catch(me){const le=me instanceof Error?me.message:"Failed to save payment method.";se("ready"),X.current=!1,n(le),(O=w.current)==null||O.call(w,{source:"save-from-token",message:le,cause:me})}},[t,l,r,n]),_e=s.useCallback(p=>{var me;const O=p.map(le=>le.message).filter(Boolean).join("; ")||"Card validation failed.";se(le=>le==="tokenizing"?"ready":le),X.current=!1,n(O),(me=w.current)==null||me.call(w,{source:"card-tokenize",message:O})},[n]),z=s.useMemo(()=>({onCardTokenized:ye,onFieldErrors:_e}),[ye,_e]),{status:h,error:v,errorSource:S,errorCause:M,tokenize:te,validity:ae,brand:H,focused:G,focusField:Y}=Dt(z),T=s.useRef(!1);s.useEffect(()=>{!P||h!=="ready"||T.current||(T.current=!0,Y(P))},[P,h,Y]);const K=_.trim().split(/\s+/).length>=2,Ce=pt(D),ve=$t(de),[q,we]=s.useState(br),J=s.useCallback(p=>we(O=>O[p]?O:{...O,[p]:!0}),[]),Pe=s.useRef(G);s.useEffect(()=>{const p=Pe.current;Pe.current=G,p.number&&!G.number&&J("number"),p.cvv&&!G.cvv&&J("cvv")},[G,J]);const ke=s.useMemo(()=>xr({hookStatus:h,validity:ae,nameValid:K,expiryValid:Ce,zipValid:ve}),[h,ae,K,Ce,ve]),ne=p=>ke.some(O=>O.field===p),Q=s.useMemo(()=>ke.map(p=>p.field),[ke]),Te=s.useMemo(()=>Q.filter(p=>q[p]),[Q,q]),$=s.useRef(re);s.useEffect(()=>{$.current=re},[re]),s.useEffect(()=>{var p;(p=$.current)==null||p.call($,{valid:Q.length===0,missing:Q,touchedInvalid:Te})},[Q,Te]);const oe=q.number&&ne("number"),Re=q.name&&ne("name"),ee=ke.find(p=>(p.field==="expiry"||p.field==="cvv"||p.field==="zip")&&q[p.field]),Ee=s.useRef(!1),Fe=s.useRef(!1),he=s.useRef(null);s.useEffect(()=>{var p;ae.cvv?Fe.current||(Fe.current=!0,(p=he.current)==null||p.focus()):Fe.current=!1},[ae.cvv]);const Ie=!K||!Ce||!ve||!ae.number||!ae.cvv,xe=ue==="tokenizing"||ue==="saving",ie=h==="ready"&&!xe&&!Ie,We=s.useRef(g);s.useEffect(()=>{We.current=g},[g]),s.useEffect(()=>{var p;(p=We.current)==null||p.call(We,ie)},[ie]);const Me=s.useRef(j);s.useEffect(()=>{Me.current=j},[j]),s.useEffect(()=>{var p;(p=Me.current)==null||p.call(Me,xe)},[xe]);const Ae=s.useCallback(()=>{const{firstName:p,lastName:O}=gr(_),{month:me,year:le}=zt(D);se("tokenizing"),te({firstName:p,lastName:O,month:me,year:le,zip:de.trim()})},[_,D,de,te]);s.useEffect(()=>{if(!N||!ie||X.current)return;const p=setTimeout(()=>{X.current=!0,Ae()},1200);return()=>clearTimeout(p)},[N,ie,Ae]);const Le=p=>{p.preventDefault(),ie&&Ae()},De=h!=="ready"||xe,Ne=s.useRef(n);return s.useEffect(()=>{Ne.current=n},[n]),s.useEffect(()=>{var p,O;v&&((p=Ne.current)==null||p.call(Ne,v),(O=w.current)==null||O.call(w,{source:S??"spreedly-script",message:v,cause:M}))},[v,S,M]),a.jsxs("form",{id:E,onSubmit:Le,className:Z("flex w-full flex-col gap-3",c),"data-testid":"movmo-card-form",children:[a.jsxs("div",{children:[a.jsx("span",{id:"movmo-card-number-label",className:"sr-only",children:"Card number"}),a.jsxs("div",{className:Z(Ct,G.number?kt:oe?Nt:Rt),"data-testid":"movmo-card-number-shell",children:[a.jsx(ze,{brand:H??"",width:32,className:"flex-shrink-0"}),a.jsxs("div",{className:"relative h-full flex-1",children:[a.jsx("div",{id:"movmo-card-number","aria-labelledby":"movmo-card-number-label","aria-busy":h!=="ready","aria-describedby":oe?"movmo-card-number-error":void 0,className:"absolute inset-0","data-testid":"movmo-card-number-mount"}),h!=="ready"?a.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-y-2 left-0 right-2 animate-pulse rounded bg-grayWarm-200"}):null]})]}),oe&&a.jsx("p",{id:"movmo-card-number-error",className:"mt-1 text-xs text-error-700","data-testid":"movmo-card-number-error",children:bt.number})]}),a.jsxs("div",{children:[a.jsxs("div",{className:"grid grid-cols-3 gap-3",children:[a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-expiry",className:"sr-only",children:"Expiry MM / YY"}),a.jsx("input",{id:"movmo-card-expiry",type:"text",inputMode:"numeric",autoComplete:"cc-exp",placeholder:"MM / YY",value:D,onChange:p=>{const O=wr(p.target.value);pe(O),pt(O)&&!Ee.current?(Ee.current=!0,Y("cvv")):pt(O)||(Ee.current=!1)},onBlur:()=>J("expiry"),"aria-invalid":q.expiry&&ne("expiry"),"aria-describedby":(ee==null?void 0:ee.field)==="expiry"?"movmo-card-row-error":void 0,className:Z(ft,q.expiry&&ne("expiry")?"border-error-500":"border-grayWarm-300"),disabled:De,required:!0,"data-testid":"movmo-card-expiry-input"})]}),a.jsxs("div",{className:"relative",children:[a.jsx("span",{id:"movmo-card-cvv-label",className:"sr-only",children:"CVV"}),a.jsxs("div",{className:Z(Ct,G.cvv?kt:q.cvv&&ne("cvv")?Nt:Rt),"data-testid":"movmo-card-cvv-shell",children:[a.jsxs("div",{className:"relative h-full flex-1",children:[a.jsx("div",{id:"movmo-card-cvv","aria-labelledby":"movmo-card-cvv-label","aria-busy":h!=="ready","aria-describedby":(ee==null?void 0:ee.field)==="cvv"?"movmo-card-row-error":void 0,className:"absolute inset-0","data-testid":"movmo-card-cvv-mount"}),h!=="ready"?a.jsx("div",{"aria-hidden":"true",className:"pointer-events-none absolute inset-y-2 left-0 right-2 animate-pulse rounded bg-grayWarm-200"}):null]}),a.jsx("button",{type:"button","aria-label":"CVV help",tabIndex:-1,className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full border border-grayWarm-300 text-xs text-grayWarm-500",title:H==="american_express"?"The 4 numbers on the front of your card.":"The 3 numbers on the back of your card.","data-testid":"movmo-cvv-help",children:"?"})]})]}),a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-zip",className:"sr-only",children:"Postal code"}),a.jsx("input",{id:"movmo-card-zip",ref:he,type:"text",autoComplete:"postal-code",placeholder:"Postal code",value:de,onChange:p=>{ge(Ut(p.target.value))},onBlur:()=>J("zip"),"aria-invalid":q.zip&&ne("zip"),"aria-describedby":(ee==null?void 0:ee.field)==="zip"?"movmo-card-row-error":void 0,className:Z(ft,q.zip&&ne("zip")?"border-error-500":"border-grayWarm-300"),disabled:De,required:!0,"data-testid":"movmo-card-zip-input"})]})]}),ee&&a.jsx("p",{id:"movmo-card-row-error",className:"mt-1 text-xs text-error-700","data-testid":"movmo-card-row-error",children:ee.message})]}),a.jsxs("div",{children:[a.jsx("label",{htmlFor:"movmo-card-cardholder-name",className:"sr-only",children:"Cardholder name"}),a.jsx("input",{id:"movmo-card-cardholder-name",type:"text",autoComplete:"cc-name",placeholder:"Cardholder name",value:_,onChange:p=>k(p.target.value),onBlur:()=>J("name"),"aria-invalid":Re,"aria-describedby":Re?"movmo-card-name-error":void 0,className:Z(ft,Re?"border-error-500":"border-grayWarm-300"),disabled:De,required:!0,"data-testid":"movmo-card-cardholder-name-input"}),Re&&a.jsx("p",{id:"movmo-card-name-error",className:"mt-1 text-xs text-error-700","data-testid":"movmo-card-name-error",children:bt.name})]}),!N&&!x?a.jsx("button",{type:"submit",disabled:!ie,className:Z("inline-flex h-11 items-center justify-center rounded-md bg-brand-500 px-4 text-sm font-semibold text-white transition-colors hover:bg-brand-600","disabled:cursor-not-allowed disabled:bg-grayWarm-300 disabled:text-grayWarm-500"),"data-testid":"movmo-card-save",children:xe?"Saving…":h==="loading"?"Loading…":"Save card"}):N?a.jsx("div",{className:"text-center","aria-live":"polite","data-testid":"movmo-card-autosave-status",children:xe?a.jsx("p",{className:"text-sm text-grayWarm-500","data-testid":"movmo-card-autosaving",children:"Saving card…"}):ke.length>0?a.jsx("p",{className:"text-xs text-grayWarm-600","data-testid":"movmo-card-autosave-hint",children:vr}):null}):null]})};gt.displayName="MovmoCardForm";const It=t=>{const[r,n]=s.useState("idle"),[o,l]=s.useState(null);return{deletePaymentMethod:s.useCallback(async m=>{n("pending"),l(null);try{await dr(t,m),n("idle")}catch(y){const f=y instanceof Error?y.message:"Failed to delete payment method.";throw l(f),n("error"),y}},[t]),status:r,error:o}},Lt=t=>{const[r,n]=s.useState("idle"),[o,l]=s.useState(null);return{setDefault:s.useCallback(async m=>{n("pending"),l(null);try{await At(t,m,{isDefault:!0}),n("idle")}catch(y){const f=y instanceof Error?y.message:"Failed to set default payment method.";throw l(f),n("error"),y}},[t]),status:r,error:o}},Bt=t=>{const[r,n]=s.useState("idle"),[o,l]=s.useState(null);return{updatePaymentMethod:s.useCallback(async(m,y)=>{n("pending"),l(null);try{await At(t,m,y),n("idle")}catch(f){const N=f instanceof Error?f.message:"Failed to update payment method.";throw l(N),n("error"),f}},[t]),status:r,error:o}},Yt=t=>{const[r,n]=s.useState([]),[o,l]=s.useState("idle"),[c,m]=s.useState(null),[y,f]=s.useState(0),N=s.useRef(null);s.useEffect(()=>{var g;if((g=N.current)==null||g.abort(),!t){N.current=null,n([]),m(null),l("ready");return}const x=new AbortController;return N.current=x,l("loading"),m(null),cr(t,x.signal).then(j=>{x.signal.aborted||(n(j),l("ready"))}).catch(j=>{if(x.signal.aborted||j instanceof DOMException&&j.name==="AbortError")return;const P=j instanceof Error?j.message:"Failed to fetch payment methods.";m(P),l("error")}),()=>{x.abort()}},[t,y]);const E=s.useCallback(()=>{f(x=>x+1)},[]);return{items:r,status:o,error:c,refetch:E}},Vt=({open:t,onClose:r,title:n,titleId:o,formId:l,saveDisabled:c,saveLabel:m="Save",isSaving:y=!1,testIdPrefix:f="payment-method",children:N})=>(s.useEffect(()=>{if(!t)return;const E=x=>{x.key==="Escape"&&r()};return document.addEventListener("keydown",E),()=>document.removeEventListener("keydown",E)},[t,r]),s.useEffect(()=>{if(!t)return;const E=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=E}},[t]),t?a.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":o,className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",onClick:E=>{E.target===E.currentTarget&&r()},"data-testid":`${f}-modal`,children:a.jsxs("div",{className:"flex max-h-full w-full max-w-md flex-col rounded-xl bg-white shadow-2xl",children:[a.jsxs("div",{className:"flex items-center gap-3 border-b border-grayWarm-200 px-4 py-3",children:[a.jsx("button",{type:"button",onClick:r,"aria-label":`Close ${n.toLowerCase()} dialog`,className:"flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg bg-grayWarm-100 p-2 text-grayWarm-950 transition-colors hover:bg-grayWarm-200","data-testid":`${f}-close`,children:a.jsx("svg",{viewBox:"0 0 20 20",width:"20",height:"20","aria-hidden":"true",children:a.jsx("path",{d:"M5 5L15 15M15 5L5 15",stroke:"currentColor",strokeWidth:"1.67",strokeLinecap:"round",strokeLinejoin:"round"})})}),a.jsx("h2",{id:o,className:"flex-1 text-center text-base font-semibold text-grayWarm-900",children:n}),a.jsx("span",{"aria-hidden":"true",className:"h-9 w-9 flex-shrink-0"})]}),a.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:N}),a.jsxs("div",{className:"flex gap-3 border-t border-grayWarm-200 p-4",children:[a.jsx("button",{type:"button",onClick:r,className:"inline-flex h-11 flex-1 items-center justify-center rounded-lg border border-grayWarm-300 px-4 text-sm font-semibold text-grayWarm-900 transition-colors hover:border-grayWarm-900 hover:shadow-[0_0_0_1px_#1c1917]","data-testid":`${f}-cancel`,children:"Cancel"}),a.jsx("button",{type:"submit",form:l,disabled:y?!1:c,"aria-disabled":y||c,"aria-busy":y,className:Z("inline-flex h-11 flex-1 items-center justify-center rounded-lg bg-brand-500 px-4 text-sm font-semibold text-white transition-colors",y?"cursor-not-allowed opacity-90 pointer-events-none":"hover:bg-brand-600 disabled:cursor-not-allowed disabled:bg-grayWarm-300 disabled:text-grayWarm-500"),"data-testid":`${f}-save`,children:y?a.jsxs(a.Fragment,{children:[a.jsxs("svg",{className:"h-[18px] w-[18px] animate-spin",viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:[a.jsx("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3",strokeOpacity:"0.25"}),a.jsx("path",{d:"M22 12a10 10 0 0 1-10 10",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]}),a.jsx("span",{className:"sr-only",children:"Saving"})]}):m})]})]})}):null),Er=({open:t,onClose:r,formId:n,saveDisabled:o,saveLabel:l="Save",isSaving:c=!1,children:m})=>a.jsx(Vt,{open:t,onClose:r,title:"Add payment method",titleId:"movmo-add-payment-title",formId:n,saveDisabled:o,saveLabel:l,isSaving:c,testIdPrefix:"add-payment-method",children:m}),jr=(t,r)=>`${String(t).padStart(2,"0")}/${r}`,_r=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},Cr=({open:t,method:r,onClose:n,onSave:o,isSaving:l=!1,error:c=null})=>{const m=s.useId(),[y,f]=s.useState(""),[N,E]=s.useState("");if(s.useEffect(()=>{t&&r&&(f(r.cardholderName??""),E(r.zip??""))},[t,r]),!r)return null;const x=y.trim(),g=N.trim(),j=x!==(r.cardholderName??"").trim(),P=g!==(r.zip??"").trim(),re=j||P,A=(!j||x.length>0)&&(!P||$t(g)),_=!re||!A,k=D=>{if(D.preventDefault(),_||l)return;const pe={};j&&(pe.cardholderName=x),P&&(pe.zip=g),o(pe).catch(()=>{})};return a.jsxs(Vt,{open:t,onClose:n,title:"Edit payment method",titleId:"movmo-edit-payment-title",formId:m,saveDisabled:_,isSaving:l,testIdPrefix:"edit-payment-method",children:[a.jsxs("div",{className:"mb-4 flex items-start gap-3 rounded-lg bg-grayWarm-50 p-3","data-testid":"edit-payment-method-context",children:[a.jsx(ze,{brand:r.brand,className:"flex-shrink-0"}),a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsxs("div",{className:"text-lg font-semibold text-grayWarm-950",children:[_r(r.brand)," •••• ",r.last4]}),a.jsxs("div",{className:"text-sm text-grayWarm-600",children:["Exp. ",jr(r.expMonth,r.expYear)]})]})]}),a.jsxs("form",{id:m,onSubmit:k,className:"flex flex-col gap-4",noValidate:!0,children:[a.jsxs("label",{className:"flex flex-col gap-1.5 text-sm font-medium text-grayWarm-700",children:["Cardholder name",a.jsx("input",{type:"text",autoComplete:"cc-name",value:y,onChange:D=>f(D.target.value),disabled:l,maxLength:255,"data-testid":"edit-payment-method-cardholder",className:"h-11 rounded-lg border border-grayWarm-300 px-3 text-base font-normal text-grayWarm-950 focus:border-grayWarm-950 focus:outline-none focus:ring-1 focus:ring-grayWarm-950"})]}),a.jsxs("label",{className:"flex flex-col gap-1.5 text-sm font-medium text-grayWarm-700",children:["Postal code",a.jsx("input",{type:"text",autoComplete:"postal-code",value:N,onChange:D=>E(Ut(D.target.value)),disabled:l,"data-testid":"edit-payment-method-zip",className:"h-11 rounded-lg border border-grayWarm-300 px-3 text-base font-normal text-grayWarm-950 focus:border-grayWarm-950 focus:outline-none focus:ring-1 focus:ring-grayWarm-950"})]}),c?a.jsx("p",{role:"alert",className:"text-sm text-error-700","data-testid":"edit-payment-method-error",children:c}):null]})]})},kr=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},Ht=({method:t,trailing:r,onClick:n,cardLabelFormat:o="branded",className:l})=>a.jsxs("div",{className:Z("flex items-center gap-3",n&&"cursor-pointer",l),onClick:n,role:n?"button":void 0,tabIndex:n?0:void 0,onKeyDown:n?c=>{(c.key==="Enter"||c.key===" ")&&(c.preventDefault(),n())}:void 0,"data-testid":`payment-method-preview-${t.id}`,children:[a.jsx(ze,{brand:t.brand,width:34,className:"flex-shrink-0"}),a.jsx("span",{className:"flex-1 text-lg font-semibold text-grayWarm-950",children:o==="masked"?`•••• ${t.last4}`:`${kr(t.brand)} ${t.last4}`}),r]}),Rr=(t,r,n=new Date)=>r<n.getFullYear()||r===n.getFullYear()&&t<n.getMonth()+1,St=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},Nr=(t,r)=>`${String(t).padStart(2,"0")}/${r}`,Sr=({method:t,selectable:r,selected:n,onSelect:o,onSetDefault:l,onRemove:c,onEdit:m,disabled:y,showDefaultBadge:f,hideSetDefaultMenuItem:N,cardLabelFormat:E="branded"})=>{const[x,g]=s.useState(!1),j=s.useRef(null),P=Rr(t.expMonth,t.expYear);s.useEffect(()=>{if(!x)return;const A=_=>{var k;(k=j.current)!=null&&k.contains(_.target)||g(!1)};return document.addEventListener("mousedown",A),()=>document.removeEventListener("mousedown",A)},[x]);const re=()=>{r&&o&&!y&&o(t)};return a.jsxs("div",{className:Z("flex items-start gap-3 transition-colors",r?"rounded-lg border px-3 py-3":"py-4",r&&!y&&"cursor-pointer",r&&(n?"border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200 hover:border-grayWarm-300")),onClick:re,"data-testid":`payment-method-row-${t.id}`,children:[r?a.jsx("input",{type:"radio",name:"movmo-payment-method",checked:n,onChange:()=>o==null?void 0:o(t),onClick:A=>A.stopPropagation(),"aria-label":`Select ${St(t.brand)} ending ${t.last4}`,className:"mr-1 h-4 w-4 mt-2 cursor-pointer appearance-none rounded-full border-2 border-grayWarm-300 checked:border-[5px] checked:border-grayWarm-950 bg-white checked:bg-white focus:ring-0 focus:ring-offset-0",disabled:y}):null,a.jsx(ze,{brand:t.brand,className:"flex-shrink-0"}),a.jsxs("div",{className:"min-w-0 flex-1",children:[a.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[a.jsx("span",{className:"text-lg font-semibold text-grayWarm-950",children:E==="masked"?`•••• ${t.last4}`:`${St(t.brand)} ${t.last4}`}),f&&t.isDefault?a.jsx("span",{className:"inline-flex items-center rounded-full bg-success-50 px-2 py-0.5 text-xs font-semibold text-success-700","data-testid":`badge-default-${t.id}`,children:"Default"}):null,P?a.jsx("span",{className:"inline-flex items-center rounded-full bg-error-50 px-2 py-0.5 text-xs font-semibold text-error-700","data-testid":`badge-expired-${t.id}`,children:"Expired"}):null]}),a.jsxs("div",{className:Z("text-base",P?"text-grayWarm-400":"text-grayWarm-600"),children:["Exp. ",Nr(t.expMonth,t.expYear)]})]}),a.jsxs("div",{className:"relative flex-shrink-0",ref:j,children:[a.jsx("button",{type:"button","aria-label":`Open actions for card ending ${t.last4}`,"aria-haspopup":"menu","aria-expanded":x,className:"rounded-lg p-2 text-grayWarm-600 transition-colors hover:bg-grayWarm-100 disabled:cursor-not-allowed disabled:opacity-50",disabled:y,onClick:A=>{A.stopPropagation(),g(_=>!_)},"data-testid":`menu-trigger-${t.id}`,children:a.jsx("svg",{viewBox:"0 0 24 24",width:"20",height:"20",fill:"currentColor","aria-hidden":"true",children:a.jsx("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"})})}),x?a.jsxs("div",{role:"menu",className:Z("absolute z-10 whitespace-nowrap rounded-lg border border-grayWarm-200 bg-white py-1 shadow-lg",r?"bottom-full left-1/2 mb-2 -translate-x-1/2":"right-0 top-full mt-1"),onClick:A=>A.stopPropagation(),"data-testid":`menu-${t.id}`,children:[r?a.jsx("span",{"aria-hidden":"true",className:"absolute -bottom-1.5 left-1/2 h-3 w-3 -translate-x-1/2 rotate-45 border-b border-r border-grayWarm-200 bg-white"}):null,!t.isDefault&&!N?a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-grayWarm-950 hover:text-grayWarm-700",onClick:()=>{g(!1),l(t)},"data-testid":`menu-set-default-${t.id}`,children:"Set as default"}):null,m&&t.vault==="spreedly"?a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-grayWarm-950 hover:text-grayWarm-700",onClick:()=>{g(!1),m(t)},"data-testid":`menu-edit-${t.id}`,children:"Edit"}):null,a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-1 text-left text-md font-semibold text-error-700 hover:text-error-500",onClick:()=>{g(!1),c(t)},"data-testid":`menu-remove-${t.id}`,children:"Delete"})]}):null]})]})},Pr=t=>`${Ye().iconCdnBaseUrl}/website/assets/icons/payments/${t}.svg`,ht=({slug:t,alt:r})=>a.jsx("img",{src:Pr(t),alt:r,height:20,loading:"lazy",style:{height:20,width:"auto"}}),ct=({type:t,label:r,iconNode:n,disabled:o=!1})=>a.jsxs("label",{className:"flex cursor-pointer items-center gap-3 rounded-lg border border-grayWarm-200 px-4 py-3 transition-colors hover:border-grayWarm-300","data-testid":`payment-type-${t}`,children:[a.jsx("input",{type:"radio",name:"movmo-payment-type",value:t,disabled:o,onChange:()=>{},className:Z("h-4 w-4 accent-grayWarm-900",o?"cursor-not-allowed":"cursor-pointer"),"aria-label":r}),a.jsxs("span",{className:"flex flex-1 items-center gap-2 text-sm font-semibold text-grayWarm-900",children:[r,n]})]}),Pt=({selected:t,onSelect:r,creditCardBody:n,disabled:o=!1,className:l})=>{const c=t==="credit_card";return a.jsxs("div",{className:Z("flex w-full flex-col gap-3",l),children:[a.jsxs("label",{className:Z("flex cursor-pointer flex-col gap-3 rounded-lg border px-4 py-3 transition-colors",c?"border-grayWarm-900 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200"),"data-testid":"payment-type-credit_card",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx("input",{type:"radio",name:"movmo-payment-type",value:"credit_card",checked:c,disabled:o,onChange:()=>{o||r("credit_card")},className:Z("h-4 w-4 accent-grayWarm-900",o?"cursor-not-allowed":"cursor-pointer"),"aria-label":"Credit card"}),a.jsx("span",{className:"flex-1 text-sm font-semibold text-grayWarm-900",children:"Credit card"}),a.jsxs("div",{className:"flex items-center gap-1.5",children:[a.jsx(ze,{brand:"mastercard",width:28}),a.jsx(ze,{brand:"visa",width:28}),a.jsx(ze,{brand:"amex",width:28}),a.jsx(ze,{brand:"discover",width:28})]})]}),c?a.jsx("div",{"data-testid":"payment-type-credit_card-body",children:n}):null]}),c?a.jsx("p",{className:"mt-2 text-sm font-semibold text-grayWarm-900","data-testid":"payment-type-other-options-header",children:"Other options"}):null,a.jsx(ct,{type:"paypal",label:"PayPal",iconNode:a.jsx(ht,{slug:"paypal",alt:"PayPal"}),disabled:o}),a.jsx(ct,{type:"googlepay",label:"GooglePay",iconNode:a.jsx(ht,{slug:"google-pay",alt:"GooglePay"}),disabled:o}),a.jsx(ct,{type:"klarna",label:"Klarna",iconNode:a.jsx(ht,{slug:"klarna",alt:"Klarna"}),disabled:o}),a.jsx(ct,{type:"ach",label:"Bank account (ACH)",iconNode:a.jsx("span",{className:"text-xs font-medium text-grayWarm-500",children:"Direct debit"}),disabled:o})]})},Tt="movmo-add-payment-form",Tr=t=>{console.error("@movmo_app/payments: failed to update payment method",t);const r=t instanceof Error?t.message.trim():"";return/spreedly-backed cards/i.test(r)?"This card's details can't be edited.":r||"Failed to update payment method."},Ft=t=>{const r=t.filter(o=>o.isDefault),n=t.filter(o=>!o.isDefault);return[...r,...n]},Wt=({message:t,testId:r})=>a.jsx("p",{role:"alert","aria-live":"polite",className:"mt-3 rounded-md bg-error-50 px-3 py-2 text-sm text-error-700","data-testid":r,children:t}),Mt=({withDefaultBadge:t=!1})=>a.jsxs("div",{className:"flex items-start justify-between py-4","data-testid":"payment-method-skeleton",children:[a.jsxs("div",{className:"flex items-start gap-3",children:[a.jsx("div",{className:"h-8 w-[46px] flex-shrink-0 animate-pulse rounded bg-grayWarm-200"}),a.jsxs("div",{className:"space-y-2",children:[a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("div",{className:"h-5 w-[120px] animate-pulse rounded bg-grayWarm-200"}),t?a.jsx("div",{className:"h-5 w-[56px] animate-pulse rounded-full bg-grayWarm-200"}):null]}),a.jsx("div",{className:"h-4 w-[100px] animate-pulse rounded bg-grayWarm-200"})]})]}),a.jsx("div",{className:"h-5 w-5 flex-shrink-0 animate-pulse rounded-full bg-grayWarm-200"})]}),Gt=({userId:t,defaultCardholderName:r,defaultCardholderFirstName:n,defaultCardholderLastName:o,selectedId:l,onSelect:c,onChange:m,onError:y,onEvent:f,paymentTypeSelector:N=!0,autoSaveFirstCard:E=!0,selectionSetsDefault:x=!1,showDefaultBadge:g=!0,collapsible:j=!1,cardLabelFormat:P="branded",className:re})=>{const{items:A,status:_,error:k,refetch:D}=Yt(t),{deletePaymentMethod:pe,status:de}=It(t),{setDefault:ge,status:ue}=Lt(t),{updatePaymentMethod:se,status:X}=Bt(t),[w,ye]=s.useState([]),_e=s.useRef(w);s.useEffect(()=>{_e.current=w},[w]);const[z,h]=s.useState(null),[v,S]=s.useState(!1),[M,te]=s.useState(null),[ae,H]=s.useState(!1),[G,Y]=s.useState(!1),[T,K]=s.useState(null),[Ce,ve]=s.useState(null),[q,we]=s.useState(null),[J,Pe]=s.useState(!1),ke=s.useRef(!1),ne=s.useRef(y);s.useEffect(()=>{ne.current=y},[y]);const Q=s.useCallback(u=>{var L;(L=ne.current)==null||L.call(ne,u)},[]),Te=s.useRef(f);s.useEffect(()=>{Te.current=f},[f]);const $=s.useCallback((u,L)=>{var I;(I=Te.current)==null||I.call(Te,u,L)},[]),oe=s.useRef(!1),Re=s.useCallback(u=>{if(u.touchedInvalid.length===0){oe.current=!1;return}oe.current||(oe.current=!0,$("validation_error",{field_count:u.touchedInvalid.length,fields:u.touchedInvalid}))},[$]),ee=s.useCallback(()=>{S(!1),te(null),we(null),oe.current=!1},[]),Ee=r??([n,o].filter(Boolean).join(" ")||void 0);s.useEffect(()=>{_==="ready"&&ye(Ft(A))},[A,_]);const Fe=s.useRef(null);s.useEffect(()=>{if(_==="error"&&k){if(Fe.current===k)return;Fe.current=k,Q({source:"list",message:k})}else _!=="error"&&(Fe.current=null)},[_,k,Q]),s.useEffect(()=>{if(!c||ke.current||_!=="ready"||w.length===0||l)return;ke.current=!0,$("autoselected",{had_saved_methods:!0});const u=w.find(L=>L.isDefault)??w[0];c(u)},[c,_,w,l,$]);const he=s.useCallback(u=>{ye(L=>{const I=typeof u=="function"?u(L):u,U=Ft(I);return queueMicrotask(()=>m==null?void 0:m(U)),U})},[m]),Ie=de==="pending"||ue==="pending"||X==="pending",xe=s.useCallback(async u=>{const L=w;h(null),he(I=>I.map(U=>({...U,isDefault:U.id===u.id})));try{await ge(u.id),D(),$("set_default")}catch(I){ye(L),m==null||m(L);const U=I instanceof Error?I.message:"Failed to set default payment method.";h(U),Q({source:"set-default",message:U,cause:I})}},[w,he,ge,D,m,Q,$]),ie=s.useCallback(u=>{c==null||c(u),x&&(u.isDefault||xe(u))},[c,x,xe]),We=s.useCallback(u=>{$("selected",{method_count:w.length}),ie(u)},[$,w,ie]),Me=s.useCallback(async u=>{const L=w;h(null);const I=w.filter(Oe=>Oe.id!==u.id);he(()=>I);const U=u.id===l&&c?I.find(Oe=>Oe.isDefault)??I[0]??null:null;U&&ie(U);const je=!!U&&x&&U!==null&&!U.isDefault;try{await pe(u.id),je||D(),$("deleted",{remaining_count:I.length})}catch(Oe){ye(L),m==null||m(L);const it=Oe instanceof Error?Oe.message:"Failed to delete payment method.";h(it),Q({source:"delete",message:it,cause:Oe})}},[w,he,pe,D,m,l,c,ie,x,Q,$]),Ae=s.useCallback(u=>{ve(null),K(u)},[]),Le=s.useCallback(()=>{K(null),ve(null)},[]),De=s.useCallback(async u=>{if(!T)return;const L=T,I=w;ve(null),he(U=>U.map(je=>je.id===L.id?{...je,...u.cardholderName!==void 0?{cardholderName:u.cardholderName}:{},...u.zip!==void 0?{zip:u.zip}:{}}:je));try{await se(L.id,u),Le(),D(),$("edited",{fields:Object.keys(u)})}catch(U){ye(I),m==null||m(I);const je=Tr(U);ve(je),Q({source:"update",message:je,cause:U})}},[T,w,he,se,D,m,Le,Q,$]),Ne=s.useCallback(u=>{ee(),he(I=>[u,...I.filter(U=>U.id!==u.id)]),ie(u),!!c&&x&&!u.isDefault||D(),$("added",{method_count:_e.current.length+1})},[ee,he,D,ie,c,x,$]),p=s.useCallback(u=>{te(u)},[]),O=s.useCallback(u=>{Y(u),u&&te(null)},[]),me=_==="ready"&&w.length===0,le=typeof c=="function",at=!le&&!j,st=w.length===0,nt=E&&w.length===0,$e=s.useCallback(u=>a.jsx(gt,{userId:t,isDefault:st,defaultCardholderName:Ee,autoSave:!u&&nt,hideInternalSaveButton:u,formId:u?Tt:void 0,onCanSubmitChange:u?H:void 0,onSavingChange:O,autoFocus:u?"number":void 0,onSuccess:Ne,onError:p,onErrorDetail:Q,onValidationChange:Re}),[t,st,Ee,nt,Ne,p,O,Q,Re]),Ve=s.useMemo(()=>$e(!1),[$e]),Se=s.useMemo(()=>$e(!0),[$e]),Ue=!t,Xe=s.useMemo(()=>N?a.jsx(Pt,{selected:q,onSelect:u=>we(u),creditCardBody:Ve,disabled:Ue}):Ve,[N,q,Ve,Ue]),ot=s.useMemo(()=>N?a.jsx(Pt,{selected:q,onSelect:u=>we(u),creditCardBody:Se,disabled:Ue}):Se,[N,q,Se,Ue]);return a.jsxs("div",{className:Z("flex w-full flex-col gap-4",re),"data-testid":"payment-methods-manager",children:[_==="loading"&&w.length===0?a.jsxs("div",{className:Z(at?"flex flex-col divide-y divide-grayWarm-200 rounded-xl border border-grayWarm-200 px-4 md:px-6":"flex flex-col gap-2"),"data-testid":"payment-methods-loading",children:[a.jsx(Mt,{withDefaultBadge:!0}),a.jsx(Mt,{})]}):null,_==="error"?a.jsxs("div",{role:"alert","aria-live":"polite",className:"flex items-center justify-between gap-3 rounded-md bg-error-50 p-3 text-sm text-error-700","data-testid":"payment-methods-list-error",children:[a.jsx("span",{children:k??"Failed to load payment methods."}),a.jsx("button",{type:"button",onClick:D,className:"rounded-md border border-error-700 px-3 py-1 text-xs font-semibold text-error-700 hover:bg-error-50",children:"Retry"})]}):null,z?a.jsx("div",{role:"alert","aria-live":"polite",className:"rounded-md bg-error-50 p-3 text-sm text-error-700","data-testid":"payment-methods-mutation-error",children:z}):null,j&&w.length>0?a.jsx("div",{className:"border-t border-grayWarm-200 pt-4",children:a.jsxs("div",{className:"flex items-center justify-between","data-testid":J?"payment-methods-drawer-header":"payment-methods-collapsed-preview",children:[J?a.jsx("h3",{className:"text-md font-semibold text-grayWarm-950",children:"Payment methods"}):a.jsx(Ht,{method:w.find(u=>u.id===l)??w.find(u=>u.isDefault)??w[0],cardLabelFormat:P,className:"flex-1"}),a.jsx("button",{type:"button","aria-label":J?"Collapse payment methods":"Expand payment methods","aria-expanded":J,className:"bg-grayWarm-100 p-2 rounded-lg hover:bg-grayWarm-200 transition-colors",onClick:()=>Pe(u=>!u),"data-testid":J?"payment-methods-drawer-close":"payment-methods-drawer-open",children:a.jsx("img",{src:`${Ye().iconCdnBaseUrl}/website/assets/icons/chevron-${J?"up":"down"}-double.svg`,alt:"",className:"w-5 h-5"})})]})}):null,w.length>0&&(!j||J)?a.jsx("div",{className:Z("flex flex-col",at?"rounded-xl border border-grayWarm-200 px-4 md:px-6 divide-y divide-grayWarm-200":"space-y-3"),children:w.map(u=>a.jsx(Sr,{method:u,selectable:le,selected:le&&u.id===l,onSelect:We,onSetDefault:xe,onRemove:Me,onEdit:Ae,disabled:Ie,showDefaultBadge:g,hideSetDefaultMenuItem:x,cardLabelFormat:P},u.id))}):null,me?a.jsxs("div",{"data-testid":"payment-methods-empty",children:[Xe,M&&!v?a.jsx(Wt,{message:M,testId:"payment-methods-inline-error"}):null]}):w.length>0&&(!j||J)?a.jsx("button",{type:"button",onClick:()=>{te(null),we(null),H(!1),S(!0),oe.current=!1},onMouseEnter:()=>{xt().catch(()=>{})},onFocus:()=>{xt().catch(()=>{})},className:"self-start rounded-lg bg-brand-50 px-6 py-3 text-md font-semibold text-brand-600 transition-colors hover:bg-brand-100","data-testid":"payment-methods-add-trigger",children:"Add payment method"}):null,a.jsxs(Er,{open:v,onClose:ee,formId:Tt,saveDisabled:!ae,isSaving:G,children:[ot,M?a.jsx(Wt,{message:M,testId:"payment-methods-modal-error"}):null]}),a.jsx(Cr,{open:T!==null,method:T,onClose:Le,onSave:De,isSaving:X==="pending",error:Ce})]})};Gt.displayName="PaymentMethodsManager";const Fr="/v1/auth/",Wr="movmo_csrf_token",Mr=t=>{if(typeof document>"u")return null;const r=document.cookie?document.cookie.split(";"):[];for(const n of r){const o=n.trim();if(o.startsWith(t+"="))return decodeURIComponent(o.substring(t.length+1))}return null},Or=t=>typeof t=="string"?t:t instanceof URL?t.href:t.url,Ar=()=>{if(typeof globalThis<"u"&&typeof globalThis.fetch=="function")return globalThis.fetch.bind(globalThis);throw new Error("@movmo_app/payments: no global fetch available in this environment")},Dr=t=>{const{refreshSession:r,onRefreshFailed:n,csrfCookieName:o=Wr,extraHeaders:l,authPathFragment:c=Fr,baseFetch:m=Ar(),readCookie:y=Mr}=t;let f=null;const N=()=>{if(f)return f;const x=(async()=>{await r()})();return f=x,x.finally(()=>{f===x&&(f=null)}).catch(()=>{}),x},E=(x,g)=>{const j=new Headers(g==null?void 0:g.headers),P=y(o);if(P&&!j.has("X-CSRF-Token")&&j.set("X-CSRF-Token",P),l){const re=l(x,g);for(const[A,_]of Object.entries(re))j.has(A)||j.set(A,_)}return{...g,headers:j,credentials:(g==null?void 0:g.credentials)??"include"}};return async function(g,j){const P=await m(g,E(g,j));if(Or(g).includes(c)||P.status!==401&&P.status!==403)return P;try{await N()}catch(_){try{n(_)}catch(k){console.error("@movmo_app/payments: onRefreshFailed callback threw — auth retry path is misconfigured",k)}return P}try{return await m(g,E(g,j))}catch(_){return console.error("@movmo_app/payments: retry after token refresh failed — returning original response",_),P}}};exports.MovmoCardForm=gt;exports.PaymentMethodPreview=Ht;exports.PaymentMethodsManager=Gt;exports.createMovmoAuthFetch=Dr;exports.getPaymentsConfig=Ye;exports.setPaymentsConfig=or;exports.useDeletePaymentMethod=It;exports.useMovmoCardFields=Dt;exports.useSetDefaultPaymentMethod=Lt;exports.useUpdatePaymentMethod=Bt;exports.useUserPaymentMethods=Yt;
31
31
  //# sourceMappingURL=index.cjs.js.map