@flopay/react 1.8.1 → 1.8.3
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 +31 -8
- package/dist/card-setup-entry.cjs +2 -2
- package/dist/card-setup-entry.mjs +1 -1
- package/dist/chunk-W24FSJC5.mjs +6 -0
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +22 -6
- package/dist/index.d.ts +22 -6
- package/dist/index.mjs +8 -8
- package/package.json +3 -3
- package/dist/chunk-VWT2TDA6.mjs +0 -6
- package/dist/payment-logos/alipay.svg +0 -1
- package/dist/payment-logos/bancontact.svg +0 -1
- package/dist/payment-logos/blik.svg +0 -1
- package/dist/payment-logos/eps.svg +0 -1
- package/dist/payment-logos/giropay.svg +0 -1
- package/dist/payment-logos/ideal.svg +0 -1
- package/dist/payment-logos/klarna.svg +0 -1
- package/dist/payment-logos/p24.svg +0 -1
- package/dist/payment-logos/sepa_debit.svg +0 -1
- package/dist/payment-logos/wechat_pay.svg +0 -1
package/README.md
CHANGED
|
@@ -55,6 +55,25 @@ function CheckoutPage() {
|
|
|
55
55
|
|
|
56
56
|
`FloPayCheckout` automatically fetches the session, initializes the correct payment providers, and renders a `SplitCardForm` with the hosted vault card widget plus the session's supported wallets, APMs, and PayPal. Customer data (email, userId, name) is injected from the session.
|
|
57
57
|
|
|
58
|
+
#### Buyer identity collection
|
|
59
|
+
|
|
60
|
+
For inline checkout creation, `createSession.account.userId` remains required,
|
|
61
|
+
but `email`, `firstName`, and `lastName` may be omitted. `FloPayCheckout`
|
|
62
|
+
creates a mountable session shell first, then collects and attaches the missing
|
|
63
|
+
identity before payment can continue:
|
|
64
|
+
|
|
65
|
+
- Hosted card checkout renders a required email field first, above name, AVS,
|
|
66
|
+
and the hosted card widget. Submit stays gated until the email passes the
|
|
67
|
+
shared `isValidEmail()` validator and a name is present.
|
|
68
|
+
- Apple Pay, Google Pay, other Stripe wallets, and PayPal use provider-returned
|
|
69
|
+
email/name automatically when available.
|
|
70
|
+
- A wallet, PayPal, or APM that does not return the missing fields opens a
|
|
71
|
+
required second pane for email/name before the SDK creates an intent or
|
|
72
|
+
processes payment.
|
|
73
|
+
|
|
74
|
+
The SDK never attaches a blank email. The merchant-supplied `userId` is not
|
|
75
|
+
replaced by provider data.
|
|
76
|
+
|
|
58
77
|
#### Merchant instrument feed
|
|
59
78
|
|
|
60
79
|
Use `onInstrument` on `FloPayCheckout` or `FloPayProvider` to forward a stable,
|
|
@@ -285,12 +304,15 @@ the entire integration change — no SDK redeploy or consumer code update is
|
|
|
285
304
|
required. Wallets only render on supported devices regardless of dashboard
|
|
286
305
|
state (Apple Pay on Safari/macOS/iOS, Google Pay on Chrome).
|
|
287
306
|
|
|
288
|
-
> **
|
|
289
|
-
>
|
|
290
|
-
>
|
|
291
|
-
>
|
|
292
|
-
>
|
|
293
|
-
> a
|
|
307
|
+
> **Payment-logo CDN and CSP:** APM brand logos load from the versioned,
|
|
308
|
+
> FloPay-owned URL `https://cdn.flopay.com/sdk-logos/v1/`. Plain absolute HTTPS
|
|
309
|
+
> URLs work in Vite with no SDK middleware or `optimizeDeps` override, and retain
|
|
310
|
+
> the same behavior in webpack 5, Rollup, Next, and esbuild. Logos stay out of
|
|
311
|
+
> the package and JavaScript bundle; card-only and vault checkouts never request
|
|
312
|
+
> one. Merchants with a strict Content Security Policy must allow the host in
|
|
313
|
+
> the image directive, for example `img-src 'self' https://cdn.flopay.com;`.
|
|
314
|
+
> A failed or CSP-blocked logo request falls back to the method's existing
|
|
315
|
+
> inline monogram, so the tile remains branded without another network request.
|
|
294
316
|
|
|
295
317
|
In `layout="buttons"`, the **Credit / Debit Card** button always opens the
|
|
296
318
|
inline card form. External wallets and PayPal keep their own lifecycle:
|
|
@@ -440,7 +462,7 @@ Skip the backend API route — create the session directly in the component:
|
|
|
440
462
|
clientId: 'your-client-id',
|
|
441
463
|
currency: 'EUR',
|
|
442
464
|
items: [{ providerItemId: 'product-1', providerItemName: 'Widget', totalAmount: 29.99 }],
|
|
443
|
-
account: { userId: 'user_1', email
|
|
465
|
+
account: { userId: 'user_1' }, // email and name are collected in checkout
|
|
444
466
|
successUrl: '/success',
|
|
445
467
|
cancelUrl: '/cancel',
|
|
446
468
|
}}
|
|
@@ -448,7 +470,8 @@ Skip the backend API route — create the session directly in the component:
|
|
|
448
470
|
/>
|
|
449
471
|
```
|
|
450
472
|
|
|
451
|
-
The component
|
|
473
|
+
The component creates a lightweight shell, renders the form, and claims the
|
|
474
|
+
session after buyer identity is available — zero merchant backend code needed.
|
|
452
475
|
|
|
453
476
|
#### Authorisation-only checkout
|
|
454
477
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var U=Object.defineProperty;var oe=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var se=(e,t)=>{for(var o in t)U(e,o,{get:t[o],enumerable:!0})},ie=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ne(t))!ae.call(e,r)&&r!==o&&U(e,r,{get:()=>t[r],enumerable:!(n=oe(t,r))||n.enumerable});return e};var le=e=>ie(U({},"__esModule",{value:!0}),e);var pe={};se(pe,{FloPayCardSetup:()=>re,FloPayCardSetupError:()=>T});module.exports=le(pe);var O=require("@flopay/js/card-setup"),c=require("@flopay/shared"),a=require("react");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 i=require("react/jsx-runtime");function j({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
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 S=require("react"),
|
|
6
|
+
`})]})})}var S=require("react"),K=require("react/jsx-runtime");function J({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?.())},D=e.on("ready",()=>{V()}),L=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)}),I={html:t,...o?{messageToken:o}:{},...n?{expectedOrigin:n}:{},...d.current?{theme:d.current}:{}};return e.mount(F,I).then(()=>{V()}).catch(p=>{v&&w.current?.(p instanceof Error?p.message:"Failed to load the secure card form.")}),()=>{v=!1,D(),L(),h(),e.unmount()}},[e,t,o,n]),(0,S.useEffect)(()=>{r&&e.applyTheme?.(r)},[e,r]),(0,K.jsx)("div",{ref:C,"data-testid":"flopay-vault-card-fields",style:m})}function ce(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 ue(e){if(typeof e=="number"||typeof e=="string")return e}function Q({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)??ce(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(ue(g?.fontWeight)??400),borderRadius:r(n?.borderRadius)??"8px"}}var f=require("react/jsx-runtime"),T=class extends c.FloPayError{constructor(t,o,n){super(t,o,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function ee(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 T(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 re({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,D]=(0,a.useState)(null),[L,h]=(0,a.useState)(null),[I,p]=(0,a.useState)(null),P=(0,a.useRef)(!1),B=(0,a.useRef)(!1),te=(0,a.useMemo)(()=>{if(typeof r=="object")return r;let s=(0,c.resolveTheme)(r);if(s)return Q({appearance:s.appearance,buttonsStyles:s.buttonsLayout,layout:"default"})},[r]),H=(0,a.useRef)(y),N=(0,a.useRef)(k),G=(0,a.useRef)(g),q=(0,a.useRef)(C),X=(0,a.useRef)(x),$=(0,a.useRef)(w),_=(0,a.useRef)(!1),W=(0,a.useRef)(!1),Y=(0,a.useRef)(0);return H.current=y,N.current=k,G.current=g,q.current=C,X.current=x,$.current=w,(0,a.useEffect)(()=>{let s=Y.current+1;return Y.current=s,()=>{queueMicrotask(()=>{Y.current===s&&(_.current||W.current||(W.current=!0,R(()=>{X.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,a.useEffect)(()=>{let s=!0,b=new O.PaymentAPI((0,c.resolveBillingApiUrl)(o),{telemetry:n});return F(null),A(null),D(null),_.current=!1,W.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 O.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:n}))}catch(M){if(!s)return;let E=ee(M);_.current=!0,D(E),R(()=>N.current?.(E))}})(),()=>{s=!1,b.destroy()}},[o,t,e,n]),(0,a.useEffect)(()=>{if(!d)return;let s=!1;B.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(z=>setTimeout(z,1200)),!B.current&&(B.current=!0,R(()=>{G.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(()=>{q.current?.({status:"declined",sessionId:e,...l.declineReason?{reason:l.declineReason}:{},...l.message?{message:l.message}:{}})}),(async()=>(await new Promise(z=>setTimeout(z,1500)),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:[L&&(0,f.jsx)(j,{status:L,errorMessage:I,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),(0,f.jsx)(J,{capture:d,html:v.html,messageToken:v.messageToken,expectedOrigin:v.expectedOrigin,theme:te,containerStyle:m,onReady:()=>{R(()=>H.current?.())},onValidation:s=>{R(()=>$.current?.(s))},onError:s=>{if(!s)return;P.current&&(P.current=!1,p(s),h("error"),setTimeout(()=>h(null),1500));let b=ee(new Error(s),{code:"card_setup_widget_failed",retryable:!0});R(()=>N.current?.(b))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as e,h as t}from"./chunk-
|
|
1
|
+
import{g as e,h as t}from"./chunk-W24FSJC5.mjs";export{t as FloPayCardSetup,e as FloPayCardSetupError};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{useEffect as J,useRef as M}from"react";import{jsx as ne}from"react/jsx-runtime";function K({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,J(()=>{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)}),I={html:n,...t?{messageToken:t}:{},...o?{expectedOrigin:o}:{},...c.current?{theme:c.current}:{}};return e.mount(P,I).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]),J(()=>{r&&e.applyTheme?.(r)},[e,r]),ne("div",{ref:y,"data-testid":"flopay-vault-card-fields",style:f})}import{PaymentAPI as le,PciVaultCardCapture as ce}from"@flopay/js/card-setup";import{FloPayError as E,isCardSetupCheckoutSession as ue,resolveBillingApiUrl as de,resolveTheme as fe}from"@flopay/shared";import{useEffect as U,useMemo as pe,useRef as u,useState as T}from"react";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{jsx as l,jsxs as w}from"react/jsx-runtime";function Q({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 ae(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 se(e){if(typeof e=="number"||typeof e=="string")return e}function Z({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)??ae(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(se(m?.fontWeight)??400),borderRadius:r(o?.borderRadius)??"8px"}}import{Fragment as te,jsx as O,jsxs as me}from"react/jsx-runtime";var H=class extends E{constructor(n,t,o){super(n,t,o),this.name="FloPayCardSetupError",this.retryable=o.retryable}};function re(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 H(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 Ae({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),[I,d]=T(null),b=u(!1),B=u(!1),oe=pe(()=>{if(typeof r=="object")return r;let a=fe(r);if(a)return Z({appearance:a.appearance,buttonsStyles:a.buttonsLayout,layout:"default"})},[r]),G=u(p),N=u(x),q=u(m),X=u(y),$=u(k),j=u(R),V=u(!1),W=u(!1),Y=u(0);return G.current=p,N.current=x,q.current=m,X.current=y,$.current=k,j.current=R,U(()=>{let a=Y.current+1;return Y.current=a,()=>{queueMicrotask(()=>{Y.current===a&&(V.current||W.current||(W.current=!0,S(()=>{$.current?.({status:"cancelled",sessionId:e})})))})}},[e]),U(()=>{let a=!0,v=new le(de(t),{telemetry:o});return P(null),F(null),L(null),V.current=!1,W.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||!ue(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 ce({sessionId:e,operation:"card_setup",telemetry:o}))}catch(_){if(!a)return;let C=re(_);V.current=!0,L(C),S(()=>N.current?.(C))}})(),()=>{a=!1,v.destroy()}},[t,n,e,o]),U(()=>{if(!c)return;let a=!1;B.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(z=>setTimeout(z,1200)),!B.current&&(B.current=!0,S(()=>{q.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(()=>{X.current?.({status:"declined",sessionId:e,...s.declineReason?{reason:s.declineReason}:{},...s.message?{message:s.message}:{}})}),(async()=>(await new Promise(z=>setTimeout(z,1500)),a||g(null)))()});return()=>{a=!0,v(),_(),C()}},[c,e]),A?O("div",{role:"alert",children:A.message}):!c||!h?.html?O(te,{children:i}):me(te,{children:[D&&O(Q,{status:D,errorMessage:I,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null}),O(K,{capture:c,html:h.html,messageToken:h.messageToken,expectedOrigin:h.expectedOrigin,theme:oe,containerStyle:f,onReady:()=>{S(()=>G.current?.())},onValidation:a=>{S(()=>j.current?.(a))},onError:a=>{if(!a)return;b.current&&(b.current=!1,d(a),g("error"),setTimeout(()=>g(null),1500));let v=re(new Error(a),{code:"card_setup_widget_failed",retryable:!0});S(()=>N.current?.(v))}})]})}export{S as a,Q as b,K as c,ae as d,se as e,Z as f,H as g,Ae as h};
|