@flopay/react 1.11.5 → 1.12.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
@@ -202,7 +202,38 @@ It drops only complete exception stacks with no app or `@flopay/*` frame and at
202
202
 
203
203
  **Theming.** `theme` accepts a `ThemeId` (default `modern-light`) or raw `VaultCardThemeColors`. A named preset styles the container surface, the hosted form (including its complete submit-button snapshot, billing API v1.9.6+), and the processing, success, and error overlay coherently. `classic` keeps the historic appearance, and raw colors are forwarded to the hosted form unchanged with no surface treatment. Changing `theme` re-skins everything in place without remounting the form.
204
204
 
205
- **`containerStyle` precedence.** Each `containerStyle` property wins over the preset's value for the same property, applied preset-first so a longhand refines a preset shorthand (for example `borderColor` keeps the preset border's width). Any `background*` member replaces the preset background entirely. With `classic` or raw colors, `containerStyle` applies alone.
205
+ **Stored themes.** `appearance` and `buttonsStyles` take the same types as on `FloPayCheckout` and resolve the same way, so a client's saved embed theme renders the add-card form exactly as it renders checkout's hosted card form. Pass the saved preset as `theme`, its `appearance` and its `buttonsStyles`; the saved `layout` is not used, because card setup has a single layout.
206
+
207
+ ```tsx
208
+ import { FloPayCardSetup, type FloPayCardSetupProps } from '@flopay/react/card-setup';
209
+
210
+ /** A client's saved embed theme, as your server stores it. */
211
+ interface StoredTheme {
212
+ themePreset: FloPayCardSetupProps['theme'];
213
+ appearance?: FloPayCardSetupProps['appearance'];
214
+ buttonsStyles?: FloPayCardSetupProps['buttonsStyles'];
215
+ }
216
+
217
+ export function AddBrandedCard(props: { sessionId: string; nonce: string; theme: StoredTheme }) {
218
+ return (
219
+ <FloPayCardSetup
220
+ sessionId={props.sessionId}
221
+ nonce={props.nonce}
222
+ theme={props.theme.themePreset}
223
+ appearance={props.theme.appearance}
224
+ buttonsStyles={props.theme.buttonsStyles}
225
+ />
226
+ );
227
+ }
228
+ ```
229
+
230
+ - `appearance` replaces the preset's appearance, and `buttonsStyles` merges over the preset's buttons layout, as in checkout. Together they style the hosted field colors and font, the hosted submit button, the container surface (`buttonsStyles.cardFormContainer`), and the processing, success and error overlay.
231
+ - An empty `{}` group is the same as leaving it out, so a preset-only saved theme renders exactly like `theme` alone.
232
+ - With `classic`, the overrides apply over the historic look; without any, `classic` is unchanged. Raw `VaultCardThemeColors` are forwarded unchanged and the overrides are ignored.
233
+ - An incomplete theme never fails the form: fields it leaves out come from the preset, unknown keys are ignored, and an unrecognized preset id renders `modern-light`. `onError` is not called for any of these.
234
+ - Changing `appearance` or `buttonsStyles` re-skins the form in place, without remounting it or reading the session again.
235
+
236
+ **`containerStyle` precedence.** Each `containerStyle` property wins over the preset's value, including a stored `buttonsStyles.cardFormContainer`, for the same property. It is applied preset-first so a longhand refines a preset shorthand (for example `borderColor` keeps the preset border's width). Any `background*` member replaces the preset background entirely. With raw colors, or with `classic` and no stored `buttonsStyles.cardFormContainer`, `containerStyle` applies alone.
206
237
 
207
238
  ### FloPayPaymentMethodSetup
208
239
 
@@ -562,6 +593,8 @@ export function ComposedCheckout({ session, nonce }: { session: CheckoutSession;
562
593
  | `billingApiUrl` | `string?` | Billing API base URL; defaults to the configured environment |
563
594
  | `telemetry` | `boolean?` | Set `false` to opt out of operational telemetry |
564
595
  | `theme` | `ThemeId \| VaultCardThemeColors` | Preset (default `modern-light`) or raw hosted-form colors |
596
+ | `appearance` | `FloPayAppearance?` | Stored appearance; replaces the preset's, as in `FloPayCheckout` |
597
+ | `buttonsStyles` | `ButtonsLayoutStyles?` | Stored buttons-layout overrides merged over the preset, as in `FloPayCheckout` |
565
598
  | `containerStyle` | `CSSProperties?` | Container styles merged over the preset surface |
566
599
  | `loading` | `ReactNode?` | Content shown while the session and form load |
567
600
  | `onReady` | `() => void` | The hosted form is mounted and accepting input |
@@ -573,7 +606,7 @@ export function ComposedCheckout({ session, nonce }: { session: CheckoutSession;
573
606
 
574
607
  ### FloPayPaymentMethodSetupProps
575
608
 
576
- The same props as `FloPayCardSetupProps`. `theme`, `containerStyle`, `onReady` and `onValidation` apply to the hosted card form as they do there; `theme` also styles the Stripe Elements of advertised wallets and alternative methods.
609
+ The same props as `FloPayCardSetupProps`, without `appearance` and `buttonsStyles`. `theme`, `containerStyle`, `onReady` and `onValidation` apply to the hosted card form as they do there; `theme` also styles the Stripe Elements of advertised wallets and alternative methods.
577
610
 
578
611
  | Prop | Type | Description |
579
612
  |------|------|-------------|
@@ -1,6 +1,6 @@
1
- "use strict";var ee=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var Pe=(e,r)=>{for(var t in r)ee(e,t,{get:r[t],enumerable:!0})},Te=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of Fe(r))!Ee.call(e,o)&&o!==t&&ee(e,o,{get:()=>r[o],enumerable:!(n=we(r,o))||n.enumerable});return e};var Ae=e=>Te(ee({},"__esModule",{value:!0}),e);var Qe={};Pe(Qe,{FloPayCardSetup:()=>xe,FloPayCardSetupError:()=>H});module.exports=Ae(Qe);var j=require("@flopay/js/card-setup"),m=require("@flopay/shared"),u=require("react");function se(e,r){if(!e)return r;let t=r??{},n=Object.keys(t),o=n.some(a=>a.startsWith("background")),i={};for(let[a,l]of Object.entries(e))a in t||o&&a.startsWith("background")||(i[a]=l);for(let a of n)i[a]=t[a];return i}var Ve=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","scale","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]);function Le(e){let r=e.replace(/^(Webkit|Moz|ms)(?=[A-Z])/,"");return Ve.has(r.charAt(0).toLowerCase()+r.slice(1))}function Be(e,r){return typeof r=="number"&&r!==0&&!Le(e)?`${r}px`:String(r).trim()}function ue(e,r){if(e.style.cssText="",!!r){for(let[t,n]of Object.entries(r))if(!(n==null||n==="")){if(t.startsWith("--")){e.style.setProperty(t,String(n));continue}e.style[t]=Be(t,n)}}}var le={light:{success:"#166534",error:"#991B1B"},dark:{success:"#4ADE80",error:"#FCA5A5"}};function ce(e){let r=e.appearance.variables??{},t=e.buttonsLayout.cardFormContainer??{},n=e.appearance.theme==="night",o=n?le.dark:le.light,i=r.colorText??(n?"#F1F5F9":"#262833"),a=e.appearance.rules?.[".Label"];return{panel:{...t.background===void 0?{}:{background:t.background},...t.backgroundColor===void 0?{}:{backgroundColor:t.backgroundColor},...t.border===void 0?{}:{border:t.border},...t.borderRadius===void 0?{}:{borderRadius:t.borderRadius},...t.boxShadow===void 0?{}:{boxShadow:t.boxShadow},color:i,...r.fontFamily?{fontFamily:r.fontFamily}:{}},spinnerTrackColor:e.buttonsLayout.cardInputBorder??(n?"#374151":"#e5e7eb"),spinnerAccentColor:r.colorPrimary??"#4A49FF",labelColors:{processing:i,success:o.success,error:o.error},noteColor:a?.color??i}}function P(e){if(!e)return;let r=t=>{console.error("[FloPay] Merchant callback failed; checkout continued.",t)};try{Promise.resolve(e()).catch(r)}catch(t){r(t)}}var d=require("react/jsx-runtime");var Oe={panel:{background:"white"},spinnerTrackColor:"#e5e7eb",spinnerAccentColor:"#4A49FF",labelColors:{processing:"#374151",success:"#16a34a",error:"#dc2626"},noteColor:"#6b7280"};function de({status:e,errorMessage:r,authorized:t=!1,processingLabel:n="PROCESSING...",successLabel:o,errorLabel:i="PAYMENT FAILED",successNote:a="You will be automatically redirected, do not close or navigate away from this window.",theme:l=Oe}){let s={fontSize:13,color:l.noteColor,fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0};return(0,d.jsx)("div",{"data-testid":"flopay-processing-overlay","data-status":e,role:"dialog","aria-modal":"true",style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.35)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3,backdropFilter:"blur(2px)"},children:(0,d.jsxs)("div",{"data-testid":"flopay-processing-overlay-panel",style:{borderRadius:12,boxShadow:"0 8px 32px rgba(0,0,0,0.18)",...l.panel,padding:"2rem 2.5rem",textAlign:"center",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[(0,d.jsxs)("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{animation:"flopay-spin 0.8s linear infinite"},children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"10",stroke:l.spinnerTrackColor,strokeWidth:"3"}),(0,d.jsx)("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:l.spinnerAccentColor})]}),e==="success"&&(0,d.jsx)("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),(0,d.jsx)("path",{d:"M7 12.5l3 3 7-7",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{strokeDasharray:20,strokeDashoffset:20,animation:"flopay-draw 0.4s 0.15s ease forwards"}})]})}),e==="error"&&(0,d.jsx)("div",{style:{animation:"flopay-shake 0.4s ease"},children:(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),(0,d.jsx)("path",{d:"M8 8l8 8M16 8l-8 8",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",style:{strokeDasharray:12,strokeDashoffset:12,animation:"flopay-draw 0.3s 0.1s ease forwards"}})]})})]}),(0,d.jsxs)("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:l.labelColors[e]},children:[e==="processing"&&n,e==="success"&&(o??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&i]}),e==="success"&&a!==null&&(0,d.jsx)("p",{style:s,children:a}),e==="error"&&r&&(0,d.jsx)("p",{style:s,children:r}),(0,d.jsx)("style",{children:`
1
+ "use strict";var $=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var ge=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var he=(e,r)=>{for(var t in r)$(e,t,{get:r[t],enumerable:!0})},Se=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of ge(r))!Ce.call(e,i)&&i!==t&&$(e,i,{get:()=>r[i],enumerable:!(o=ye(r,i))||o.enumerable});return e};var ve=e=>Se($({},"__esModule",{value:!0}),e);var Te={};he(Te,{FloPayCardSetup:()=>fe,FloPayCardSetupError:()=>z});module.exports=ve(Te);var q=require("@flopay/js/card-setup"),l=require("@flopay/shared"),n=require("react");var J=require("@flopay/shared"),Re=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","scale","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]);function be(e){let r=e.replace(/^(Webkit|Moz|ms)(?=[A-Z])/,"");return Re.has(r.charAt(0).toLowerCase()+r.slice(1))}function Ee(e,r){return typeof r=="number"&&r!==0&&!be(e)?`${r}px`:String(r).trim()}function se(e,r){if(e.style.cssText="",!!r){for(let[t,o]of Object.entries(r))if(!(o==null||o==="")){if(t.startsWith("--")){e.style.setProperty(t,String(o));continue}e.style[t]=Ee(t,o)}}}var K=require("@flopay/shared"),we=require("@flopay/shared");function ie(e){let{vaultTheme:r,surface:t,overlayTheme:o}=(0,K.resolveCardSetupTheme)(e);return{vaultTheme:r,surface:t,overlayTheme:o}}var h=require("@flopay/shared");var a=require("react/jsx-runtime");var xe={panel:{background:"white"},spinnerTrackColor:"#e5e7eb",spinnerAccentColor:"#4A49FF",labelColors:{processing:"#374151",success:"#16a34a",error:"#dc2626"},noteColor:"#6b7280"};function le({status:e,errorMessage:r,authorized:t=!1,processingLabel:o="PROCESSING...",successLabel:i,errorLabel:p="PAYMENT FAILED",successNote:b="You will be automatically redirected, do not close or navigate away from this window.",theme:m=xe}){let E={fontSize:13,color:m.noteColor,fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0};return(0,a.jsx)("div",{"data-testid":"flopay-processing-overlay","data-status":e,role:"dialog","aria-modal":"true",style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.35)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3,backdropFilter:"blur(2px)"},children:(0,a.jsxs)("div",{"data-testid":"flopay-processing-overlay-panel",style:{borderRadius:12,boxShadow:"0 8px 32px rgba(0,0,0,0.18)",...m.panel,padding:"2rem 2.5rem",textAlign:"center",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[(0,a.jsxs)("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&(0,a.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{animation:"flopay-spin 0.8s linear infinite"},children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"10",stroke:m.spinnerTrackColor,strokeWidth:"3"}),(0,a.jsx)("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:m.spinnerAccentColor})]}),e==="success"&&(0,a.jsx)("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:(0,a.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),(0,a.jsx)("path",{d:"M7 12.5l3 3 7-7",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{strokeDasharray:20,strokeDashoffset:20,animation:"flopay-draw 0.4s 0.15s ease forwards"}})]})}),e==="error"&&(0,a.jsx)("div",{style:{animation:"flopay-shake 0.4s ease"},children:(0,a.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,a.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),(0,a.jsx)("path",{d:"M8 8l8 8M16 8l-8 8",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",style:{strokeDasharray:12,strokeDashoffset:12,animation:"flopay-draw 0.3s 0.1s ease forwards"}})]})})]}),(0,a.jsxs)("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:m.labelColors[e]},children:[e==="processing"&&o,e==="success"&&(i??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&p]}),e==="success"&&b!==null&&(0,a.jsx)("p",{style:E,children:b}),e==="error"&&r&&(0,a.jsx)("p",{style:E,children:r}),(0,a.jsx)("style",{children:`
2
2
  @keyframes flopay-spin { to { transform: rotate(360deg); } }
3
3
  @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
4
4
  @keyframes flopay-draw { to { stroke-dashoffset: 0; } }
5
5
  @keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }
