@movmo_app/payments 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +10 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +67 -6
- package/dist/index.es.js +1169 -866
- package/dist/index.es.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react");var Ze={exports:{}},Oe={};/**
|
|
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
|
|
9
|
+
*/var dt;function Vt(){if(dt)return Oe;dt=1;var t=o,r=Symbol.for("react.element"),s=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,c=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,d={key:!0,ref:!0,__self:!0,__source:!0};function p(y,v,D){var C,g={},W=null,A=null;D!==void 0&&(W=""+D),v.key!==void 0&&(W=""+v.key),v.ref!==void 0&&(A=v.ref);for(C in v)i.call(v,C)&&!d.hasOwnProperty(C)&&(g[C]=v[C]);if(y&&y.defaultProps)for(C in v=y.defaultProps,v)g[C]===void 0&&(g[C]=v[C]);return{$$typeof:r,type:y,key:W,ref:A,props:g,_owner:c.current}}return Oe.Fragment=s,Oe.jsx=p,Oe.jsxs=p,Oe}var De={};/**
|
|
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
|
|
18
|
-
`+
|
|
19
|
-
`),
|
|
20
|
-
`),$=
|
|
21
|
-
`+
|
|
17
|
+
*/var ut;function qt(){return ut||(ut=1,process.env.NODE_ENV!=="production"&&function(){var t=o,r=Symbol.for("react.element"),s=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),c=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),p=Symbol.for("react.provider"),y=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),D=Symbol.for("react.suspense"),C=Symbol.for("react.suspense_list"),g=Symbol.for("react.memo"),W=Symbol.for("react.lazy"),A=Symbol.for("react.offscreen"),J=Symbol.iterator,P="@@iterator";function re(e){if(e===null||typeof e!="object")return null;var n=J&&e[J]||e[P];return typeof n=="function"?n:null}var _=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function T(e){{for(var n=arguments.length,l=new Array(n>1?n-1:0),m=1;m<n;m++)l[m-1]=arguments[m];V("error",e,l)}}function V(e,n,l){{var m=_.ReactDebugCurrentFrame,j=m.getStackAddendum();j!==""&&(n+="%s",l=l.concat([j]));var S=l.map(function(x){return String(x)});S.unshift("Warning: "+n),Function.prototype.apply.call(console[e],console,S)}}var le=!1,X=!1,w=!1,te=!1,fe=!1,I;I=Symbol.for("react.module.reference");function N(e){return!!(typeof e=="string"||typeof e=="function"||e===i||e===d||fe||e===c||e===D||e===C||te||e===A||le||X||w||typeof e=="object"&&e!==null&&(e.$$typeof===W||e.$$typeof===g||e.$$typeof===p||e.$$typeof===y||e.$$typeof===v||e.$$typeof===I||e.getModuleId!==void 0))}function u(e,n,l){var m=e.displayName;if(m)return m;var j=n.displayName||n.name||"";return j!==""?l+"("+j+")":l}function k(e){return e.displayName||"Context"}function E(e){if(e==null)return null;if(typeof e.tag=="number"&&T("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 i:return"Fragment";case s:return"Portal";case d:return"Profiler";case c:return"StrictMode";case D:return"Suspense";case C:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case y:var n=e;return k(n)+".Consumer";case p:var l=e;return k(l._context)+".Provider";case v:return u(e,e.render,"ForwardRef");case g:var m=e.displayName||null;return m!==null?m:E(e.type)||"Memo";case W:{var j=e,S=j._payload,x=j._init;try{return E(x(S))}catch{return null}}}return null}var M=Object.assign,K=0,L,H,B,R,F,de,me;function he(){}he.__reactDisabledLog=!0;function be(){{if(K===0){L=console.log,H=console.info,B=console.warn,R=console.error,F=console.group,de=console.groupCollapsed,me=console.groupEnd;var e={configurable:!0,enumerable:!0,value:he,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}K++}}function ce(){{if(K--,K===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:M({},e,{value:L}),info:M({},e,{value:H}),warn:M({},e,{value:B}),error:M({},e,{value:R}),group:M({},e,{value:F}),groupCollapsed:M({},e,{value:de}),groupEnd:M({},e,{value:me})})}K<0&&T("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var xe=_.ReactCurrentDispatcher,pe;function q(e,n,l){{if(pe===void 0)try{throw Error()}catch(j){var m=j.stack.trim().match(/\n( *(at )?)/);pe=m&&m[1]||""}return`
|
|
18
|
+
`+pe+e}}var ae=!1,ne;{var ye=typeof WeakMap=="function"?WeakMap:Map;ne=new ye}function ge(e,n){if(!e||ae)return"";{var l=ne.get(e);if(l!==void 0)return l}var m;ae=!0;var j=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var S;S=xe.current,xe.current=null,be();try{if(n){var x=function(){throw Error()};if(Object.defineProperty(x.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(x,[])}catch(ee){m=ee}Reflect.construct(e,[],x)}else{try{x.call()}catch(ee){m=ee}e.call(x.prototype)}}else{try{throw Error()}catch(ee){m=ee}e()}}catch(ee){if(ee&&m&&typeof ee.stack=="string"){for(var b=ee.stack.split(`
|
|
19
|
+
`),Z=m.stack.split(`
|
|
20
|
+
`),$=b.length-1,U=Z.length-1;$>=1&&U>=0&&b[$]!==Z[U];)U--;for(;$>=1&&U>=0;$--,U--)if(b[$]!==Z[U]){if($!==1||U!==1)do if($--,U--,U<0||b[$]!==Z[U]){var ie=`
|
|
21
|
+
`+b[$].replace(" at new "," at ");return e.displayName&&ie.includes("<anonymous>")&&(ie=ie.replace("<anonymous>",e.displayName)),typeof e=="function"&&ne.set(e,ie),ie}while($>=1&&U>=0);break}}}finally{ae=!1,xe.current=S,ce(),Error.prepareStackTrace=j}var Ne=e?e.displayName||e.name:"",je=Ne?q(Ne):"";return typeof e=="function"&&ne.set(e,je),je}function Ee(e,n,l){return ge(e,!1)}function we(e){var n=e.prototype;return!!(n&&n.isReactComponent)}function se(e,n,l){if(e==null)return"";if(typeof e=="function")return ge(e,we(e));if(typeof e=="string")return q(e);switch(e){case D:return q("Suspense");case C:return q("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case v:return Ee(e.render);case g:return se(e.type,n,l);case W:{var m=e,j=m._payload,S=m._init;try{return se(S(j),n,l)}catch{}}}return""}var h=Object.prototype.hasOwnProperty,O={},Y=_.ReactDebugCurrentFrame;function ue(e){if(e){var n=e._owner,l=se(e.type,e._source,n?n.type:null);Y.setExtraStackFrame(l)}else Y.setExtraStackFrame(null)}function Ie(e,n,l,m,j){{var S=Function.call.bind(h);for(var x in e)if(S(e,x)){var b=void 0;try{if(typeof e[x]!="function"){var Z=Error((m||"React class")+": "+l+" type `"+x+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[x]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw Z.name="Invariant Violation",Z}b=e[x](n,x,m,l,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch($){b=$}b&&!(b instanceof Error)&&(ue(j),T("%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).",m||"React class",l,x,typeof b),ue(null)),b instanceof Error&&!(b.message in O)&&(O[b.message]=!0,ue(j),T("Failed %s type: %s",l,b.message),ue(null))}}}var Ue=Array.isArray;function f(e){return Ue(e)}function oe(e){{var n=typeof Symbol=="function"&&Symbol.toStringTag,l=n&&e[Symbol.toStringTag]||e.constructor.name||"Object";return l}}function Q(e){try{return z(e),!1}catch{return!0}}function z(e){return""+e}function $e(e){if(Q(e))return T("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",oe(e)),z(e)}var ve=_.ReactCurrentOwner,Le={key:!0,ref:!0,__self:!0,__source:!0},tt,rt;function kt(e){if(h.call(e,"ref")){var n=Object.getOwnPropertyDescriptor(e,"ref").get;if(n&&n.isReactWarning)return!1}return e.ref!==void 0}function St(e){if(h.call(e,"key")){var n=Object.getOwnPropertyDescriptor(e,"key").get;if(n&&n.isReactWarning)return!1}return e.key!==void 0}function Pt(e,n){typeof e.ref=="string"&&ve.current}function Tt(e,n){{var l=function(){tt||(tt=!0,T("%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)",n))};l.isReactWarning=!0,Object.defineProperty(e,"key",{get:l,configurable:!0})}}function Ft(e,n){{var l=function(){rt||(rt=!0,T("%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)",n))};l.isReactWarning=!0,Object.defineProperty(e,"ref",{get:l,configurable:!0})}}var Ot=function(e,n,l,m,j,S,x){var b={$$typeof:r,type:e,key:n,ref:l,props:x,_owner:S};return b._store={},Object.defineProperty(b._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(b,"_self",{configurable:!1,enumerable:!1,writable:!1,value:m}),Object.defineProperty(b,"_source",{configurable:!1,enumerable:!1,writable:!1,value:j}),Object.freeze&&(Object.freeze(b.props),Object.freeze(b)),b};function Dt(e,n,l,m,j){{var S,x={},b=null,Z=null;l!==void 0&&($e(l),b=""+l),St(n)&&($e(n.key),b=""+n.key),kt(n)&&(Z=n.ref,Pt(n,j));for(S in n)h.call(n,S)&&!Le.hasOwnProperty(S)&&(x[S]=n[S]);if(e&&e.defaultProps){var $=e.defaultProps;for(S in $)x[S]===void 0&&(x[S]=$[S])}if(b||Z){var U=typeof e=="function"?e.displayName||e.name||"Unknown":e;b&&Tt(x,U),Z&&Ft(x,U)}return Ot(e,b,Z,j,m,ve.current,x)}}var Be=_.ReactCurrentOwner,at=_.ReactDebugCurrentFrame;function Ce(e){if(e){var n=e._owner,l=se(e.type,e._source,n?n.type:null);at.setExtraStackFrame(l)}else at.setExtraStackFrame(null)}var Ye;Ye=!1;function ze(e){return typeof e=="object"&&e!==null&&e.$$typeof===r}function nt(){{if(Be.current){var e=E(Be.current.type);if(e)return`
|
|
22
22
|
|
|
23
|
-
Check the render method of \``+e+"`."}return""}}function
|
|
23
|
+
Check the render method of \``+e+"`."}return""}}function Wt(e){return""}var st={};function Mt(e){{var n=nt();if(!n){var l=typeof e=="string"?e:e.displayName||e.name;l&&(n=`
|
|
24
24
|
|
|
25
|
-
Check the top-level render call using <`+l+">.")}return n}}function
|
|
25
|
+
Check the top-level render call using <`+l+">.")}return n}}function ot(e,n){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var l=Mt(n);if(st[l])return;st[l]=!0;var m="";e&&e._owner&&e._owner!==Be.current&&(m=" It was passed a child from "+E(e._owner.type)+"."),Ce(e),T('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',l,m),Ce(null)}}function it(e,n){{if(typeof e!="object")return;if(f(e))for(var l=0;l<e.length;l++){var m=e[l];ze(m)&&ot(m,n)}else if(ze(e))e._store&&(e._store.validated=!0);else if(e){var j=re(e);if(typeof j=="function"&&j!==e.entries)for(var S=j.call(e),x;!(x=S.next()).done;)ze(x.value)&&ot(x.value,n)}}}function $t(e){{var n=e.type;if(n==null||typeof n=="string")return;var l;if(typeof n=="function")l=n.propTypes;else if(typeof n=="object"&&(n.$$typeof===v||n.$$typeof===g))l=n.propTypes;else return;if(l){var m=E(n);Ie(l,e.props,"prop",m,e)}else if(n.PropTypes!==void 0&&!Ye){Ye=!0;var j=E(n);T("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",j||"Unknown")}typeof n.getDefaultProps=="function"&&!n.getDefaultProps.isReactClassApproved&&T("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function At(e){{for(var n=Object.keys(e.props),l=0;l<n.length;l++){var m=n[l];if(m!=="children"&&m!=="key"){Ce(e),T("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",m),Ce(null);break}}e.ref!==null&&(Ce(e),T("Invalid attribute `ref` supplied to `React.Fragment`."),Ce(null))}}var lt={};function ct(e,n,l,m,j,S){{var x=N(e);if(!x){var b="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(b+=" 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 Z=Wt();Z?b+=Z:b+=nt();var $;e===null?$="null":f(e)?$="array":e!==void 0&&e.$$typeof===r?($="<"+(E(e.type)||"Unknown")+" />",b=" Did you accidentally export a JSX literal instead of a component?"):$=typeof e,T("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",$,b)}var U=Dt(e,n,l,j,S);if(U==null)return U;if(x){var ie=n.children;if(ie!==void 0)if(m)if(f(ie)){for(var Ne=0;Ne<ie.length;Ne++)it(ie[Ne],e);Object.freeze&&Object.freeze(ie)}else T("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 it(ie,e)}if(h.call(n,"key")){var je=E(e),ee=Object.keys(n).filter(function(zt){return zt!=="key"}),Ve=ee.length>0?"{key: someKey, "+ee.join(": ..., ")+": ...}":"{key: someKey}";if(!lt[je+Ve]){var Yt=ee.length>0?"{"+ee.join(": ..., ")+": ...}":"{}";T(`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} />`,De,ye,Ar,ye),Qe[ye+De]=!0}}return e===o?Or(L):Tr(L),L}}function Fr(e,n,l){return er(e,n,l,!0)}function Dr(e,n,l){return er(e,n,l,!1)}var Mr=Dr,Wr=Fr;Ee.Fragment=o,Ee.jsx=Mr,Ee.jsxs=Wr}()),Ee}process.env.NODE_ENV==="production"?Ue.exports=Ir():Ue.exports=Ur();var a=Ue.exports;function cr(r){var t,s,o="";if(typeof r=="string"||typeof r=="number")o+=r;else if(typeof r=="object")if(Array.isArray(r)){var c=r.length;for(t=0;t<c;t++)r[t]&&(s=cr(r[t]))&&(o&&(o+=" "),o+=s)}else for(s in r)r[s]&&(o&&(o+=" "),o+=s);return o}function re(){for(var r,t,s=0,o="",c=arguments.length;s<c;s++)(r=arguments[s])&&(t=cr(r))&&(o&&(o+=" "),o+=t);return o}const Lr="https://core.spreedly.com/iframe/iframe-v1.min.js",Yr="https://cdn.e2e.movmo.io";let je={};const Vr=r=>{je={...je,...r}},Me=r=>{var s;const t=globalThis.process;return(s=t==null?void 0:t.env)==null?void 0:s[r]},_e=()=>({baseUrl:je.baseUrl??Me("REACT_APP_MOVMO_API_URL")??"",spreedlyScriptUrl:je.spreedlyScriptUrl??Me("REACT_APP_SPREEDLY_SCRIPT_URL")??Lr,iconCdnBaseUrl:je.iconCdnBaseUrl??Me("REACT_APP_MOVMO_ICON_CDN_URL")??Yr}),dr=r=>({id:r.id,last4:r.last4,brand:r.brand,expMonth:r.expMonth,expYear:r.expYear,isDefault:r.isDefault}),Re={Accept:"application/json","Content-Type":"application/json"},Ce=r=>{const{baseUrl:t}=_e();if(!t)throw new Error("@movmo_app/payments: baseUrl is not configured. Call setPaymentsConfig({ baseUrl }) at app boot, or set REACT_APP_MOVMO_API_URL.");return`${t}${r}`},Se=async(r,t)=>{try{return(await r.json()).message||t}catch{return t}},zr=async()=>{const r=await fetch(Ce("/v1/payments/tokenization-session"),{method:"GET",headers:Re,credentials:"include"});if(!r.ok)throw new Error(await Se(r,`Failed to fetch tokenization session (${r.status})`));return await r.json()},Br=async(r,t,s)=>{const o=await fetch(Ce(`/v1/users/${encodeURIComponent(r)}/payment-methods/from-token`),{method:"POST",headers:Re,credentials:"include",body:JSON.stringify({tokenizedPaymentMethodId:t,isDefault:s})});if(!o.ok)throw new Error(await Se(o,`Failed to save payment method (${o.status})`));const c=await o.json();return dr(c)},qr=async r=>{const t=await fetch(Ce(`/v1/users/${encodeURIComponent(r)}/payment-methods`),{method:"GET",headers:Re,credentials:"include"});if(!t.ok)throw new Error(await Se(t,`Failed to fetch payment methods (${t.status})`));return(await t.json()??[]).map(dr)},Kr=async(r,t)=>{const s=await fetch(Ce(`/v1/users/${encodeURIComponent(r)}/payment-methods/${encodeURIComponent(t)}`),{method:"DELETE",headers:Re,credentials:"include"});if(!s.ok)throw new Error(await Se(s,`Failed to delete payment method (${s.status})`))},Gr=async(r,t,s)=>{const o=await fetch(Ce(`/v1/users/${encodeURIComponent(r)}/payment-methods/${encodeURIComponent(t)}`),{method:"PUT",headers:Re,credentials:"include",body:JSON.stringify(s)});if(!o.ok)throw new Error(await Se(o,`Failed to update payment method (${o.status})`))},Jr={visa:"visa",master:"mastercard",mastercard:"mastercard",american_express:"amex",amex:"amex",discover:"discover"},Hr=28,ve=({brand:r,className:t,width:s=46})=>{const o=Jr[r.toLowerCase()]??"credit-card",c=Math.max(s,Hr),m=Math.round(c*24/34),{iconCdnBaseUrl:u}=_e();return a.jsx("img",{src:`${u}/website/assets/icons/payments/${o}.svg`,alt:o==="credit-card"?"card":`${o} card`,"data-testid":`card-brand-${r.toLowerCase()}`,className:t,width:c,height:m,loading:"lazy"})};let we=null;const Zr=()=>{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(we)return we;const{spreedlyScriptUrl:r}=_e();return we=new Promise((t,s)=>{const o=document.querySelector(`script[src="${r}"]`),c=()=>{window.Spreedly?t(window.Spreedly):s(new Error("Spreedly script loaded but window.Spreedly is undefined."))};if(o){if(window.Spreedly){c();return}o.addEventListener("load",c,{once:!0}),o.addEventListener("error",()=>{o.remove(),s(new Error("Failed to load Spreedly iframe script."))},{once:!0});return}const m=document.createElement("script");m.src=r,m.async=!0,m.onload=c,m.onerror=()=>{m.remove(),s(new Error("Failed to load Spreedly iframe script."))},document.head.appendChild(m)}).catch(t=>{throw we=null,t}),we},Xr="movmo-card-number",Qr="movmo-card-cvv",et=r=>({first_name:r.firstName,last_name:r.lastName,month:r.month,year:r.year,...r.email?{email:r.email}:{},...r.zip?{zip:r.zip}:{}}),ur=(r={})=>{const{numberEl:t=Xr,cvvEl:s=Qr,onCardTokenized:o,onFieldErrors:c,onValidityChange:m,onBrandChange:u}=r,[h,v]=i.useState("idle"),[T,E]=i.useState(null),[w,F]=i.useState({number:!1,cvv:!1}),[R,D]=i.useState(null),C=i.useRef(null),q=i.useRef(o),O=i.useRef(c),S=i.useRef(m),K=i.useRef(u);i.useEffect(()=>{q.current=o},[o]),i.useEffect(()=>{O.current=c},[c]),i.useEffect(()=>{S.current=m},[m]),i.useEffect(()=>{K.current=u},[u]);const M=i.useRef({number:!1,cvv:!1});i.useEffect(()=>{let W=!1;return v("loading"),E(null),F({number:!1,cvv:!1}),D(null),M.current={number:!1,cvv:!1},(async()=>{try{const[b,g]=await Promise.all([zr(),Zr()]);if(W)return;C.current=g,g.on("ready",()=>{var I;if(!W){v("ready");try{(I=g.setNumberFormat)==null||I.call(g,"prettyFormat")}catch{}}}),g.on("paymentMethod",I=>{var U;(U=q.current)==null||U.call(q,I)}),g.on("errors",I=>{var U;(U=O.current)==null||U.call(O,I)}),g.on("fieldEvent",(I,U,ne,z)=>{var le;if(W||U!=="input")return;const P=z??{};if(I==="number"){if(P.numberLength===0)D(V=>{var k;return V!==null&&((k=K.current)==null||k.call(K,null)),null});else if(P.cardType!==void 0){const V=P.cardType||null;D(k=>{var se;return k!==V&&((se=K.current)==null||se.call(K,V)),V})}}const Y=I==="number"?typeof P.validNumber=="boolean"?P.validNumber:void 0:typeof P.validCvv=="boolean"?P.validCvv:void 0;if(typeof Y=="boolean"){const V=M.current,k=I==="number"?{...V,number:Y}:{...V,cvv:Y};(k.number!==V.number||k.cvv!==V.cvv)&&(M.current=k,F(k),(le=S.current)==null||le.call(S,k))}}),g.on("consoleError",I=>{var ne;const U=I instanceof Error?I.message:"An unexpected error occurred while securing your card.";(ne=O.current)==null||ne.call(O,[{message:U}])}),g.init(b.environmentKey,{numberEl:t,cvvEl:s,nonce:b.nonce,timestamp:String(b.timestamp),certificateToken:b.certificateToken,signature:b.signature})}catch(b){if(W)return;const g=b instanceof Error?b.message:"Failed to initialize card form.";E(g),v("error")}})(),()=>{var b,g;W=!0;try{(g=(b=C.current)==null?void 0:b.removeHandlers)==null||g.call(b)}catch{}C.current=null}},[t,s]);const te=i.useCallback(W=>{var b;(b=C.current)==null||b.tokenizeCreditCard(et(W))},[]),ae=i.useCallback(W=>{var b,g;(g=(b=C.current)==null?void 0:b.transferFocus)==null||g.call(b,W)},[]);return{status:h,error:T,tokenize:te,validity:w,brand:R,focusField:ae}},We="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]",ar="flex h-11 w-full items-center gap-2 rounded-md border border-grayWarm-300 bg-white px-3 py-2 transition-shadow focus-within:border-grayWarm-950 focus-within:shadow-[0_0_0_1px_#1c1917]",rt=r=>{const t=r.trim();if(!t)return{firstName:"",lastName:""};const s=t.lastIndexOf(" ");return s===-1?{firstName:t,lastName:""}:{firstName:t.slice(0,s).trim(),lastName:t.slice(s+1).trim()}},fr=r=>{const t=r.replace(/\D/g,"");if(t.length<4)return{month:"",year:""};const s=t.slice(0,2),o=t.slice(2),c=o.length===2?`20${o}`:o.slice(0,4);return{month:s,year:c}},tt=r=>{const t=r.replace(/\D/g,"").slice(0,4);return t.length<=2?t:`${t.slice(0,2)} / ${t.slice(2)}`},Ae=r=>{const{month:t,year:s}=fr(r);if(!t||!s)return!1;const o=parseInt(t,10),c=parseInt(s,10);if(isNaN(o)||o<1||o>12)return!1;const m=new Date;return!(c<m.getFullYear()||c>m.getFullYear()+20||c===m.getFullYear()&&o<m.getMonth()+1)},$e=r=>/^\d{5}(-\d{4})?$/.test(r.trim()),at=r=>{const t=r.replace(/[^\d]/g,"").slice(0,9);return t.length<=5?t:`${t.slice(0,5)}-${t.slice(5)}`},Le=({userId:r,onSuccess:t,onError:s,isDefault:o=!1,className:c,defaultCardholderName:m,defaultCardholderFirstName:u="",defaultCardholderLastName:h="",autoSave:v=!1,formId:T="movmo-card-form",hideInternalSaveButton:E=!1,onCanSubmitChange:w})=>{const F=m??[u,h].filter(Boolean).join(" "),[R,D]=i.useState(F),[C,q]=i.useState(""),[O,S]=i.useState(""),[K,M]=i.useState("idle"),[te,ae]=i.useState(null),W=i.useRef(!1),b=i.useCallback(async N=>{M("saving");try{const d=await Br(r,N,o);M("ready"),t(d)}catch(d){const j=d instanceof Error?d.message:"Failed to save payment method.";ae(j),M("ready"),W.current=!1,s(j)}},[r,o,t,s]),g=i.useCallback(N=>{const d=N.map(j=>j.message).filter(Boolean).join("; ")||"Card validation failed.";ae(d),M(j=>j==="tokenizing"?"ready":j),W.current=!1,s(d)},[s]),I=i.useMemo(()=>({onCardTokenized:b,onFieldErrors:g}),[b,g]),{status:U,error:ne,tokenize:z,validity:P,brand:Y,focusField:le}=ur(I),V=R.trim().split(/\s+/).length>=2,k=Ae(C),se=$e(O),oe=i.useRef(!1),ce=i.useRef(!1),de=i.useRef(!1),ue=i.useRef(null),pe=i.useRef(null);i.useEffect(()=>{var N;P.cvv?ce.current||(ce.current=!0,(N=ue.current)==null||N.focus()):ce.current=!1},[P.cvv]);const be=!V||!k||!se||!P.number||!P.cvv,ee=K==="tokenizing"||K==="saving",H=U==="ready"&&!ee&&!be,Z=i.useRef(w);i.useEffect(()=>{Z.current=w},[w]),i.useEffect(()=>{var N;(N=Z.current)==null||N.call(Z,H)},[H]);const X=i.useCallback(()=>{const{firstName:N,lastName:d}=rt(R),{month:j,year:A}=fr(C);ae(null),M("tokenizing"),z({firstName:N,lastName:d,month:j,year:A,zip:O.trim()})},[R,C,O,z]);i.useEffect(()=>{if(!v||!H||W.current)return;const N=setTimeout(()=>{W.current=!0,X()},1200);return()=>clearTimeout(N)},[v,H,X]);const ie=N=>{N.preventDefault(),H&&X()},fe=te??ne,me=U!=="ready"||ee;return a.jsxs("form",{id:T,onSubmit:ie,className:re("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:ar,children:[a.jsx(ve,{brand:Y??"",width:32,className:"flex-shrink-0"}),a.jsx("div",{id:"movmo-card-number","aria-labelledby":"movmo-card-number-label",className:"flex-1","data-testid":"movmo-card-number-mount"})]})]}),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:C,onChange:N=>{const d=tt(N.target.value);q(d),Ae(d)&&!oe.current?(oe.current=!0,le("cvv")):Ae(d)||(oe.current=!1)},className:re(We,C&&!k&&"border-error-500"),disabled:me,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:ar,children:[a.jsx("div",{id:"movmo-card-cvv","aria-labelledby":"movmo-card-cvv-label",className:"flex-1","data-testid":"movmo-card-cvv-mount"}),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:Y==="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:ue,type:"text",inputMode:"numeric",autoComplete:"postal-code",placeholder:"ZIP code",value:O,onChange:N=>{var j;const d=at(N.target.value);S(d),$e(d)&&!de.current?(de.current=!0,(j=pe.current)==null||j.focus()):$e(d)||(de.current=!1)},className:re(We,O&&!se&&"border-error-500"),disabled:me,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:pe,type:"text",autoComplete:"cc-name",placeholder:"Cardholder name",value:R,onChange:N=>D(N.target.value),className:We,disabled:me,required:!0,"data-testid":"movmo-card-cardholder-name-input"})]}),fe?a.jsx("p",{role:"alert",className:"rounded-md bg-error-50 px-3 py-2 text-sm text-error-700","data-testid":"movmo-card-error",children:fe}):null,!v&&!E?a.jsx("button",{type:"submit",disabled:!H,className:re("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:ee?"Saving…":U==="loading"?"Loading…":"Save card"}):ee?a.jsx("p",{className:"text-center text-sm text-grayWarm-500","data-testid":"movmo-card-autosaving",children:"Saving card…"}):null]})};Le.displayName="MovmoCardForm";const mr=r=>{const[t,s]=i.useState("idle"),[o,c]=i.useState(null);return{deletePaymentMethod:i.useCallback(async u=>{s("pending"),c(null);try{await Kr(r,u),s("idle")}catch(h){const v=h instanceof Error?h.message:"Failed to delete payment method.";throw c(v),s("error"),h}},[r]),status:t,error:o}},pr=r=>{const[t,s]=i.useState("idle"),[o,c]=i.useState(null);return{setDefault:i.useCallback(async u=>{s("pending"),c(null);try{await Gr(r,u,{isDefault:!0}),s("idle")}catch(h){const v=h instanceof Error?h.message:"Failed to set default payment method.";throw c(v),s("error"),h}},[r]),status:t,error:o}},yr=r=>{const[t,s]=i.useState([]),[o,c]=i.useState("idle"),[m,u]=i.useState(null),[h,v]=i.useState(0),T=i.useRef(null);i.useEffect(()=>{var F;(F=T.current)==null||F.abort();const w=new AbortController;return T.current=w,c("loading"),u(null),qr(r).then(R=>{w.signal.aborted||(s(R),c("ready"))}).catch(R=>{if(w.signal.aborted)return;const D=R instanceof Error?R.message:"Failed to fetch payment methods.";u(D),c("error")}),()=>{w.abort()}},[r,h]);const E=i.useCallback(()=>{v(w=>w+1)},[]);return{items:t,status:o,error:m,refetch:E}},nt=({open:r,onClose:t,formId:s,saveDisabled:o,saveLabel:c="Save",children:m})=>(i.useEffect(()=>{if(!r)return;const u=h=>{h.key==="Escape"&&t()};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[r,t]),i.useEffect(()=>{if(!r)return;const u=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=u}},[r]),r?a.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"movmo-add-payment-title",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",onClick:u=>{u.target===u.currentTarget&&t()},"data-testid":"add-payment-method-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:t,"aria-label":"Close add-payment dialog",className:"flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-md border border-grayWarm-200 text-grayWarm-700 hover:bg-grayWarm-100","data-testid":"add-payment-method-close",children:a.jsx("svg",{viewBox:"0 0 16 16",width:"14",height:"14","aria-hidden":"true",children:a.jsx("path",{d:"M3 3L13 13M13 3L3 13",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round"})})}),a.jsx("h2",{id:"movmo-add-payment-title",className:"flex-1 text-center text-base font-semibold text-grayWarm-900",children:"Add payment method"}),a.jsx("span",{"aria-hidden":"true",className:"h-8 w-8 flex-shrink-0"})]}),a.jsx("div",{className:"flex-1 overflow-y-auto p-4",children:m}),a.jsxs("div",{className:"flex gap-3 border-t border-grayWarm-200 p-4",children:[a.jsx("button",{type:"button",onClick:t,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":"add-payment-method-cancel",children:"Cancel"}),a.jsx("button",{type:"submit",form:s,disabled:o,className:re("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 hover:bg-brand-600","disabled:cursor-not-allowed disabled:bg-grayWarm-300 disabled:text-grayWarm-500"),"data-testid":"add-payment-method-save",children:c})]})]})}):null),st=(r,t,s=new Date)=>t<s.getFullYear()||t===s.getFullYear()&&r<s.getMonth()+1,nr=r=>{const t=r.toLowerCase();return t==="amex"?"Amex":t?t.charAt(0).toUpperCase()+t.slice(1):"Card"},ot=(r,t)=>`${String(r).padStart(2,"0")}/${t}`,it=({method:r,selectable:t,selected:s,onSelect:o,onSetDefault:c,onRemove:m,disabled:u,showDefaultBadge:h,hideSetDefaultMenuItem:v})=>{const[T,E]=i.useState(!1),w=i.useRef(null),F=st(r.expMonth,r.expYear);i.useEffect(()=>{if(!T)return;const D=C=>{var q;(q=w.current)!=null&&q.contains(C.target)||E(!1)};return document.addEventListener("mousedown",D),()=>document.removeEventListener("mousedown",D)},[T]);const R=()=>{t&&o&&!u&&o(r)};return a.jsxs("div",{className:re("flex items-center gap-3 rounded-lg border px-3 py-3 transition-colors",t&&!u&&"cursor-pointer",s?"border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200 hover:border-grayWarm-300"),onClick:R,"data-testid":`payment-method-row-${r.id}`,children:[t?a.jsx("input",{type:"radio",name:"movmo-payment-method",checked:s,onChange:()=>o==null?void 0:o(r),onClick:D=>D.stopPropagation(),"aria-label":`Select ${nr(r.brand)} ending ${r.last4}`,className:"h-4 w-4 cursor-pointer accent-grayWarm-950",disabled:u}):null,a.jsx(ve,{brand:r.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.jsxs("span",{className:"text-base font-semibold text-grayWarm-900",children:[nr(r.brand)," ••••",r.last4]}),h&&r.isDefault?a.jsx("span",{className:"inline-flex items-center rounded-full bg-success-50 px-2 py-0.5 text-xs font-medium text-success-700","data-testid":`badge-default-${r.id}`,children:"Default"}):null,F?a.jsx("span",{className:"inline-flex items-center rounded-full bg-error-50 px-2 py-0.5 text-xs font-medium text-error-700","data-testid":`badge-expired-${r.id}`,children:"Expired"}):null]}),a.jsxs("div",{className:re("text-sm",F?"text-grayWarm-400":"text-grayWarm-600"),children:["Exp. ",ot(r.expMonth,r.expYear)]})]}),a.jsxs("div",{className:"relative flex-shrink-0",ref:w,children:[a.jsx("button",{type:"button","aria-label":`Open actions for card ending ${r.last4}`,"aria-haspopup":"menu","aria-expanded":T,className:"rounded-lg p-2 text-grayWarm-600 transition-colors hover:bg-grayWarm-100 disabled:cursor-not-allowed disabled:opacity-50",disabled:u,onClick:D=>{D.stopPropagation(),E(C=>!C)},"data-testid":`menu-trigger-${r.id}`,children:a.jsxs("svg",{viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true",children:[a.jsx("circle",{cx:"3",cy:"8",r:"1.5",fill:"currentColor"}),a.jsx("circle",{cx:"8",cy:"8",r:"1.5",fill:"currentColor"}),a.jsx("circle",{cx:"13",cy:"8",r:"1.5",fill:"currentColor"})]})}),T?a.jsxs("div",{role:"menu",className:"absolute right-0 top-full z-10 mt-1 min-w-[160px] rounded-lg border border-grayWarm-200 bg-white py-1 shadow-lg",onClick:D=>D.stopPropagation(),"data-testid":`menu-${r.id}`,children:[!r.isDefault&&!v?a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-2 text-left text-sm text-grayWarm-700 hover:bg-grayWarm-100",onClick:()=>{E(!1),c(r)},"data-testid":`menu-set-default-${r.id}`,children:"Set as default"}):null,a.jsx("button",{type:"button",role:"menuitem",className:"block w-full px-4 py-2 text-left text-sm text-error-700 hover:bg-error-50",onClick:()=>{E(!1),m(r)},"data-testid":`menu-remove-${r.id}`,children:"Remove"})]}):null]})]})},lt=r=>`${_e().iconCdnBaseUrl}/website/assets/icons/payments/${r}.svg`,Ie=({slug:r,alt:t})=>a.jsx("img",{src:lt(r),alt:t,height:20,loading:"lazy",style:{height:20,width:"auto"}}),Ne=({type:r,label:t,iconNode:s})=>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-${r}`,children:[a.jsx("input",{type:"radio",name:"movmo-payment-type",value:r,onChange:()=>{},className:"h-4 w-4 cursor-pointer accent-grayWarm-900","aria-label":t}),a.jsxs("span",{className:"flex flex-1 items-center gap-2 text-sm font-semibold text-grayWarm-900",children:[t,s]})]}),sr=({selected:r,onSelect:t,creditCardBody:s,className:o})=>{const c=r==="credit_card";return a.jsxs("div",{className:re("flex w-full flex-col gap-3",o),children:[a.jsxs("label",{className:re("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,onChange:()=>t("credit_card"),className:"h-4 w-4 cursor-pointer accent-grayWarm-900","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(ve,{brand:"mastercard",width:28}),a.jsx(ve,{brand:"visa",width:28}),a.jsx(ve,{brand:"amex",width:28}),a.jsx(ve,{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(Ne,{type:"paypal",label:"PayPal",iconNode:a.jsx(Ie,{slug:"paypal",alt:"PayPal"})}),a.jsx(Ne,{type:"googlepay",label:"GooglePay",iconNode:a.jsx(Ie,{slug:"google-pay",alt:"GooglePay"})}),a.jsx(Ne,{type:"klarna",label:"Klarna",iconNode:a.jsx(Ie,{slug:"klarna",alt:"Klarna"})}),a.jsx(Ne,{type:"ach",label:"Bank account (ACH)",iconNode:a.jsx("span",{className:"text-xs font-medium text-grayWarm-500",children:"Direct debit"})})]})},or="movmo-add-payment-form",ir=r=>{const t=r.filter(o=>o.isDefault),s=r.filter(o=>!o.isDefault);return[...t,...s]},lr=()=>a.jsxs("div",{className:"flex items-center gap-3 rounded-lg border border-grayWarm-200 px-3 py-3","data-testid":"payment-method-skeleton",children:[a.jsx("div",{className:"h-8 w-[46px] flex-shrink-0 animate-pulse rounded bg-grayWarm-200"}),a.jsxs("div",{className:"flex-1 space-y-2",children:[a.jsx("div",{className:"h-4 w-32 animate-pulse rounded bg-grayWarm-200"}),a.jsx("div",{className:"h-3 w-20 animate-pulse rounded bg-grayWarm-200"})]}),a.jsx("div",{className:"h-8 w-8 animate-pulse rounded bg-grayWarm-200"})]}),vr=({userId:r,defaultCardholderName:t,defaultCardholderFirstName:s,defaultCardholderLastName:o,selectedId:c,onSelect:m,onChange:u,paymentTypeSelector:h=!0,autoSaveFirstCard:v=!0,selectionSetsDefault:T=!1,showDefaultBadge:E=!0,className:w})=>{const{items:F,status:R,error:D,refetch:C}=yr(r),{deletePaymentMethod:q,status:O}=mr(r),{setDefault:S,status:K}=pr(r),[M,te]=i.useState([]),[ae,W]=i.useState(null),[b,g]=i.useState(!1),[I,U]=i.useState(null),[ne,z]=i.useState(!1),[P,Y]=i.useState(null),le=i.useCallback(()=>{g(!1),U(null),Y(null)},[]),V=t??([s,o].filter(Boolean).join(" ")||void 0);i.useEffect(()=>{R==="ready"&&te(ir(F))},[F,R]);const k=i.useCallback(d=>{te(j=>{const A=typeof d=="function"?d(j):d,G=ir(A);return u==null||u(G),G})},[u]),se=O==="pending"||K==="pending",oe=i.useCallback(async d=>{const j=M;W(null),k(A=>A.map(G=>({...G,isDefault:G.id===d.id})));try{await S(d.id),C()}catch(A){te(j),u==null||u(j);const G=A instanceof Error?A.message:"Failed to set default payment method.";W(G)}},[M,k,S,C,u]),ce=i.useCallback(d=>{m==null||m(d),T&&(d.isDefault||oe(d))},[m,T,oe]),de=i.useCallback(async d=>{const j=M;W(null),k(A=>A.filter(G=>G.id!==d.id));try{await q(d.id),C()}catch(A){te(j),u==null||u(j);const G=A instanceof Error?A.message:"Failed to delete payment method.";W(G)}},[M,k,q,C,u]),ue=i.useCallback(d=>{U(null),g(!1),Y(null),k(j=>[d,...j.filter(A=>A.id!==d.id)]),C()},[k,C]),pe=i.useCallback(d=>{U(d)},[]),be=R==="ready"&&M.length===0,ee=typeof m=="function",H=M.length===0,Z=v&&M.length===0,X=i.useCallback(d=>a.jsx(Le,{userId:r,isDefault:H,defaultCardholderName:V,autoSave:!d&&Z,hideInternalSaveButton:d,formId:d?or:void 0,onCanSubmitChange:d?z:void 0,onSuccess:ue,onError:pe}),[r,H,V,Z,ue,pe]),ie=i.useMemo(()=>X(!1),[X]),fe=i.useMemo(()=>X(!0),[X]),me=i.useMemo(()=>h?a.jsx(sr,{selected:P,onSelect:d=>Y(d),creditCardBody:ie}):ie,[h,P,ie]),N=i.useMemo(()=>h?a.jsx(sr,{selected:P,onSelect:d=>Y(d),creditCardBody:fe}):fe,[h,P,fe]);return a.jsxs("div",{className:re("flex w-full flex-col gap-4",w),"data-testid":"payment-methods-manager",children:[R==="loading"?a.jsxs("div",{className:"flex flex-col gap-2","data-testid":"payment-methods-loading",children:[a.jsx(lr,{}),a.jsx(lr,{})]}):null,R==="error"?a.jsxs("div",{role:"alert",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:D??"Failed to load payment methods."}),a.jsx("button",{type:"button",onClick:C,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,ae?a.jsx("div",{role:"alert",className:"rounded-md bg-error-50 p-3 text-sm text-error-700","data-testid":"payment-methods-mutation-error",children:ae}):null,R==="ready"&&M.length>0?a.jsx("div",{className:"flex flex-col gap-2",children:M.map(d=>a.jsx(it,{method:d,selectable:ee,selected:ee&&d.id===c,onSelect:ce,onSetDefault:oe,onRemove:de,disabled:se,showDefaultBadge:E,hideSetDefaultMenuItem:T},d.id))}):null,be?a.jsx("div",{"data-testid":"payment-methods-empty",children:me}):R==="ready"?a.jsx("button",{type:"button",onClick:()=>{U(null),Y(null),z(!1),g(!0)},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(nt,{open:b,onClose:le,formId:or,saveDisabled:!ne,children:[N,I?a.jsx("p",{role:"alert",className:"mt-3 rounded-md bg-error-50 px-3 py-2 text-sm text-error-700","data-testid":"payment-methods-modal-error",children:I}):null]})]})};vr.displayName="PaymentMethodsManager";const ct=r=>{const t=r.toLowerCase();return t==="amex"?"Amex":t?t.charAt(0).toUpperCase()+t.slice(1):"Card"},dt=({method:r,trailing:t,onClick:s,className:o})=>a.jsxs("div",{className:re("flex items-center gap-3 py-2",s&&"cursor-pointer",o),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-${r.id}`,children:[a.jsx(ve,{brand:r.brand,className:"flex-shrink-0"}),a.jsxs("span",{className:"flex-1 text-base font-semibold text-grayWarm-900",children:[ct(r.brand)," ",r.last4]}),t]});exports.MovmoCardForm=Le;exports.PaymentMethodPreview=dt;exports.PaymentMethodsManager=vr;exports.getPaymentsConfig=_e;exports.setPaymentsConfig=Vr;exports.useDeletePaymentMethod=mr;exports.useMovmoCardFields=ur;exports.useSetDefaultPaymentMethod=pr;exports.useUserPaymentMethods=yr;
|
|
30
|
+
<%s key={someKey} {...props} />`,Ve,je,Yt,je),lt[je+Ve]=!0}}return e===i?At(U):$t(U),U}}function It(e,n,l){return ct(e,n,l,!0)}function Ut(e,n,l){return ct(e,n,l,!1)}var Lt=Ut,Bt=It;De.Fragment=i,De.jsx=Lt,De.jsxs=Bt}()),De}process.env.NODE_ENV==="production"?Ze.exports=Vt():Ze.exports=qt();var a=Ze.exports;function gt(t){var r,s,i="";if(typeof t=="string"||typeof t=="number")i+=t;else if(typeof t=="object")if(Array.isArray(t)){var c=t.length;for(r=0;r<c;r++)t[r]&&(s=gt(t[r]))&&(i&&(i+=" "),i+=s)}else for(s in t)t[s]&&(i&&(i+=" "),i+=s);return i}function G(){for(var t,r,s=0,i="",c=arguments.length;s<c;s++)(t=arguments[s])&&(r=gt(t))&&(i&&(i+=" "),i+=r);return i}const Kt="https://core.spreedly.com/iframe/iframe-v1.min.js",Gt="https://cdn.e2e.movmo.io";let ke={};const Jt=t=>{ke={...ke,...t}},qe=t=>{var s;const r=globalThis.process;return(s=r==null?void 0:r.env)==null?void 0:s[t]},Re=()=>({baseUrl:ke.baseUrl??qe("REACT_APP_MOVMO_API_URL")??"",spreedlyScriptUrl:ke.spreedlyScriptUrl??qe("REACT_APP_SPREEDLY_SCRIPT_URL")??Kt,iconCdnBaseUrl:ke.iconCdnBaseUrl??qe("REACT_APP_MOVMO_ICON_CDN_URL")??Gt,fetch:ke.fetch??(typeof globalThis<"u"&&typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):(()=>{throw new Error("@movmo_app/payments: no fetch available")})())}),Xe=t=>({id:t.id,last4:t.last4,brand:t.brand,expMonth:t.expMonth,expYear:t.expYear,isDefault:t.isDefault}),Se={Accept:"application/json","Content-Type":"application/json"},Pe=t=>{const{baseUrl:r}=Re();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}`},Te=(t,r)=>{const{fetch:s}=Re();return s(t,r)},Fe=async(t,r)=>{try{return(await t.json()).message||r}catch{return r}};let We=null;const Qe=()=>{if(We)return We;const t=(async()=>{const r=await Te(Pe("/v1/payments/tokenization-session"),{method:"GET",headers:Se,credentials:"include"});if(!r.ok)throw new Error(await Fe(r,`Failed to fetch tokenization session (${r.status})`));return await r.json()})();return We=t,t.finally(()=>{We===t&&(We=null)}).catch(()=>{}),t},Ht=t=>typeof t.brand=="string"&&typeof t.last4=="string"&&typeof t.expMonth=="number"&&typeof t.expYear=="number",Zt=async(t,r,s)=>{const i=await Te(Pe(`/v1/users/${encodeURIComponent(t)}/payment-methods/from-token`),{method:"POST",headers:Se,credentials:"include",body:JSON.stringify({tokenizedPaymentMethodId:r,isDefault:s})});if(!i.ok)throw new Error(await Fe(i,`Failed to save payment method (${i.status})`));const c=await i.json();if(Ht(c))return Xe(c);const d=await Te(Pe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(c.id)}`),{method:"GET",headers:Se,credentials:"include"});if(!d.ok)throw new Error(await Fe(d,`Failed to fetch saved payment method (${d.status})`));const p=await d.json();return Xe(p)},Xt=async t=>{const r=await Te(Pe(`/v1/users/${encodeURIComponent(t)}/payment-methods`),{method:"GET",headers:Se,credentials:"include"});if(!r.ok)throw new Error(await Fe(r,`Failed to fetch payment methods (${r.status})`));return(await r.json()??[]).map(Xe)},Qt=async(t,r)=>{const s=await Te(Pe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"DELETE",headers:Se,credentials:"include"});if(!s.ok)throw new Error(await Fe(s,`Failed to delete payment method (${s.status})`))},er=async(t,r,s)=>{const i=await Te(Pe(`/v1/users/${encodeURIComponent(t)}/payment-methods/${encodeURIComponent(r)}`),{method:"PUT",headers:Se,credentials:"include",body:JSON.stringify(s)});if(!i.ok)throw new Error(await Fe(i,`Failed to update payment method (${i.status})`))},tr={visa:"visa",master:"mastercard",mastercard:"mastercard",american_express:"amex",amex:"amex",discover:"discover"},rr=28,_e=({brand:t,className:r,width:s=46})=>{const i=t?tr[t.toLowerCase()]??"credit-card":"credit-card",c=Math.max(s,rr),d=Math.round(c*24/34),{iconCdnBaseUrl:p}=Re();return a.jsx("img",{src:`${p}/website/assets/icons/payments/${i}.svg`,alt:i==="credit-card"?"card":`${i} card`,"data-testid":`card-brand-${t.toLowerCase()}`,className:r,width:c,height:d,loading:"lazy"})};let Me=null;const ar=()=>{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(Me)return Me;const{spreedlyScriptUrl:t}=Re();return Me=new Promise((r,s)=>{const i=document.querySelector(`script[src="${t}"]`),c=()=>{window.Spreedly?r(window.Spreedly):s(new Error("Spreedly script loaded but window.Spreedly is undefined."))};if(i){if(window.Spreedly){c();return}i.addEventListener("load",c,{once:!0}),i.addEventListener("error",()=>{i.remove(),s(new Error("Failed to load Spreedly iframe script."))},{once:!0});return}const d=document.createElement("script");d.src=t,d.async=!0,d.onload=c,d.onerror=()=>{d.remove(),s(new Error("Failed to load Spreedly iframe script."))},document.head.appendChild(d)}).catch(r=>{throw Me=null,r}),Me},nr="movmo-card-number",sr="movmo-card-cvv",or=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=nr,cvvEl:s=sr,onCardTokenized:i,onFieldErrors:c,onValidityChange:d,onBrandChange:p}=t,[y,v]=o.useState("idle"),[D,C]=o.useState(null),[g,W]=o.useState({number:!1,cvv:!1}),[A,J]=o.useState(null),[P,re]=o.useState({number:!1,cvv:!1}),_=o.useRef(null),T=o.useRef(i),V=o.useRef(c),le=o.useRef(d),X=o.useRef(p);o.useEffect(()=>{T.current=i},[i]),o.useEffect(()=>{V.current=c},[c]),o.useEffect(()=>{le.current=d},[d]),o.useEffect(()=>{X.current=p},[p]);const w=o.useRef({number:!1,cvv:!1});o.useEffect(()=>{let I=!1;return v("loading"),C(null),W({number:!1,cvv:!1}),J(null),w.current={number:!1,cvv:!1},(async()=>{try{const[N,u]=await Promise.all([Qe(),ar()]);if(I)return;_.current=u,u.on("ready",()=>{var k,E,M,K,L,H;if(!I){v("ready");try{(k=u.setFieldType)==null||k.call(u,"number","tel"),(E=u.setFieldType)==null||E.call(u,"cvv","tel")}catch{}try{typeof u.setNumberFormat=="function"?u.setNumberFormat("prettyFormat"):console.warn("@movmo_app/payments: Spreedly.setNumberFormat is missing — card-number digits will not be space-grouped.")}catch(B){console.warn("@movmo_app/payments: setNumberFormat failed",B)}try{(M=u.setPlaceholder)==null||M.call(u,"number","Card number"),(K=u.setPlaceholder)==null||K.call(u,"cvv","CVV");const B='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;';(L=u.setStyle)==null||L.call(u,"number",B),(H=u.setStyle)==null||H.call(u,"cvv",B)}catch{}}}),u.on("paymentMethod",k=>{var E;(E=T.current)==null||E.call(T,k)}),u.on("errors",k=>{var E;(E=V.current)==null||E.call(V,k)}),u.on("fieldEvent",(k,E,M,K)=>{var B;if(I)return;if(E==="focus"){re(R=>R[k]?R:{...R,[k]:!0});return}if(E==="blur"){re(R=>R[k]?{...R,[k]:!1}:R);return}if(E!=="input")return;const L=K??{};if(k==="number"){if(L.numberLength===0)J(R=>{var F;return R!==null&&((F=X.current)==null||F.call(X,null)),null});else if(L.cardType!==void 0){const R=L.cardType||null;J(F=>{var de;return F!==R&&((de=X.current)==null||de.call(X,R)),R})}}const H=k==="number"?typeof L.validNumber=="boolean"?L.validNumber:void 0:typeof L.validCvv=="boolean"?L.validCvv:void 0;if(typeof H=="boolean"){const R=w.current,F=k==="number"?{...R,number:H}:{...R,cvv:H};(F.number!==R.number||F.cvv!==R.cvv)&&(w.current=F,W(F),(B=le.current)==null||B.call(le,F))}}),u.on("consoleError",k=>{var M;const E=k instanceof Error?k.message:"An unexpected error occurred while securing your card.";(M=V.current)==null||M.call(V,[{message:E}])}),u.init(N.environmentKey,{numberEl:r,cvvEl:s,nonce:N.nonce,timestamp:String(N.timestamp),certificateToken:N.certificateToken,signature:N.signature})}catch(N){if(I)return;const u=N instanceof Error?N.message:"Failed to initialize card form.";C(u),v("error")}})(),()=>{var N,u;I=!0;try{(u=(N=_.current)==null?void 0:N.removeHandlers)==null||u.call(N)}catch{}_.current=null}},[r,s]);const te=o.useCallback(I=>{var N;(N=_.current)==null||N.tokenizeCreditCard(or(I))},[]),fe=o.useCallback(I=>{var N,u;(u=(N=_.current)==null?void 0:N.transferFocus)==null||u.call(N,I)},[]);return{status:y,error:D,tokenize:te,validity:g,brand:A,focused:P,focusField:fe}},Ke="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]",ft="flex h-11 w-full items-center gap-2 rounded-md border bg-white px-3 py-2 transition-shadow",mt="border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]",pt="border-grayWarm-300",ir=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()}},Et=t=>{const r=t.replace(/\D/g,"");if(r.length<4)return{month:"",year:""};const s=r.slice(0,2),i=r.slice(2),c=i.length===2?`20${i}`:i.slice(0,4);return{month:s,year:c}},lr=t=>{const r=t.replace(/\D/g,"").slice(0,4);return r.length<=2?r:`${r.slice(0,2)} / ${r.slice(2)}`},Ge=t=>{const{month:r,year:s}=Et(t);if(!r||!s)return!1;const i=parseInt(r,10),c=parseInt(s,10);if(isNaN(i)||i<1||i>12)return!1;const d=new Date;return!(c<d.getFullYear()||c>d.getFullYear()+20||c===d.getFullYear()&&i<d.getMonth()+1)},Je=t=>/^\d{5}(-\d{4})?$/.test(t.trim()),cr=t=>{const r=t.replace(/[^\d]/g,"").slice(0,9);return r.length<=5?r:`${r.slice(0,5)}-${r.slice(5)}`},et=({userId:t,onSuccess:r,onError:s,isDefault:i=!1,className:c,defaultCardholderName:d,defaultCardholderFirstName:p="",defaultCardholderLastName:y="",autoSave:v=!1,formId:D="movmo-card-form",hideInternalSaveButton:C=!1,onCanSubmitChange:g,onSavingChange:W,autoFocus:A})=>{const J=d??[p,y].filter(Boolean).join(" "),[P,re]=o.useState(J),[_,T]=o.useState(""),[V,le]=o.useState(""),[X,w]=o.useState("idle"),te=o.useRef(!1),fe=o.useCallback(async h=>{w("saving");try{const O=await Zt(t,h,i);w("ready"),r(O)}catch(O){const Y=O instanceof Error?O.message:"Failed to save payment method.";w("ready"),te.current=!1,s(Y)}},[t,i,r,s]),I=o.useCallback(h=>{const O=h.map(Y=>Y.message).filter(Boolean).join("; ")||"Card validation failed.";w(Y=>Y==="tokenizing"?"ready":Y),te.current=!1,s(O)},[s]),N=o.useMemo(()=>({onCardTokenized:fe,onFieldErrors:I}),[fe,I]),{status:u,error:k,tokenize:E,validity:M,brand:K,focused:L,focusField:H}=wt(N),B=o.useRef(!1);o.useEffect(()=>{!A||u!=="ready"||B.current||(B.current=!0,H(A))},[A,u,H]);const R=P.trim().split(/\s+/).length>=2,F=Ge(_),de=Je(V),me=o.useRef(!1),he=o.useRef(!1),be=o.useRef(!1),ce=o.useRef(null),xe=o.useRef(null);o.useEffect(()=>{var h;M.cvv?he.current||(he.current=!0,(h=ce.current)==null||h.focus()):he.current=!1},[M.cvv]);const pe=!R||!F||!de||!M.number||!M.cvv,q=X==="tokenizing"||X==="saving",ae=u==="ready"&&!q&&!pe,ne=o.useRef(g);o.useEffect(()=>{ne.current=g},[g]),o.useEffect(()=>{var h;(h=ne.current)==null||h.call(ne,ae)},[ae]);const ye=o.useRef(W);o.useEffect(()=>{ye.current=W},[W]),o.useEffect(()=>{var h;(h=ye.current)==null||h.call(ye,q)},[q]);const ge=o.useCallback(()=>{const{firstName:h,lastName:O}=ir(P),{month:Y,year:ue}=Et(_);w("tokenizing"),E({firstName:h,lastName:O,month:Y,year:ue,zip:V.trim()})},[P,_,V,E]);o.useEffect(()=>{if(!v||!ae||te.current)return;const h=setTimeout(()=>{te.current=!0,ge()},1200);return()=>clearTimeout(h)},[v,ae,ge]);const Ee=h=>{h.preventDefault(),ae&&ge()},we=u!=="ready"||q,se=o.useRef(s);return o.useEffect(()=>{se.current=s},[s]),o.useEffect(()=>{var h;k&&((h=se.current)==null||h.call(se,k))},[k]),a.jsxs("form",{id:D,onSubmit:Ee,className:G("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:G(ft,L.number?mt:pt),children:[a.jsx(_e,{brand:K??"",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":u!=="ready",className:"absolute inset-0","data-testid":"movmo-card-number-mount"}),u!=="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:_,onChange:h=>{const O=lr(h.target.value);T(O),Ge(O)&&!me.current?(me.current=!0,H("cvv")):Ge(O)||(me.current=!1)},className:G(Ke,_&&!F&&"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:G(ft,L.cvv?mt:pt),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":u!=="ready",className:"absolute inset-0","data-testid":"movmo-card-cvv-mount"}),u!=="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:K==="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:ce,type:"text",inputMode:"numeric",autoComplete:"postal-code",placeholder:"ZIP code",value:V,onChange:h=>{var Y;const O=cr(h.target.value);le(O),Je(O)&&!be.current?(be.current=!0,(Y=xe.current)==null||Y.focus()):Je(O)||(be.current=!1)},className:G(Ke,V&&!de&&"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:xe,type:"text",autoComplete:"cc-name",placeholder:"Cardholder name",value:P,onChange:h=>re(h.target.value),className:Ke,disabled:we,required:!0,"data-testid":"movmo-card-cardholder-name-input"})]}),!v&&!C?a.jsx("button",{type:"submit",disabled:!ae,className:G("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:q?"Saving…":u==="loading"?"Loading…":"Save card"}):q&&v?a.jsx("p",{className:"text-center text-sm text-grayWarm-500","aria-live":"polite","data-testid":"movmo-card-autosaving",children:"Saving card…"}):null]})};et.displayName="MovmoCardForm";const jt=t=>{const[r,s]=o.useState("idle"),[i,c]=o.useState(null);return{deletePaymentMethod:o.useCallback(async p=>{s("pending"),c(null);try{await Qt(t,p),s("idle")}catch(y){const v=y instanceof Error?y.message:"Failed to delete payment method.";throw c(v),s("error"),y}},[t]),status:r,error:i}},_t=t=>{const[r,s]=o.useState("idle"),[i,c]=o.useState(null);return{setDefault:o.useCallback(async p=>{s("pending"),c(null);try{await er(t,p,{isDefault:!0}),s("idle")}catch(y){const v=y instanceof Error?y.message:"Failed to set default payment method.";throw c(v),s("error"),y}},[t]),status:r,error:i}},Rt=t=>{const[r,s]=o.useState([]),[i,c]=o.useState("idle"),[d,p]=o.useState(null),[y,v]=o.useState(0),D=o.useRef(null);o.useEffect(()=>{var W;(W=D.current)==null||W.abort();const g=new AbortController;return D.current=g,c("loading"),p(null),Xt(t).then(A=>{g.signal.aborted||(s(A),c("ready"))}).catch(A=>{if(g.signal.aborted)return;const J=A instanceof Error?A.message:"Failed to fetch payment methods.";p(J),c("error")}),()=>{g.abort()}},[t,y]);const C=o.useCallback(()=>{v(g=>g+1)},[]);return{items:r,status:i,error:d,refetch:C}},dr=({open:t,onClose:r,formId:s,saveDisabled:i,saveLabel:c="Save",isSaving:d=!1,children:p})=>(o.useEffect(()=>{if(!t)return;const y=v=>{v.key==="Escape"&&r()};return document.addEventListener("keydown",y),()=>document.removeEventListener("keydown",y)},[t,r]),o.useEffect(()=>{if(!t)return;const y=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=y}},[t]),t?a.jsx("div",{role:"dialog","aria-modal":"true","aria-labelledby":"movmo-add-payment-title",className:"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4",onClick:y=>{y.target===y.currentTarget&&r()},"data-testid":"add-payment-method-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 add-payment 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":"add-payment-method-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:"movmo-add-payment-title",className:"flex-1 text-center text-base font-semibold text-grayWarm-900",children:"Add payment method"}),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:p}),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":"add-payment-method-cancel",children:"Cancel"}),a.jsx("button",{type:"submit",form:s,disabled:d?!1:i,"aria-disabled":d||i,"aria-busy":d,className:G("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",d?"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":"add-payment-method-save",children:d?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 card"})]}):c})]})]})}):null),ur=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},Ct=({method:t,trailing:r,onClick:s,cardLabelFormat:i="branded",className:c})=>a.jsxs("div",{className:G("flex items-center gap-3",s&&"cursor-pointer",c),onClick:s,role:s?"button":void 0,tabIndex:s?0:void 0,onKeyDown:s?d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),s())}:void 0,"data-testid":`payment-method-preview-${t.id}`,children:[a.jsx(_e,{brand:t.brand,width:34,className:"flex-shrink-0"}),a.jsx("span",{className:"flex-1 text-lg font-semibold text-grayWarm-950",children:i==="masked"?`•••• ${t.last4}`:`${ur(t.brand)} ${t.last4}`}),r]}),fr=(t,r,s=new Date)=>r<s.getFullYear()||r===s.getFullYear()&&t<s.getMonth()+1,yt=t=>{if(!t)return"Card";const r=t.toLowerCase();return r==="amex"?"Amex":r.charAt(0).toUpperCase()+r.slice(1)},mr=(t,r)=>`${String(t).padStart(2,"0")}/${r}`,pr=({method:t,selectable:r,selected:s,onSelect:i,onSetDefault:c,onRemove:d,disabled:p,showDefaultBadge:y,hideSetDefaultMenuItem:v,cardLabelFormat:D="branded"})=>{const[C,g]=o.useState(!1),W=o.useRef(null),A=fr(t.expMonth,t.expYear);o.useEffect(()=>{if(!C)return;const P=re=>{var _;(_=W.current)!=null&&_.contains(re.target)||g(!1)};return document.addEventListener("mousedown",P),()=>document.removeEventListener("mousedown",P)},[C]);const J=()=>{r&&i&&!p&&i(t)};return a.jsxs("div",{className:G("flex items-start gap-3 transition-colors",r?"rounded-lg border px-3 py-3":"py-4",r&&!p&&"cursor-pointer",r&&(s?"border-grayWarm-950 shadow-[0_0_0_1px_#1c1917]":"border-grayWarm-200 hover:border-grayWarm-300")),onClick:J,"data-testid":`payment-method-row-${t.id}`,children:[r?a.jsx("input",{type:"radio",name:"movmo-payment-method",checked:s,onChange:()=>i==null?void 0:i(t),onClick:P=>P.stopPropagation(),"aria-label":`Select ${yt(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:p}):null,a.jsx(_e,{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:D==="masked"?`•••• ${t.last4}`:`${yt(t.brand)} ${t.last4}`}),y&&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,A?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:G("text-base",A?"text-grayWarm-400":"text-grayWarm-600"),children:["Exp. ",mr(t.expMonth,t.expYear)]})]}),a.jsxs("div",{className:"relative flex-shrink-0",ref:W,children:[a.jsx("button",{type:"button","aria-label":`Open actions for card ending ${t.last4}`,"aria-haspopup":"menu","aria-expanded":C,className:"rounded-lg p-2 text-grayWarm-600 transition-colors hover:bg-grayWarm-100 disabled:cursor-not-allowed disabled:opacity-50",disabled:p,onClick:P=>{P.stopPropagation(),g(re=>!re)},"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"})})}),C?a.jsxs("div",{role:"menu",className:G("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:P=>P.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&&!v?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),c(t)},"data-testid":`menu-set-default-${t.id}`,children:"Set as default"}):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),d(t)},"data-testid":`menu-remove-${t.id}`,children:"Delete"})]}):null]})]})},yr=t=>`${Re().iconCdnBaseUrl}/website/assets/icons/payments/${t}.svg`,He=({slug:t,alt:r})=>a.jsx("img",{src:yr(t),alt:r,height:20,loading:"lazy",style:{height:20,width:"auto"}}),Ae=({type:t,label:r,iconNode:s})=>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,onChange:()=>{},className:"h-4 w-4 cursor-pointer accent-grayWarm-900","aria-label":r}),a.jsxs("span",{className:"flex flex-1 items-center gap-2 text-sm font-semibold text-grayWarm-900",children:[r,s]})]}),vt=({selected:t,onSelect:r,creditCardBody:s,className:i})=>{const c=t==="credit_card";return a.jsxs("div",{className:G("flex w-full flex-col gap-3",i),children:[a.jsxs("label",{className:G("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,onChange:()=>r("credit_card"),className:"h-4 w-4 cursor-pointer accent-grayWarm-900","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(_e,{brand:"mastercard",width:28}),a.jsx(_e,{brand:"visa",width:28}),a.jsx(_e,{brand:"amex",width:28}),a.jsx(_e,{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(Ae,{type:"paypal",label:"PayPal",iconNode:a.jsx(He,{slug:"paypal",alt:"PayPal"})}),a.jsx(Ae,{type:"googlepay",label:"GooglePay",iconNode:a.jsx(He,{slug:"google-pay",alt:"GooglePay"})}),a.jsx(Ae,{type:"klarna",label:"Klarna",iconNode:a.jsx(He,{slug:"klarna",alt:"Klarna"})}),a.jsx(Ae,{type:"ach",label:"Bank account (ACH)",iconNode:a.jsx("span",{className:"text-xs font-medium text-grayWarm-500",children:"Direct debit"})})]})},ht="movmo-add-payment-form",bt=t=>{const r=t.filter(i=>i.isDefault),s=t.filter(i=>!i.isDefault);return[...r,...s]},xt=({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"})]}),Nt=({userId:t,defaultCardholderName:r,defaultCardholderFirstName:s,defaultCardholderLastName:i,selectedId:c,onSelect:d,onChange:p,paymentTypeSelector:y=!0,autoSaveFirstCard:v=!0,selectionSetsDefault:D=!1,showDefaultBadge:C=!0,collapsible:g=!1,cardLabelFormat:W="branded",className:A})=>{const{items:J,status:P,error:re,refetch:_}=Rt(t),{deletePaymentMethod:T,status:V}=jt(t),{setDefault:le,status:X}=_t(t),[w,te]=o.useState([]),[fe,I]=o.useState(null),[N,u]=o.useState(!1),[k,E]=o.useState(null),[M,K]=o.useState(!1),[L,H]=o.useState(!1),[B,R]=o.useState(null),[F,de]=o.useState(!1),me=o.useRef(!1),he=o.useCallback(()=>{u(!1),E(null),R(null)},[]),be=r??([s,i].filter(Boolean).join(" ")||void 0);o.useEffect(()=>{P==="ready"&&te(bt(J))},[J,P]),o.useEffect(()=>{if(!d||me.current||P!=="ready"||w.length===0||c)return;me.current=!0;const f=w.find(oe=>oe.isDefault)??w[0];d(f)},[d,P,w,c]);const ce=o.useCallback(f=>{te(oe=>{const Q=typeof f=="function"?f(oe):f,z=bt(Q);return p==null||p(z),z})},[p]),xe=V==="pending"||X==="pending",pe=o.useCallback(async f=>{const oe=w;I(null),ce(Q=>Q.map(z=>({...z,isDefault:z.id===f.id})));try{await le(f.id),_()}catch(Q){te(oe),p==null||p(oe);const z=Q instanceof Error?Q.message:"Failed to set default payment method.";I(z)}},[w,ce,le,_,p]),q=o.useCallback(f=>{d==null||d(f),D&&(f.isDefault||pe(f))},[d,D,pe]),ae=o.useCallback(async f=>{const oe=w;I(null);const Q=w.filter(ve=>ve.id!==f.id);ce(()=>Q);const z=f.id===c&&d?Q.find(ve=>ve.isDefault)??Q[0]??null:null;z&&q(z);const $e=!!z&&D&&z!==null&&!z.isDefault;try{await T(f.id),$e||_()}catch(ve){te(oe),p==null||p(oe);const Le=ve instanceof Error?ve.message:"Failed to delete payment method.";I(Le)}},[w,ce,T,_,p,c,d,q,D]),ne=o.useCallback(f=>{E(null),u(!1),R(null),ce(Q=>[f,...Q.filter(z=>z.id!==f.id)]),q(f),!!d&&D&&!f.isDefault||_()},[ce,_,q,d,D]),ye=o.useCallback(f=>{E(f)},[]),ge=P==="ready"&&w.length===0,Ee=typeof d=="function",we=!Ee&&!g,se=w.length===0,h=v&&w.length===0,O=o.useCallback(f=>a.jsx(et,{userId:t,isDefault:se,defaultCardholderName:be,autoSave:!f&&h,hideInternalSaveButton:f,formId:f?ht:void 0,onCanSubmitChange:f?K:void 0,onSavingChange:f?H:void 0,autoFocus:f?"number":void 0,onSuccess:ne,onError:ye}),[t,se,be,h,ne,ye]),Y=o.useMemo(()=>O(!1),[O]),ue=o.useMemo(()=>O(!0),[O]),Ie=o.useMemo(()=>y?a.jsx(vt,{selected:B,onSelect:f=>R(f),creditCardBody:Y}):Y,[y,B,Y]),Ue=o.useMemo(()=>y?a.jsx(vt,{selected:B,onSelect:f=>R(f),creditCardBody:ue}):ue,[y,B,ue]);return a.jsxs("div",{className:G("flex w-full flex-col gap-4",A),"data-testid":"payment-methods-manager",children:[P==="loading"&&w.length===0?a.jsxs("div",{className:G(we?"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(xt,{withDefaultBadge:!0}),a.jsx(xt,{})]}):null,P==="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:re??"Failed to load payment methods."}),a.jsx("button",{type:"button",onClick:_,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,fe?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:fe}):null,g&&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":F?"payment-methods-drawer-header":"payment-methods-collapsed-preview",children:[F?a.jsx("h3",{className:"text-md font-semibold text-grayWarm-950",children:"Payment methods"}):a.jsx(Ct,{method:w.find(f=>f.id===c)??w.find(f=>f.isDefault)??w[0],cardLabelFormat:W,className:"flex-1"}),a.jsx("button",{type:"button","aria-label":F?"Collapse payment methods":"Expand payment methods","aria-expanded":F,className:"bg-grayWarm-100 p-2 rounded-lg hover:bg-grayWarm-200 transition-colors",onClick:()=>de(f=>!f),"data-testid":F?"payment-methods-drawer-close":"payment-methods-drawer-open",children:a.jsx("img",{src:`${Re().iconCdnBaseUrl}/website/assets/icons/chevron-${F?"up":"down"}-double.svg`,alt:"",className:"w-5 h-5"})})]})}):null,w.length>0&&(!g||F)?a.jsx("div",{className:G("flex flex-col",we?"rounded-xl border border-grayWarm-200 px-4 md:px-6 divide-y divide-grayWarm-200":"space-y-3"),children:w.map(f=>a.jsx(pr,{method:f,selectable:Ee,selected:Ee&&f.id===c,onSelect:q,onSetDefault:pe,onRemove:ae,disabled:xe,showDefaultBadge:C,hideSetDefaultMenuItem:D,cardLabelFormat:W},f.id))}):null,ge?a.jsx("div",{"data-testid":"payment-methods-empty",children:Ie}):w.length>0&&(!g||F)?a.jsx("button",{type:"button",onClick:()=>{E(null),R(null),K(!1),u(!0)},onMouseEnter:()=>{Qe().catch(()=>{})},onFocus:()=>{Qe().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(dr,{open:N,onClose:he,formId:ht,saveDisabled:!M,isSaving:L,children:[Ue,k?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:k}):null]})]})};Nt.displayName="PaymentMethodsManager";exports.MovmoCardForm=et;exports.PaymentMethodPreview=Ct;exports.PaymentMethodsManager=Nt;exports.getPaymentsConfig=Re;exports.setPaymentsConfig=Jt;exports.useDeletePaymentMethod=jt;exports.useMovmoCardFields=wt;exports.useSetDefaultPaymentMethod=_t;exports.useUserPaymentMethods=Rt;
|
|
31
31
|
//# sourceMappingURL=index.cjs.js.map
|