@flopay/react 1.9.11 → 1.9.14
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 +71 -2
- package/dist/card-setup-entry.cjs +2 -2
- package/dist/card-setup-entry.mjs +1 -1
- package/dist/chunk-Z6LBB432.mjs +6 -0
- package/dist/index.cjs +9 -9
- package/dist/index.d.cts +45 -3
- package/dist/index.d.ts +45 -3
- package/dist/index.mjs +8 -8
- package/package.json +3 -3
- package/dist/chunk-M4FGYFX6.mjs +0 -6
package/README.md
CHANGED
|
@@ -80,6 +80,29 @@ whitespace normalization, so an authorised wallet name can replace it. Name
|
|
|
80
80
|
selection is atomic: first and last name always come from one source, and are
|
|
81
81
|
omitted when neither source is usable. Email precedence is unchanged.
|
|
82
82
|
|
|
83
|
+
#### Wallet confirmation recovery
|
|
84
|
+
|
|
85
|
+
Google Pay and Apple Pay authentication may legitimately outlive the SDK's
|
|
86
|
+
provider observation threshold. The SDK does not cancel that provider promise.
|
|
87
|
+
Instead, it retrieves the original PaymentIntent or SetupIntent with the same
|
|
88
|
+
client secret and routes the provider promise and status read through one
|
|
89
|
+
settlement gate:
|
|
90
|
+
|
|
91
|
+
- an authoritative success continues to `/process` exactly once;
|
|
92
|
+
- `canceled` or `requires_payment_method` is treated as authoritative,
|
|
93
|
+
non-chargeable terminal evidence and exposes wallet retry;
|
|
94
|
+
- `requires_action`, an unavailable/mismatched status, or a failed/bounded-out
|
|
95
|
+
status read keeps payment submission locked and exposes only **Check payment
|
|
96
|
+
status**.
|
|
97
|
+
|
|
98
|
+
Rejected confirmations, returned technical errors, and malformed fulfilled
|
|
99
|
+
results use this same recovery contract. A lost intent-create response also
|
|
100
|
+
reuses the authorization-attempt UUID on deliberate retry, so provider
|
|
101
|
+
idempotency cannot mint a second intent. A bounded pending-confirmation handoff
|
|
102
|
+
keeps teardown/remount from exposing another wallet surface while the first
|
|
103
|
+
intent may still complete. Existing component props and merchant callbacks are
|
|
104
|
+
unchanged.
|
|
105
|
+
|
|
83
106
|
#### Merchant instrument feed
|
|
84
107
|
|
|
85
108
|
Use `onInstrument` on `FloPayCheckout` or `FloPayProvider` to forward a stable,
|
|
@@ -139,6 +162,49 @@ backend telemetry setting, so `telemetry={false}` does not disable it.
|
|
|
139
162
|
|
|
140
163
|
The mode can also be set on the session itself via the billing API's `checkoutMode` field. The `checkoutMode` prop overrides the session value.
|
|
141
164
|
|
|
165
|
+
`confirmLabel` only labels the saved-payment button in confirm mode. To change
|
|
166
|
+
the full checkout's hosted card button, use
|
|
167
|
+
[`submitLabel`](#hosted-card-submit-label).
|
|
168
|
+
|
|
169
|
+
#### Hosted card submit label
|
|
170
|
+
|
|
171
|
+
In full checkout, the button that pays by card lives inside the hosted vault
|
|
172
|
+
widget. Set `submitLabel` on `FloPayCheckout` (or `SplitCardForm`) to replace
|
|
173
|
+
its wording, for example with the amount the buyer is about to pay:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<FloPayCheckout
|
|
177
|
+
sessionId="sess_abc123"
|
|
178
|
+
submitLabel={`Pay ${orderSummary.formattedTotal}`} // e.g. "Pay $10"
|
|
179
|
+
onComplete={handleSuccess}
|
|
180
|
+
/>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
- **Merchant-owned wording.** Pass the final, already-localized plain text
|
|
184
|
+
from your own order summary. The SDK does not calculate, format, or translate
|
|
185
|
+
the amount; it sends your string unchanged.
|
|
186
|
+
- **Live updates.** Changing the prop updates the hosted button in place,
|
|
187
|
+
without remounting the card form, so the buyer's entered card details, focus,
|
|
188
|
+
and caret are kept. The SDK re-sends the latest label whenever the hosted
|
|
189
|
+
form becomes ready again.
|
|
190
|
+
- **Defaults and reset.** Omit the prop (or pass `null`) to keep the hosted
|
|
191
|
+
default, `CONFIRM PAYMENT`. Clearing it after a label was shown restores that
|
|
192
|
+
default, and so does blank text: the hosted form trims the label, allows up to 64
|
|
193
|
+
characters, rejects control and hidden formatting characters, and shows the
|
|
194
|
+
default for anything it rejects. Card setup (`FloPayCardSetup`) keeps its own
|
|
195
|
+
`ADD CARD` wording.
|
|
196
|
+
- **Prop ownership.** `submitLabel` only changes the hosted card button.
|
|
197
|
+
`confirmLabel` labels the saved-payment button in `checkoutMode="confirm"`,
|
|
198
|
+
`cardButtonContent` renders the buttons-layout card tile, and wallet, PayPal,
|
|
199
|
+
processing, and retry wording is unchanged.
|
|
200
|
+
- **Custom layouts.** Like `sessionId` and `nonce`, `FloPayCheckout` injects
|
|
201
|
+
`submitLabel` into its direct custom-layout children; a child's own
|
|
202
|
+
`submitLabel` wins.
|
|
203
|
+
- **Compatibility.** Custom labels need billing API v1.9.35+, whose vault block
|
|
204
|
+
carries the `messageToken` and `expectedOrigin` that authenticate the label.
|
|
205
|
+
The SDK sends the label only to that exact origin, bound to the checkout
|
|
206
|
+
session. Against an older backend the hosted form keeps its default.
|
|
207
|
+
|
|
142
208
|
### Secure saved-card setup
|
|
143
209
|
|
|
144
210
|
Use `FloPayCardSetup` to let a customer add or verify a card without creating a
|
|
@@ -837,8 +903,10 @@ PaymentIntent (created **and** confirmed server-side), **3DS**, and the result,
|
|
|
837
903
|
so **no Stripe.js runs on the card path** and PAN / CVC never enter the SDK
|
|
838
904
|
runtime. Wallets / PayPal / APMs render exactly as before.
|
|
839
905
|
|
|
840
|
-
Because the widget owns the form, `SplitCardForm`
|
|
841
|
-
|
|
906
|
+
Because the widget owns the form, `SplitCardForm` renders no SDK card-entry
|
|
907
|
+
fields or submit button of its own; `submitLabel` only sets the wording of the
|
|
908
|
+
widget's button (see [Hosted card submit label](#hosted-card-submit-label)).
|
|
909
|
+
Host-collected AVS fields remain outside the PCI
|
|
842
910
|
widget and gate its submit. The flow is:
|
|
843
911
|
|
|
844
912
|
```text
|
|
@@ -1134,6 +1202,7 @@ Key payment-surface props include:
|
|
|
1134
1202
|
| `directPaypal` | `{ clientId: string; environment?: GatewayEnvironment }?` | *Deprecated input on `FloPayCheckout`* — auto-resolved from `gateways.paypal` on the session response. Still accepted on `SplitCardForm` for advanced consumers wiring providers manually. |
|
|
1135
1203
|
| `totalAmount` | `number` | Amount in cents for PayPal / wallet config |
|
|
1136
1204
|
| `currency` | `string` | Currency code for PayPal / wallet config (default: `'usd'`) |
|
|
1205
|
+
| `submitLabel` | `(string \| null)?` | Final, already-localized wording for the hosted card button (e.g. `'Pay $10'`). Updates live without remounting the card form; omitted, cleared, `null`, or blank shows the hosted default `CONFIRM PAYMENT`. See [Hosted card submit label](#hosted-card-submit-label). |
|
|
1137
1206
|
| `onFirstNameChange` | `(value: string) => void` | First name change callback |
|
|
1138
1207
|
| `onLastNameChange` | `(value: string) => void` | Last name change callback |
|
|
1139
1208
|
| `onBuyerIdentityReady` | `(identity) => MaybePromise<void>?` | Called once checkout has collected a missing buyer email (or a wallet / PayPal approval supplied one) on a still-anonymous session. `FloPayCheckout` wires its late-buyer `PATCH /claim` here — including for custom-layout children, via `CheckoutContext`. A standalone form around a `session` with `buyerIdentified: false` that is given neither a prop nor a context claim builds its own from `sessionId` + `nonce`, so the hosted vault charge is never submitted against an unbound buyer. Supply the prop to take the claim over yourself. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var J=Object.defineProperty;var xe=Object.getOwnPropertyDescriptor;var ve=Object.getOwnPropertyNames;var Fe=Object.prototype.hasOwnProperty;var Ee=(e,r)=>{for(var t in r)J(e,t,{get:r[t],enumerable:!0})},Pe=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of ve(r))!Fe.call(e,o)&&o!==t&&J(e,o,{get:()=>r[o],enumerable:!(n=xe(r,o))||n.enumerable});return e};var Te=e=>Pe(J({},"__esModule",{value:!0}),e);var Je={};Ee(Je,{FloPayCardSetup:()=>Re,FloPayCardSetupError:()=>W});module.exports=Te(Je);var U=require("@flopay/js/card-setup"),h=require("@flopay/shared"),u=require("react");function ae(e,r){if(!e)return r;let t=r??{},n=Object.keys(t),o=n.some(i=>i.startsWith("background")),a={};for(let[i,l]of Object.entries(e))i in t||o&&i.startsWith("background")||(a[i]=l);for(let i of n)a[i]=t[i];return a}var Ve=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","scale","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]);function Ae(e){let r=e.replace(/^(Webkit|Moz|ms)(?=[A-Z])/,"");return Ve.has(r.charAt(0).toLowerCase()+r.slice(1))}function Le(e,r){return typeof r=="number"&&r!==0&&!Ae(e)?`${r}px`:String(r).trim()}function ie(e,r){if(e.style.cssText="",!!r){for(let[t,n]of Object.entries(r))if(!(n==null||n==="")){if(t.startsWith("--")){e.style.setProperty(t,String(n));continue}e.style[t]=Le(t,n)}}}var se={light:{success:"#166534",error:"#991B1B"},dark:{success:"#4ADE80",error:"#FCA5A5"}};function ue(e){let r=e.appearance.variables??{},t=e.buttonsLayout.cardFormContainer??{},n=e.appearance.theme==="night",o=n?se.dark:se.light,a=r.colorText??(n?"#F1F5F9":"#262833"),i=e.appearance.rules?.[".Label"];return{panel:{...t.background===void 0?{}:{background:t.background},...t.backgroundColor===void 0?{}:{backgroundColor:t.backgroundColor},...t.border===void 0?{}:{border:t.border},...t.borderRadius===void 0?{}:{borderRadius:t.borderRadius},...t.boxShadow===void 0?{}:{boxShadow:t.boxShadow},color:a,...r.fontFamily?{fontFamily:r.fontFamily}:{}},spinnerTrackColor:e.buttonsLayout.cardInputBorder??(n?"#374151":"#e5e7eb"),spinnerAccentColor:r.colorPrimary??"#4A49FF",labelColors:{processing:a,success:o.success,error:o.error},noteColor:i?.color??a}}function T(e){if(!e)return;let r=t=>{console.error("[FloPay] Merchant callback failed; checkout continued.",t)};try{Promise.resolve(e()).catch(r)}catch(t){r(t)}}var d=require("react/jsx-runtime");var Be={panel:{background:"white"},spinnerTrackColor:"#e5e7eb",spinnerAccentColor:"#4A49FF",labelColors:{processing:"#374151",success:"#16a34a",error:"#dc2626"},noteColor:"#6b7280"};function le({status:e,errorMessage:r,authorized:t=!1,processingLabel:n="PROCESSING...",successLabel:o,errorLabel:a="PAYMENT FAILED",successNote:i="You will be automatically redirected, do not close or navigate away from this window.",theme:l=Be}){let s={fontSize:13,color:l.noteColor,fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0};return(0,d.jsx)("div",{"data-testid":"flopay-processing-overlay","data-status":e,role:"dialog","aria-modal":"true",style:{position:"fixed",inset:0,background:"rgba(0,0,0,0.35)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3,backdropFilter:"blur(2px)"},children:(0,d.jsxs)("div",{"data-testid":"flopay-processing-overlay-panel",style:{borderRadius:12,boxShadow:"0 8px 32px rgba(0,0,0,0.18)",...l.panel,padding:"2rem 2.5rem",textAlign:"center",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[(0,d.jsxs)("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{animation:"flopay-spin 0.8s linear infinite"},children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"10",stroke:l.spinnerTrackColor,strokeWidth:"3"}),(0,d.jsx)("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:l.spinnerAccentColor})]}),e==="success"&&(0,d.jsx)("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),(0,d.jsx)("path",{d:"M7 12.5l3 3 7-7",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{strokeDasharray:20,strokeDashoffset:20,animation:"flopay-draw 0.4s 0.15s ease forwards"}})]})}),e==="error"&&(0,d.jsx)("div",{style:{animation:"flopay-shake 0.4s ease"},children:(0,d.jsxs)("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[(0,d.jsx)("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),(0,d.jsx)("path",{d:"M8 8l8 8M16 8l-8 8",stroke:"white",strokeWidth:"2.5",strokeLinecap:"round",style:{strokeDasharray:12,strokeDashoffset:12,animation:"flopay-draw 0.3s 0.1s ease forwards"}})]})})]}),(0,d.jsxs)("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:l.labelColors[e]},children:[e==="processing"&&n,e==="success"&&(o??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&a]}),e==="success"&&i!==null&&(0,d.jsx)("p",{style:s,children:i}),e==="error"&&r&&(0,d.jsx)("p",{style:s,children:r}),(0,d.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 k=require("react");var z=require("react"),se=typeof window>"u"?z.useEffect:z.useLayoutEffect;var le=require("react/jsx-runtime");function ue({capture:e,html:r,messageToken:t,expectedOrigin:n,theme:o,containerStyle:a,onReady:i,onError:l,onValidation:s}){let c=(0,k.useRef)(null),d=(0,k.useRef)(i),m=(0,k.useRef)(l),C=(0,k.useRef)(s);d.current=i,m.current=l,C.current=s;let g=(0,k.useRef)(o);g.current=o;let T=(0,k.useRef)(null);return(0,k.useEffect)(()=>{let S=c.current;if(!S)return;let V=!0,A=!1,L=()=>{!V||A||(A=!0,d.current?.())},D=e.on("ready",()=>{L()}),x=e.on("error",y=>{m.current?.(y.message??"There was a problem loading the secure card form.")}),G=e.on("validation",y=>{C.current?.(y.message??null)}),B={html:r,...t?{messageToken:t}:{},...n?{expectedOrigin:n}:{},...g.current?{theme:g.current}:{}};return T.current=g.current??null,e.mount(S,B).then(()=>{L()}).catch(y=>{V&&m.current?.(y instanceof Error?y.message:"Failed to load the secure card form.")}),()=>{V=!1,D(),x(),G(),e.unmount()}},[e,r,t,n]),se(()=>{let S=c.current;S&&ne(S,a)},[a]),(0,k.useEffect)(()=>{o!==void 0&&(o===null&&T.current===null||(T.current=o,e.applyTheme?.(o)))},[e,o]),(0,le.jsx)("div",{ref:c,"data-testid":"flopay-vault-card-fields"})}var de=/^#([0-9a-f]{6})$/i,Be=/^#([0-9a-f]{3})$/i,fe=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i,pe=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+|1\.0+)\s*\)$/i,Oe=/^linear-gradient\(\s*(-?\d+(?:\.\d+)?)deg\s*,\s*(.+)\)$/i,Ie=/^(-?\d+(?:\.\d+)?)(?:px)?$/,Me=/^(-?\d+(?:\.\d+)?)em$/,_e=/^blur\(\s*(\d+(?:\.\d+)?)(?:px)?\s*\)$/i,Ne=/^[a-z][a-z0-9 -]{0,31}$/i,De=new Set(["none","uppercase","lowercase","capitalize"]);function me(e){if(typeof e!="string")return null;let r=e.trim(),t=de.exec(r);if(t){let d=Number.parseInt(t[1],16);return{r:d>>16&255,g:d>>8&255,b:d&255,a:null}}let n=Be.exec(r);if(n){let[d,m,C]=n[1].split("").map(g=>Number.parseInt(g+g,16));return{r:d,g:m,b:C,a:null}}let o=fe.exec(r),a=o?null:pe.exec(r),i=o??a;if(!i)return null;let l=Number(i[1]),s=Number(i[2]),c=Number(i[3]);return l>255||s>255||c>255?null:{r:l,g:s,b:c,a:a?Number(a[4]):null}}function ge({r:e,g:r,b:t,a:n}){return n===null?`#${(1<<24|e<<16|r<<8|t).toString(16).slice(1)}`:`rgba(${e},${r},${t},${n})`}function M(e){if(typeof e!="string")return;let r=e.trim();if(de.test(r)||fe.test(r))return r;let t=pe.exec(r);if(t&&/^\d/.test(t[4]))return r;let n=me(r);return n?ge(n):void 0}function W(e,r=.12){let t=me(e);if(!t)return e;let n=Math.max(0,Math.min(1,1-r));return ge({r:Math.round(t.r*n),g:Math.round(t.g*n),b:Math.round(t.b*n),a:t.a})}function _(e,r){let t=[],n=0,o="";for(let a of e){if(a==="("&&(n+=1),a===")"&&(n-=1),a===r&&n===0){o.trim()&&t.push(o.trim()),o="";continue}o+=a}return o.trim()&&t.push(o.trim()),t}function P(e,r,t){if(typeof e!="number"&&typeof e!="string")return;let n=Ie.exec(String(e).trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function ze(e,r,t){if(typeof e!="string")return;let n=Me.exec(e.trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function We(e){let r=_(e,",");if(r.length<2||r.length>5)return;let t=[];for(let[n,o]of r.entries()){let a=_(o," "),i=M(a[0]);if(!i)return;let l=n/(r.length-1)*100,s=a[1]===void 0?l:Number(/^(\d+(?:\.\d+)?)%$/.exec(a[1])?.[1]),c=t[t.length-1]?.position??-1;if(!Number.isFinite(s)||s<0||s>100||s<c)return;t.push({color:i,position:s})}return{type:"linearGradient",angle:0,stops:t}}function $e(e){if(typeof e!="string")return;let r=e.trim(),t=M(r);if(t)return{type:"solid",color:t};let n=Oe.exec(r);if(!n)return;let o=Number(n[1]);if(!Number.isFinite(o)||o<0||o>360)return;let a=We(n[2]);return a&&a.type==="linearGradient"?{...a,angle:o}:void 0}function Ge(e){return e.type==="solid"?{type:"solid",color:W(e.color)}:{...e,stops:e.stops.map(r=>({...r,color:W(r.color)}))}}function He(e){let r=!1,t,n=[];for(let s of _(e," ")){if(s.toLowerCase()==="inset"){r=!0;continue}let c=M(s);if(c){t=c;continue}let d=P(s,-128,128);if(d===void 0)return;n.push(d)}if(!t||n.length<2||n.length>4)return;let[o,a,i=0,l=0]=n;if(!(Math.abs(o)>64||Math.abs(a)>64||i>128||Math.abs(l)>32))return{color:t,inset:r,offsetX:o,offsetY:a,blur:i,spread:l}}function Ye(e){if(typeof e!="string")return;let r=e.trim();if(r.toLowerCase()==="none")return[];let t=_(r,",").map(He);if(!(t.length===0||t.length>4))return t.every(n=>n!==void 0)?t:void 0}function ce(e){if(typeof e!="string")return;let r=_(e,",").map(t=>t.replace(/^['"]|['"]$/g,"").trim()).filter(t=>Ne.test(t)).slice(0,4);return r.length>0?r:void 0}function Ue(e){let r=typeof e=="string"?e.trim().split(/\s+/):[e],t=P(r[0],0,64),n=P(r[1]??r[0],0,64);if(!(t===void 0||n===void 0))return{paddingBlock:t,paddingInline:n}}function Xe(e){if(e==="bold")return 700;if(e==="normal")return 400;let r=Number(e);return Number.isInteger(r)&&r>=100&&r<=900?r:void 0}function ye({appearance:e,buttonsStyles:r,fontFamily:t}){let n=r.submitButton;if(!n)return;let o=e?.variables,a=$e(n.background??n.backgroundColor),i=M(o?.colorPrimaryHover),l=i?{type:"solid",color:i}:a&&Ge(a),s={fontFamilies:ce(n.fontFamily)??ce(t),fontSize:P(n.fontSize??r.submitButtonFontSize,10,32)??16,fontWeight:Xe(n.fontWeight)??600,letterSpacing:ze(n.letterSpacing,-.1,.5)??.01,lineHeight:P(n.lineHeight,.8,2)??1,textTransform:De.has(String(n.textTransform))?n.textTransform:"uppercase"},c=Ue(n.padding),d=Ye(n.boxShadow),m=P(n.borderRadius,0,9999),C=typeof n.backdropFilter=="string"?P(_e.exec(n.backdropFilter.trim())?.[1],0,40):void 0;return{foregroundColor:M(n.color)??"#FFFFFF",...a?{background:a,disabledBackground:a}:{},...l?{hoverBackground:l}:{},typography:s,...c?{spacing:c}:{},...d?{shadow:d}:{},...m===void 0?{}:{borderRadius:m},disabledOpacity:e?.theme==="night"?.8:.6,...C===void 0?{}:{backdropBlur:C}}}function je(e,r=.12){let t=e.trim(),n=/^[0-9a-fA-F]{6}$/.test(t)?`#${t}`:t;return/^#[0-9a-fA-F]{6}$/.test(n)?W(n,r):e}function qe(e){if(typeof e=="number"||typeof e=="string")return e}function he({appearance:e,buttonsStyles:r,layout:t="default"}){let n=e?.variables,o=m=>typeof m=="string"&&m?m:void 0,a=r.submitButton,i=o(n?.colorPrimary)??o(a?.backgroundColor)??"#4A49FF",l=t==="buttons",s=r.nameInput,c=o(s?.fontFamily)??o(n?.fontFamily)??"Poppins, sans-serif",d=ye({appearance:e,buttonsStyles:r,fontFamily:c});return{primaryColor:i,primaryHoverColor:o(n?.colorPrimaryHover)??je(i,.12),inputBackgroundColor:o(r.cardInputBackground)??o(n?.colorBackground)??"#ffffff",textColor:o(r.cardInputColor)??o(s?.color)??o(n?.colorText)??"#262833",borderColor:o(r.cardInputBorder)??(l?"#e5e7eb":"#A4A4FF"),placeholderColor:o(r.cardInputPlaceholderColor)??"#9ca3af",errorColor:o(n?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:c,fontSize:o(r.cardInputFontSize)??o(n?.fontSizeBase)??"16px",fontWeight:String(qe(s?.fontWeight)??400),borderRadius:o(n?.borderRadius)??"8px",...d?{submitButton:d}:{}}}var w=require("react/jsx-runtime"),N=class extends b.FloPayError{constructor(r,t,n){super(r,t,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function Ce(e,r={}){let t=e instanceof b.FloPayError?e:void 0,n=t?.statusCode,o=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof n=="number"&&n>=500||t?.code==="vault_capture_timeout"||!t);return new N(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:o,...t?.param?{param:t.param}:{},...n===void 0?{}:{statusCode:n}})}function Se({sessionId:e,nonce:r,billingApiUrl:t,telemetry:n,theme:o="modern-light",containerStyle:a,loading:i=null,onReady:l,onComplete:s,onDecline:c,onCancel:d,onValidation:m,onError:C}){let[g,T]=(0,u.useState)(null),[S,V]=(0,u.useState)(null),[A,L]=(0,u.useState)(null),[D,x]=(0,u.useState)(null),[G,B]=(0,u.useState)(null),y=(0,u.useRef)(!1),H=(0,u.useRef)(!1),R=(0,u.useMemo)(()=>typeof o=="object"?void 0:(0,b.resolveTheme)(o),[o]),ke=(0,u.useMemo)(()=>typeof o=="object"?o:R?he({appearance:R.appearance,buttonsStyles:R.buttonsLayout,layout:"default"}):null,[R,o]),we=(0,u.useMemo)(()=>te(R?.buttonsLayout.cardFormContainer,a),[R,a]),K=(0,u.useMemo)(()=>R?ae(R):void 0,[R]),Z=(0,u.useRef)(l),Y=(0,u.useRef)(C),J=(0,u.useRef)(s),Q=(0,u.useRef)(c),ee=(0,u.useRef)(d),re=(0,u.useRef)(m),O=(0,u.useRef)(!1),U=(0,u.useRef)(!1),X=(0,u.useRef)(0);return Z.current=l,Y.current=C,J.current=s,Q.current=c,ee.current=d,re.current=m,(0,u.useEffect)(()=>{let p=X.current+1;return X.current=p,()=>{queueMicrotask(()=>{X.current===p&&(O.current||U.current||(U.current=!0,F(()=>{ee.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,u.useEffect)(()=>{let p=!0,E=new $.PaymentAPI((0,b.resolveBillingApiUrl)(t),{telemetry:n});return T(null),V(null),L(null),O.current=!1,U.current=!1,(async()=>{try{if(!e.trim())throw new b.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new b.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let I=await E.getUnifiedCheckoutSession(e,r);if(!p)return;let v=I.data.session;if(!v||!(0,b.isCardSetupCheckoutSession)(v))throw new b.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let h=v.vault;if(h?.html?.trim()||(h=await E.getVaultCapture(e,r)),!h.html?.trim())throw new b.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!p)return;V(h),T(new $.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:n}))}catch(I){if(!p)return;let v=Ce(I);O.current=!0,L(v),F(()=>Y.current?.(v))}})(),()=>{p=!1,E.destroy()}},[t,r,e,n]),(0,u.useEffect)(()=>{if(!g)return;let p=!1;H.current=!1,y.current=!1;let E=g.on("submitting",()=>{y.current=!0,B(null),x("processing")}),I=g.on("complete",h=>{O.current=!0,y.current=!1,x("success"),(async()=>(await new Promise(j=>setTimeout(j,600)),!H.current&&(H.current=!0,F(()=>{J.current?.({status:"succeeded",sessionId:e,...h.paymentMethod?{paymentMethod:h.paymentMethod}:{}})}),p||x(null))))()}),v=g.on("decline",h=>{O.current=!0,y.current=!1,B(h.message??null),x("error"),F(()=>{Q.current?.({status:"declined",sessionId:e,...h.declineReason?{reason:h.declineReason}:{},...h.message?{message:h.message}:{}})}),(async()=>(await new Promise(j=>setTimeout(j,400)),p||x(null)))()});return()=>{p=!0,E(),I(),v()}},[g,e]),A?(0,w.jsx)("div",{role:"alert",children:A.message}):!g||!S?.html?(0,w.jsx)(w.Fragment,{children:i}):(0,w.jsxs)(w.Fragment,{children:[D&&(0,w.jsx)(ie,{status:D,errorMessage:G,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...K?{theme:K}:{}}),(0,w.jsx)(ue,{capture:g,html:S.html,messageToken:S.messageToken,expectedOrigin:S.expectedOrigin,theme:ke,containerStyle:we,onReady:()=>{F(()=>Z.current?.())},onValidation:p=>{F(()=>re.current?.(p))},onError:p=>{if(!p)return;y.current&&(y.current=!1,B(p),x("error"),setTimeout(()=>x(null),400));let E=Ce(new Error(p),{code:"card_setup_widget_failed",retryable:!0});F(()=>Y.current?.(E))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
|
|
6
|
+
`})]})})}var b=require("react");var H=require("react"),ce=typeof window>"u"?H.useEffect:H.useLayoutEffect;var fe=require("react/jsx-runtime"),Q=new WeakSet;function de({capture:e,html:r,messageToken:t,expectedOrigin:n,theme:o,submitLabel:a,containerStyle:i,onReady:l,onError:s,onValidation:f}){let c=(0,b.useRef)(null),m=(0,b.useRef)(l),C=(0,b.useRef)(s),g=(0,b.useRef)(f);m.current=l,C.current=s,g.current=f;let V=(0,b.useRef)(o);V.current=o;let v=(0,b.useRef)(null),w=a??void 0,A=(0,b.useRef)(w);A.current=w;let O=(0,b.useRef)(void 0);return(0,b.useEffect)(()=>{let F=c.current;if(!F)return;let S=!0,$=!1,I=()=>{!S||$||($=!0,m.current?.())},E=e.on("ready",()=>{I()}),M=e.on("error",x=>{C.current?.(x.message??"There was a problem loading the secure card form.")}),k=e.on("validation",x=>{g.current?.(x.message??null)}),G=A.current??(Q.has(e)?null:void 0),X={html:r,...t?{messageToken:t}:{},...n?{expectedOrigin:n}:{},...V.current?{theme:V.current}:{},...G===void 0?{}:{submitLabel:G}};return v.current=V.current??null,O.current=A.current,A.current!==void 0&&Q.add(e),e.mount(F,X).then(()=>{I()}).catch(x=>{S&&C.current?.(x instanceof Error?x.message:"Failed to load the secure card form.")}),()=>{S=!1,E(),M(),k(),e.unmount()}},[e,r,t,n]),ce(()=>{let F=c.current;F&&ie(F,i)},[i]),(0,b.useEffect)(()=>{o!==void 0&&(o===null&&v.current===null||(v.current=o,e.applyTheme?.(o)))},[e,o]),(0,b.useEffect)(()=>{w!==O.current&&(O.current=w,w!==void 0&&Q.add(e),e.setSubmitLabel?.(w??null))},[e,w]),(0,fe.jsx)("div",{ref:c,"data-testid":"flopay-vault-card-fields"})}var me=/^#([0-9a-f]{6})$/i,Oe=/^#([0-9a-f]{3})$/i,ge=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i,ye=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+|1\.0+)\s*\)$/i,Ie=/^linear-gradient\(\s*(-?\d+(?:\.\d+)?)deg\s*,\s*(.+)\)$/i,Me=/^(-?\d+(?:\.\d+)?)(?:px)?$/,_e=/^(-?\d+(?:\.\d+)?)em$/,Ne=/^blur\(\s*(\d+(?:\.\d+)?)(?:px)?\s*\)$/i,De=/^[a-z][a-z0-9 -]{0,31}$/i,ze=new Set(["none","uppercase","lowercase","capitalize"]);function be(e){if(typeof e!="string")return null;let r=e.trim(),t=me.exec(r);if(t){let c=Number.parseInt(t[1],16);return{r:c>>16&255,g:c>>8&255,b:c&255,a:null}}let n=Oe.exec(r);if(n){let[c,m,C]=n[1].split("").map(g=>Number.parseInt(g+g,16));return{r:c,g:m,b:C,a:null}}let o=ge.exec(r),a=o?null:ye.exec(r),i=o??a;if(!i)return null;let l=Number(i[1]),s=Number(i[2]),f=Number(i[3]);return l>255||s>255||f>255?null:{r:l,g:s,b:f,a:a?Number(a[4]):null}}function he({r:e,g:r,b:t,a:n}){return n===null?`#${(1<<24|e<<16|r<<8|t).toString(16).slice(1)}`:`rgba(${e},${r},${t},${n})`}function D(e){if(typeof e!="string")return;let r=e.trim();if(me.test(r)||ge.test(r))return r;let t=ye.exec(r);if(t&&/^\d/.test(t[4]))return r;let n=be(r);return n?he(n):void 0}function Y(e,r=.12){let t=be(e);if(!t)return e;let n=Math.max(0,Math.min(1,1-r));return he({r:Math.round(t.r*n),g:Math.round(t.g*n),b:Math.round(t.b*n),a:t.a})}function z(e,r){let t=[],n=0,o="";for(let a of e){if(a==="("&&(n+=1),a===")"&&(n-=1),a===r&&n===0){o.trim()&&t.push(o.trim()),o="";continue}o+=a}return o.trim()&&t.push(o.trim()),t}function B(e,r,t){if(typeof e!="number"&&typeof e!="string")return;let n=Me.exec(String(e).trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function We(e,r,t){if(typeof e!="string")return;let n=_e.exec(e.trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function $e(e){let r=z(e,",");if(r.length<2||r.length>5)return;let t=[];for(let[n,o]of r.entries()){let a=z(o," "),i=D(a[0]);if(!i)return;let l=n/(r.length-1)*100,s=a[1]===void 0?l:Number(/^(\d+(?:\.\d+)?)%$/.exec(a[1])?.[1]),f=t[t.length-1]?.position??-1;if(!Number.isFinite(s)||s<0||s>100||s<f)return;t.push({color:i,position:s})}return{type:"linearGradient",angle:0,stops:t}}function Ge(e){if(typeof e!="string")return;let r=e.trim(),t=D(r);if(t)return{type:"solid",color:t};let n=Ie.exec(r);if(!n)return;let o=Number(n[1]);if(!Number.isFinite(o)||o<0||o>360)return;let a=$e(n[2]);return a&&a.type==="linearGradient"?{...a,angle:o}:void 0}function He(e){return e.type==="solid"?{type:"solid",color:Y(e.color)}:{...e,stops:e.stops.map(r=>({...r,color:Y(r.color)}))}}function Ye(e){let r=!1,t,n=[];for(let s of z(e," ")){if(s.toLowerCase()==="inset"){r=!0;continue}let f=D(s);if(f){t=f;continue}let c=B(s,-128,128);if(c===void 0)return;n.push(c)}if(!t||n.length<2||n.length>4)return;let[o,a,i=0,l=0]=n;if(!(Math.abs(o)>64||Math.abs(a)>64||i>128||Math.abs(l)>32))return{color:t,inset:r,offsetX:o,offsetY:a,blur:i,spread:l}}function Ue(e){if(typeof e!="string")return;let r=e.trim();if(r.toLowerCase()==="none")return[];let t=z(r,",").map(Ye);if(!(t.length===0||t.length>4))return t.every(n=>n!==void 0)?t:void 0}function pe(e){if(typeof e!="string")return;let r=z(e,",").map(t=>t.replace(/^['"]|['"]$/g,"").trim()).filter(t=>De.test(t)).slice(0,4);return r.length>0?r:void 0}function Xe(e){let r=typeof e=="string"?e.trim().split(/\s+/):[e],t=B(r[0],0,64),n=B(r[1]??r[0],0,64);if(!(t===void 0||n===void 0))return{paddingBlock:t,paddingInline:n}}function je(e){if(e==="bold")return 700;if(e==="normal")return 400;let r=Number(e);return Number.isInteger(r)&&r>=100&&r<=900?r:void 0}function Ce({appearance:e,buttonsStyles:r,fontFamily:t}){let n=r.submitButton;if(!n)return;let o=e?.variables,a=Ge(n.background??n.backgroundColor),i=D(o?.colorPrimaryHover),l=i?{type:"solid",color:i}:a&&He(a),s={fontFamilies:pe(n.fontFamily)??pe(t),fontSize:B(n.fontSize??r.submitButtonFontSize,10,32)??16,fontWeight:je(n.fontWeight)??600,letterSpacing:We(n.letterSpacing,-.1,.5)??.01,lineHeight:B(n.lineHeight,.8,2)??1,textTransform:ze.has(String(n.textTransform))?n.textTransform:"uppercase"},f=Xe(n.padding),c=Ue(n.boxShadow),m=B(n.borderRadius,0,9999),C=typeof n.backdropFilter=="string"?B(Ne.exec(n.backdropFilter.trim())?.[1],0,40):void 0;return{foregroundColor:D(n.color)??"#FFFFFF",...a?{background:a,disabledBackground:a}:{},...l?{hoverBackground:l}:{},typography:s,...f?{spacing:f}:{},...c?{shadow:c}:{},...m===void 0?{}:{borderRadius:m},disabledOpacity:e?.theme==="night"?.8:.6,...C===void 0?{}:{backdropBlur:C}}}function qe(e,r=.12){let t=e.trim(),n=/^[0-9a-fA-F]{6}$/.test(t)?`#${t}`:t;return/^#[0-9a-fA-F]{6}$/.test(n)?Y(n,r):e}function Ke(e){if(typeof e=="number"||typeof e=="string")return e}function Se({appearance:e,buttonsStyles:r,layout:t="default"}){let n=e?.variables,o=m=>typeof m=="string"&&m?m:void 0,a=r.submitButton,i=o(n?.colorPrimary)??o(a?.backgroundColor)??"#4A49FF",l=t==="buttons",s=r.nameInput,f=o(s?.fontFamily)??o(n?.fontFamily)??"Poppins, sans-serif",c=Ce({appearance:e,buttonsStyles:r,fontFamily:f});return{primaryColor:i,primaryHoverColor:o(n?.colorPrimaryHover)??qe(i,.12),inputBackgroundColor:o(r.cardInputBackground)??o(n?.colorBackground)??"#ffffff",textColor:o(r.cardInputColor)??o(s?.color)??o(n?.colorText)??"#262833",borderColor:o(r.cardInputBorder)??(l?"#e5e7eb":"#A4A4FF"),placeholderColor:o(r.cardInputPlaceholderColor)??"#9ca3af",errorColor:o(n?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:f,fontSize:o(r.cardInputFontSize)??o(n?.fontSizeBase)??"16px",fontWeight:String(Ke(s?.fontWeight)??400),borderRadius:o(n?.borderRadius)??"8px",...c?{submitButton:c}:{}}}var R=require("react/jsx-runtime"),W=class extends h.FloPayError{constructor(r,t,n){super(r,t,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function we(e,r={}){let t=e instanceof h.FloPayError?e:void 0,n=t?.statusCode,o=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof n=="number"&&n>=500||t?.code==="vault_capture_timeout"||!t);return new W(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:o,...t?.param?{param:t.param}:{},...n===void 0?{}:{statusCode:n}})}function Re({sessionId:e,nonce:r,billingApiUrl:t,telemetry:n,theme:o="modern-light",containerStyle:a,loading:i=null,onReady:l,onComplete:s,onDecline:f,onCancel:c,onValidation:m,onError:C}){let[g,V]=(0,u.useState)(null),[v,w]=(0,u.useState)(null),[A,O]=(0,u.useState)(null),[F,S]=(0,u.useState)(null),[$,I]=(0,u.useState)(null),E=(0,u.useRef)(!1),M=(0,u.useRef)(!1),k=(0,u.useMemo)(()=>typeof o=="object"?void 0:(0,h.resolveTheme)(o),[o]),G=(0,u.useMemo)(()=>typeof o=="object"?o:k?Se({appearance:k.appearance,buttonsStyles:k.buttonsLayout,layout:"default"}):null,[k,o]),X=(0,u.useMemo)(()=>ae(k?.buttonsLayout.cardFormContainer,a),[k,a]),x=(0,u.useMemo)(()=>k?ue(k):void 0,[k]),ee=(0,u.useRef)(l),j=(0,u.useRef)(C),re=(0,u.useRef)(s),te=(0,u.useRef)(f),ne=(0,u.useRef)(c),oe=(0,u.useRef)(m),_=(0,u.useRef)(!1),q=(0,u.useRef)(!1),K=(0,u.useRef)(0);return ee.current=l,j.current=C,re.current=s,te.current=f,ne.current=c,oe.current=m,(0,u.useEffect)(()=>{let p=K.current+1;return K.current=p,()=>{queueMicrotask(()=>{K.current===p&&(_.current||q.current||(q.current=!0,T(()=>{ne.current?.({status:"cancelled",sessionId:e})})))})}},[e]),(0,u.useEffect)(()=>{let p=!0,L=new U.PaymentAPI((0,h.resolveBillingApiUrl)(t),{telemetry:n});return V(null),w(null),O(null),_.current=!1,q.current=!1,(async()=>{try{if(!e.trim())throw new h.FloPayError("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new h.FloPayError("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let N=await L.getUnifiedCheckoutSession(e,r);if(!p)return;let P=N.data.session;if(!P||!(0,h.isCardSetupCheckoutSession)(P))throw new h.FloPayError("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let y=P.vault;if(y?.html?.trim()||(y=await L.getVaultCapture(e,r)),!y.html?.trim())throw new h.FloPayError("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!p)return;w(y),V(new U.PciVaultCardCapture({sessionId:e,operation:"card_setup",telemetry:n}))}catch(N){if(!p)return;let P=we(N);_.current=!0,O(P),T(()=>j.current?.(P))}})(),()=>{p=!1,L.destroy()}},[t,r,e,n]),(0,u.useEffect)(()=>{if(!g)return;let p=!1;M.current=!1,E.current=!1;let L=g.on("submitting",()=>{E.current=!0,I(null),S("processing")}),N=g.on("complete",y=>{_.current=!0,E.current=!1,S("success"),(async()=>(await new Promise(Z=>setTimeout(Z,600)),!M.current&&(M.current=!0,T(()=>{re.current?.({status:"succeeded",sessionId:e,...y.paymentMethod?{paymentMethod:y.paymentMethod}:{}})}),p||S(null))))()}),P=g.on("decline",y=>{_.current=!0,E.current=!1,I(y.message??null),S("error"),T(()=>{te.current?.({status:"declined",sessionId:e,...y.declineReason?{reason:y.declineReason}:{},...y.message?{message:y.message}:{}})}),(async()=>(await new Promise(Z=>setTimeout(Z,400)),p||S(null)))()});return()=>{p=!0,L(),N(),P()}},[g,e]),A?(0,R.jsx)("div",{role:"alert",children:A.message}):!g||!v?.html?(0,R.jsx)(R.Fragment,{children:i}):(0,R.jsxs)(R.Fragment,{children:[F&&(0,R.jsx)(le,{status:F,errorMessage:$,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...x?{theme:x}:{}}),(0,R.jsx)(de,{capture:g,html:v.html,messageToken:v.messageToken,expectedOrigin:v.expectedOrigin,theme:G,containerStyle:X,onReady:()=>{T(()=>ee.current?.())},onValidation:p=>{T(()=>oe.current?.(p))},onError:p=>{if(!p)return;E.current&&(E.current=!1,I(p),S("error"),setTimeout(()=>S(null),400));let L=we(new Error(p),{code:"card_setup_widget_failed",retryable:!0});T(()=>j.current?.(L))}})]})}0&&(module.exports={FloPayCardSetup,FloPayCardSetupError});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{h as e,i as t}from"./chunk-
|
|
1
|
+
import{h as e,i as t}from"./chunk-Z6LBB432.mjs";export{t as FloPayCardSetup,e as FloPayCardSetupError};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{useEffect as J,useRef as F}from"react";function se(e,r){if(!e)return r;let t=r??{},n=Object.keys(t),o=n.some(i=>i.startsWith("background")),a={};for(let[i,u]of Object.entries(e))i in t||o&&i.startsWith("background")||(a[i]=u);for(let i of n)a[i]=t[i];return a}var ve=new Set(["animationIterationCount","aspectRatio","borderImageOutset","borderImageSlice","borderImageWidth","boxFlex","boxFlexGroup","boxOrdinalGroup","columnCount","columns","flex","flexGrow","flexPositive","flexShrink","flexNegative","flexOrder","gridArea","gridRow","gridRowEnd","gridRowSpan","gridRowStart","gridColumn","gridColumnEnd","gridColumnSpan","gridColumnStart","fontWeight","lineClamp","lineHeight","opacity","order","orphans","scale","tabSize","widows","zIndex","zoom","fillOpacity","floodOpacity","stopOpacity","strokeDasharray","strokeDashoffset","strokeMiterlimit","strokeOpacity","strokeWidth"]);function Fe(e){let r=e.replace(/^(Webkit|Moz|ms)(?=[A-Z])/,"");return ve.has(r.charAt(0).toLowerCase()+r.slice(1))}function Ee(e,r){return typeof r=="number"&&r!==0&&!Fe(e)?`${r}px`:String(r).trim()}function ue(e,r){if(e.style.cssText="",!!r){for(let[t,n]of Object.entries(r))if(!(n==null||n==="")){if(t.startsWith("--")){e.style.setProperty(t,String(n));continue}e.style[t]=Ee(t,n)}}}import{useEffect as Te,useLayoutEffect as Pe}from"react";var le=typeof window>"u"?Te:Pe;import{jsx as Ve}from"react/jsx-runtime";var Q=new WeakSet;function ce({capture:e,html:r,messageToken:t,expectedOrigin:n,theme:o,submitLabel:a,containerStyle:i,onReady:u,onError:s,onValidation:c}){let l=F(null),f=F(u),y=F(s),p=F(c);f.current=u,y.current=s,p.current=c;let T=F(o);T.current=o;let w=F(null),S=a??void 0,P=F(S);P.current=S;let L=F(void 0);return J(()=>{let R=l.current;if(!R)return;let b=!0,$=!1,B=()=>{!b||$||($=!0,f.current?.())},x=e.on("ready",()=>{B()}),M=e.on("error",k=>{y.current?.(k.message??"There was a problem loading the secure card form.")}),h=e.on("validation",k=>{p.current?.(k.message??null)}),G=P.current??(Q.has(e)?null:void 0),X={html:r,...t?{messageToken:t}:{},...n?{expectedOrigin:n}:{},...T.current?{theme:T.current}:{},...G===void 0?{}:{submitLabel:G}};return w.current=T.current??null,L.current=P.current,P.current!==void 0&&Q.add(e),e.mount(R,X).then(()=>{B()}).catch(k=>{b&&y.current?.(k instanceof Error?k.message:"Failed to load the secure card form.")}),()=>{b=!1,x(),M(),h(),e.unmount()}},[e,r,t,n]),le(()=>{let R=l.current;R&&ue(R,i)},[i]),J(()=>{o!==void 0&&(o===null&&w.current===null||(w.current=o,e.applyTheme?.(o)))},[e,o]),J(()=>{S!==L.current&&(L.current=S,S!==void 0&&Q.add(e),e.setSubmitLabel?.(S??null))},[e,S]),Ve("div",{ref:l,"data-testid":"flopay-vault-card-fields"})}import{PaymentAPI as Ke,PciVaultCardCapture as Ze}from"@flopay/js/card-setup";import{FloPayError as I,isCardSetupCheckoutSession as Je,resolveBillingApiUrl as Qe,resolveTheme as er}from"@flopay/shared";import{useEffect as ee,useMemo as Y,useRef as C,useState as W}from"react";var de={light:{success:"#166534",error:"#991B1B"},dark:{success:"#4ADE80",error:"#FCA5A5"}};function fe(e){let r=e.appearance.variables??{},t=e.buttonsLayout.cardFormContainer??{},n=e.appearance.theme==="night",o=n?de.dark:de.light,a=r.colorText??(n?"#F1F5F9":"#262833"),i=e.appearance.rules?.[".Label"];return{panel:{...t.background===void 0?{}:{background:t.background},...t.backgroundColor===void 0?{}:{backgroundColor:t.backgroundColor},...t.border===void 0?{}:{border:t.border},...t.borderRadius===void 0?{}:{borderRadius:t.borderRadius},...t.boxShadow===void 0?{}:{boxShadow:t.boxShadow},color:a,...r.fontFamily?{fontFamily:r.fontFamily}:{}},spinnerTrackColor:e.buttonsLayout.cardInputBorder??(n?"#374151":"#e5e7eb"),spinnerAccentColor:r.colorPrimary??"#4A49FF",labelColors:{processing:a,success:o.success,error:o.error},noteColor:i?.color??a}}function E(e){if(!e)return;let r=t=>{console.error("[FloPay] Merchant callback failed; checkout continued.",t)};try{Promise.resolve(e()).catch(r)}catch(t){r(t)}}import{jsx as g,jsxs as O}from"react/jsx-runtime";var Ae={panel:{background:"white"},spinnerTrackColor:"#e5e7eb",spinnerAccentColor:"#4A49FF",labelColors:{processing:"#374151",success:"#16a34a",error:"#dc2626"},noteColor:"#6b7280"};function pe({status:e,errorMessage:r,authorized:t=!1,processingLabel:n="PROCESSING...",successLabel:o,errorLabel:a="PAYMENT FAILED",successNote:i="You will be automatically redirected, do not close or navigate away from this window.",theme:u=Ae}){let s={fontSize:13,color:u.noteColor,fontWeight:400,maxWidth:260,lineHeight:1.4,margin:0};return g("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:O("div",{"data-testid":"flopay-processing-overlay-panel",style:{borderRadius:12,boxShadow:"0 8px 32px rgba(0,0,0,0.18)",...u.panel,padding:"2rem 2.5rem",textAlign:"center",minWidth:240,display:"flex",flexDirection:"column",alignItems:"center",gap:16},children:[O("div",{style:{width:48,height:48,position:"relative"},children:[e==="processing"&&O("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",style:{animation:"flopay-spin 0.8s linear infinite"},children:[g("circle",{cx:"12",cy:"12",r:"10",stroke:u.spinnerTrackColor,strokeWidth:"3"}),g("path",{d:"M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z",fill:u.spinnerAccentColor})]}),e==="success"&&g("div",{style:{animation:"flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)"},children:O("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[g("circle",{cx:"12",cy:"12",r:"11",fill:"#22c55e"}),g("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"&&g("div",{style:{animation:"flopay-shake 0.4s ease"},children:O("svg",{"aria-hidden":"true",width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[g("circle",{cx:"12",cy:"12",r:"11",fill:"#ef4444"}),g("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"}})]})})]}),O("span",{style:{fontSize:14,fontWeight:600,letterSpacing:"0.05em",color:u.labelColors[e]},children:[e==="processing"&&n,e==="success"&&(o??(t?"PAYMENT AUTHORISED":"PAYMENT SUCCESSFUL")),e==="error"&&a]}),e==="success"&&i!==null&&g("p",{style:s,children:i}),e==="error"&&r&&g("p",{style:s,children:r}),g("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
|
+
`})]})})}var ge=/^#([0-9a-f]{6})$/i,Le=/^#([0-9a-f]{3})$/i,ye=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i,be=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0|1|0?\.\d+|1\.0+)\s*\)$/i,Be=/^linear-gradient\(\s*(-?\d+(?:\.\d+)?)deg\s*,\s*(.+)\)$/i,Oe=/^(-?\d+(?:\.\d+)?)(?:px)?$/,Ie=/^(-?\d+(?:\.\d+)?)em$/,Me=/^blur\(\s*(\d+(?:\.\d+)?)(?:px)?\s*\)$/i,_e=/^[a-z][a-z0-9 -]{0,31}$/i,Ne=new Set(["none","uppercase","lowercase","capitalize"]);function he(e){if(typeof e!="string")return null;let r=e.trim(),t=ge.exec(r);if(t){let l=Number.parseInt(t[1],16);return{r:l>>16&255,g:l>>8&255,b:l&255,a:null}}let n=Le.exec(r);if(n){let[l,f,y]=n[1].split("").map(p=>Number.parseInt(p+p,16));return{r:l,g:f,b:y,a:null}}let o=ye.exec(r),a=o?null:be.exec(r),i=o??a;if(!i)return null;let u=Number(i[1]),s=Number(i[2]),c=Number(i[3]);return u>255||s>255||c>255?null:{r:u,g:s,b:c,a:a?Number(a[4]):null}}function Ce({r:e,g:r,b:t,a:n}){return n===null?`#${(1<<24|e<<16|r<<8|t).toString(16).slice(1)}`:`rgba(${e},${r},${t},${n})`}function D(e){if(typeof e!="string")return;let r=e.trim();if(ge.test(r)||ye.test(r))return r;let t=be.exec(r);if(t&&/^\d/.test(t[4]))return r;let n=he(r);return n?Ce(n):void 0}function H(e,r=.12){let t=he(e);if(!t)return e;let n=Math.max(0,Math.min(1,1-r));return Ce({r:Math.round(t.r*n),g:Math.round(t.g*n),b:Math.round(t.b*n),a:t.a})}function z(e,r){let t=[],n=0,o="";for(let a of e){if(a==="("&&(n+=1),a===")"&&(n-=1),a===r&&n===0){o.trim()&&t.push(o.trim()),o="";continue}o+=a}return o.trim()&&t.push(o.trim()),t}function A(e,r,t){if(typeof e!="number"&&typeof e!="string")return;let n=Oe.exec(String(e).trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function De(e,r,t){if(typeof e!="string")return;let n=Ie.exec(e.trim());if(!n)return;let o=Number(n[1]);return Number.isFinite(o)&&o>=r&&o<=t?o:void 0}function ze(e){let r=z(e,",");if(r.length<2||r.length>5)return;let t=[];for(let[n,o]of r.entries()){let a=z(o," "),i=D(a[0]);if(!i)return;let u=n/(r.length-1)*100,s=a[1]===void 0?u:Number(/^(\d+(?:\.\d+)?)%$/.exec(a[1])?.[1]),c=t[t.length-1]?.position??-1;if(!Number.isFinite(s)||s<0||s>100||s<c)return;t.push({color:i,position:s})}return{type:"linearGradient",angle:0,stops:t}}function We(e){if(typeof e!="string")return;let r=e.trim(),t=D(r);if(t)return{type:"solid",color:t};let n=Be.exec(r);if(!n)return;let o=Number(n[1]);if(!Number.isFinite(o)||o<0||o>360)return;let a=ze(n[2]);return a&&a.type==="linearGradient"?{...a,angle:o}:void 0}function $e(e){return e.type==="solid"?{type:"solid",color:H(e.color)}:{...e,stops:e.stops.map(r=>({...r,color:H(r.color)}))}}function Ge(e){let r=!1,t,n=[];for(let s of z(e," ")){if(s.toLowerCase()==="inset"){r=!0;continue}let c=D(s);if(c){t=c;continue}let l=A(s,-128,128);if(l===void 0)return;n.push(l)}if(!t||n.length<2||n.length>4)return;let[o,a,i=0,u=0]=n;if(!(Math.abs(o)>64||Math.abs(a)>64||i>128||Math.abs(u)>32))return{color:t,inset:r,offsetX:o,offsetY:a,blur:i,spread:u}}function He(e){if(typeof e!="string")return;let r=e.trim();if(r.toLowerCase()==="none")return[];let t=z(r,",").map(Ge);if(!(t.length===0||t.length>4))return t.every(n=>n!==void 0)?t:void 0}function me(e){if(typeof e!="string")return;let r=z(e,",").map(t=>t.replace(/^['"]|['"]$/g,"").trim()).filter(t=>_e.test(t)).slice(0,4);return r.length>0?r:void 0}function Ye(e){let r=typeof e=="string"?e.trim().split(/\s+/):[e],t=A(r[0],0,64),n=A(r[1]??r[0],0,64);if(!(t===void 0||n===void 0))return{paddingBlock:t,paddingInline:n}}function Ue(e){if(e==="bold")return 700;if(e==="normal")return 400;let r=Number(e);return Number.isInteger(r)&&r>=100&&r<=900?r:void 0}function Se({appearance:e,buttonsStyles:r,fontFamily:t}){let n=r.submitButton;if(!n)return;let o=e?.variables,a=We(n.background??n.backgroundColor),i=D(o?.colorPrimaryHover),u=i?{type:"solid",color:i}:a&&$e(a),s={fontFamilies:me(n.fontFamily)??me(t),fontSize:A(n.fontSize??r.submitButtonFontSize,10,32)??16,fontWeight:Ue(n.fontWeight)??600,letterSpacing:De(n.letterSpacing,-.1,.5)??.01,lineHeight:A(n.lineHeight,.8,2)??1,textTransform:Ne.has(String(n.textTransform))?n.textTransform:"uppercase"},c=Ye(n.padding),l=He(n.boxShadow),f=A(n.borderRadius,0,9999),y=typeof n.backdropFilter=="string"?A(Me.exec(n.backdropFilter.trim())?.[1],0,40):void 0;return{foregroundColor:D(n.color)??"#FFFFFF",...a?{background:a,disabledBackground:a}:{},...u?{hoverBackground:u}:{},typography:s,...c?{spacing:c}:{},...l?{shadow:l}:{},...f===void 0?{}:{borderRadius:f},disabledOpacity:e?.theme==="night"?.8:.6,...y===void 0?{}:{backdropBlur:y}}}function Xe(e,r=.12){let t=e.trim(),n=/^[0-9a-fA-F]{6}$/.test(t)?`#${t}`:t;return/^#[0-9a-fA-F]{6}$/.test(n)?H(n,r):e}function je(e){if(typeof e=="number"||typeof e=="string")return e}function ke({appearance:e,buttonsStyles:r,layout:t="default"}){let n=e?.variables,o=f=>typeof f=="string"&&f?f:void 0,a=r.submitButton,i=o(n?.colorPrimary)??o(a?.backgroundColor)??"#4A49FF",u=t==="buttons",s=r.nameInput,c=o(s?.fontFamily)??o(n?.fontFamily)??"Poppins, sans-serif",l=Se({appearance:e,buttonsStyles:r,fontFamily:c});return{primaryColor:i,primaryHoverColor:o(n?.colorPrimaryHover)??Xe(i,.12),inputBackgroundColor:o(r.cardInputBackground)??o(n?.colorBackground)??"#ffffff",textColor:o(r.cardInputColor)??o(s?.color)??o(n?.colorText)??"#262833",borderColor:o(r.cardInputBorder)??(u?"#e5e7eb":"#A4A4FF"),placeholderColor:o(r.cardInputPlaceholderColor)??"#9ca3af",errorColor:o(n?.colorDanger)??"#dc2626",successColor:"#16a34a",fontFamily:c,fontSize:o(r.cardInputFontSize)??o(n?.fontSizeBase)??"16px",fontWeight:String(je(s?.fontWeight)??400),borderRadius:o(n?.borderRadius)??"8px",...l?{submitButton:l}:{}}}import{Fragment as xe,jsx as U,jsxs as rr}from"react/jsx-runtime";var re=class extends I{constructor(r,t,n){super(r,t,n),this.name="FloPayCardSetupError",this.retryable=n.retryable}};function Re(e,r={}){let t=e instanceof I?e:void 0,n=t?.statusCode,o=r.retryable??(t?.type==="network_error"||t?.type==="rate_limit_error"||typeof n=="number"&&n>=500||t?.code==="vault_capture_timeout"||!t);return new re(t?.message??(e instanceof Error?e.message:"Failed to load the secure card form."),t?.type??"api_error",{code:r.code??t?.code??"card_setup_load_failed",retryable:o,...t?.param?{param:t.param}:{},...n===void 0?{}:{statusCode:n}})}function Fr({sessionId:e,nonce:r,billingApiUrl:t,telemetry:n,theme:o="modern-light",containerStyle:a,loading:i=null,onReady:u,onComplete:s,onDecline:c,onCancel:l,onValidation:f,onError:y}){let[p,T]=W(null),[w,S]=W(null),[P,L]=W(null),[R,b]=W(null),[$,B]=W(null),x=C(!1),M=C(!1),h=Y(()=>typeof o=="object"?void 0:er(o),[o]),G=Y(()=>typeof o=="object"?o:h?ke({appearance:h.appearance,buttonsStyles:h.buttonsLayout,layout:"default"}):null,[h,o]),X=Y(()=>se(h?.buttonsLayout.cardFormContainer,a),[h,a]),k=Y(()=>h?fe(h):void 0,[h]),te=C(u),j=C(y),ne=C(s),oe=C(c),ae=C(l),ie=C(f),_=C(!1),q=C(!1),K=C(0);return te.current=u,j.current=y,ne.current=s,oe.current=c,ae.current=l,ie.current=f,ee(()=>{let d=K.current+1;return K.current=d,()=>{queueMicrotask(()=>{K.current===d&&(_.current||q.current||(q.current=!0,E(()=>{ae.current?.({status:"cancelled",sessionId:e})})))})}},[e]),ee(()=>{let d=!0,V=new Ke(Qe(t),{telemetry:n});return T(null),S(null),L(null),_.current=!1,q.current=!1,(async()=>{try{if(!e.trim())throw new I("FloPayCardSetup requires a sessionId.","validation_error",{code:"MissingCheckoutSessionId",param:"sessionId"});if(!r.trim())throw new I("FloPayCardSetup requires a session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let N=await V.getUnifiedCheckoutSession(e,r);if(!d)return;let v=N.data.session;if(!v||!Je(v))throw new I("FloPayCardSetup only accepts a zero-amount, productless setup session.","validation_error",{code:"InvalidCardSetupSession",param:"sessionId"});let m=v.vault;if(m?.html?.trim()||(m=await V.getVaultCapture(e,r)),!m.html?.trim())throw new I("FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.","api_error",{code:"UnsupportedBackendVaultCapability"});if(!d)return;S(m),T(new Ze({sessionId:e,operation:"card_setup",telemetry:n}))}catch(N){if(!d)return;let v=Re(N);_.current=!0,L(v),E(()=>j.current?.(v))}})(),()=>{d=!1,V.destroy()}},[t,r,e,n]),ee(()=>{if(!p)return;let d=!1;M.current=!1,x.current=!1;let V=p.on("submitting",()=>{x.current=!0,B(null),b("processing")}),N=p.on("complete",m=>{_.current=!0,x.current=!1,b("success"),(async()=>(await new Promise(Z=>setTimeout(Z,600)),!M.current&&(M.current=!0,E(()=>{ne.current?.({status:"succeeded",sessionId:e,...m.paymentMethod?{paymentMethod:m.paymentMethod}:{}})}),d||b(null))))()}),v=p.on("decline",m=>{_.current=!0,x.current=!1,B(m.message??null),b("error"),E(()=>{oe.current?.({status:"declined",sessionId:e,...m.declineReason?{reason:m.declineReason}:{},...m.message?{message:m.message}:{}})}),(async()=>(await new Promise(Z=>setTimeout(Z,400)),d||b(null)))()});return()=>{d=!0,V(),N(),v()}},[p,e]),P?U("div",{role:"alert",children:P.message}):!p||!w?.html?U(xe,{children:i}):rr(xe,{children:[R&&U(pe,{status:R,errorMessage:$,processingLabel:"SAVING CARD...",successLabel:"CARD SAVED",errorLabel:"CARD NOT SAVED",successNote:null,...k?{theme:k}:{}}),U(ce,{capture:p,html:w.html,messageToken:w.messageToken,expectedOrigin:w.expectedOrigin,theme:G,containerStyle:X,onReady:()=>{E(()=>te.current?.())},onValidation:d=>{E(()=>ie.current?.(d))},onError:d=>{if(!d)return;x.current&&(x.current=!1,B(d),b("error"),setTimeout(()=>b(null),400));let V=Re(new Error(d),{code:"card_setup_widget_failed",retryable:!0});E(()=>j.current?.(V))}})]})}export{E as a,pe as b,le as c,ce as d,Xe as e,je as f,ke as g,re as h,Fr as i};
|