6
- `})]})})}var h=require("react");var X=require("react"),fe=typeof window>"u"?X.useEffect:X.useLayoutEffect;var te=require("react/jsx-runtime"),re=new WeakSet;function pe({capture:e,html:r,messageToken:t,expectedOrigin:n,verificationRequired:o,theme:i,submitLabel:a,containerStyle:l,onReady:s,onError:f,onValidation:c}){let g=(0,h.useRef)(null),k=(0,h.useRef)(s),y=(0,h.useRef)(f),I=(0,h.useRef)(c);k.current=s,y.current=f,I.current=c;let v=(0,h.useRef)(i);v.current=i;let V=(0,h.useRef)(null),R=a??void 0,T=(0,h.useRef)(R);T.current=R;let L=(0,h.useRef)(void 0);return(0,h.useEffect)(()=>{let b=g.current;if(!b)return;let _=!0,B=!1,w=()=>{!_||B||(B=!0,k.current?.())},N=e.on("ready",()=>{w()}),S=e.on("error",F=>{y.current?.(F.message??"There was a problem loading the secure card form.")}),K=e.on("validation",F=>{I.current?.(F.message??null)}),U=T.current??(re.has(e)?null:void 0),Y={html:r,...t?{messageToken:t}:{},...n?{expectedOrigin:n}:{},...o?{verificationRequired:!0}:{},...v.current?{theme:v.current}:{},...U===void 0?{}:{submitLabel:U}};return V.current=v.current??null,L.current=T.current,T.current!==void 0&&re.add(e),e.mount(b,Y).then(()=>{w()}).catch(F=>{_&&y.current?.(F instanceof Error?F.message:"Failed to load the secure card form.")}),()=>{_=!1,N(),S(),K(),e.unmount()}},[e,r,t,n,o]),fe(()=>{let b=g.current;b&&ue(b,l)},[l]),(0,h.useEffect)(()=>{i!==void 0&&(i===null&&V.current===null||(V.current=i,e.applyTheme?.(i)))},[e,i]),(0,h.useEffect)(()=>{R!==L.current&&(L.current=R,R!==void 0&&re.add(e),e.setSubmitLabel?.(R??null))},[e,R]),(0,te.jsx)("div",{ref:g,"data-testid":"flopay-vault-card-fields"})}var ge=/^#([0-9a-f]{6})$/i,Me=/^#([0-9a-f]{3})$/i,ye=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i,be=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+|1\.0+)\s*\)$/i,Ie=/^linear-gradient\(\s*(-?\d+(?:\.\d+)?)deg\s*,\s*(.+)\)$/i,_e=/^(-?\d+(?:\.\d+)?)(?:px)?$/,Ne=/^(-?\d+(?:\.\d+)?)em$/,De=/^blur\(\s*(\d+(?:\.\d+)?)(?:px)?\s*\)$/i,ze=/^[a-z][a-z0-9 -]{0,31}$/i,We=new Set(["none","uppercase","lowercase","capitalize"]);function he(e){if(typeof e!="string")return null;let r=e.trim(),t=ge.exec(r);if(t){let c=Number.parseInt(t[1],16);return{r:c>>16&255,g:c>>8&255,b:c&255,a:null}}let n=Me.exec(r);if(n){let[c,g,k]=n[1].split("").map(y=>Number.parseInt(y+y,16));return{r:c,g,b:k,a:null}}let o=ye.exec(r),i=o?null:be.exec(r),a=o??i;if(!a)return null;let l=Number(a[1]),s=Number(a[2]),f=Number(a[3]);return l>255||s>255||f>255?null:{r:l,g:s,b:f,a:i?Number(i[4]):null}}function Ce({r:e,g:r,b:t,a:n}){return n===null?`#${(1<<24|e<<16|r<<8|t).toString(16).slice(1)}`:`rgba(${e},${r},${t},${n})`}function $(e){if(typeof e!="string")return;let r=e.trim();if(ge.test(r)||ye.test(r))return r;let t=be.exec(r);if(t&&/^\d/.test(t[4]))return r;let n=he(r);return n?Ce(n):void 0}function q(e,r=.12){let t=he(e);if(!t)return e;let n=Math.max(0,Math.min(1,1-r));return Ce({r:Math.round(t.r*n),g:Math.round(t.g*n),b:Math.round(t.b*n),a:t.a})}function G(e,r){let t=[],n=0,o="";for(let i of e){if(i==="("&&(n+=1),i===")"&&(n-=1),i===r&&n===0){o.trim()&&t.push(o.trim()),o="";continue}o+=i}return o.trim()&&t.push(o.trim()),t}function A(e,r,t){if(typeof e!="number"&&typeof e!="string")return;let n=_e.exec(String(e).trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function $e(e,r,t){if(typeof e!="string")return;let n=Ne.exec(e.trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function Ge(e){let r=G(e,",");if(r.length<2||r.length>5)return;let t=[];for(let[n,o]of r.entries()){let i=G(o," "),a=$(i[0]);if(!a)return;let l=n/(r.length-1)*100,s=i[1]===void 0?l:Number(/^(\d+(?:\.\d+)?)%$/.exec(i[1])?.[1]),f=t[t.length-1]?.position??-1;if(!Number.isFinite(s)||s<0||s>100||s<f)return;t.push({color:a,position:s})}return{type:"linearGradient",angle:0,stops:t}}function He(e){if(typeof e!="string")return;let r=e.trim(),t=$(r);if(t)return{type:"solid",color:t};let n=Ie.exec(r);if(!n)return;let o=Number(n[1]);if(!Number.isFinite(o)||o<0||o>360)return;let i=Ge(n[2]);return i&&i.type==="linearGradient"?{...i,angle:o}:void 0}function Ue(e){return e.type==="solid"?{type:"solid",color:q(e.color)}:{...e,stops:e.stops.map(r=>({...r,color:q(r.color)}))}}function Ye(e){let r=!1,t,n=[];for(let s of G(e," ")){if(s.toLowerCase()==="inset"){r=!0;continue}let f=$(s);if(f){t=f;continue}let c=A(s,-128,128);if(c===void 0)return;n.push(c)}if(!t||n.length<2||n.length>4)return;let[o,i,a=0,l=0]=n;if(!(Math.abs(o)>64||Math.abs(i)>64||a>128||Math.abs(l)>32))return{color:t,inset:r,offsetX:o,offsetY:i,blur:a,spread:l}}function Xe(e){if(typeof e!="string")return;let r=e.trim();if(r.toLowerCase()==="none")return[];let t=G(r,",").map(Ye);if(!(t.length===0||t.length>4))return t.every(n=>n!==void 0)?t:void 0}function me(e){if(typeof e!="string")return;let r=G(e,",").map(t=>t.replace(/^['"]|['"]$/g,"").trim()).filter(t=>ze.test(t)).slice(0,4);return r.length>0?r:void 0}function qe(e){let r=typeof e=="string"?e.trim().split(/\s+/):[e],t=A(r[0],0,64),n=A(r[1]??r[0],0,64);if(!(t===void 0||n===void 0))return{paddingBlock:t,paddingInline:n}}function je(e){if(e==="bold")return 700;if(e==="normal")return 400;let r=Number(e);return Number.isInteger(r)&&r>=100&&r<=900?r:void 0}function Se({appearance:e,buttonsStyles:r,fontFamily:t}){let n=r.submitButton;if(!n)return;let o=e?.variables,i=He(n.background??n.backgroundColor),a=$(o?.colorPrimaryHover),l=a?{type:"solid",color:a}:i&&Ue(i),s={fontFamilies:me(n.fontFamily)??me(t),fontSize:A(n.fontSize??r.submitButtonFontSize,10,32)??16,fontWeight:je(n.fontWeight)??600,letterSpacing:$e(n.letterSpacing,-.1,.5)??.01,lineHeight:A(n.lineHeight,.8,2)??1,textTransform:We.has(String(n.textTransform))?n.textTransform:"uppercase"},f=qe(n.padding),c=Xe(n.boxShadow),g=A(n.borderRadius,0,9999),k=typeof n.backdropFilter=="string"?A(De.exec(n.backdropFilter.trim())?.[1],0,40):void 0;return{foregroundColor:$(n.color)??"#FFFFFF",...i?{background:i,disabledBackground:i}:{},...l?{hoverBackground:l}:{},typography:s,...f?{spacing:f}:{},...c?{shadow:c}:{},...g===void 0?{}:{borderRadius:g},disabledOpacity:e?.theme==="night"?.8:.6,...k===void 0?{}:{backdropBlur:k}}}function Ke(e,r=.12){let t=e.trim(),n=/^[0-9a-fA-F]{6}$/.test(t)?`#${t}`:t;return/^#[0-9a-fA-F]{6}$/.test(n)?q(n,r):e}function Ze(e){if(typeof e=="number"||typeof e=="string")return e}function ke({appearance:e,buttonsStyles:r,layout:t="default"}){let n=e?.variables,o=g=>typeof g=="string"&&g?g:void 0,i=r.submitButton,a=o(n?.colorPrimary)??o(i?.backgroundColor)??"#4A49FF",l=t==="buttons",s=r.nameInput,f=o(s?.fontFamily)??o(n?.fontFamily)??"Poppins, sans-serif",c=Se({appearance:e,buttonsStyles:r,fontFamily:f});return{primaryColor:a,primaryHoverColor:o(n?.colorPrimaryHover)??Ke(a,.12),inputBackgroundColor:o(r.cardInputBackground)??o(n?.colorBackground)??"#ffffff",textColor:o(r.cardInputColor)??o(s?.color)??o(n?.colorText)??"#262833",borderColor:o(r.cardInputBorder)??(l?"#e5e7eb":"#A4A4FF"),placeholderColor:o(r.cardInputPlaceholderColor)??"#9ca3af",errorColor:o(n?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:f,fontSize:o(r.cardInputFontSize)??o(n?.fontSizeBase)??"16px",fontWeight:String(Ze(s?.fontWeight)??400),borderRadius:o(n?.borderRadius)??"8px",...c?{submitButton:c}:{}}}var x=require("react/jsx-runtime"),H=class extends m.FloPayError{constructor(r,t,n){super(r,t,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function Re(e,r={}){let t=e instanceof m.FloPayError?e:void 0,n=t?.statusCode,o=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof n=="number"&&n>=500||t?.code==="vault_capture_timeout"||!t);return new H(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:o,...t?.param?{param:t.param}:{},...n===void 0?{}:{statusCode:n}})}function xe({sessionId:e,nonce:r,billingApiUrl:t,telemetry:n,theme:o="modern-light",containerStyle:i,loading:a=null,onReady:l,onComplete:s,onDecline:f,onCancel:c,onValidation:g,onError:k}){let[y,I]=(0,u.useState)(null),[v,V]=(0,u.useState)(null),[R,T]=(0,u.useState)(null),[L,b]=(0,u.useState)(null),[_,B]=(0,u.useState)(null),w=(0,u.useRef)(!1),N=(0,u.useRef)(!1),S=(0,u.useMemo)(()=>typeof o=="object"?void 0:(0,m.resolveTheme)(o),[o]),K=(0,u.useMemo)(()=>typeof o=="object"?o:S?ke({appearance:S.appearance,buttonsStyles:S.buttonsLayout,layout:"default"}):null,[S,o]),U=(0,u.useMemo)(()=>se(S?.buttonsLayout.cardFormContainer,i),[S,i]),Y=(0,u.useMemo)(()=>S?ce(S):void 0,[S]),F=(0,u.useRef)(l),Z=(0,u.useRef)(k),ne=(0,u.useRef)(s),oe=(0,u.useRef)(f),ie=(0,u.useRef)(c),ae=(0,u.useRef)(g),D=(0,u.useRef)(!1),J=(0,u.useRef)(!1),Q=(0,u.useRef)(0);return F.current=l,Z.current=k,ne.current=s,oe.current=f,ie.current=c,ae.current=g,(0,u.useEffect)(()=>{let p=Q.current+1;return Q.current=p,()=>{queueMicrotask(()=>{Q.current===p&&(D.current||J.current||(J.current=!0,P(()=>{ie.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,u.useEffect)(()=>{let p=!0,O=(0,m.resolveBillingApiUrl)(t),z=new j.PaymentAPI(O,{telemetry:n});return I(null),V(null),T(null),D.current=!1,J.current=!1,(async()=>{try{if(!e.trim())throw new m.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new m.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let W=await z.getUnifiedCheckoutSession(e,r);if(!p)return;let E=W.data.session;if(!E||!(0,m.isCardSetupCheckoutSession)(E))throw new m.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let C=E.vault;(0,m.isMountableVaultBlock)(C)||(C=await z.getVaultCapture(e,r));let M=(0,m.resolveVaultMountOptions)(C,{billingApiUrl:O,sessionId:e,nonce:r});if(!M)throw new m.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!p)return;V(M),I(new j.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:n}))}catch(W){if(!p)return;let E=Re(W);D.current=!0,T(E),P(()=>Z.current?.(E))}})(),()=>{p=!1,z.destroy()}},[t,r,e,n]),(0,u.useEffect)(()=>{if(!y)return;let p=!1;N.current=!1,w.current=!1;let O=y.on("submitting",()=>{w.current=!0,B(null),b("processing")}),z=y.on("complete",C=>{D.current=!0,w.current=!1,b("success"),(async()=>(await new Promise(M=>setTimeout(M,600)),!N.current&&(N.current=!0,P(()=>{ne.current?.({status:"succeeded",sessionId:e,...C.paymentMethod?{paymentMethod:C.paymentMethod}:{}})}),p||b(null))))()}),W=y.on("decline",C=>{D.current=!0,w.current=!1,B(C.message??null),b("error"),P(()=>{oe.current?.({status:"declined",sessionId:e,...C.declineReason?{reason:C.declineReason}:{},...C.message?{message:C.message}:{}})}),(async()=>(await new Promise(M=>setTimeout(M,400)),p||b(null)))()}),E=y.on("challenge_dismissed",()=>{b(null)});return()=>{p=!0,O(),z(),W(),E()}},[y,e]),R?(0,x.jsx)("div",{role:"alert",children:R.message}):!y||!v?.html?(0,x.jsx)(x.Fragment,{children:a}):(0,x.jsxs)(x.Fragment,{children:[L&&(0,x.jsx)(de,{status:L,errorMessage:_,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...Y?{theme:Y}:{}}),(0,x.jsx)(pe,{capture:y,html:v.html,messageToken:v.messageToken,expectedOrigin:v.expectedOrigin,verificationRequired:v.verificationRequired,theme:K,containerStyle:U,onReady:()=>{P(()=>F.current?.())},onValidation:p=>{P(()=>ae.current?.(p))},onError:p=>{if(!p)return;w.current&&(w.current=!1,B(p),b("error"),setTimeout(()=>b(null),400));let O=Re(new Error(p),{code:"card_setup_widget_failed",retryable:!0});P(()=>Z.current?.(O))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
6
+ `})]})})}var d=require("react");var H=require("react"),ue=typeof window>"u"?H.useEffect:H.useLayoutEffect;var ee=require("react/jsx-runtime"),Q=new WeakSet;function ce({capture:e,html:r,messageToken:t,expectedOrigin:o,verificationRequired:i,theme:p,submitLabel:b,containerStyle:m,onReady:E,onError:L,onValidation:_}){let x=(0,d.useRef)(null),M=(0,d.useRef)(E),P=(0,d.useRef)(L),V=(0,d.useRef)(_);M.current=E,P.current=L,V.current=_;let u=(0,d.useRef)(p);u.current=p;let T=(0,d.useRef)(null),c=b??void 0,w=(0,d.useRef)(c);w.current=c;let k=(0,d.useRef)(void 0);return(0,d.useEffect)(()=>{let S=x.current;if(!S)return;let O=!0,y=!1,Y=()=>{!O||y||(y=!0,M.current?.())},D=e.on("ready",()=>{Y()}),v=e.on("error",C=>{P.current?.(C.message??"There was a problem loading the secure card form.")}),I=e.on("validation",C=>{V.current?.(C.message??null)}),B=w.current??(Q.has(e)?null:void 0),G={html:r,...t?{messageToken:t}:{},...o?{expectedOrigin:o}:{},...i?{verificationRequired:!0}:{},...u.current?{theme:u.current}:{},...B===void 0?{}:{submitLabel:B}};return T.current=u.current??null,k.current=w.current,w.current!==void 0&&Q.add(e),e.mount(S,G).then(()=>{Y()}).catch(C=>{O&&P.current?.(C instanceof Error?C.message:"Failed to load the secure card form.")}),()=>{O=!1,D(),v(),I(),e.unmount()}},[e,r,t,o,i]),ue(()=>{let S=x.current;S&&se(S,m)},[m]),(0,d.useEffect)(()=>{p!==void 0&&(p===null&&T.current===null||(T.current=p,e.applyTheme?.(p)))},[e,p]),(0,d.useEffect)(()=>{c!==k.current&&(k.current=c,c!==void 0&&Q.add(e),e.setSubmitLabel?.(c??null))},[e,c]),(0,ee.jsx)("div",{ref:x,"data-testid":"flopay-vault-card-fields"})}var g=require("react/jsx-runtime"),z=class extends l.FloPayError{constructor(r,t,o){super(r,t,o),this.name="FloPayCardSetupError",this.retryable=o.retryable}};function pe(e,r={}){let t=e instanceof l.FloPayError?e:void 0,o=t?.statusCode,i=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof o=="number"&&o>=500||t?.code==="vault_capture_timeout"||!t);return new z(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:i,...t?.param?{param:t.param}:{},...o===void 0?{}:{statusCode:o}})}function fe({sessionId:e,nonce:r,billingApiUrl:t,telemetry:o,theme:i="modern-light",containerStyle:p,appearance:b,buttonsStyles:m,loading:E=null,onReady:L,onComplete:_,onDecline:x,onCancel:M,onValidation:P,onError:V}){let[u,T]=(0,n.useState)(null),[c,w]=(0,n.useState)(null),[k,S]=(0,n.useState)(null),[O,y]=(0,n.useState)(null),[Y,D]=(0,n.useState)(null),v=(0,n.useRef)(!1),I=(0,n.useRef)(!1),{vaultTheme:B,surface:G,overlayTheme:C}=(0,n.useMemo)(()=>ie({theme:i,appearance:b,buttonsStyles:m}),[i,b,m]),me=(0,n.useMemo)(()=>(0,J.mergeCardSetupSurface)(G,p),[G,p]),re=(0,n.useRef)(L),X=(0,n.useRef)(V),te=(0,n.useRef)(_),oe=(0,n.useRef)(x),ne=(0,n.useRef)(M),ae=(0,n.useRef)(P),N=(0,n.useRef)(!1),j=(0,n.useRef)(!1),Z=(0,n.useRef)(0);return re.current=L,X.current=V,te.current=_,oe.current=x,ne.current=M,ae.current=P,(0,n.useEffect)(()=>{let s=Z.current+1;return Z.current=s,()=>{queueMicrotask(()=>{Z.current===s&&(N.current||j.current||(j.current=!0,(0,h.invokeMerchantCallback)(()=>{ne.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,n.useEffect)(()=>{let s=!0,F=(0,l.resolveBillingApiUrl)(t),U=new q.PaymentAPI(F,{telemetry:o});return T(null),w(null),S(null),N.current=!1,j.current=!1,(async()=>{try{if(!e.trim())throw new l.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new l.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let W=await U.getUnifiedCheckoutSession(e,r);if(!s)return;let R=W.data.session;if(!R||!(0,l.isCardSetupCheckoutSession)(R))throw new l.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let f=R.vault;(0,l.isMountableVaultBlock)(f)||(f=await U.getVaultCapture(e,r));let A=(0,l.resolveVaultMountOptions)(f,{billingApiUrl:F,sessionId:e,nonce:r});if(!A)throw new l.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!s)return;w(A),T(new q.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:o}))}catch(W){if(!s)return;let R=pe(W);N.current=!0,S(R),(0,h.invokeMerchantCallback)(()=>X.current?.(R))}})(),()=>{s=!1,U.destroy()}},[t,r,e,o]),(0,n.useEffect)(()=>{if(!u)return;let s=!1;I.current=!1,v.current=!1;let F=u.on("submitting",()=>{v.current=!0,D(null),y("processing")}),U=u.on("complete",f=>{N.current=!0,v.current=!1,y("success"),(async()=>(await new Promise(A=>setTimeout(A,600)),!I.current&&(I.current=!0,(0,h.invokeMerchantCallback)(()=>{te.current?.({status:"succeeded",sessionId:e,...f.paymentMethod?{paymentMethod:f.paymentMethod}:{}})}),s||y(null))))()}),W=u.on("decline",f=>{N.current=!0,v.current=!1,D(f.message??null),y("error"),(0,h.invokeMerchantCallback)(()=>{oe.current?.({status:"declined",sessionId:e,...f.declineReason?{reason:f.declineReason}:{},...f.message?{message:f.message}:{}})}),(async()=>(await new Promise(A=>setTimeout(A,400)),s||y(null)))()}),R=u.on("challenge_dismissed",()=>{y(null)});return()=>{s=!0,F(),U(),W(),R()}},[u,e]),k?(0,g.jsx)("div",{role:"alert",children:k.message}):!u||!c?.html?(0,g.jsx)(g.Fragment,{children:E}):(0,g.jsxs)(g.Fragment,{children:[O&&(0,g.jsx)(le,{status:O,errorMessage:Y,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...C?{theme:C}:{}}),(0,g.jsx)(ce,{capture:u,html:c.html,messageToken:c.messageToken,expectedOrigin:c.expectedOrigin,verificationRequired:c.verificationRequired,theme:B,containerStyle:me,onReady:()=>{(0,h.invokeMerchantCallback)(()=>re.current?.())},onValidation:s=>{(0,h.invokeMerchantCallback)(()=>ae.current?.(s))},onError:s=>{if(!s)return;v.current&&(v.current=!1,D(s),y("error"),setTimeout(()=>y(null),400));let F=pe(new Error(s),{code:"card_setup_widget_failed",retryable:!0});(0,h.invokeMerchantCallback)(()=>X.current?.(F))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
@@ -1,4 +1,4 @@
1
- import { ThemeId, VaultCardThemeColors, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
1
+ import { ThemeId, VaultCardThemeColors, FloPayAppearance, ButtonsLayoutStyles, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
2
2
  import React from 'react';
3
3
 
4
4
  /** Verified terminal result from a no-charge card setup. */
@@ -45,19 +45,42 @@ interface FloPayCardSetupProps {
45
45
  * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
46
46
  * bundle, so one value styles both surfaces identically) or raw
47
47
  * {@link VaultCardThemeColors} for full manual control. Defaults to
48
- * `'modern-light'`; pass `'classic'` for the historic FloPay look.
48
+ * `'modern-light'`, which an unrecognized preset id also falls back to; pass
49
+ * `'classic'` for the historic FloPay look.
49
50
  */
50
51
  theme?: ThemeId | VaultCardThemeColors;
51
52
  /**
52
53
  * Inline styles for the hosted-widget container. A named preset first gives
53
54
  * that container the same complete surface as the checkout's credit-card
54
- * pane (background, border, radius, shadow, padding); each `containerStyle`
55
- * property then wins over the preset's for the same property, a longhand
56
- * refines a preset shorthand (`borderColor` recolors the preset border), and
57
- * any `background*` member replaces the preset background entirely.
58
- * `'classic'` and raw colors add no surface, so `containerStyle` applies alone.
55
+ * pane (background, border, radius, shadow, padding), with any stored
56
+ * `buttonsStyles.cardFormContainer` merged over it; each `containerStyle`
57
+ * property then wins over that surface for the same property, a longhand
58
+ * refines a surface shorthand (`borderColor` recolors the preset border), and
59
+ * any `background*` member replaces the surface background entirely.
60
+ * Raw colors add no surface. `'classic'` adds one only from a stored
61
+ * `buttonsStyles.cardFormContainer`, merged beneath `containerStyle` the same
62
+ * way; otherwise `containerStyle` applies alone.
59
63
  */
60
64
  containerStyle?: React.CSSProperties;
65
+ /**
66
+ * Appearance override, the same prop and type as `FloPayCheckout`'s (for
67
+ * example a client's saved embed theme `appearance`). It replaces the preset's
68
+ * appearance outright, as checkout does: its variables (primary color, text,
69
+ * font, radius, …) drive the hosted card fields, the hosted submit button
70
+ * and the outcome overlay. Ignored with raw {@link VaultCardThemeColors}; an
71
+ * empty `{}` is the same as omitting it. Changes restyle in place.
72
+ */
73
+ appearance?: FloPayAppearance;
74
+ /**
75
+ * Buttons-layout style overrides, the same prop and type as
76
+ * `FloPayCheckout`'s (for example a client's saved embed theme
77
+ * `buttonsStyles`), merged over the preset's buttons layout the way checkout
78
+ * merges them. `submitButton` and the `cardInput*` members style the hosted
79
+ * card form, and `cardFormContainer` the pane around it and the outcome
80
+ * overlay's panel. Ignored with raw {@link VaultCardThemeColors}; an empty
81
+ * `{}` is the same as omitting it. Changes restyle in place.
82
+ */
83
+ buttonsStyles?: ButtonsLayoutStyles;
61
84
  /** Optional content shown while the session and hosted widget are loading. */
62
85
  loading?: React.ReactNode;
63
86
  /** Fired once the hosted widget has mounted and can accept card input. */
@@ -78,6 +101,6 @@ interface FloPayCardSetupProps {
78
101
  * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
79
102
  * Elements surface.
80
103
  */
81
- declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
104
+ declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, appearance, buttonsStyles, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
82
105
 
83
106
  export { FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps };
@@ -1,4 +1,4 @@
1
- import { ThemeId, VaultCardThemeColors, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
1
+ import { ThemeId, VaultCardThemeColors, FloPayAppearance, ButtonsLayoutStyles, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
2
2
  import React from 'react';
3
3
 
4
4
  /** Verified terminal result from a no-charge card setup. */
@@ -45,19 +45,42 @@ interface FloPayCardSetupProps {
45
45
  * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
46
46
  * bundle, so one value styles both surfaces identically) or raw
47
47
  * {@link VaultCardThemeColors} for full manual control. Defaults to
48
- * `'modern-light'`; pass `'classic'` for the historic FloPay look.
48
+ * `'modern-light'`, which an unrecognized preset id also falls back to; pass
49
+ * `'classic'` for the historic FloPay look.
49
50
  */
50
51
  theme?: ThemeId | VaultCardThemeColors;
51
52
  /**
52
53
  * Inline styles for the hosted-widget container. A named preset first gives
53
54
  * that container the same complete surface as the checkout's credit-card
54
- * pane (background, border, radius, shadow, padding); each `containerStyle`
55
- * property then wins over the preset's for the same property, a longhand
56
- * refines a preset shorthand (`borderColor` recolors the preset border), and
57
- * any `background*` member replaces the preset background entirely.
58
- * `'classic'` and raw colors add no surface, so `containerStyle` applies alone.
55
+ * pane (background, border, radius, shadow, padding), with any stored
56
+ * `buttonsStyles.cardFormContainer` merged over it; each `containerStyle`
57
+ * property then wins over that surface for the same property, a longhand
58
+ * refines a surface shorthand (`borderColor` recolors the preset border), and
59
+ * any `background*` member replaces the surface background entirely.
60
+ * Raw colors add no surface. `'classic'` adds one only from a stored
61
+ * `buttonsStyles.cardFormContainer`, merged beneath `containerStyle` the same
62
+ * way; otherwise `containerStyle` applies alone.
59
63
  */
60
64
  containerStyle?: React.CSSProperties;
65
+ /**
66
+ * Appearance override, the same prop and type as `FloPayCheckout`'s (for
67
+ * example a client's saved embed theme `appearance`). It replaces the preset's
68
+ * appearance outright, as checkout does: its variables (primary color, text,
69
+ * font, radius, …) drive the hosted card fields, the hosted submit button
70
+ * and the outcome overlay. Ignored with raw {@link VaultCardThemeColors}; an
71
+ * empty `{}` is the same as omitting it. Changes restyle in place.
72
+ */
73
+ appearance?: FloPayAppearance;
74
+ /**
75
+ * Buttons-layout style overrides, the same prop and type as
76
+ * `FloPayCheckout`'s (for example a client's saved embed theme
77
+ * `buttonsStyles`), merged over the preset's buttons layout the way checkout
78
+ * merges them. `submitButton` and the `cardInput*` members style the hosted
79
+ * card form, and `cardFormContainer` the pane around it and the outcome
80
+ * overlay's panel. Ignored with raw {@link VaultCardThemeColors}; an empty
81
+ * `{}` is the same as omitting it. Changes restyle in place.
82
+ */
83
+ buttonsStyles?: ButtonsLayoutStyles;
61
84
  /** Optional content shown while the session and hosted widget are loading. */
62
85
  loading?: React.ReactNode;
63
86
  /** Fired once the hosted widget has mounted and can accept card input. */
@@ -78,6 +101,6 @@ interface FloPayCardSetupProps {
78
101
  * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
79
102
  * Elements surface.
80
103
  */
81
- declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
104
+ declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, appearance, buttonsStyles, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
82
105
 
83
106
  export { FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps };
@@ -1 +1 @@
1
- import{k as e,m as t}from"./chunk-AW5LOT2K.mjs";export{t as FloPayCardSetup,e as FloPayCardSetupError};
1
+ import{h as e,j as t}from"./chunk-XVCGDHF2.mjs";export{t as FloPayCardSetup,e as FloPayCardSetupError};
@@ -0,0 +1 @@
1
+ import{a as Be,b as Ae,c as C,d as Te,f as xe,g as Ie,i as w}from"./chunk-XVCGDHF2.mjs";import{PaymentAPI as Ge,PciVaultCardCapture as rt}from"@flopay/js/card-setup";import{FloPayError as F,isCardSetupCheckoutSession as nt,isMountableVaultBlock as at,resolveBillingApiUrl as te,resolveTheme as ot,resolveVaultMountOptions as st}from"@flopay/shared";import it,{Suspense as Ke,useCallback as O,useEffect as re,useMemo as T,useRef as u,useState as b}from"react";import{clearSetupRedirectParams as De,readSetupRedirectReturn as Le}from"@flopay/js/card-setup";import{advertisedMethodKeys as ee,advertisesAnyMethod as Ne,readSetupAdvertisement as We,setupOverlayLabels as Ye,stripeMethodCategory as Y}from"@flopay/shared";import{computeVaultCardThemeColors as qe}from"@flopay/shared";import{Fragment as He,jsx as c,jsxs as ae}from"react/jsx-runtime";var lt=15,ut=2e3;function dt(y){return{userId:y.customer?.id??"",email:y.customer?.email??""}}function ne(y){return new Promise(v=>setTimeout(v,y))}async function ct(y,v,a){if(!v.trim())throw new F("FloPayPaymentMethodSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!a.trim())throw new F("FloPayPaymentMethodSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let d=await y.getUnifiedCheckoutSession(v,a),f=d.data.session;if(!f||!nt(f))throw new F("FloPayPaymentMethodSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidPaymentMethodSetupSession",param:"sessionId"});let o=We(d);if(!Ne(o)){let{skippedForMissingCurrency:l}=o,x=l.length>0?`FloPay: this setup session advertises only Stripe methods (${l.join(", ")}), and they need the session's currency, which the setup-session read did not carry.`:"FloPay: this setup session advertises no payment method.";throw new F(x,"validation_error",{code:"NoAdvertisedPaymentMethods",param:"sessionId"})}return{session:f,advertisement:o}}async function pt(y,v,a,d,f){let o=v.vault??null;at(o)||(o=await y.getVaultCapture(a,d));let l=st(o,{billingApiUrl:f,sessionId:a,nonce:d});if(!l)throw new F("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});return l}var q=class extends it.Component{constructor(){super(...arguments);this.state={failed:!1}}static getDerivedStateFromError(){return{failed:!0}}componentDidCatch(a){this.props.onFailed(a,{code:"payment_method_setup_load_failed",retryable:!1})}render(){return this.state.failed?null:this.props.children}};function Ut({branches:{StripeSetupMethod:y,PayPalSetupMethod:v},sessionId:a,nonce:d,billingApiUrl:f,telemetry:o,theme:l="modern-light",containerStyle:x,loading:ze=null,onReady:oe,onComplete:se,onDecline:ie,onCancel:le,onValidation:ue,onError:de}){let[j]=b(Le),[I,G]=b(null),[$e,K]=b(!1),[S,ce]=b(null),[_,pe]=b(null),[me,ye]=b(null),[D,p]=b(null),[H,z]=b(()=>new Set),M=u(H),$=u(null);$.current=I;let g=u(!1),J=u(!1),V=u(!1),Q=u(!1),X=u(0),L=u(0),E=u(!1),m=T(()=>typeof l=="object"?void 0:ot(l),[l]),Je=T(()=>typeof l=="object"?l:m?qe({appearance:m.appearance,buttonsStyles:m.buttonsLayout,layout:"default"}):null,[m,l]),Qe=T(()=>Be(m?.buttonsLayout.cardFormContainer,x),[m,x]),fe=T(()=>m?Ae(m):void 0,[m]),s=u({sessionId:a,nonce:d,billingApiUrl:f,telemetry:o,onReady:oe,onComplete:se,onDecline:ie,onCancel:le,onValidation:ue,onError:de});s.current={sessionId:a,nonce:d,billingApiUrl:f,telemetry:o,onReady:oe,onComplete:se,onDecline:ie,onCancel:le,onValidation:ue,onError:de},re(()=>{E.current=!0;let e=X.current+1;return X.current=e,()=>{E.current=!1,L.current+=1,queueMicrotask(()=>{X.current===e&&(V.current||Q.current||(Q.current=!0,C(()=>{s.current.onCancel?.({status:"cancelled",sessionId:a})})))})}},[a]);let U=O((e,t)=>{V.current=!0,g.current=!1,p({status:"success",wording:e,message:null}),(async()=>(await ne(600),!J.current&&(J.current=!0,C(()=>{s.current.onComplete?.({status:"succeeded",sessionId:s.current.sessionId,...t?{paymentMethod:t}:{}})}),E.current&&p(null))))()},[]),k=O((e,t)=>{V.current=!0,g.current=!1,p({status:"error",wording:e,message:t.message??null}),C(()=>{s.current.onDecline?.({status:"declined",sessionId:s.current.sessionId,...t.reason?{reason:t.reason}:{},...t.message?{message:t.message}:{}})}),(async()=>(await ne(400),E.current&&p(null)))()},[]),P=O((e,t)=>{g.current?(g.current=!1,p({status:"error",wording:e,message:t.message}),setTimeout(()=>{E.current&&p(null)},400)):p(null),C(()=>s.current.onError?.(t))},[]),N=O(async e=>{let t=L.current+1;L.current=t;let n=()=>!E.current||t!==L.current;g.current=!0,p({status:"processing",wording:"payment_method",message:null});let i=new Ge(te(s.current.billingApiUrl),{telemetry:s.current.telemetry});try{for(let r=0;r<lt;r+=1){if((r>0||e.waitFirst)&&await ne(ut),n())return;let h=await i.getUnifiedCheckoutSession(s.current.sessionId,s.current.nonce);if(n())return;let R=h.data.session?.status;if(R==="complete"){K(!0),U("payment_method");return}if(R==="expired")throw new F("This setup session expired before the payment method was saved.","validation_error",{code:"payment_method_setup_expired"})}throw new F("The payment method could not be confirmed yet. Please try again.","api_error",{code:"payment_method_setup_unverified"})}catch(r){if(n())return;let h=r instanceof F&&r.code==="payment_method_setup_unverified";P("payment_method",w(r,h?{retryable:!0}:{}))}finally{i.destroy()}},[P,U]);re(()=>{let e=!0,t=te(f),n=new Ge(t,{telemetry:o});G(null),K(!1),ce(null),pe(null),ye(null);let i=new Set;return M.current=i,z(i),V.current=!1,Q.current=!1,J.current=!1,(async()=>{try{let{session:r,advertisement:h}=await ct(n,a,d);if(!e)return;let R={advertisement:h,customer:dt(r),...r.futureUse?{futureUse:r.futureUse}:{},...r.futureUseUnsupported?{futureUseUnsupported:r.futureUseUnsupported}:{}};if(j){if(De(),r.status==="complete"){K(!0),G(R),U("payment_method");return}j.failed?k("payment_method",{reason:"redirect_failed"}):N({waitFirst:!0})}let Ve=h.card?await pt(n,r,a,d,t):null;if(!e)return;G(R),Ve&&(pe(Ve),ce(new rt({sessionId:a,operation:"card_setup",telemetry:o})))}catch(r){if(!e)return;let h=w(r);V.current=!0,ye(h),C(()=>s.current.onError?.(h))}})(),()=>{e=!1,n.destroy()}},[f,d,j,k,U,a,o,N]),re(()=>{if(!S)return;g.current=!1;let e=S.on("submitting",()=>{g.current=!0,p({status:"processing",wording:"card",message:null})}),t=S.on("complete",r=>{U("card",r.paymentMethod)}),n=S.on("decline",r=>{k("card",{...r.declineReason?{reason:r.declineReason}:{},...r.message?{message:r.message}:{}})}),i=S.on("challenge_dismissed",()=>{p(null)});return()=>{e(),t(),n(),i()}},[S,k,U]);let he=O((e,t,n)=>{if(n.retryable){P("payment_method",w(t,n));return}if(M.current.has(e))return;let i=new Set(M.current);i.add(e),M.current=i,z(i);let r=$.current?.advertisement,h=r?ee(r).some(R=>!i.has(R)):!1;P("payment_method",w(t,{code:n.code,retryable:h}))},[P]),ve=T(()=>({onSubmitting:()=>{g.current=!0,p({status:"processing",wording:"payment_method",message:null})},onConfirmed:()=>{N({waitFirst:!1})},onDeclined:e=>k("payment_method",e),onValidation:e=>{C(()=>s.current.onValidation?.(e))},onAbandoned:()=>{g.current=!1,p(null)}}),[k,N]),Se=u(he);Se.current=he;let ge=u(new Map),W=e=>{let t=ge.current.get(e);if(t)return t;let n=(i,r)=>Se.current(e,i,r);return ge.current.set(e,n),n},Ce=O(e=>{if(M.current.has(e))return;let t=new Set(M.current);t.add(e),M.current=t,z(t);let n=$.current?.advertisement;n&&ee(n).some(r=>!t.has(r))||P("payment_method",w(new Error("FloPay: none of the advertised payment methods can be used here."),{code:"payment_method_setup_unavailable",retryable:!1}))},[P]),Pe=u(Ce);Pe.current=Ce;let be=u(new Map),Fe=e=>{let t=be.current.get(e);if(t)return t;let n=()=>Pe.current(e);return be.current.set(e,n),n},Me=D?c(Te,{status:D.status,errorMessage:D.message,...Ye(D.wording),successNote:null,...fe?{theme:fe}:{}}):null;if(me)return c("div",{role:"alert",children:me.message});if(!I||$e)return ae(He,{children:[Me,I?null:ze]});let{advertisement:B,customer:Xe,futureUse:Re,futureUseUnsupported:we}=I,_e=te(f),Ee=o===void 0?{}:{telemetry:o},Z=B.stripe.filter(({method:e})=>!H.has(e)),A=H.has("paypal")?null:B.paypal,Ue=!!(B.card&&S&&_?.html),ke=({method:e,publishableKey:t,currency:n})=>c("div",{"data-flopay-payment-method":e,style:{display:"contents"},children:c(q,{onFailed:W(e),children:c(Ke,{fallback:null,children:c(y,{method:e,category:Y(e),publishableKey:t,currency:n,...Re?{futureUse:Re}:{},...we?{futureUseUnsupported:we}:{},sessionId:a,nonce:d,billingApiUrl:_e,...Ee,...m?{appearance:m.appearance,buttonsLayout:m.buttonsLayout}:{},...typeof l=="string"?{themeId:l}:{},...ve,onFailed:W(e),onUnavailable:Fe(e)})})})},e),Ze=Z.filter(({method:e})=>Y(e)==="wallet"),et=Z.filter(({method:e})=>Y(e)!=="wallet"),Oe=Z.length>0||A!==null;return ae(He,{children:[Me,Oe?ae("div",{"data-flopay-payment-methods":"",style:{position:"relative",display:"flex",flexDirection:"column",gap:"0.5rem"},children:[Ze.map(ke),A?c("div",{"data-flopay-payment-method":"paypal",children:c(q,{onFailed:W("paypal"),children:c(Ke,{fallback:null,children:c(v,{clientId:A.clientId,...A.environment?{environment:A.environment}:{},...B.currency?{currency:B.currency}:{},sessionId:a,nonce:d,billingApiUrl:_e,customer:Xe,...Ee,...ve,onFailed:W("paypal"),onUnavailable:Fe("paypal")})})})}):null,et.map(ke)]}):null,Ue&&Oe?c(Ie,{label:"or add a card"}):null,Ue&&S&&_?.html?c("div",{"data-flopay-payment-method":"card",children:c(xe,{capture:S,html:_.html,messageToken:_.messageToken,expectedOrigin:_.expectedOrigin,verificationRequired:_.verificationRequired,theme:Je,containerStyle:Qe,onReady:()=>{C(()=>s.current.onReady?.())},onValidation:e=>{C(()=>s.current.onValidation?.(e))},onError:e=>{e&&P("card",w(new Error(e),{code:"card_setup_widget_failed",retryable:!0}))}})}):null]})}export{Ut as a};
@@ -0,0 +1,22 @@
1
+ import{a as U,b as N,h as D,j as H,l as X}from"./chunk-VK67324N.mjs";import{PaymentAPI as he}from"@flopay/js/card-setup";import{FloPayError as ge,getStripeMethodDisplayName as Se,resolveSetupFutureUsage as be,toStripeAppearance as ve}from"@flopay/shared";import{Elements as Ee,ExpressCheckoutElement as ke,PaymentElement as xe,useElements as we,useStripe as Pe}from"@stripe/react-stripe-js";import{loadStripe as Re}from"@stripe/stripe-js";import{useCallback as Q,useMemo as _e,useRef as Ce,useState as S}from"react";import{getStripeMethodDisplayName as z,hasVendoredStripeMethodLogo as le,resolveStripeMethodBrandVariant as de,stripeExpressMethodToOptionKey as ce}from"@flopay/shared";import{useState as ue}from"react";var Y={alipay:"https://cdn.flopay.com/sdk-logos/v1/alipay.svg",bancontact:"https://cdn.flopay.com/sdk-logos/v1/bancontact.svg",blik:"https://cdn.flopay.com/sdk-logos/v1/blik.svg",eps:"https://cdn.flopay.com/sdk-logos/v1/eps.svg",giropay:"https://cdn.flopay.com/sdk-logos/v1/giropay.svg",ideal:"https://cdn.flopay.com/sdk-logos/v1/ideal.svg",klarna:"https://cdn.flopay.com/sdk-logos/v1/klarna.svg",p24:"https://cdn.flopay.com/sdk-logos/v1/p24.svg",sepa_debit:"https://cdn.flopay.com/sdk-logos/v1/sepa_debit.svg",wechat_pay:"https://cdn.flopay.com/sdk-logos/v1/wechat_pay.svg"};import{Fragment as fe,jsx as s,jsxs as L}from"react/jsx-runtime";var ye=`
2
+ .paypal-buttons { margin: 0 !important; vertical-align: top !important; }
3
+ @keyframes flopay-spin { to { transform: rotate(360deg); } }
4
+ @keyframes flopay-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }
5
+ @keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
6
+ @keyframes flopay-buttons-enter {
7
+ 0% { opacity: 0; transform: translateX(-16px) scale(0.97); }
8
+ 100% { opacity: 1; transform: translateX(0) scale(1); }
9
+ }
10
+ @keyframes flopay-buttons-exit {
11
+ 0% { opacity: 1; transform: translateX(0) scale(1); }
12
+ 100% { opacity: 0; transform: translateX(-16px) scale(0.97); }
13
+ }
14
+ @keyframes flopay-card-enter {
15
+ 0% { opacity: 0; transform: translateX(16px) scale(0.97); }
16
+ 100% { opacity: 1; transform: translateX(0) scale(1); }
17
+ }
18
+ @keyframes flopay-card-exit {
19
+ 0% { opacity: 1; transform: translateX(0) scale(1); }
20
+ 100% { opacity: 0; transform: translateX(16px) scale(0.97); }
21
+ }
22
+ `,me=44;function K(){return s("style",{children:ye})}function W(e,r){let t=e.availablePaymentMethods;return t&&r.some(o=>t[o])?"ready":"unavailable"}function $({state:e,placeholderTestId:r,borderRadius:t=8,children:o}){return e==="unavailable"||e==="load_error"?null:L("div",{style:{position:"relative",minHeight:44},children:[s("div",{"data-testid":r,"aria-hidden":e==="ready",style:{position:"absolute",inset:0,height:44,borderRadius:t,background:"#e5e7eb",animation:e==="ready"?void 0:"flopay-pulse 1.5s ease-in-out infinite",opacity:e==="ready"?0:1,transform:e==="ready"?"scale(0.985)":"scale(1)",transition:"opacity 140ms ease-out, transform 140ms ease-out",pointerEvents:"none"}}),s("div",{style:{minHeight:44,opacity:e==="ready"?1:0,transform:e==="ready"?"translateY(0)":"translateY(2px)",transition:"opacity 140ms ease-out, transform 140ms ease-out",pointerEvents:e==="ready"?"auto":"none"},children:o})]})}function De(e){return e!=="unavailable"&&e!=="load_error"}function j({method:e,themeId:r,submitting:t=!1,disabled:o=!1,highlighted:l=!1,hasNextStep:d=!1,onClick:i,backgroundColor:f,borderColor:c,textColor:h,borderRadius:g,fontFamily:w}){let u=de(e,r),b=Y[e],[E,v]=ue(!1),y=!!b&&!E,k=u?.backgroundColor??f??"#ffffff",P=u?.borderColor??c??"#d1d5db",R=u?.textColor??h??"#262833";return s("button",{type:"button","data-testid":`flopay-stripe-method-button-${e}`,"data-method":e,onClick:()=>{!t&&!o&&i()},disabled:t||o,"aria-busy":t||void 0,style:{position:"relative",width:"100%",boxSizing:"border-box",height:me,padding:"0 1rem",backgroundColor:k,color:R,border:`1px solid ${P}`,borderRadius:g??8,fontSize:"0.95rem",fontWeight:600,fontFamily:w,cursor:t||o?"not-allowed":"pointer",opacity:o&&!t?.55:1,animation:t?"flopay-pulse 1.5s ease-in-out infinite":void 0,display:"flex",alignItems:"center",justifyContent:"center",gap:8,transition:"transform 0.1s, opacity 140ms ease-out, border-color 140ms ease-out",boxShadow:l?"0 0 0 2px rgba(74, 73, 255, 0.15)":void 0},children:t?s("span",{style:{margin:"0 auto"},children:`Connecting to ${z(e)}\u2026`}):L(fe,{children:[L("span",{style:{display:"inline-flex",alignItems:"center",gap:le(e)?8:0},children:[y?s("img",{src:b,alt:"","aria-hidden":"true",onError:()=>v(!0),loading:"lazy",decoding:"async",width:30,height:20,style:{width:30,height:20,flexShrink:0,borderRadius:3,objectFit:"contain",display:"inline-flex"}}):null,!y&&u?.logoSvg?s("span",{"aria-hidden":"true",style:{width:30,height:20,flexShrink:0,display:"inline-flex",borderRadius:3,overflow:"hidden"},dangerouslySetInnerHTML:{__html:u.logoSvg}}):null,s("span",{children:z(e)})]}),d&&s("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:R,strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{position:"absolute",right:"1rem",top:"50%",transform:"translateY(-50%)",flexShrink:0,opacity:.7},"aria-hidden":"true",children:s("path",{d:"M9 18l6-6-6-6"})})]})})}function G(e){let r=new Set(e.map(ce)),t=o=>o==="applePay"||o==="googlePay"?"always":"auto";return Object.fromEntries(["applePay","googlePay","paypal","link","amazonPay","klarna"].map(o=>[o,r.has(o)?t(o):"never"]))}var V={buttonType:{applePay:"plain",googlePay:"plain"},layout:{maxColumns:1,overflow:"never"}},q={type:"accordion",defaultCollapsed:!1,radios:"never"};function J({testId:e,attributes:r,disabled:t,onClick:o,color:l,borderRadius:d,style:i,children:f}){return s("button",{type:"button","data-testid":e,...r,onClick:o,disabled:t,style:{width:"100%",marginTop:"0.75rem",padding:"0.875rem",backgroundColor:l,color:"white",border:"none",borderRadius:d,fontSize:"1rem",fontWeight:600,cursor:t?"not-allowed":"pointer",opacity:t?.5:1,transition:"opacity 120ms ease-out",...i??{}},children:f})}import{Fragment as ee,jsx as m,jsxs as I}from"react/jsx-runtime";var te={apple_pay:{types:["card"],wallet:"applePay"},google_pay:{types:["card"],wallet:"googlePay"},link:{types:["link"],wallet:"link"},paypal:{types:["paypal"],wallet:"paypal"},amazon_pay:{types:["amazon_pay"],wallet:"amazonPay"}},B=new Map;function Me(e){let r=B.get(e);if(r)return r;let t=Re(e).catch(o=>{throw B.delete(e),o});return B.set(e,t),t}function Te(e){return e?ve(e):void 0}function Le(e){return D(e)||e.code==="setup_intent_authentication_failure"||e.code==="payment_method_provider_decline"}function Z(e){return e==="paypal"?"PayPal":Se(e)}function Be(){return typeof window>"u"?"":window.location.href}var Ie={position:"absolute",width:"100%",height:0,overflow:"hidden",visibility:"hidden",pointerEvents:"none"};function qe(e){let{publishableKey:r,method:t,currency:o,futureUse:l,futureUseUnsupported:d,appearance:i}=e,[f]=S(()=>Me(r)),c=_e(()=>{let h=Te(i),g=be({futureUse:l,futureUseUnsupported:d},t,"setup");return{mode:"setup",currency:o.toLowerCase(),paymentMethodTypes:te[t]?.types??[t],...g?{setupFutureUsage:g}:{},...h?{appearance:h}:{}}},[i,o,l,d,t]);return m(Ee,{stripe:f,options:c,children:m(Ae,{...e})})}function Ae({method:e,category:r,sessionId:t,nonce:o,billingApiUrl:l,telemetry:d,appearance:i,themeId:f,buttonsLayout:c,onSubmitting:h,onConfirmed:g,onDeclined:w,onFailed:u,onValidation:b,onUnavailable:E}){let v=Pe(),y=we(),[k,P]=S(!1),[R,A]=S("loading"),[oe,re]=S(!1),[_,ae]=S(!1),C=Ce(!1),[x]=S(()=>H()),[ne,se]=S(!1),M=Q((a,p)=>{if(N(a,{inAppBrowser:x.inAppBrowser,handoffObserved:!1}).popupBlocked){se(!0),u(new Error(U(Z(e),!0,x.inAppBrowser)),{code:"popup_blocked",retryable:!0});return}u(p.message===void 0?a:new Error(p.message),{code:p.code,retryable:!0})},[x.inAppBrowser,e,u]),F=Q(async()=>{if(!(!v||!y||C.current)){C.current=!0,P(!0);try{let a=await y.submit();if(a.error){b(a.error.message??null);return}h();let p=await new he(l,{telemetry:d}).createSessionIntent(t,o,{provider:"stripe",paymentMethodCategory:r,paymentMethodType:e,paymentMethodId:null,intentKind:"setup"});if(p.provider!=="stripe"||p.intentKind!=="setup")throw new ge("The billing API returned a non-setup intent.","api_error",{code:"InvalidSessionIntentResponse"});let n=await v.confirmSetup({elements:y,clientSecret:p.clientSecret,confirmParams:{return_url:Be()},redirect:"if_required"});if(n.error){Le(n.error)?w({...n.error.decline_code||n.error.code?{reason:n.error.decline_code??n.error.code}:{},...n.error.message?{message:n.error.message}:{}}):M(n.error,{code:"payment_method_setup_provider_failed",message:n.error.message??"The payment method could not be saved."});return}g()}catch(a){M(a,{code:"payment_method_setup_failed"})}finally{C.current=!1,P(!1)}}},[l,r,y,e,o,g,w,h,b,M,t,v,d]),T=te[e]?.wallet,ie=T==="paypal"&&X(x,"auto",ne?"blocked":x.popupCapability)==="redirect",O=i?.variables?.borderRadius??c?.cardButton?.borderRadius??8;if(r==="wallet"&&T&&!ie)return I(ee,{children:[m(K,{}),m($,{state:R,borderRadius:O,children:m(ke,{options:{...V,paymentMethods:G([e])},onReady:a=>{let p=W(a,[T]);A(p),p==="unavailable"&&E()},onLoadError:()=>{A("load_error"),E()},onConfirm:()=>{F()}})})]});let pe=Z(e);return I(ee,{children:[oe?m(j,{method:e,themeId:f,hasNextStep:!0,highlighted:_,disabled:k,onClick:()=>ae(a=>!a),backgroundColor:c?.cardButton?.backgroundColor,borderColor:c?.cardInputBorder,textColor:c?.cardButton?.color,borderRadius:O}):null,I("div",{"data-testid":`flopay-stripe-method-form-${e}`,"aria-hidden":!_,style:_?{display:"flex",flexDirection:"column"}:Ie,children:[m(xe,{options:{layout:q},onReady:()=>re(!0),onLoadError:()=>E(),onChange:a=>{a.complete&&b(null)}}),m(J,{testId:`flopay-payment-method-save-${e}`,attributes:{"data-flopay-payment-method-save":e},disabled:!v||!y||k||!_,onClick:()=>{F()},color:i?.variables?.colorPrimary??"#4A49FF",borderRadius:i?.variables?.borderRadius??"8px",style:c?.submitButton,children:k?"Saving\u2026":`Save ${pe}`})]})]})}export{me as a,K as b,W as c,$ as d,De as e,j as f,G as g,V as h,q as i,J as j,qe as k};
@@ -1 +1 @@
1
- import{a as T,g as A,i as R}from"./chunk-M7R46EDF.mjs";import{PaymentAPI as I}from"@flopay/js/card-setup";import{FloPayError as p,PAYPAL_VAULTED_PAYMENT_METHOD_TYPE as B}from"@flopay/shared";import{loadScript as x}from"@paypal/paypal-js";import{useEffect as D,useRef as C,useState as O}from"react";import{jsx as F}from"react/jsx-runtime";function z({clientId:d,environment:o,currency:s,sessionId:i,nonce:l,billingApiUrl:y,telemetry:f,customer:{userId:m,email:P},onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b}){let w=C(null),t=C({onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b});t.current={onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b};let[c]=O(()=>R().inAppBrowser);return D(()=>{let a=!0,k,u=new I(y,{telemetry:f}),g={userId:m,email:P};return(async()=>{try{let n=await x({clientId:d,...s?{currency:s.toUpperCase()}:{},components:"buttons",...o==="sandbox"||o==="production"?{environment:o}:{}}),M=w.current;if(!a||!M)return;if(!n?.Buttons)throw new p("PayPal could not be loaded.","api_error",{code:"paypal_unavailable"});let E=n.Buttons({createVaultSetupToken:async()=>{t.current.onSubmitting();let e=await u.createSessionIntent(i,l,{provider:"paypal",paymentMethodCategory:"wallet",paymentMethodType:B,paymentMethodId:null,intentKind:"setup"});if(e.provider!=="paypal"||e.providerObjectType!=="setup_token")throw new p("The billing API did not return a PayPal setup token.","api_error",{code:"InvalidSessionIntentResponse"});return e.providerObjectId},onApprove:async e=>{let r=e.vaultSetupToken;if(!r)throw new p("PayPal approved without a setup token.","api_error",{code:"paypal_setup_token_missing"});let S=await u.processPayment(g.userId,{sessionId:i,nonce:l,paymentMethodCategory:"paypal",tokenizedData:{id:r,type:"paypal_setup_token",isPaypal:!0,gateway:"paypal",paymentMethodType:B},accountData:g});if(!S.ok)throw new p("PayPal could not be saved.","api_error",{code:"paypal_setup_failed",statusCode:S.status});a&&t.current.onConfirmed()},onCancel:()=>{a&&t.current.onAbandoned()},onError:e=>{if(!a)return;let{popupBlocked:r}=A(e,{inAppBrowser:c,handoffObserved:!1});t.current.onFailed(r?new Error(T("PayPal",!0,c)):e,{code:r?"popup_blocked":"paypal_setup_failed",retryable:!0})}});k=()=>E.close(),await E.render(M)}catch(n){if(!a)return;t.current.onFailed(n,{code:"paypal_unavailable",retryable:!0})}})(),()=>{a=!1,k?.().catch(()=>{}),u.destroy()}},[y,d,s,P,o,c,l,i,f,m]),F("div",{ref:w,"data-flopay-paypal-setup":""})}export{z as a};
1
+ import{a as T,b as A,j as R}from"./chunk-VK67324N.mjs";import{PaymentAPI as I}from"@flopay/js/card-setup";import{FloPayError as p,PAYPAL_VAULTED_PAYMENT_METHOD_TYPE as B}from"@flopay/shared";import{loadScript as x}from"@paypal/paypal-js";import{useEffect as D,useRef as C,useState as O}from"react";import{jsx as F}from"react/jsx-runtime";function z({clientId:d,environment:o,currency:s,sessionId:i,nonce:l,billingApiUrl:y,telemetry:f,customer:{userId:m,email:P},onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b}){let w=C(null),t=C({onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b});t.current={onSubmitting:h,onConfirmed:_,onFailed:v,onAbandoned:b};let[c]=O(()=>R().inAppBrowser);return D(()=>{let a=!0,k,u=new I(y,{telemetry:f}),g={userId:m,email:P};return(async()=>{try{let n=await x({clientId:d,...s?{currency:s.toUpperCase()}:{},components:"buttons",...o==="sandbox"||o==="production"?{environment:o}:{}}),M=w.current;if(!a||!M)return;if(!n?.Buttons)throw new p("PayPal could not be loaded.","api_error",{code:"paypal_unavailable"});let E=n.Buttons({createVaultSetupToken:async()=>{t.current.onSubmitting();let e=await u.createSessionIntent(i,l,{provider:"paypal",paymentMethodCategory:"wallet",paymentMethodType:B,paymentMethodId:null,intentKind:"setup"});if(e.provider!=="paypal"||e.providerObjectType!=="setup_token")throw new p("The billing API did not return a PayPal setup token.","api_error",{code:"InvalidSessionIntentResponse"});return e.providerObjectId},onApprove:async e=>{let r=e.vaultSetupToken;if(!r)throw new p("PayPal approved without a setup token.","api_error",{code:"paypal_setup_token_missing"});let S=await u.processPayment(g.userId,{sessionId:i,nonce:l,paymentMethodCategory:"paypal",tokenizedData:{id:r,type:"paypal_setup_token",isPaypal:!0,gateway:"paypal",paymentMethodType:B},accountData:g});if(!S.ok)throw new p("PayPal could not be saved.","api_error",{code:"paypal_setup_failed",statusCode:S.status});a&&t.current.onConfirmed()},onCancel:()=>{a&&t.current.onAbandoned()},onError:e=>{if(!a)return;let{popupBlocked:r}=A(e,{inAppBrowser:c,handoffObserved:!1});t.current.onFailed(r?new Error(T("PayPal",!0,c)):e,{code:r?"popup_blocked":"paypal_setup_failed",retryable:!0})}});k=()=>E.close(),await E.render(M)}catch(n){if(!a)return;t.current.onFailed(n,{code:"paypal_unavailable",retryable:!0})}})(),()=>{a=!1,k?.().catch(()=>{}),u.destroy()}},[y,d,s,P,o,c,l,i,f,m]),F("div",{ref:w,"data-flopay-paypal-setup":""})}export{z as a};
@@ -0,0 +1 @@
1
+ import{buildExternalMethodRecoveryMessage as o,classifyExternalMethodFailure as t,EXTERNAL_METHOD_CALLBACK_GRACE_MS as n,getProviderDeclineCode as a,getProviderErrorCode as i,isPayPalAcknowledgementDeadWindow as l,isPopupBlockedError as s,isProviderDecline as P,sanitizeExternalFailureCode as d}from"@flopay/shared";import{detectPayPalEnvironment as E}from"@flopay/shared";import{detectPayPalEnvironment as v}from"@flopay/shared";import{resolvePayPalPresentationMode as f,resolveStripePayPalPresentation as x}from"@flopay/shared";export{o as a,t as b,n as c,a as d,i as e,l as f,s as g,P as h,d as i,v as j,f as k,x as l};
@@ -0,0 +1,6 @@
1
+ import{useEffect as $,useRef as h}from"react";import{mergeCardSetupSurface as se}from"@flopay/shared";var ge=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","scale","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]);function Ce(e){let r=e.replace(/^(Webkit|Moz|ms)(?=[A-Z])/,"");return ge.has(r.charAt(0).toLowerCase()+r.slice(1))}function he(e,r){return typeof r=="number"&&r!==0&&!Ce(e)?`${r}px`:String(r).trim()}function ae(e,r){if(e.style.cssText="",!!r){for(let[t,o]of Object.entries(r))if(!(o==null||o==="")){if(t.startsWith("--")){e.style.setProperty(t,String(o));continue}e.style[t]=he(t,o)}}}import{useEffect as Se,useLayoutEffect as ve}from"react";var ie=typeof window>"u"?Se:ve;import{jsx as H,jsxs as Re}from"react/jsx-runtime";var J=new WeakSet;function le({capture:e,html:r,messageToken:t,expectedOrigin:o,verificationRequired:f,theme:i,submitLabel:v,containerStyle:c,onReady:R,onError:F,onValidation:_}){let E=h(null),M=h(R),w=h(F),V=h(_);M.current=R,w.current=F,V.current=_;let a=h(i);a.current=i;let x=h(null),s=v??void 0,b=h(s);b.current=s;let T=h(void 0);return $(()=>{let y=E.current;if(!y)return;let P=!0,d=!1,Y=()=>{!P||d||(d=!0,M.current?.())},D=e.on("ready",()=>{Y()}),g=e.on("error",m=>{w.current?.(m.message??"There was a problem loading the secure card form.")}),I=e.on("validation",m=>{V.current?.(m.message??null)}),B=b.current??(J.has(e)?null:void 0),G={html:r,...t?{messageToken:t}:{},...o?{expectedOrigin:o}:{},...f?{verificationRequired:!0}:{},...a.current?{theme:a.current}:{},...B===void 0?{}:{submitLabel:B}};return x.current=a.current??null,T.current=b.current,b.current!==void 0&&J.add(e),e.mount(y,G).then(()=>{Y()}).catch(m=>{P&&w.current?.(m instanceof Error?m.message:"Failed to load the secure card form.")}),()=>{P=!1,D(),g(),I(),e.unmount()}},[e,r,t,o,f]),ie(()=>{let y=E.current;y&&ae(y,c)},[c]),$(()=>{i!==void 0&&(i===null&&x.current===null||(x.current=i,e.applyTheme?.(i)))},[e,i]),$(()=>{s!==T.current&&(T.current=s,s!==void 0&&J.add(e),e.setSubmitLabel?.(s??null))},[e,s]),H("div",{ref:E,"data-testid":"flopay-vault-card-fields"})}function We({label:e}){return Re("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem",margin:"0.5rem 0 0.75rem",color:"#999",fontSize:"0.85rem"},children:[H("div",{style:{flex:1,height:1,backgroundColor:"#ddd"}}),H("span",{children:e}),H("div",{style:{flex:1,height:1,backgroundColor:"#ddd"}})]})}import{PaymentAPI as Te,PciVaultCardCapture as Pe}from"@flopay/js/card-setup";import{FloPayError as L,isCardSetupCheckoutSession as ke,isMountableVaultBlock as Oe,resolveBillingApiUrl as Ae,resolveVaultMountOptions as Le}from"@flopay/shared";import{useEffect as K,useMemo as pe,useRef as p,useState as z}from"react";import{computeCardSetupOverlayTheme as be,resolveCardSetupTheme as Ee}from"@flopay/shared";import{mergeButtonsStyles as Xe}from"@flopay/shared";function Ge(e){return be(e)}function ue(e){let{vaultTheme:r,surface:t,overlayTheme:o}=Ee(e);return{vaultTheme:r,surface:t,overlayTheme:o}}import{invokeMerchantCallback as S}from"@flopay/shared";import{jsx as u,jsxs as A}from"react/jsx-runtime";var we={panel:{background:"white"},spinnerTrackColor:"#e5e7eb",spinnerAccentColor:"#4A49FF",labelColors:{processing:"#374151",success:"#16a34a",error:"#dc2626"},noteColor:"#6b7280"};function ce({status:e,errorMessage:r,authorized:t=!1,processingLabel:o="PROCESSING...",successLabel:f,errorLabel:i="PAYMENT FAILED",successNote:v="You will be automatically redirected, do not close or navigate away from this window.",theme:c=we}){let R={fontSize:13,color:c.noteColor,fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0};return u("div",{"data-testid":"flopay-processing-overlay","data-status":e,role:"dialog","aria-modal":"true",style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.35)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3,backdropFilter:"blur(2px)"},children:A("div",{"data-testid":"flopay-processing-overlay-panel",style:{borderRadius:12,boxShadow:"0 8px 32px rgba(0,0,0,0.18)",...c.panel,padding:"2rem 2.5rem",textAlign:"center",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[A("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&A("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{animation:"flopay-spin 0.8s linear infinite"},children:[u("circle",{cx:"12",cy:"12",r:"10",stroke:c.spinnerTrackColor,strokeWidth:"3"}),u("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:c.spinnerAccentColor})]}),e==="success"&&u("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:A("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[u("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),u("path",{d:"M7 12.5l3 3 7-7",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{strokeDasharray:20,strokeDashoffset:20,animation:"flopay-draw 0.4s 0.15s ease forwards"}})]})}),e==="error"&&u("div",{style:{animation:"flopay-shake 0.4s ease"},children:A("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[u("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),u("path",{d:"M8 8l8 8M16 8l-8 8",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",style:{strokeDasharray:12,strokeDashoffset:12,animation:"flopay-draw 0.3s 0.1s ease forwards"}})]})})]}),A("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:c.labelColors[e]},children:[e==="processing"&&o,e==="success"&&(f??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&i]}),e==="success"&&v!==null&&u("p",{style:R,children:v}),e==="error"&&r&&u("p",{style:R,children:r}),u("style",{children:`
2
+ @keyframes flopay-spin { to { transform: rotate(360deg); } }
3
+ @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
4
+ @keyframes flopay-draw { to { stroke-dashoffset: 0; } }
5
+ @keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }
6
+ `})]})})}import{Fragment as me,jsx as q,jsxs as Fe}from"react/jsx-runtime";var Q=class extends L{constructor(r,t,o){super(r,t,o),this.name="FloPayCardSetupError",this.retryable=o.retryable}};function fe(e,r={}){let t=e instanceof L?e:void 0,o=t?.statusCode,f=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof o=="number"&&o>=500||t?.code==="vault_capture_timeout"||!t);return new Q(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:f,...t?.param?{param:t.param}:{},...o===void 0?{}:{statusCode:o}})}function sr({sessionId:e,nonce:r,billingApiUrl:t,telemetry:o,theme:f="modern-light",containerStyle:i,appearance:v,buttonsStyles:c,loading:R=null,onReady:F,onComplete:_,onDecline:E,onCancel:M,onValidation:w,onError:V}){let[a,x]=z(null),[s,b]=z(null),[T,y]=z(null),[P,d]=z(null),[Y,D]=z(null),g=p(!1),I=p(!1),{vaultTheme:B,surface:G,overlayTheme:m}=pe(()=>ue({theme:f,appearance:v,buttonsStyles:c}),[f,v,c]),ye=pe(()=>se(G,i),[G,i]),ee=p(F),X=p(V),re=p(_),te=p(E),oe=p(M),ne=p(w),N=p(!1),j=p(!1),Z=p(0);return ee.current=F,X.current=V,re.current=_,te.current=E,oe.current=M,ne.current=w,K(()=>{let n=Z.current+1;return Z.current=n,()=>{queueMicrotask(()=>{Z.current===n&&(N.current||j.current||(j.current=!0,S(()=>{oe.current?.({status:"cancelled",sessionId:e})})))})}},[e]),K(()=>{let n=!0,k=Ae(t),U=new Te(k,{telemetry:o});return x(null),b(null),y(null),N.current=!1,j.current=!1,(async()=>{try{if(!e.trim())throw new L("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new L("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let W=await U.getUnifiedCheckoutSession(e,r);if(!n)return;let C=W.data.session;if(!C||!ke(C))throw new L("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let l=C.vault;Oe(l)||(l=await U.getVaultCapture(e,r));let O=Le(l,{billingApiUrl:k,sessionId:e,nonce:r});if(!O)throw new L("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!n)return;b(O),x(new Pe({sessionId:e,operation:"card_setup",telemetry:o}))}catch(W){if(!n)return;let C=fe(W);N.current=!0,y(C),S(()=>X.current?.(C))}})(),()=>{n=!1,U.destroy()}},[t,r,e,o]),K(()=>{if(!a)return;let n=!1;I.current=!1,g.current=!1;let k=a.on("submitting",()=>{g.current=!0,D(null),d("processing")}),U=a.on("complete",l=>{N.current=!0,g.current=!1,d("success"),(async()=>(await new Promise(O=>setTimeout(O,600)),!I.current&&(I.current=!0,S(()=>{re.current?.({status:"succeeded",sessionId:e,...l.paymentMethod?{paymentMethod:l.paymentMethod}:{}})}),n||d(null))))()}),W=a.on("decline",l=>{N.current=!0,g.current=!1,D(l.message??null),d("error"),S(()=>{te.current?.({status:"declined",sessionId:e,...l.declineReason?{reason:l.declineReason}:{},...l.message?{message:l.message}:{}})}),(async()=>(await new Promise(O=>setTimeout(O,400)),n||d(null)))()}),C=a.on("challenge_dismissed",()=>{d(null)});return()=>{n=!0,k(),U(),W(),C()}},[a,e]),T?q("div",{role:"alert",children:T.message}):!a||!s?.html?q(me,{children:R}):Fe(me,{children:[P&&q(ce,{status:P,errorMessage:Y,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...m?{theme:m}:{}}),q(le,{capture:a,html:s.html,messageToken:s.messageToken,expectedOrigin:s.expectedOrigin,verificationRequired:s.verificationRequired,theme:B,containerStyle:ye,onReady:()=>{S(()=>ee.current?.())},onValidation:n=>{S(()=>ne.current?.(n))},onError:n=>{if(!n)return;g.current&&(g.current=!1,D(n),d("error"),setTimeout(()=>d(null),400));let k=fe(new Error(n),{code:"card_setup_widget_failed",retryable:!0});S(()=>X.current?.(k))}})]})}export{se as a,Ge as b,S as c,ce as d,ie as e,le as f,We as g,Q as h,fe as i,sr as j};