@flopay/react 1.4.23 → 1.4.24

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
@@ -134,6 +134,18 @@ card, then ask your server to delete the old card. `FloPayCardSetup` deliberatel
134
134
  has no customer-id, merchant-credential, list, delete, purchase, or Stripe
135
135
  Elements prop.
136
136
 
137
+ Prefer importing it from the dedicated subpath on pages that never run a
138
+ checkout:
139
+
140
+ ```tsx
141
+ import { FloPayCardSetup } from '@flopay/react/card-setup';
142
+ ```
143
+
144
+ The main entry re-exports the component for back-compat, but its module graph
145
+ eagerly loads Stripe.js (a deliberate checkout preload); the `card-setup`
146
+ entry's graph never reaches Stripe, so saved-card pages stay free of Stripe
147
+ network activity by construction.
148
+
137
149
  #### Expired Sessions
138
150
 
139
151
  When `FloPayCheckout` or `FloPayAutomaticPaymentButton` loads a checkout session whose `status` is `expired`, the component calls `onError` with a `FloPayError` so your app can route the customer into a recovery flow.
@@ -0,0 +1,6 @@
1
+ "use strict";var H=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var ie=Object.prototype.hasOwnProperty;var le=(e,t)=>{for(var o in t)H(e,o,{get:t[o],enumerable:!0})},ce=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of se(t))!ie.call(e,r)&&r!==o&&H(e,r,{get:()=>t[r],enumerable:!(n=ae(t,r))||n.enumerable});return e};var ue=e=>ce(H({},"__esModule",{value:!0}),e);var fe={};le(fe,{FloPayCardSetup:()=>oe,FloPayCardSetupError:()=>D});module.exports=ue(fe);var a=require("react"),I=require("@flopay/js/card-setup"),c=require("@flopay/shared");var S=require("react"),Q=require("react/jsx-runtime");function K({capture:e,html:t,messageToken:o,expectedOrigin:n,theme:r,containerStyle:m,onReady:u,onError:y,onValidation:g}){let C=(0,S.useRef)(null),x=(0,S.useRef)(u),w=(0,S.useRef)(y),k=(0,S.useRef)(g);x.current=u,w.current=y,k.current=g;let d=(0,S.useRef)(r);return d.current=r,(0,S.useEffect)(()=>{let F=C.current;if(!F)return;let v=!0,A=!1,V=()=>{!v||A||(A=!0,x.current?.())},L=e.on("ready",()=>{V()}),O=e.on("error",p=>{w.current?.(p.message??"There was a problem loading the secure card form.")}),h=e.on("validation",p=>{k.current?.(p.message??null)}),B={html:t,...o?{messageToken:o}:{},...n?{expectedOrigin:n}:{},...d.current?{theme:d.current}:{}};return e.mount(F,B).then(()=>{V()}).catch(p=>{v&&w.current?.(p instanceof Error?p.message:"Failed to load the secure card form.")}),()=>{v=!1,L(),O(),h(),e.unmount()}},[e,t,o,n]),(0,S.useEffect)(()=>{r&&e.applyTheme?.(r)},[e,r]),(0,Q.jsx)("div",{ref:C,"data-testid":"flopay-vault-card-fields",style:m})}function R(e){if(!e)return;let t=o=>{console.error("[FloPay] Merchant callback failed; checkout continued.",o)};try{Promise.resolve(e()).catch(t)}catch(o){t(o)}}var ve=require("react"),i=require("react/jsx-runtime"),Z=1200,G=1500;function ee({status:e,errorMessage:t,authorized:o=!1,processingLabel:n="PROCESSING...",successLabel:r,errorLabel:m="PAYMENT FAILED",successNote:u="You will be automatically redirected, do not close or navigate away from this window."}){return(0,i.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,i.jsxs)("div",{style:{background:"white",borderRadius:12,padding:"2rem 2.5rem",textAlign:"center",boxShadow:"0 8px 32px rgba(0,0,0,0.18)",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[(0,i.jsxs)("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&(0,i.jsxs)("svg",{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,i.jsx)("circle",{cx:"12",cy:"12",r:"10",stroke:"#e5e7eb",strokeWidth:"3"}),(0,i.jsx)("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:"#4A49FF"})]}),e==="success"&&(0,i.jsx)("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:(0,i.jsxs)("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,i.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),(0,i.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,i.jsx)("div",{style:{animation:"flopay-shake 0.4s ease"},children:(0,i.jsxs)("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,i.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),(0,i.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,i.jsxs)("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:e==="success"?"#16a34a":e==="error"?"#dc2626":"#374151"},children:[e==="processing"&&n,e==="success"&&(r??(o?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&m]}),e==="success"&&u!==null&&(0,i.jsx)("p",{style:{fontSize:13,color:"#6b7280",fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0},children:u}),e==="error"&&t&&(0,i.jsx)("p",{style:{fontSize:13,color:"#6b7280",fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0},children:t}),(0,i.jsx)("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
+ `})]})})}function de(e,t=.12){let o=/^#?([0-9a-fA-F]{6})$/.exec(e.trim());if(!o)return e;let n=parseInt(o[1],16),r=Math.max(0,Math.min(1,1-t)),m=Math.round((n>>16&255)*r),u=Math.round((n>>8&255)*r),y=Math.round((n&255)*r);return`#${(1<<24|m<<16|u<<8|y).toString(16).slice(1)}`}function pe(e){if(typeof e=="number"||typeof e=="string")return e}function re({appearance:e,buttonsStyles:t,layout:o="default"}){let n=e?.variables,r=C=>typeof C=="string"&&C?C:void 0,m=t.submitButton,u=r(n?.colorPrimary)??r(m?.backgroundColor)??"#4A49FF",y=o==="buttons",g=t.nameInput;return{primaryColor:u,primaryHoverColor:r(n?.colorPrimaryHover)??de(u,.12),inputBackgroundColor:r(t.cardInputBackground)??r(n?.colorBackground)??"#ffffff",textColor:r(t.cardInputColor)??r(g?.color)??r(n?.colorText)??"#262833",borderColor:r(t.cardInputBorder)??(y?"#e5e7eb":"#A4A4FF"),placeholderColor:r(t.cardInputPlaceholderColor)??"#9ca3af",errorColor:r(n?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:r(g?.fontFamily)??r(n?.fontFamily)??"Poppins, sans-serif",fontSize:r(t.cardInputFontSize)??r(n?.fontSizeBase)??"16px",fontWeight:String(pe(g?.fontWeight)??400),borderRadius:r(n?.borderRadius)??"8px"}}var f=require("react/jsx-runtime"),D=class extends c.FloPayError{constructor(t,o,n){super(t,o,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function te(e,t={}){let o=e instanceof c.FloPayError?e:void 0,n=o?.statusCode,r=t.retryable??(o?.type==="network_error"||o?.type==="rate_limit_error"||typeof n=="number"&&n>=500||o?.code==="vault_capture_timeout"||!o);return new D(o?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),o?.type??"api_error",{code:t.code??o?.code??"card_setup_load_failed",retryable:r,...o?.param?{param:o.param}:{},...n!==void 0?{statusCode:n}:{}})}function oe({sessionId:e,nonce:t,billingApiUrl:o,telemetry:n,theme:r="modern-light",containerStyle:m,loading:u=null,onReady:y,onComplete:g,onDecline:C,onCancel:x,onValidation:w,onError:k}){let[d,F]=(0,a.useState)(null),[v,A]=(0,a.useState)(null),[V,L]=(0,a.useState)(null),[O,h]=(0,a.useState)(null),[B,p]=(0,a.useState)(null),P=(0,a.useRef)(!1),N=(0,a.useRef)(!1),ne=(0,a.useMemo)(()=>{if(typeof r=="object")return r;let s=(0,c.resolveTheme)(r);if(s)return re({appearance:s.appearance,buttonsStyles:s.buttonsLayout,layout:"default"})},[r]),q=(0,a.useRef)(y),W=(0,a.useRef)(k),X=(0,a.useRef)(g),$=(0,a.useRef)(C),j=(0,a.useRef)(x),J=(0,a.useRef)(w),_=(0,a.useRef)(!1),Y=(0,a.useRef)(!1),z=(0,a.useRef)(0);return q.current=y,W.current=k,X.current=g,$.current=C,j.current=x,J.current=w,(0,a.useEffect)(()=>{let s=z.current+1;return z.current=s,()=>{queueMicrotask(()=>{z.current===s&&(_.current||Y.current||(Y.current=!0,R(()=>{j.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,a.useEffect)(()=>{let s=!0,b=new I.PaymentAPI((0,c.resolveBillingApiUrl)(o),{telemetry:n});return F(null),A(null),L(null),_.current=!1,Y.current=!1,(async()=>{try{if(!e.trim())throw new c.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!t.trim())throw new c.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let M=await b.getUnifiedCheckoutSession(e,t);if(!s)return;let E=M.data.session;if(!E||!(0,c.isCardSetupCheckoutSession)(E))throw new c.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let l=E.vault;if(l?.html?.trim()||(l=await b.getVaultCapture(e,t)),!l.html?.trim())throw new c.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!s)return;A(l),F(new I.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:n}))}catch(M){if(!s)return;let E=te(M);_.current=!0,L(E),R(()=>W.current?.(E))}})(),()=>{s=!1,b.destroy()}},[o,t,e,n]),(0,a.useEffect)(()=>{if(!d)return;let s=!1;N.current=!1,P.current=!1;let b=d.on("submitting",()=>{P.current=!0,p(null),h("processing")}),M=d.on("complete",l=>{_.current=!0,P.current=!1,h("success"),(async()=>(await new Promise(U=>setTimeout(U,Z)),!N.current&&(N.current=!0,R(()=>{X.current?.({status:"succeeded",sessionId:e,...l.paymentMethod?{paymentMethod:l.paymentMethod}:{}})}),s||h(null))))()}),E=d.on("decline",l=>{_.current=!0,P.current=!1,p(l.message??null),h("error"),R(()=>{$.current?.({status:"declined",sessionId:e,...l.declineReason?{reason:l.declineReason}:{},...l.message?{message:l.message}:{}})}),(async()=>(await new Promise(U=>setTimeout(U,G)),s||h(null)))()});return()=>{s=!0,b(),M(),E()}},[d,e]),V?(0,f.jsx)("div",{role:"alert",children:V.message}):!d||!v?.html?(0,f.jsx)(f.Fragment,{children:u}):(0,f.jsxs)(f.Fragment,{children:[O&&(0,f.jsx)(ee,{status:O,errorMessage:B,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),(0,f.jsx)(K,{capture:d,html:v.html,messageToken:v.messageToken,expectedOrigin:v.expectedOrigin,theme:ne,containerStyle:m,onReady:()=>{R(()=>q.current?.())},onValidation:s=>{R(()=>J.current?.(s))},onError:s=>{if(!s)return;P.current&&(P.current=!1,p(s),h("error"),setTimeout(()=>h(null),G));let b=te(new Error(s),{code:"card_setup_widget_failed",retryable:!0});R(()=>W.current?.(b))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { ThemeId, VaultCardThemeColors, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
3
+
4
+ /** Verified terminal result from a no-charge card setup. */
5
+ interface FloPayCardSetupCompleteEvent {
6
+ status: 'succeeded';
7
+ sessionId: string;
8
+ /** Present when the backend terminal message includes the saved-card display DTO. */
9
+ paymentMethod?: SavedCardDisplay;
10
+ }
11
+ /** Provider-neutral terminal decline from card verification. */
12
+ interface FloPayCardSetupDeclineEvent {
13
+ status: 'declined';
14
+ sessionId: string;
15
+ reason?: string;
16
+ message?: string;
17
+ }
18
+ /** Abandoned setup result emitted when the component unmounts pre-terminally. */
19
+ interface FloPayCardSetupCancelEvent {
20
+ status: 'cancelled';
21
+ sessionId: string;
22
+ }
23
+ /** Structured technical/validation failure from the card-setup surface. */
24
+ declare class FloPayCardSetupError extends FloPayError {
25
+ readonly retryable: boolean;
26
+ constructor(message: string, type: FloPayErrorType, options: {
27
+ code: string;
28
+ retryable: boolean;
29
+ param?: string;
30
+ statusCode?: number;
31
+ });
32
+ }
33
+ /** Props for the browser-only secure card-setup surface. */
34
+ interface FloPayCardSetupProps {
35
+ /** Opaque id returned by the merchant-authenticated setup-session endpoint. */
36
+ sessionId: string;
37
+ /** Session-bound token returned alongside {@link FloPayCardSetupProps.sessionId}. */
38
+ nonce: string;
39
+ /** Billing API base URL. Defaults to the configured FloPay environment URL. */
40
+ billingApiUrl?: string;
41
+ /** Flo-owned privacy-safe telemetry is enabled by default; set false to opt out. */
42
+ telemetry?: boolean;
43
+ /**
44
+ * Theme for FloPay's hosted, PCI-compliant card widget. Accepts the same
45
+ * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
46
+ * bundle, so one value styles both surfaces identically) or raw
47
+ * {@link VaultCardThemeColors} for full manual control. Defaults to
48
+ * `'modern-light'`; pass `'classic'` for the historic FloPay look.
49
+ */
50
+ theme?: ThemeId | VaultCardThemeColors;
51
+ /** Inline styles for the hosted-widget container. */
52
+ containerStyle?: React.CSSProperties;
53
+ /** Optional content shown while the session and hosted widget are loading. */
54
+ loading?: React.ReactNode;
55
+ /** Fired once the hosted widget has mounted and can accept card input. */
56
+ onReady?: () => void;
57
+ /** Fired only after the backend reports that the card is verified and usable. */
58
+ onComplete?: (event: FloPayCardSetupCompleteEvent) => void;
59
+ /** Fired when verification terminally declines; never paired with `onComplete`. */
60
+ onDecline?: (event: FloPayCardSetupDeclineEvent) => void;
61
+ /** Fired exactly once if the setup surface unmounts before a terminal outcome. */
62
+ onCancel?: (event: FloPayCardSetupCancelEvent) => void;
63
+ /** Live hosted-field validation message, or `null` when validation clears. */
64
+ onValidation?: (message: string | null) => void;
65
+ /** Fired for setup-session validation, transport, or hosted-widget failures. */
66
+ onError?: (error: FloPayCardSetupError) => void;
67
+ }
68
+ /**
69
+ * Mounts FloPay's hosted card capture for a setup session created by the
70
+ * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
71
+ * Elements surface.
72
+ */
73
+ declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
74
+
75
+ export { FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps };
@@ -0,0 +1,75 @@
1
+ import React from 'react';
2
+ import { ThemeId, VaultCardThemeColors, SavedCardDisplay, FloPayError, FloPayErrorType } from '@flopay/shared';
3
+
4
+ /** Verified terminal result from a no-charge card setup. */
5
+ interface FloPayCardSetupCompleteEvent {
6
+ status: 'succeeded';
7
+ sessionId: string;
8
+ /** Present when the backend terminal message includes the saved-card display DTO. */
9
+ paymentMethod?: SavedCardDisplay;
10
+ }
11
+ /** Provider-neutral terminal decline from card verification. */
12
+ interface FloPayCardSetupDeclineEvent {
13
+ status: 'declined';
14
+ sessionId: string;
15
+ reason?: string;
16
+ message?: string;
17
+ }
18
+ /** Abandoned setup result emitted when the component unmounts pre-terminally. */
19
+ interface FloPayCardSetupCancelEvent {
20
+ status: 'cancelled';
21
+ sessionId: string;
22
+ }
23
+ /** Structured technical/validation failure from the card-setup surface. */
24
+ declare class FloPayCardSetupError extends FloPayError {
25
+ readonly retryable: boolean;
26
+ constructor(message: string, type: FloPayErrorType, options: {
27
+ code: string;
28
+ retryable: boolean;
29
+ param?: string;
30
+ statusCode?: number;
31
+ });
32
+ }
33
+ /** Props for the browser-only secure card-setup surface. */
34
+ interface FloPayCardSetupProps {
35
+ /** Opaque id returned by the merchant-authenticated setup-session endpoint. */
36
+ sessionId: string;
37
+ /** Session-bound token returned alongside {@link FloPayCardSetupProps.sessionId}. */
38
+ nonce: string;
39
+ /** Billing API base URL. Defaults to the configured FloPay environment URL. */
40
+ billingApiUrl?: string;
41
+ /** Flo-owned privacy-safe telemetry is enabled by default; set false to opt out. */
42
+ telemetry?: boolean;
43
+ /**
44
+ * Theme for FloPay's hosted, PCI-compliant card widget. Accepts the same
45
+ * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
46
+ * bundle, so one value styles both surfaces identically) or raw
47
+ * {@link VaultCardThemeColors} for full manual control. Defaults to
48
+ * `'modern-light'`; pass `'classic'` for the historic FloPay look.
49
+ */
50
+ theme?: ThemeId | VaultCardThemeColors;
51
+ /** Inline styles for the hosted-widget container. */
52
+ containerStyle?: React.CSSProperties;
53
+ /** Optional content shown while the session and hosted widget are loading. */
54
+ loading?: React.ReactNode;
55
+ /** Fired once the hosted widget has mounted and can accept card input. */
56
+ onReady?: () => void;
57
+ /** Fired only after the backend reports that the card is verified and usable. */
58
+ onComplete?: (event: FloPayCardSetupCompleteEvent) => void;
59
+ /** Fired when verification terminally declines; never paired with `onComplete`. */
60
+ onDecline?: (event: FloPayCardSetupDeclineEvent) => void;
61
+ /** Fired exactly once if the setup surface unmounts before a terminal outcome. */
62
+ onCancel?: (event: FloPayCardSetupCancelEvent) => void;
63
+ /** Live hosted-field validation message, or `null` when validation clears. */
64
+ onValidation?: (message: string | null) => void;
65
+ /** Fired for setup-session validation, transport, or hosted-widget failures. */
66
+ onError?: (error: FloPayCardSetupError) => void;
67
+ }
68
+ /**
69
+ * Mounts FloPay's hosted card capture for a setup session created by the
70
+ * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
71
+ * Elements surface.
72
+ */
73
+ declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
74
+
75
+ export { FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps };
@@ -0,0 +1 @@
1
+ import{i as e,j as t}from"./chunk-P5QXEIBB.mjs";export{t as FloPayCardSetup,e as FloPayCardSetupError};
@@ -0,0 +1,6 @@
1
+ import{useEffect as Z,useRef as M}from"react";import{jsx as ie}from"react/jsx-runtime";function ee({capture:e,html:n,messageToken:t,expectedOrigin:o,theme:r,containerStyle:f,onReady:i,onError:p,onValidation:m}){let y=M(null),k=M(i),R=M(p),x=M(m);k.current=i,R.current=p,x.current=m;let c=M(r);return c.current=r,Z(()=>{let P=y.current;if(!P)return;let h=!0,F=!1,A=()=>{!h||F||(F=!0,k.current?.())},L=e.on("ready",()=>{A()}),D=e.on("error",d=>{R.current?.(d.message??"There was a problem loading the secure card form.")}),g=e.on("validation",d=>{x.current?.(d.message??null)}),N={html:n,...t?{messageToken:t}:{},...o?{expectedOrigin:o}:{},...c.current?{theme:c.current}:{}};return e.mount(P,N).then(()=>{A()}).catch(d=>{h&&R.current?.(d instanceof Error?d.message:"Failed to load the secure card form.")}),()=>{h=!1,L(),D(),g(),e.unmount()}},[e,n,t,o]),Z(()=>{r&&e.applyTheme?.(r)},[e,r]),ie("div",{ref:y,"data-testid":"flopay-vault-card-fields",style:f})}import{useEffect as q,useMemo as ue,useRef as u,useState as T}from"react";import{PaymentAPI as de,PciVaultCardCapture as fe}from"@flopay/js/card-setup";import{FloPayError as E,isCardSetupCheckoutSession as pe,resolveBillingApiUrl as me,resolveTheme as ye}from"@flopay/shared";function S(e){if(!e)return;let n=t=>{console.error("[FloPay] Merchant callback failed; checkout continued.",t)};try{Promise.resolve(e()).catch(n)}catch(t){n(t)}}import"react";import{jsx as l,jsxs as w}from"react/jsx-runtime";var re=1200,G=1500;function te({status:e,errorMessage:n,authorized:t=!1,processingLabel:o="PROCESSING...",successLabel:r,errorLabel:f="PAYMENT FAILED",successNote:i="You will be automatically redirected, do not close or navigate away from this window."}){return l("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:w("div",{style:{background:"white",borderRadius:12,padding:"2rem 2.5rem",textAlign:"center",boxShadow:"0 8px 32px rgba(0,0,0,0.18)",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[w("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&w("svg",{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:[l("circle",{cx:"12",cy:"12",r:"10",stroke:"#e5e7eb",strokeWidth:"3"}),l("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:"#4A49FF"})]}),e==="success"&&l("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:w("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[l("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),l("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"&&l("div",{style:{animation:"flopay-shake 0.4s ease"},children:w("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[l("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),l("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"}})]})})]}),w("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:e==="success"?"#16a34a":e==="error"?"#dc2626":"#374151"},children:[e==="processing"&&o,e==="success"&&(r??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&f]}),e==="success"&&i!==null&&l("p",{style:{fontSize:13,color:"#6b7280",fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0},children:i}),e==="error"&&n&&l("p",{style:{fontSize:13,color:"#6b7280",fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0},children:n}),l("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
+ `})]})})}function le(e,n=.12){let t=/^#?([0-9a-fA-F]{6})$/.exec(e.trim());if(!t)return e;let o=parseInt(t[1],16),r=Math.max(0,Math.min(1,1-n)),f=Math.round((o>>16&255)*r),i=Math.round((o>>8&255)*r),p=Math.round((o&255)*r);return`#${(1<<24|f<<16|i<<8|p).toString(16).slice(1)}`}function ce(e){if(typeof e=="number"||typeof e=="string")return e}function oe({appearance:e,buttonsStyles:n,layout:t="default"}){let o=e?.variables,r=y=>typeof y=="string"&&y?y:void 0,f=n.submitButton,i=r(o?.colorPrimary)??r(f?.backgroundColor)??"#4A49FF",p=t==="buttons",m=n.nameInput;return{primaryColor:i,primaryHoverColor:r(o?.colorPrimaryHover)??le(i,.12),inputBackgroundColor:r(n.cardInputBackground)??r(o?.colorBackground)??"#ffffff",textColor:r(n.cardInputColor)??r(m?.color)??r(o?.colorText)??"#262833",borderColor:r(n.cardInputBorder)??(p?"#e5e7eb":"#A4A4FF"),placeholderColor:r(n.cardInputPlaceholderColor)??"#9ca3af",errorColor:r(o?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:r(m?.fontFamily)??r(o?.fontFamily)??"Poppins, sans-serif",fontSize:r(n.cardInputFontSize)??r(o?.fontSizeBase)??"16px",fontWeight:String(ce(m?.fontWeight)??400),borderRadius:r(o?.borderRadius)??"8px"}}import{Fragment as ae,jsx as B,jsxs as ge}from"react/jsx-runtime";var X=class extends E{constructor(n,t,o){super(n,t,o),this.name="FloPayCardSetupError",this.retryable=o.retryable}};function ne(e,n={}){let t=e instanceof E?e:void 0,o=t?.statusCode,r=n.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof o=="number"&&o>=500||t?.code==="vault_capture_timeout"||!t);return new X(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:n.code??t?.code??"card_setup_load_failed",retryable:r,...t?.param?{param:t.param}:{},...o!==void 0?{statusCode:o}:{}})}function Ne({sessionId:e,nonce:n,billingApiUrl:t,telemetry:o,theme:r="modern-light",containerStyle:f,loading:i=null,onReady:p,onComplete:m,onDecline:y,onCancel:k,onValidation:R,onError:x}){let[c,P]=T(null),[h,F]=T(null),[A,L]=T(null),[D,g]=T(null),[N,d]=T(null),b=u(!1),W=u(!1),se=ue(()=>{if(typeof r=="object")return r;let a=ye(r);if(a)return oe({appearance:a.appearance,buttonsStyles:a.buttonsLayout,layout:"default"})},[r]),$=u(p),Y=u(x),j=u(m),J=u(y),K=u(k),Q=u(R),V=u(!1),z=u(!1),U=u(0);return $.current=p,Y.current=x,j.current=m,J.current=y,K.current=k,Q.current=R,q(()=>{let a=U.current+1;return U.current=a,()=>{queueMicrotask(()=>{U.current===a&&(V.current||z.current||(z.current=!0,S(()=>{K.current?.({status:"cancelled",sessionId:e})})))})}},[e]),q(()=>{let a=!0,v=new de(me(t),{telemetry:o});return P(null),F(null),L(null),V.current=!1,z.current=!1,(async()=>{try{if(!e.trim())throw new E("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!n.trim())throw new E("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let _=await v.getUnifiedCheckoutSession(e,n);if(!a)return;let C=_.data.session;if(!C||!pe(C))throw new E("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let s=C.vault;if(s?.html?.trim()||(s=await v.getVaultCapture(e,n)),!s.html?.trim())throw new E("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!a)return;F(s),P(new fe({sessionId:e,operation:"card_setup",telemetry:o}))}catch(_){if(!a)return;let C=ne(_);V.current=!0,L(C),S(()=>Y.current?.(C))}})(),()=>{a=!1,v.destroy()}},[t,n,e,o]),q(()=>{if(!c)return;let a=!1;W.current=!1,b.current=!1;let v=c.on("submitting",()=>{b.current=!0,d(null),g("processing")}),_=c.on("complete",s=>{V.current=!0,b.current=!1,g("success"),(async()=>(await new Promise(H=>setTimeout(H,re)),!W.current&&(W.current=!0,S(()=>{j.current?.({status:"succeeded",sessionId:e,...s.paymentMethod?{paymentMethod:s.paymentMethod}:{}})}),a||g(null))))()}),C=c.on("decline",s=>{V.current=!0,b.current=!1,d(s.message??null),g("error"),S(()=>{J.current?.({status:"declined",sessionId:e,...s.declineReason?{reason:s.declineReason}:{},...s.message?{message:s.message}:{}})}),(async()=>(await new Promise(H=>setTimeout(H,G)),a||g(null)))()});return()=>{a=!0,v(),_(),C()}},[c,e]),A?B("div",{role:"alert",children:A.message}):!c||!h?.html?B(ae,{children:i}):ge(ae,{children:[D&&B(te,{status:D,errorMessage:N,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),B(ee,{capture:c,html:h.html,messageToken:h.messageToken,expectedOrigin:h.expectedOrigin,theme:se,containerStyle:f,onReady:()=>{S(()=>$.current?.())},onValidation:a=>{S(()=>Q.current?.(a))},onError:a=>{if(!a)return;b.current&&(b.current=!1,d(a),g("error"),setTimeout(()=>g(null),G));let v=ne(new Error(a),{code:"card_setup_widget_failed",retryable:!0});S(()=>Y.current?.(v))}})]})}export{ee as a,S as b,re as c,G as d,te as e,le as f,ce as g,oe as h,X as i,Ne as j};
package/dist/index.cjs CHANGED
@@ -44,4 +44,4 @@ ${Ze.join(`
44
44
  40% { opacity: 1; }
45
45
  100% { opacity: 1; max-height: 600px; transform: translateY(0); }
46
46
  }
47
- `})]})}return(0,k.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[t&&I(vr),n&&(i||r)&&I(vr),n&&(0,k.jsx)("button",{type:"button",onClick:()=>{e?.("card"),S(!0)},style:{width:"100%",...x,backgroundColor:"white",color:"#262833",border:"1px solid #d1d5db",borderRadius:"8px",fontSize:p.cardButtonFontSize??"0.95rem",fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"0.625rem",boxShadow:"0 1px 2px rgba(0,0,0,0.04)",transition:"transform 0.1s",position:"relative",opacity:1,...p.cardButton},onMouseDown:g=>{g.currentTarget.style.transform="scale(0.985)"},onMouseUp:g=>{g.currentTarget.style.transform="scale(1)"},children:(0,k.jsx)(lr,{content:v})}),(0,k.jsx)("style",{children:"@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }"})]})}var Ai=require("@flopay/shared");var rr=require("react");var ki=require("react/jsx-runtime");function Ci(e,t){function n({className:i,id:r,style:s,options:u,onChange:d,onReady:v,onFocus:A,onBlur:h,onEscape:E}){let S=(0,rr.useRef)(null),_=(0,rr.useRef)(null),{elements:p,reportInteractive:P}=(0,rr.useContext)(Mn);return(0,rr.useEffect)(()=>{if(!p||!S.current)return;let I=!0;return(async()=>{let x=p.getElement(e);x||(x=await p.create(e,u)),!(!I||!S.current)&&(x.mount(S.current),_.current=x,d&&x.on("change",d),x.on("ready",()=>{P?.(),v?.()}),A&&x.on("focus",A),h&&x.on("blur",h),E&&x.on("escape",E))})(),()=>{if(I=!1,_.current){try{_.current.unmount()}catch{}_.current=null}}},[p,P]),(0,ki.jsx)("div",{ref:S,className:i,id:r,style:s})}return n.displayName=t,n}var Si=Ci("payment","PaymentElement"),wi=Ci("address","AddressElement");var it=require("react"),Ro=require("@flopay/js"),Gt=require("@flopay/shared");var En=require("react/jsx-runtime"),Vr=class extends Gt.FloPayError{constructor(t,n,i){super(t,n,i),this.name="FloPayCardSetupError",this.retryable=i.retryable}};function Ri(e,t={}){let n=e instanceof Gt.FloPayError?e:void 0,i=n?.statusCode,r=t.retryable??(n?.type==="network_error"||n?.type==="rate_limit_error"||typeof i=="number"&&i>=500||n?.code==="vault_capture_timeout"||!n);return new Vr(n?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),n?.type??"api_error",{code:t.code??n?.code??"card_setup_load_failed",retryable:r,...n?.param?{param:n.param}:{},...i!==void 0?{statusCode:i}:{}})}function Ei({sessionId:e,nonce:t,billingApiUrl:n,telemetry:i,theme:r="modern-light",containerStyle:s,loading:u=null,onReady:d,onComplete:v,onDecline:A,onCancel:h,onValidation:E,onError:S}){let[_,p]=(0,it.useState)(null),[P,I]=(0,it.useState)(null),[x,g]=(0,it.useState)(null),[ye,R]=(0,it.useState)(null),[pe,oe]=(0,it.useState)(null),O=(0,it.useRef)(!1),ee=(0,it.useRef)(!1),Q=(0,it.useMemo)(()=>{if(typeof r=="object")return r;let Z=(0,Gt.resolveTheme)(r);if(Z)return ro({appearance:Z.appearance,buttonsStyles:Z.buttonsLayout,layout:"default"})},[r]),le=(0,it.useRef)(d),j=(0,it.useRef)(S),G=(0,it.useRef)(v),me=(0,it.useRef)(A),_e=(0,it.useRef)(h),be=(0,it.useRef)(E),ce=(0,it.useRef)(!1),ae=(0,it.useRef)(!1),ge=(0,it.useRef)(0);return le.current=d,j.current=S,G.current=v,me.current=A,_e.current=h,be.current=E,(0,it.useEffect)(()=>{let Z=ge.current+1;return ge.current=Z,()=>{queueMicrotask(()=>{ge.current===Z&&(ce.current||ae.current||(ae.current=!0,Ge(()=>{_e.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,it.useEffect)(()=>{let Z=!0,X=new Ro.PaymentAPI((0,Gt.resolveBillingApiUrl)(n),{telemetry:i});return p(null),I(null),g(null),ce.current=!1,ae.current=!1,(async()=>{try{if(!e.trim())throw new Gt.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!t.trim())throw new Gt.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let xe=await X.getUnifiedCheckoutSession(e,t);if(!Z)return;let ve=xe.data.session;if(!ve||!(0,Gt.isCardSetupCheckoutSession)(ve))throw new Gt.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let ie=ve.vault;if(ie?.html?.trim()||(ie=await X.getVaultCapture(e,t)),!ie.html?.trim())throw new Gt.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!Z)return;I(ie),p(new Ro.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:i}))}catch(xe){if(!Z)return;let ve=Ri(xe);ce.current=!0,g(ve),Ge(()=>j.current?.(ve))}})(),()=>{Z=!1,X.destroy()}},[n,t,e,i]),(0,it.useEffect)(()=>{if(!_)return;let Z=!1;ee.current=!1,O.current=!1;let X=_.on("submitting",()=>{O.current=!0,oe(null),R("processing")}),xe=_.on("complete",ie=>{ce.current=!0,O.current=!1,R("success"),(async()=>(await new Promise(W=>setTimeout(W,yn)),!ee.current&&(ee.current=!0,Ge(()=>{G.current?.({status:"succeeded",sessionId:e,...ie.paymentMethod?{paymentMethod:ie.paymentMethod}:{}})}),Z||R(null))))()}),ve=_.on("decline",ie=>{ce.current=!0,O.current=!1,oe(ie.message??null),R("error"),Ge(()=>{me.current?.({status:"declined",sessionId:e,...ie.declineReason?{reason:ie.declineReason}:{},...ie.message?{message:ie.message}:{}})}),(async()=>(await new Promise(W=>setTimeout(W,Yt)),Z||R(null)))()});return()=>{Z=!0,X(),xe(),ve()}},[_,e]),x?(0,En.jsx)("div",{role:"alert",children:x.message}):!_||!P?.html?(0,En.jsx)(En.Fragment,{children:u}):(0,En.jsxs)(En.Fragment,{children:[ye&&(0,En.jsx)(sn,{status:ye,errorMessage:pe,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),(0,En.jsx)(ur,{capture:_,html:P.html,messageToken:P.messageToken,expectedOrigin:P.expectedOrigin,theme:Q,containerStyle:s,onReady:()=>{Ge(()=>le.current?.())},onValidation:Z=>{Ge(()=>be.current?.(Z))},onError:Z=>{if(!Z)return;O.current&&(O.current=!1,oe(Z),R("error"),setTimeout(()=>R(null),Yt));let X=Ri(new Error(Z),{code:"card_setup_widget_failed",retryable:!0});Ge(()=>j.current?.(X))}})]})}var Ii=require("@flopay/js"),_i=require("@flopay/shared"),Pn=require("react");var hn=require("react/jsx-runtime");function xi({sessionId:e,nonce:t,billingApiUrl:n,email:i,userId:r,firstName:s,lastName:u,chv:d,onTokenizedBody:v,onComplete:A,onErrorChange:h,isProcessing:E=!1}){let S=mn(),_=ao(),p=io(),[P,I]=(0,Pn.useState)(!1),[x,g]=(0,Pn.useState)(!1),ye=(0,Pn.useRef)(!1),R=(n||p).replace(/\/+$/,""),pe=(0,Pn.useCallback)(async ee=>{try{let le=await new Ii.PaymentAPI(R).processPayment(r??"",{sessionId:e,nonce:t,tokenizedData:ee,accountData:{userId:r??"",email:i??"",firstName:s??"",lastName:u??""},chv:d});if(le.ok){A?.();return}let j=await le.json().catch(()=>null);h?.(j?.message??"Payment failed. Please try again.")}catch(Q){h?.(Q instanceof Error?Q.message:"An unexpected error occurred")}},[R,e,t,r,i,s,u,d,A,h]),oe=(0,Pn.useCallback)(ee=>{v?v(ee):pe(ee)},[v,pe]);(0,Pn.useEffect)(()=>{if(!S||ye.current)return;let ee=new URLSearchParams(window.location.search),Q=ee.get("payment_intent"),le=ee.get("payment_intent_client_secret"),j=ee.get("redirect_status");!Q||!le||(ye.current=!0,(async()=>{try{if(g(!0),j==="failed"){h?.("PayPal payment was declined. Please try again.");return}let G=S.getRawProvider();if(!G?.retrievePaymentIntent){h?.("Cannot retrieve PayPal payment status.");return}let{paymentIntent:me,error:_e}=await G.retrievePaymentIntent(le);if(_e){h?.(_e.message??"Failed to retrieve PayPal payment status.");return}if(me&&(me.status==="requires_capture"||me.status==="succeeded")){let be=typeof me.payment_method=="string"?me.payment_method:me.payment_method?.id;oe({id:be??me.id,type:"card",threeDSecureActionResultTokenId:me.id,isPaypal:!0});let ce=new URL(window.location.href);ce.searchParams.delete("payment_intent"),ce.searchParams.delete("payment_intent_client_secret"),ce.searchParams.delete("redirect_status"),window.history.replaceState({},"",ce.toString())}else h?.("PayPal payment was not completed. Please try again.")}catch(G){h?.(G instanceof Error?G.message:"Failed to complete PayPal payment.")}finally{g(!1)}})())},[S,oe,h]);let O=(0,Pn.useCallback)(async()=>{if(!(!S||!_))try{if(g(!0),h?.(null),!e||!i)throw new _i.FloPayError("Missing sessionId or email for PayPal payment","validation_error");let ee=await S.confirmPayPalPayment({billingApiUrl:R,sessionId:e,nonce:t,email:i,returnUrl:window.location.href});if(ee.error){h?.(ee.error.message);return}ee.paymentIntentId&&(ee.status==="succeeded"||ee.status==="processing"||ee.status==="requires_capture")&&oe({id:ee.paymentMethodId??ee.paymentIntentId,type:"card",threeDSecureActionResultTokenId:ee.paymentIntentId,isPaypal:!0})}catch(ee){h?.(ee instanceof Error?ee.message:"PayPal payment failed. Please try again.")}finally{g(!1)}},[S,_,e,t,i,R,oe,h]);return!S||!_?(0,hn.jsx)("div",{style:{height:45,background:"#f0f0f0",borderRadius:6,animation:"pulse 1.5s infinite"}}):(0,hn.jsxs)(hn.Fragment,{children:[!P&&(0,hn.jsx)("div",{style:{height:45,background:"#f0f0f0",borderRadius:6}}),(0,hn.jsx)("div",{style:P?{}:{display:"none"},children:(0,hn.jsx)("button",{type:"button",onClick:O,disabled:x||E,style:{width:"100%",height:45,backgroundColor:"#ffc439",color:"#003087",border:"none",borderRadius:6,fontSize:"1rem",fontWeight:700,cursor:x||E?"not-allowed":"pointer",opacity:x||E?.6:1},ref:()=>I(!0),children:x?"Processing...":"PayPal"})}),(x||E)&&(0,hn.jsx)("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.4)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3},children:(0,hn.jsx)("div",{style:{background:"white",borderRadius:8,padding:"1.5rem",textAlign:"center",boxShadow:"0 4px 24px rgba(0,0,0,0.15)",width:280},children:"Processing PayPal payment..."})})]})}var ze=require("react"),Eo=require("@flopay/js"),Jt=require("@flopay/shared");var bn=require("react/jsx-runtime"),Ws=44;function Ti(e){return new Promise(t=>setTimeout(t,e))}function Ys(e,t){return e instanceof Jt.FloPayError?e:new Jt.FloPayError(e instanceof Error?e.message:t,"api_error")}function Gs(e,t){return!(!t||e.type==="validation_error"||e.checkoutMethod&&e.checkoutMethod!=="card"&&e.checkoutMethod!=="paypal")}function Js(e){if(e.createSession)return{...e.createSession,checkoutMode:"auto"};if(!e.clientId||!e.account||!e.successUrl||!e.cancelUrl)return null;let t=e.products!=null;return{clientId:e.clientId,products:e.products,items:t?void 0:e.items,subscriptions:t?void 0:e.subscriptions,account:e.account,successUrl:e.successUrl,cancelUrl:e.cancelUrl,couponCodes:e.couponCodes,tagsData:e.tagsData,utmMetadata:e.utmMetadata,checkoutMode:"auto"}}function Mi({sessionId:e,nonce:t,createSession:n,paymentMethodId:i,checkoutMethod:r,clientId:s,products:u,items:d,subscriptions:v,account:A,successUrl:h,cancelUrl:E,couponCodes:S,tagsData:_,utmMetadata:p,billingApiUrl:P,locale:I,theme:x,appearance:g,buttonsTheme:ye,buttonsStyles:R,onSuccess:pe,onError:oe,onDecline:O,children:ee,disabled:Q=!1,type:le="button",style:j,...G}){let me=(0,ze.useMemo)(()=>(0,Jt.resolveBillingApiUrl)(P),[P]),_e=(0,ze.useMemo)(()=>Js({createSession:n,clientId:s,products:u,items:d,subscriptions:v,account:A,successUrl:h,cancelUrl:E,couponCodes:S,tagsData:_,utmMetadata:p}),[A,E,s,S,n,u,d,v,h,_,p]),[be,ce]=(0,ze.useState)(!1),[ae,ge]=(0,ze.useState)(null),[Z,X]=(0,ze.useState)(null),[xe,ve]=(0,ze.useState)(!1),[ie,W]=(0,ze.useState)(null),w=(0,ze.useRef)(!0),de=(0,ze.useRef)(null),je=(0,ze.useRef)(ie),$e=(0,ze.useRef)(pe),he=(0,ze.useRef)(oe),B=(0,ze.useRef)(O);(0,ze.useEffect)(()=>{je.current=ie},[ie]),(0,ze.useEffect)(()=>{$e.current=pe},[pe]),(0,ze.useEffect)(()=>{he.current=oe},[oe]),(0,ze.useEffect)(()=>{B.current=O},[O]),(0,ze.useEffect)(()=>(w.current=!0,()=>{w.current=!1,de.current?.abort()}),[]),(0,ze.useEffect)(()=>{if(typeof window>"u")return;let T=ke=>{ke.key==="Escape"&&W(null)};return window.addEventListener("keydown",T),()=>{window.removeEventListener("keydown",T)}},[]);let fe=(0,ze.useCallback)((T,ke=Ur)=>{B.current?.(Et(ke,T,{code:T.code,declineCode:T.declineCode}))},[]),te=(0,ze.useCallback)(async T=>{w.current&&(X(null),ve(T.result.status==="authorized"),ge("success"),await Ti(yn),w.current&&$e.current?.(T))},[]),Me=(0,ze.useCallback)(async(T,ke)=>{w.current&&(he.current?.(T),ke?.emitDecline&&fe(T,ke.method),X(T.message),ve(!1),ge("error"),await Ti(Yt))},[fe]),pt=(0,ze.useCallback)(async(T,ke,Xe)=>{let Ae=T.data.session??null;if(!Ae)throw new Jt.FloPayError("No session data returned","api_error");let Ct=Ae.clientSecret||t;if(fr(Ae)){await te({result:Zn(Ae,ke),session:Ae,sessionId:Ae.id||ke,autoCompleted:!1});return}if(Ae.status==="expired")throw so(Ae);try{if(T.autoProcessingPending){let et=(await new Eo.PaymentAPI(me).waitForCheckoutSessionCompletion(T.autoProcessingPending.sessionId,{initialDelayMs:T.autoProcessingPending.retryAfterMs})).data.session;if(!fr(et))throw lo(et);await te({result:Zn(et,ke),session:et,sessionId:et.id||ke,autoCompleted:!1});return}if(T.autoProcessingError){if(T.autoProcessingError.type==="3ds_required"&&T.autoProcessingError.nextActionRedirectUrl&&ke&&Ct){let Ke=new AbortController;de.current=Ke;let ot;try{ot=await fi({billingApiUrl:me,sessionId:ke,nonce:Ct,nextActionRedirectUrl:T.autoProcessingError.nextActionRedirectUrl,signal:Ke.signal})}finally{de.current===Ke&&(de.current=null)}if(ot.status==="declined")throw Vn({type:ot.declineReason??"decline",message:"Card was declined.",gatewayErrorCode:ot.gatewayDeclineReason??void 0},"Card was declined.",{checkoutMethod:T.autoProcessingError.checkoutMethod});let st=(await new Eo.PaymentAPI(me).waitForCheckoutSessionCompletion(ke,{initialDelayMs:0,nonce:Ct})).data.session;if(!fr(st))throw Vn({type:"unknown",message:"Card authentication was not completed."},"Card authentication was not completed.",{checkoutMethod:T.autoProcessingError.checkoutMethod});await te({result:Zn(st,ke),session:st,sessionId:st.id||ke,autoCompleted:!1});return}throw Vn(T.autoProcessingError,"Automatic payment failed. Please try again.",{checkoutMethod:T.autoProcessingError.checkoutMethod})}if(Xe?.fromCreateSession&&T.autoProcessingAttempted===!0)throw Vn({type:"unknown",message:"Automatic payment failed. Please try again."},"Automatic payment failed. Please try again.");let We=await br({billingApiUrl:me,sessionId:ke??Ae.id,session:Ae,nonce:Ct});if(We.type!=="success")throw Vn({type:"unknown",message:"Automatic payment failed. Please try again."},"Automatic payment failed. Please try again.");await te({result:We.result,session:Ae,sessionId:Ae.id||ke,autoCompleted:!1})}catch(We){let Ke=tr(We),ot=Ae.id||ke;await Me(Ke,{emitDecline:!0,method:Ke.checkoutMethod??Ur}),Gs(Ke,ot)&&ot&&w.current&&W({sessionId:ot,errorMessage:Ke.message,nonce:Ct||void 0})}},[t,me,Me,te]),Ze=(0,ze.useCallback)(async T=>{if(G.onClick?.(T),!(T.defaultPrevented||Q||be)){if(W(null),e&&_e){let ke=new Jt.FloPayError("Provide either sessionId or create-session props, not both.","validation_error");await Me(ke),w.current&&(ge(null),X(null));return}if(!e&&!_e){let ke=new Jt.FloPayError("Provide a sessionId or the props required to create an automatic payment session.","validation_error");await Me(ke),w.current&&(ge(null),X(null));return}ce(!0),X(null),ve(!1),ge("processing");try{let ke=new Eo.PaymentAPI(me);if(e){let Xe=await ke.getUnifiedCheckoutSession(e,t);await pt(Xe,e);return}try{let Xe=await ke.createAndFetchSession({..._e});await pt(Xe,Xe.data.session?.id??null,{fromCreateSession:!0})}catch(Xe){if(Xe instanceof Jt.FloPayError&&Xe.code==="session_auto_completed"){await te({result:{status:"succeeded"},session:null,sessionId:null,autoCompleted:!0});return}throw Xe}}catch(ke){await Me(Ys(ke,"Automatic payment failed. Please try again."))}finally{w.current&&(ge(null),X(null),ce(!1))}}},[G,_e,Q,be,t,pt,me,e,Me,te]),mt=(0,ze.useCallback)(T=>{let ke=je.current;W(null),$e.current?.({result:T,session:null,sessionId:ke?.sessionId??null,autoCompleted:!1})},[]),L=(0,ze.useCallback)(T=>{he.current?.(T)},[]),ne=(0,ze.useCallback)(T=>{B.current?.(T)},[]),rt=(0,ze.useMemo)(()=>(0,Jt.resolveTheme)(x),[x]),He=(0,ze.useMemo)(()=>{let T=rt?.buttonsLayout??(0,Jt.resolveButtonsLayoutTheme)(ye);return R?{...T,...R,cardButton:{...T.cardButton,...R.cardButton}}:T},[rt,ye,R]),yt=(0,ze.useMemo)(()=>{let T=rt?.appearance;return g?T?{...T,...g,variables:{...T.variables,...g.variables}}:g:T},[g,rt]),qe=yt?.variables,Je=qe?.colorPrimary??"#4A49FF",Xt=qe?.colorPrimaryHover??dr(Je,.12),Qe=qe?.borderRadius??"8px";return(0,bn.jsxs)(bn.Fragment,{children:[(0,bn.jsx)("button",{...G,type:le,onClick:Ze,disabled:Q||be,"aria-busy":be,style:{width:"100%",...ee===void 0?{boxSizing:"border-box",height:Ws,padding:"0 1rem"}:{padding:"0.9rem 1rem"},...He.cardButton,...Xo({themeBundle:rt,resolvedPrimaryColor:Je,resolvedBorderRadius:Qe,submitButtonStyle:He.submitButton,explicitPrimaryColor:qe?.colorPrimary}),fontSize:He.cardButtonFontSize??"0.95rem",fontWeight:600,cursor:Q||be?"not-allowed":"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"0.625rem",transition:"background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",position:"relative",opacity:Q||be?.6:1,...j},onMouseEnter:T=>{G.onMouseEnter?.(T),!T.defaultPrevented&&!Q&&!be&&(rt||qe?.colorPrimary)&&(T.currentTarget.style.backgroundColor=Xt)},onMouseLeave:T=>{G.onMouseLeave?.(T),!T.defaultPrevented&&(rt||qe?.colorPrimary)&&(T.currentTarget.style.backgroundColor=Je)},onMouseDown:T=>{G.onMouseDown?.(T),T.defaultPrevented||(T.currentTarget.style.transform="scale(0.985)")},onMouseUp:T=>{G.onMouseUp?.(T),T.defaultPrevented||(T.currentTarget.style.transform="scale(1)")},children:(0,bn.jsx)(lr,{content:ee})}),ae&&(0,bn.jsx)(sn,{status:ae,errorMessage:Z,authorized:xe}),ie&&(0,bn.jsx)("div",{"data-testid":"flopay-automatic-payment-fallback",role:"dialog","aria-modal":"true",onClick:T=>{T.target===T.currentTarget&&W(null)},style:{position:"fixed",inset:0,background:"rgba(0, 0, 0, 0.45)",display:"flex",alignItems:"center",justifyContent:"center",padding:"1.5rem",zIndex:1100},children:(0,bn.jsx)("div",{style:{width:"100%",maxWidth:520,maxHeight:"90vh",overflowY:"auto",background:"white",borderRadius:20,padding:"1.5rem",boxShadow:"0 24px 80px rgba(15, 23, 42, 0.28)",display:"flex",flexDirection:"column",gap:"1rem"},children:(0,bn.jsx)(ko,{sessionId:ie.sessionId,nonce:ie.nonce,checkoutMode:"full",billingApiUrl:me,locale:I,theme:x,...yt?{appearance:yt}:{},buttonsTheme:ye,buttonsStyles:R,initialErrorMessage:ie.errorMessage,cardTitleContent:null,onComplete:mt,onError:L,onDecline:ne})})})]})}0&&(module.exports={AddressElement,DirectPayPalButton,FloPayAutomaticPaymentButton,FloPayCardSetup,FloPayCardSetupError,FloPayCheckout,FloPayProvider,PayPalButton,PaymentElement,SplitCardForm,VaultCardFields,dropThirdPartyOnlyError,useCheckout,useElements,useFloPay,usePayPalFloPay});
47
+ `})]})}return(0,k.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem"},children:[t&&I(vr),n&&(i||r)&&I(vr),n&&(0,k.jsx)("button",{type:"button",onClick:()=>{e?.("card"),S(!0)},style:{width:"100%",...x,backgroundColor:"white",color:"#262833",border:"1px solid #d1d5db",borderRadius:"8px",fontSize:p.cardButtonFontSize??"0.95rem",fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"0.625rem",boxShadow:"0 1px 2px rgba(0,0,0,0.04)",transition:"transform 0.1s",position:"relative",opacity:1,...p.cardButton},onMouseDown:g=>{g.currentTarget.style.transform="scale(0.985)"},onMouseUp:g=>{g.currentTarget.style.transform="scale(1)"},children:(0,k.jsx)(lr,{content:v})}),(0,k.jsx)("style",{children:"@keyframes flopay-interim-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }"})]})}var Ai=require("@flopay/shared");var rr=require("react");var ki=require("react/jsx-runtime");function Ci(e,t){function n({className:i,id:r,style:s,options:u,onChange:d,onReady:v,onFocus:A,onBlur:h,onEscape:E}){let S=(0,rr.useRef)(null),_=(0,rr.useRef)(null),{elements:p,reportInteractive:P}=(0,rr.useContext)(Mn);return(0,rr.useEffect)(()=>{if(!p||!S.current)return;let I=!0;return(async()=>{let x=p.getElement(e);x||(x=await p.create(e,u)),!(!I||!S.current)&&(x.mount(S.current),_.current=x,d&&x.on("change",d),x.on("ready",()=>{P?.(),v?.()}),A&&x.on("focus",A),h&&x.on("blur",h),E&&x.on("escape",E))})(),()=>{if(I=!1,_.current){try{_.current.unmount()}catch{}_.current=null}}},[p,P]),(0,ki.jsx)("div",{ref:S,className:i,id:r,style:s})}return n.displayName=t,n}var Si=Ci("payment","PaymentElement"),wi=Ci("address","AddressElement");var it=require("react"),Ro=require("@flopay/js/card-setup"),Gt=require("@flopay/shared");var En=require("react/jsx-runtime"),Vr=class extends Gt.FloPayError{constructor(t,n,i){super(t,n,i),this.name="FloPayCardSetupError",this.retryable=i.retryable}};function Ri(e,t={}){let n=e instanceof Gt.FloPayError?e:void 0,i=n?.statusCode,r=t.retryable??(n?.type==="network_error"||n?.type==="rate_limit_error"||typeof i=="number"&&i>=500||n?.code==="vault_capture_timeout"||!n);return new Vr(n?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),n?.type??"api_error",{code:t.code??n?.code??"card_setup_load_failed",retryable:r,...n?.param?{param:n.param}:{},...i!==void 0?{statusCode:i}:{}})}function Ei({sessionId:e,nonce:t,billingApiUrl:n,telemetry:i,theme:r="modern-light",containerStyle:s,loading:u=null,onReady:d,onComplete:v,onDecline:A,onCancel:h,onValidation:E,onError:S}){let[_,p]=(0,it.useState)(null),[P,I]=(0,it.useState)(null),[x,g]=(0,it.useState)(null),[ye,R]=(0,it.useState)(null),[pe,oe]=(0,it.useState)(null),O=(0,it.useRef)(!1),ee=(0,it.useRef)(!1),Q=(0,it.useMemo)(()=>{if(typeof r=="object")return r;let Z=(0,Gt.resolveTheme)(r);if(Z)return ro({appearance:Z.appearance,buttonsStyles:Z.buttonsLayout,layout:"default"})},[r]),le=(0,it.useRef)(d),j=(0,it.useRef)(S),G=(0,it.useRef)(v),me=(0,it.useRef)(A),_e=(0,it.useRef)(h),be=(0,it.useRef)(E),ce=(0,it.useRef)(!1),ae=(0,it.useRef)(!1),ge=(0,it.useRef)(0);return le.current=d,j.current=S,G.current=v,me.current=A,_e.current=h,be.current=E,(0,it.useEffect)(()=>{let Z=ge.current+1;return ge.current=Z,()=>{queueMicrotask(()=>{ge.current===Z&&(ce.current||ae.current||(ae.current=!0,Ge(()=>{_e.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,it.useEffect)(()=>{let Z=!0,X=new Ro.PaymentAPI((0,Gt.resolveBillingApiUrl)(n),{telemetry:i});return p(null),I(null),g(null),ce.current=!1,ae.current=!1,(async()=>{try{if(!e.trim())throw new Gt.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!t.trim())throw new Gt.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let xe=await X.getUnifiedCheckoutSession(e,t);if(!Z)return;let ve=xe.data.session;if(!ve||!(0,Gt.isCardSetupCheckoutSession)(ve))throw new Gt.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let ie=ve.vault;if(ie?.html?.trim()||(ie=await X.getVaultCapture(e,t)),!ie.html?.trim())throw new Gt.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!Z)return;I(ie),p(new Ro.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:i}))}catch(xe){if(!Z)return;let ve=Ri(xe);ce.current=!0,g(ve),Ge(()=>j.current?.(ve))}})(),()=>{Z=!1,X.destroy()}},[n,t,e,i]),(0,it.useEffect)(()=>{if(!_)return;let Z=!1;ee.current=!1,O.current=!1;let X=_.on("submitting",()=>{O.current=!0,oe(null),R("processing")}),xe=_.on("complete",ie=>{ce.current=!0,O.current=!1,R("success"),(async()=>(await new Promise(W=>setTimeout(W,yn)),!ee.current&&(ee.current=!0,Ge(()=>{G.current?.({status:"succeeded",sessionId:e,...ie.paymentMethod?{paymentMethod:ie.paymentMethod}:{}})}),Z||R(null))))()}),ve=_.on("decline",ie=>{ce.current=!0,O.current=!1,oe(ie.message??null),R("error"),Ge(()=>{me.current?.({status:"declined",sessionId:e,...ie.declineReason?{reason:ie.declineReason}:{},...ie.message?{message:ie.message}:{}})}),(async()=>(await new Promise(W=>setTimeout(W,Yt)),Z||R(null)))()});return()=>{Z=!0,X(),xe(),ve()}},[_,e]),x?(0,En.jsx)("div",{role:"alert",children:x.message}):!_||!P?.html?(0,En.jsx)(En.Fragment,{children:u}):(0,En.jsxs)(En.Fragment,{children:[ye&&(0,En.jsx)(sn,{status:ye,errorMessage:pe,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),(0,En.jsx)(ur,{capture:_,html:P.html,messageToken:P.messageToken,expectedOrigin:P.expectedOrigin,theme:Q,containerStyle:s,onReady:()=>{Ge(()=>le.current?.())},onValidation:Z=>{Ge(()=>be.current?.(Z))},onError:Z=>{if(!Z)return;O.current&&(O.current=!1,oe(Z),R("error"),setTimeout(()=>R(null),Yt));let X=Ri(new Error(Z),{code:"card_setup_widget_failed",retryable:!0});Ge(()=>j.current?.(X))}})]})}var Ii=require("@flopay/js"),_i=require("@flopay/shared"),Pn=require("react");var hn=require("react/jsx-runtime");function xi({sessionId:e,nonce:t,billingApiUrl:n,email:i,userId:r,firstName:s,lastName:u,chv:d,onTokenizedBody:v,onComplete:A,onErrorChange:h,isProcessing:E=!1}){let S=mn(),_=ao(),p=io(),[P,I]=(0,Pn.useState)(!1),[x,g]=(0,Pn.useState)(!1),ye=(0,Pn.useRef)(!1),R=(n||p).replace(/\/+$/,""),pe=(0,Pn.useCallback)(async ee=>{try{let le=await new Ii.PaymentAPI(R).processPayment(r??"",{sessionId:e,nonce:t,tokenizedData:ee,accountData:{userId:r??"",email:i??"",firstName:s??"",lastName:u??""},chv:d});if(le.ok){A?.();return}let j=await le.json().catch(()=>null);h?.(j?.message??"Payment failed. Please try again.")}catch(Q){h?.(Q instanceof Error?Q.message:"An unexpected error occurred")}},[R,e,t,r,i,s,u,d,A,h]),oe=(0,Pn.useCallback)(ee=>{v?v(ee):pe(ee)},[v,pe]);(0,Pn.useEffect)(()=>{if(!S||ye.current)return;let ee=new URLSearchParams(window.location.search),Q=ee.get("payment_intent"),le=ee.get("payment_intent_client_secret"),j=ee.get("redirect_status");!Q||!le||(ye.current=!0,(async()=>{try{if(g(!0),j==="failed"){h?.("PayPal payment was declined. Please try again.");return}let G=S.getRawProvider();if(!G?.retrievePaymentIntent){h?.("Cannot retrieve PayPal payment status.");return}let{paymentIntent:me,error:_e}=await G.retrievePaymentIntent(le);if(_e){h?.(_e.message??"Failed to retrieve PayPal payment status.");return}if(me&&(me.status==="requires_capture"||me.status==="succeeded")){let be=typeof me.payment_method=="string"?me.payment_method:me.payment_method?.id;oe({id:be??me.id,type:"card",threeDSecureActionResultTokenId:me.id,isPaypal:!0});let ce=new URL(window.location.href);ce.searchParams.delete("payment_intent"),ce.searchParams.delete("payment_intent_client_secret"),ce.searchParams.delete("redirect_status"),window.history.replaceState({},"",ce.toString())}else h?.("PayPal payment was not completed. Please try again.")}catch(G){h?.(G instanceof Error?G.message:"Failed to complete PayPal payment.")}finally{g(!1)}})())},[S,oe,h]);let O=(0,Pn.useCallback)(async()=>{if(!(!S||!_))try{if(g(!0),h?.(null),!e||!i)throw new _i.FloPayError("Missing sessionId or email for PayPal payment","validation_error");let ee=await S.confirmPayPalPayment({billingApiUrl:R,sessionId:e,nonce:t,email:i,returnUrl:window.location.href});if(ee.error){h?.(ee.error.message);return}ee.paymentIntentId&&(ee.status==="succeeded"||ee.status==="processing"||ee.status==="requires_capture")&&oe({id:ee.paymentMethodId??ee.paymentIntentId,type:"card",threeDSecureActionResultTokenId:ee.paymentIntentId,isPaypal:!0})}catch(ee){h?.(ee instanceof Error?ee.message:"PayPal payment failed. Please try again.")}finally{g(!1)}},[S,_,e,t,i,R,oe,h]);return!S||!_?(0,hn.jsx)("div",{style:{height:45,background:"#f0f0f0",borderRadius:6,animation:"pulse 1.5s infinite"}}):(0,hn.jsxs)(hn.Fragment,{children:[!P&&(0,hn.jsx)("div",{style:{height:45,background:"#f0f0f0",borderRadius:6}}),(0,hn.jsx)("div",{style:P?{}:{display:"none"},children:(0,hn.jsx)("button",{type:"button",onClick:O,disabled:x||E,style:{width:"100%",height:45,backgroundColor:"#ffc439",color:"#003087",border:"none",borderRadius:6,fontSize:"1rem",fontWeight:700,cursor:x||E?"not-allowed":"pointer",opacity:x||E?.6:1},ref:()=>I(!0),children:x?"Processing...":"PayPal"})}),(x||E)&&(0,hn.jsx)("div",{style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.4)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3},children:(0,hn.jsx)("div",{style:{background:"white",borderRadius:8,padding:"1.5rem",textAlign:"center",boxShadow:"0 4px 24px rgba(0,0,0,0.15)",width:280},children:"Processing PayPal payment..."})})]})}var ze=require("react"),Eo=require("@flopay/js"),Jt=require("@flopay/shared");var bn=require("react/jsx-runtime"),Ws=44;function Ti(e){return new Promise(t=>setTimeout(t,e))}function Ys(e,t){return e instanceof Jt.FloPayError?e:new Jt.FloPayError(e instanceof Error?e.message:t,"api_error")}function Gs(e,t){return!(!t||e.type==="validation_error"||e.checkoutMethod&&e.checkoutMethod!=="card"&&e.checkoutMethod!=="paypal")}function Js(e){if(e.createSession)return{...e.createSession,checkoutMode:"auto"};if(!e.clientId||!e.account||!e.successUrl||!e.cancelUrl)return null;let t=e.products!=null;return{clientId:e.clientId,products:e.products,items:t?void 0:e.items,subscriptions:t?void 0:e.subscriptions,account:e.account,successUrl:e.successUrl,cancelUrl:e.cancelUrl,couponCodes:e.couponCodes,tagsData:e.tagsData,utmMetadata:e.utmMetadata,checkoutMode:"auto"}}function Mi({sessionId:e,nonce:t,createSession:n,paymentMethodId:i,checkoutMethod:r,clientId:s,products:u,items:d,subscriptions:v,account:A,successUrl:h,cancelUrl:E,couponCodes:S,tagsData:_,utmMetadata:p,billingApiUrl:P,locale:I,theme:x,appearance:g,buttonsTheme:ye,buttonsStyles:R,onSuccess:pe,onError:oe,onDecline:O,children:ee,disabled:Q=!1,type:le="button",style:j,...G}){let me=(0,ze.useMemo)(()=>(0,Jt.resolveBillingApiUrl)(P),[P]),_e=(0,ze.useMemo)(()=>Js({createSession:n,clientId:s,products:u,items:d,subscriptions:v,account:A,successUrl:h,cancelUrl:E,couponCodes:S,tagsData:_,utmMetadata:p}),[A,E,s,S,n,u,d,v,h,_,p]),[be,ce]=(0,ze.useState)(!1),[ae,ge]=(0,ze.useState)(null),[Z,X]=(0,ze.useState)(null),[xe,ve]=(0,ze.useState)(!1),[ie,W]=(0,ze.useState)(null),w=(0,ze.useRef)(!0),de=(0,ze.useRef)(null),je=(0,ze.useRef)(ie),$e=(0,ze.useRef)(pe),he=(0,ze.useRef)(oe),B=(0,ze.useRef)(O);(0,ze.useEffect)(()=>{je.current=ie},[ie]),(0,ze.useEffect)(()=>{$e.current=pe},[pe]),(0,ze.useEffect)(()=>{he.current=oe},[oe]),(0,ze.useEffect)(()=>{B.current=O},[O]),(0,ze.useEffect)(()=>(w.current=!0,()=>{w.current=!1,de.current?.abort()}),[]),(0,ze.useEffect)(()=>{if(typeof window>"u")return;let T=ke=>{ke.key==="Escape"&&W(null)};return window.addEventListener("keydown",T),()=>{window.removeEventListener("keydown",T)}},[]);let fe=(0,ze.useCallback)((T,ke=Ur)=>{B.current?.(Et(ke,T,{code:T.code,declineCode:T.declineCode}))},[]),te=(0,ze.useCallback)(async T=>{w.current&&(X(null),ve(T.result.status==="authorized"),ge("success"),await Ti(yn),w.current&&$e.current?.(T))},[]),Me=(0,ze.useCallback)(async(T,ke)=>{w.current&&(he.current?.(T),ke?.emitDecline&&fe(T,ke.method),X(T.message),ve(!1),ge("error"),await Ti(Yt))},[fe]),pt=(0,ze.useCallback)(async(T,ke,Xe)=>{let Ae=T.data.session??null;if(!Ae)throw new Jt.FloPayError("No session data returned","api_error");let Ct=Ae.clientSecret||t;if(fr(Ae)){await te({result:Zn(Ae,ke),session:Ae,sessionId:Ae.id||ke,autoCompleted:!1});return}if(Ae.status==="expired")throw so(Ae);try{if(T.autoProcessingPending){let et=(await new Eo.PaymentAPI(me).waitForCheckoutSessionCompletion(T.autoProcessingPending.sessionId,{initialDelayMs:T.autoProcessingPending.retryAfterMs})).data.session;if(!fr(et))throw lo(et);await te({result:Zn(et,ke),session:et,sessionId:et.id||ke,autoCompleted:!1});return}if(T.autoProcessingError){if(T.autoProcessingError.type==="3ds_required"&&T.autoProcessingError.nextActionRedirectUrl&&ke&&Ct){let Ke=new AbortController;de.current=Ke;let ot;try{ot=await fi({billingApiUrl:me,sessionId:ke,nonce:Ct,nextActionRedirectUrl:T.autoProcessingError.nextActionRedirectUrl,signal:Ke.signal})}finally{de.current===Ke&&(de.current=null)}if(ot.status==="declined")throw Vn({type:ot.declineReason??"decline",message:"Card was declined.",gatewayErrorCode:ot.gatewayDeclineReason??void 0},"Card was declined.",{checkoutMethod:T.autoProcessingError.checkoutMethod});let st=(await new Eo.PaymentAPI(me).waitForCheckoutSessionCompletion(ke,{initialDelayMs:0,nonce:Ct})).data.session;if(!fr(st))throw Vn({type:"unknown",message:"Card authentication was not completed."},"Card authentication was not completed.",{checkoutMethod:T.autoProcessingError.checkoutMethod});await te({result:Zn(st,ke),session:st,sessionId:st.id||ke,autoCompleted:!1});return}throw Vn(T.autoProcessingError,"Automatic payment failed. Please try again.",{checkoutMethod:T.autoProcessingError.checkoutMethod})}if(Xe?.fromCreateSession&&T.autoProcessingAttempted===!0)throw Vn({type:"unknown",message:"Automatic payment failed. Please try again."},"Automatic payment failed. Please try again.");let We=await br({billingApiUrl:me,sessionId:ke??Ae.id,session:Ae,nonce:Ct});if(We.type!=="success")throw Vn({type:"unknown",message:"Automatic payment failed. Please try again."},"Automatic payment failed. Please try again.");await te({result:We.result,session:Ae,sessionId:Ae.id||ke,autoCompleted:!1})}catch(We){let Ke=tr(We),ot=Ae.id||ke;await Me(Ke,{emitDecline:!0,method:Ke.checkoutMethod??Ur}),Gs(Ke,ot)&&ot&&w.current&&W({sessionId:ot,errorMessage:Ke.message,nonce:Ct||void 0})}},[t,me,Me,te]),Ze=(0,ze.useCallback)(async T=>{if(G.onClick?.(T),!(T.defaultPrevented||Q||be)){if(W(null),e&&_e){let ke=new Jt.FloPayError("Provide either sessionId or create-session props, not both.","validation_error");await Me(ke),w.current&&(ge(null),X(null));return}if(!e&&!_e){let ke=new Jt.FloPayError("Provide a sessionId or the props required to create an automatic payment session.","validation_error");await Me(ke),w.current&&(ge(null),X(null));return}ce(!0),X(null),ve(!1),ge("processing");try{let ke=new Eo.PaymentAPI(me);if(e){let Xe=await ke.getUnifiedCheckoutSession(e,t);await pt(Xe,e);return}try{let Xe=await ke.createAndFetchSession({..._e});await pt(Xe,Xe.data.session?.id??null,{fromCreateSession:!0})}catch(Xe){if(Xe instanceof Jt.FloPayError&&Xe.code==="session_auto_completed"){await te({result:{status:"succeeded"},session:null,sessionId:null,autoCompleted:!0});return}throw Xe}}catch(ke){await Me(Ys(ke,"Automatic payment failed. Please try again."))}finally{w.current&&(ge(null),X(null),ce(!1))}}},[G,_e,Q,be,t,pt,me,e,Me,te]),mt=(0,ze.useCallback)(T=>{let ke=je.current;W(null),$e.current?.({result:T,session:null,sessionId:ke?.sessionId??null,autoCompleted:!1})},[]),L=(0,ze.useCallback)(T=>{he.current?.(T)},[]),ne=(0,ze.useCallback)(T=>{B.current?.(T)},[]),rt=(0,ze.useMemo)(()=>(0,Jt.resolveTheme)(x),[x]),He=(0,ze.useMemo)(()=>{let T=rt?.buttonsLayout??(0,Jt.resolveButtonsLayoutTheme)(ye);return R?{...T,...R,cardButton:{...T.cardButton,...R.cardButton}}:T},[rt,ye,R]),yt=(0,ze.useMemo)(()=>{let T=rt?.appearance;return g?T?{...T,...g,variables:{...T.variables,...g.variables}}:g:T},[g,rt]),qe=yt?.variables,Je=qe?.colorPrimary??"#4A49FF",Xt=qe?.colorPrimaryHover??dr(Je,.12),Qe=qe?.borderRadius??"8px";return(0,bn.jsxs)(bn.Fragment,{children:[(0,bn.jsx)("button",{...G,type:le,onClick:Ze,disabled:Q||be,"aria-busy":be,style:{width:"100%",...ee===void 0?{boxSizing:"border-box",height:Ws,padding:"0 1rem"}:{padding:"0.9rem 1rem"},...He.cardButton,...Xo({themeBundle:rt,resolvedPrimaryColor:Je,resolvedBorderRadius:Qe,submitButtonStyle:He.submitButton,explicitPrimaryColor:qe?.colorPrimary}),fontSize:He.cardButtonFontSize??"0.95rem",fontWeight:600,cursor:Q||be?"not-allowed":"pointer",display:"flex",alignItems:"center",justifyContent:"center",gap:"0.625rem",transition:"background-color 0.15s, border-color 0.2s, box-shadow 0.2s, transform 0.1s",position:"relative",opacity:Q||be?.6:1,...j},onMouseEnter:T=>{G.onMouseEnter?.(T),!T.defaultPrevented&&!Q&&!be&&(rt||qe?.colorPrimary)&&(T.currentTarget.style.backgroundColor=Xt)},onMouseLeave:T=>{G.onMouseLeave?.(T),!T.defaultPrevented&&(rt||qe?.colorPrimary)&&(T.currentTarget.style.backgroundColor=Je)},onMouseDown:T=>{G.onMouseDown?.(T),T.defaultPrevented||(T.currentTarget.style.transform="scale(0.985)")},onMouseUp:T=>{G.onMouseUp?.(T),T.defaultPrevented||(T.currentTarget.style.transform="scale(1)")},children:(0,bn.jsx)(lr,{content:ee})}),ae&&(0,bn.jsx)(sn,{status:ae,errorMessage:Z,authorized:xe}),ie&&(0,bn.jsx)("div",{"data-testid":"flopay-automatic-payment-fallback",role:"dialog","aria-modal":"true",onClick:T=>{T.target===T.currentTarget&&W(null)},style:{position:"fixed",inset:0,background:"rgba(0, 0, 0, 0.45)",display:"flex",alignItems:"center",justifyContent:"center",padding:"1.5rem",zIndex:1100},children:(0,bn.jsx)("div",{style:{width:"100%",maxWidth:520,maxHeight:"90vh",overflowY:"auto",background:"white",borderRadius:20,padding:"1.5rem",boxShadow:"0 24px 80px rgba(15, 23, 42, 0.28)",display:"flex",flexDirection:"column",gap:"1rem"},children:(0,bn.jsx)(ko,{sessionId:ie.sessionId,nonce:ie.nonce,checkoutMode:"full",billingApiUrl:me,locale:I,theme:x,...yt?{appearance:yt}:{},buttonsTheme:ye,buttonsStyles:R,initialErrorMessage:ie.errorMessage,cardTitleContent:null,onComplete:mt,onError:L,onDecline:ne})})})]})}0&&(module.exports={AddressElement,DirectPayPalButton,FloPayAutomaticPaymentButton,FloPayCardSetup,FloPayCardSetupError,FloPayCheckout,FloPayProvider,PayPalButton,PaymentElement,SplitCardForm,VaultCardFields,dropThirdPartyOnlyError,useCheckout,useElements,useFloPay,usePayPalFloPay});
package/dist/index.d.cts CHANGED
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import { FloPay, FloPayElements } from '@flopay/js';
3
3
  import * as _flopay_shared from '@flopay/shared';
4
- import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CardCaptureAdapter, VaultCardThemeColors, ThemeId, SavedCardDisplay, FloPayErrorType, CheckoutProduct, CheckoutItem, CheckoutSubscription, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
4
+ import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CardCaptureAdapter, VaultCardThemeColors, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
5
5
  export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessionDraft, InlineSessionPatch, SentryEventLike, SentryStackFrameLike, dropThirdPartyOnlyError } from '@flopay/shared';
6
+ export { FloPayCardSetup, FloPayCardSetupCancelEvent, FloPayCardSetupCompleteEvent, FloPayCardSetupDeclineEvent, FloPayCardSetupError, FloPayCardSetupProps } from './card-setup-entry.cjs';
6
7
 
7
8
  /** Props for the `FloPayProvider` component. */
8
9
  interface FloPayProviderProps {
@@ -640,77 +641,6 @@ interface VaultCardFieldsProps {
640
641
  */
641
642
  declare function VaultCardFields({ capture, html, messageToken, expectedOrigin, theme, containerStyle, onReady, onError, onValidation, }: VaultCardFieldsProps): React.ReactElement;
642
643
 
643
- /** Verified terminal result from a no-charge card setup. */
644
- interface FloPayCardSetupCompleteEvent {
645
- status: 'succeeded';
646
- sessionId: string;
647
- /** Present when the backend terminal message includes the saved-card display DTO. */
648
- paymentMethod?: SavedCardDisplay;
649
- }
650
- /** Provider-neutral terminal decline from card verification. */
651
- interface FloPayCardSetupDeclineEvent {
652
- status: 'declined';
653
- sessionId: string;
654
- reason?: string;
655
- message?: string;
656
- }
657
- /** Abandoned setup result emitted when the component unmounts pre-terminally. */
658
- interface FloPayCardSetupCancelEvent {
659
- status: 'cancelled';
660
- sessionId: string;
661
- }
662
- /** Structured technical/validation failure from the card-setup surface. */
663
- declare class FloPayCardSetupError extends FloPayError {
664
- readonly retryable: boolean;
665
- constructor(message: string, type: FloPayErrorType, options: {
666
- code: string;
667
- retryable: boolean;
668
- param?: string;
669
- statusCode?: number;
670
- });
671
- }
672
- /** Props for the browser-only secure card-setup surface. */
673
- interface FloPayCardSetupProps {
674
- /** Opaque id returned by the merchant-authenticated setup-session endpoint. */
675
- sessionId: string;
676
- /** Session-bound token returned alongside {@link FloPayCardSetupProps.sessionId}. */
677
- nonce: string;
678
- /** Billing API base URL. Defaults to the configured FloPay environment URL. */
679
- billingApiUrl?: string;
680
- /** Flo-owned privacy-safe telemetry is enabled by default; set false to opt out. */
681
- telemetry?: boolean;
682
- /**
683
- * Theme for FloPay's hosted, PCI-compliant card widget. Accepts the same
684
- * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
685
- * bundle, so one value styles both surfaces identically) or raw
686
- * {@link VaultCardThemeColors} for full manual control. Defaults to
687
- * `'modern-light'`; pass `'classic'` for the historic FloPay look.
688
- */
689
- theme?: ThemeId | VaultCardThemeColors;
690
- /** Inline styles for the hosted-widget container. */
691
- containerStyle?: React.CSSProperties;
692
- /** Optional content shown while the session and hosted widget are loading. */
693
- loading?: React.ReactNode;
694
- /** Fired once the hosted widget has mounted and can accept card input. */
695
- onReady?: () => void;
696
- /** Fired only after the backend reports that the card is verified and usable. */
697
- onComplete?: (event: FloPayCardSetupCompleteEvent) => void;
698
- /** Fired when verification terminally declines; never paired with `onComplete`. */
699
- onDecline?: (event: FloPayCardSetupDeclineEvent) => void;
700
- /** Fired exactly once if the setup surface unmounts before a terminal outcome. */
701
- onCancel?: (event: FloPayCardSetupCancelEvent) => void;
702
- /** Live hosted-field validation message, or `null` when validation clears. */
703
- onValidation?: (message: string | null) => void;
704
- /** Fired for setup-session validation, transport, or hosted-widget failures. */
705
- onError?: (error: FloPayCardSetupError) => void;
706
- }
707
- /**
708
- * Mounts FloPay's hosted card capture for a setup session created by the
709
- * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
710
- * Elements surface.
711
- */
712
- declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
713
-
714
644
  /**
715
645
  * Props for the `PayPalButton` component.
716
646
  *
@@ -968,4 +898,4 @@ interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttribu
968
898
  }
969
899
  declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, appearance, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
970
900
 
971
- export { AddressElement, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, type PaymentElementProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useElements, useFloPay, usePayPalFloPay };
901
+ export { AddressElement, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, type PaymentElementProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useElements, useFloPay, usePayPalFloPay };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
  import { FloPay, FloPayElements } from '@flopay/js';
3
3
  import * as _flopay_shared from '@flopay/shared';
4
- import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CardCaptureAdapter, VaultCardThemeColors, ThemeId, SavedCardDisplay, FloPayErrorType, CheckoutProduct, CheckoutItem, CheckoutSubscription, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
4
+ import { FloPayAppearance, InlineSessionDraft, FloPayError, PaymentResult, DeclineEvent, CheckoutButtonMethod, BeforeButtonClickEvent, InlineSessionPatch, CheckoutMode, CheckoutSession, ElementOptions, ElementChangeEvent, TokenizedBody, AVSFieldConfig, GatewayEnvironment, CardCaptureAdapter, VaultCardThemeColors, CheckoutProduct, CheckoutItem, CheckoutSubscription, ThemeId, ButtonsLayoutTheme, ButtonsLayoutStyles } from '@flopay/shared';
5
5
  export { BeforeButtonClickEvent, CheckoutButtonMethod, DeclineEvent, InlineSessionDraft, InlineSessionPatch, SentryEventLike, SentryStackFrameLike, dropThirdPartyOnlyError } from '@flopay/shared';
6
+ export { FloPayCardSetup, FloPayCardSetupCancelEvent, FloPayCardSetupCompleteEvent, FloPayCardSetupDeclineEvent, FloPayCardSetupError, FloPayCardSetupProps } from './card-setup-entry.js';
6
7
 
7
8
  /** Props for the `FloPayProvider` component. */
8
9
  interface FloPayProviderProps {
@@ -640,77 +641,6 @@ interface VaultCardFieldsProps {
640
641
  */
641
642
  declare function VaultCardFields({ capture, html, messageToken, expectedOrigin, theme, containerStyle, onReady, onError, onValidation, }: VaultCardFieldsProps): React.ReactElement;
642
643
 
643
- /** Verified terminal result from a no-charge card setup. */
644
- interface FloPayCardSetupCompleteEvent {
645
- status: 'succeeded';
646
- sessionId: string;
647
- /** Present when the backend terminal message includes the saved-card display DTO. */
648
- paymentMethod?: SavedCardDisplay;
649
- }
650
- /** Provider-neutral terminal decline from card verification. */
651
- interface FloPayCardSetupDeclineEvent {
652
- status: 'declined';
653
- sessionId: string;
654
- reason?: string;
655
- message?: string;
656
- }
657
- /** Abandoned setup result emitted when the component unmounts pre-terminally. */
658
- interface FloPayCardSetupCancelEvent {
659
- status: 'cancelled';
660
- sessionId: string;
661
- }
662
- /** Structured technical/validation failure from the card-setup surface. */
663
- declare class FloPayCardSetupError extends FloPayError {
664
- readonly retryable: boolean;
665
- constructor(message: string, type: FloPayErrorType, options: {
666
- code: string;
667
- retryable: boolean;
668
- param?: string;
669
- statusCode?: number;
670
- });
671
- }
672
- /** Props for the browser-only secure card-setup surface. */
673
- interface FloPayCardSetupProps {
674
- /** Opaque id returned by the merchant-authenticated setup-session endpoint. */
675
- sessionId: string;
676
- /** Session-bound token returned alongside {@link FloPayCardSetupProps.sessionId}. */
677
- nonce: string;
678
- /** Billing API base URL. Defaults to the configured FloPay environment URL. */
679
- billingApiUrl?: string;
680
- /** Flo-owned privacy-safe telemetry is enabled by default; set false to opt out. */
681
- telemetry?: boolean;
682
- /**
683
- * Theme for FloPay's hosted, PCI-compliant card widget. Accepts the same
684
- * high-level {@link ThemeId} as `FloPayCheckout` (resolved through the same
685
- * bundle, so one value styles both surfaces identically) or raw
686
- * {@link VaultCardThemeColors} for full manual control. Defaults to
687
- * `'modern-light'`; pass `'classic'` for the historic FloPay look.
688
- */
689
- theme?: ThemeId | VaultCardThemeColors;
690
- /** Inline styles for the hosted-widget container. */
691
- containerStyle?: React.CSSProperties;
692
- /** Optional content shown while the session and hosted widget are loading. */
693
- loading?: React.ReactNode;
694
- /** Fired once the hosted widget has mounted and can accept card input. */
695
- onReady?: () => void;
696
- /** Fired only after the backend reports that the card is verified and usable. */
697
- onComplete?: (event: FloPayCardSetupCompleteEvent) => void;
698
- /** Fired when verification terminally declines; never paired with `onComplete`. */
699
- onDecline?: (event: FloPayCardSetupDeclineEvent) => void;
700
- /** Fired exactly once if the setup surface unmounts before a terminal outcome. */
701
- onCancel?: (event: FloPayCardSetupCancelEvent) => void;
702
- /** Live hosted-field validation message, or `null` when validation clears. */
703
- onValidation?: (message: string | null) => void;
704
- /** Fired for setup-session validation, transport, or hosted-widget failures. */
705
- onError?: (error: FloPayCardSetupError) => void;
706
- }
707
- /**
708
- * Mounts FloPay's hosted card capture for a setup session created by the
709
- * merchant's server. It has no customer-id, list, delete, purchase, or Stripe
710
- * Elements surface.
711
- */
712
- declare function FloPayCardSetup({ sessionId, nonce, billingApiUrl, telemetry, theme, containerStyle, loading, onReady, onComplete, onDecline, onCancel, onValidation, onError, }: FloPayCardSetupProps): React.ReactElement;
713
-
714
644
  /**
715
645
  * Props for the `PayPalButton` component.
716
646
  *
@@ -968,4 +898,4 @@ interface FloPayAutomaticPaymentButtonProps extends Omit<React.ButtonHTMLAttribu
968
898
  }
969
899
  declare function FloPayAutomaticPaymentButton({ sessionId, nonce, createSession, paymentMethodId: _deprecatedPaymentMethodId, checkoutMethod: _deprecatedCheckoutMethod, clientId, products, items, subscriptions, account, successUrl, cancelUrl, couponCodes, tagsData, utmMetadata, billingApiUrl, locale, theme, appearance, buttonsTheme, buttonsStyles: stylesOverride, onSuccess, onError, onDecline, children, disabled, type, style, ...buttonProps }: FloPayAutomaticPaymentButtonProps): React.JSX.Element;
970
900
 
971
- export { AddressElement, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCardSetup, type FloPayCardSetupCancelEvent, type FloPayCardSetupCompleteEvent, type FloPayCardSetupDeclineEvent, FloPayCardSetupError, type FloPayCardSetupProps, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, type PaymentElementProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useElements, useFloPay, usePayPalFloPay };
901
+ export { AddressElement, type CheckoutState, DirectPayPalButton, type DirectPayPalButtonProps, type DirectPayPalInitializationState, type ElementComponentProps, FloPayAutomaticPaymentButton, type FloPayAutomaticPaymentButtonProps, type FloPayAutomaticPaymentSuccessEvent, FloPayCheckout, type FloPayCheckoutProps, FloPayProvider, type FloPayProviderProps, PayPalButton, type PayPalButtonProps, PaymentElement, type PaymentElementProps, SplitCardForm, type SplitCardFormProps, VaultCardFields, type VaultCardFieldsProps, useCheckout, useElements, useFloPay, usePayPalFloPay };