@flopay/js 1.8.4 → 1.8.6
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 +20 -16
- package/dist/{card-setup-BAB6HdeS.d.cts → card-setup-B-_Bnluz.d.cts} +22 -18
- package/dist/{card-setup-BAB6HdeS.d.ts → card-setup-B-_Bnluz.d.ts} +22 -18
- package/dist/card-setup.cjs +1 -1
- package/dist/card-setup.d.cts +1 -1
- package/dist/card-setup.d.ts +1 -1
- package/dist/card-setup.mjs +1 -1
- package/dist/chunk-UOFQ6V54.mjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-QRHEWEAL.mjs +0 -1
package/README.md
CHANGED
|
@@ -214,14 +214,16 @@ SDK issues two:
|
|
|
214
214
|
same customer. The backend routes a gateway for it from `currency` and the
|
|
215
215
|
buyer's `country`, so the response already carries `gateways` and the hosted
|
|
216
216
|
`vault` block: **the card form can mount from it.**
|
|
217
|
-
2. `PATCH /v1/checkouts/sessions/{id}/claim` — attaches
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
2. `PATCH /v1/checkouts/sessions/{id}/claim` — attaches products and coupons in
|
|
218
|
+
the background. When the draft already has an email, the same request also
|
|
219
|
+
attaches the buyer. An email-less draft sends no `accountData` block, so the
|
|
220
|
+
returned session has its full catalog, totals and eligible method metadata
|
|
221
|
+
while `buyerIdentified` remains `false`.
|
|
220
222
|
|
|
221
223
|
`PaymentAPI.createDetachedSession(params)` exposes both phases. When the draft
|
|
222
|
-
already has an email, the
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
already has an email, the combined catalog-and-buyer claim starts immediately.
|
|
225
|
+
When email is missing, a catalog-only claim still starts immediately; the
|
|
226
|
+
caller can attach the buyer later with the separate `claim(account)` operation:
|
|
225
227
|
|
|
226
228
|
```ts
|
|
227
229
|
const detached = await api.createDetachedSession({
|
|
@@ -230,18 +232,20 @@ const detached = await api.createDetachedSession({
|
|
|
230
232
|
});
|
|
231
233
|
|
|
232
234
|
mountCardForm(detached.shell.data.session?.vault); // interactive immediately
|
|
233
|
-
await detached.
|
|
235
|
+
const session = await detached.claimed; // catalog, totals, methods; buyerIdentified === false
|
|
236
|
+
|
|
237
|
+
const identified = await detached.claim({
|
|
234
238
|
email: 'buyer@example.com',
|
|
235
239
|
firstName: 'Jane',
|
|
236
240
|
lastName: 'Doe',
|
|
237
|
-
});
|
|
238
|
-
const session = await detached.claimed; // cart, coupons, totals, buyer
|
|
241
|
+
}); // buyerIdentified === true
|
|
239
242
|
```
|
|
240
243
|
|
|
241
|
-
|
|
242
|
-
claim
|
|
243
|
-
|
|
244
|
-
`
|
|
244
|
+
The catalog claim and late buyer claim are independently replay-safe. Repeated
|
|
245
|
+
valid `claim(account)` calls return the same buyer-attachment promise; a local
|
|
246
|
+
invalid-email rejection does not consume the operation. Blank/null identity
|
|
247
|
+
fields are omitted. `createAndFetchSession` also accepts an email-less draft and
|
|
248
|
+
resolves with the catalog-attached anonymous session.
|
|
245
249
|
|
|
246
250
|
Nothing may be charged before `claimed` settles: the billing API rejects
|
|
247
251
|
process / intent / decline calls on an unclaimed session with
|
|
@@ -249,9 +253,9 @@ process / intent / decline calls on an unclaimed session with
|
|
|
249
253
|
charge with a retryable `503`. `@flopay/react` gates the card widget's submit
|
|
250
254
|
button for exactly this window.
|
|
251
255
|
|
|
252
|
-
With an email present, `createAndFetchSession` uses the same two-phase flow but
|
|
253
|
-
|
|
254
|
-
|
|
256
|
+
With an email present, `createAndFetchSession` uses the same two-phase flow but
|
|
257
|
+
awaits the combined claim, so its resolved value and request contract are
|
|
258
|
+
unchanged. Detached creation requires billing API `v1.7.12` or newer,
|
|
255
259
|
`checkoutMode: 'full'`, is skipped when `tokenizedData` is supplied, and there
|
|
256
260
|
is **no fallback** to the one-shot create: it needs a billing API with the claim
|
|
257
261
|
endpoint. Pass `deferDataAttachment: false` to force the one-shot create.
|
|
@@ -91,6 +91,7 @@ interface RawCheckoutSession {
|
|
|
91
91
|
/** Final charge amount after coupon discount (cart-currency major units). */
|
|
92
92
|
totalAmount?: number;
|
|
93
93
|
checkoutMode?: CheckoutSessionMode;
|
|
94
|
+
buyerIdentified?: boolean;
|
|
94
95
|
captureMethod?: 'automatic' | 'manual';
|
|
95
96
|
paymentId?: string;
|
|
96
97
|
authorizationExpiresAt?: string;
|
|
@@ -105,10 +106,10 @@ interface RawCheckoutSession {
|
|
|
105
106
|
*/
|
|
106
107
|
providerPaymentMethodId?: string | null;
|
|
107
108
|
accountData: {
|
|
108
|
-
userId: string;
|
|
109
|
-
firstName: string;
|
|
110
|
-
lastName: string;
|
|
111
|
-
email: string;
|
|
109
|
+
userId: string | null;
|
|
110
|
+
firstName: string | null;
|
|
111
|
+
lastName: string | null;
|
|
112
|
+
email: string | null;
|
|
112
113
|
gender?: string | null;
|
|
113
114
|
city?: string | null;
|
|
114
115
|
state?: string | null;
|
|
@@ -328,8 +329,9 @@ declare class PaymentAPI {
|
|
|
328
329
|
*
|
|
329
330
|
* Eligible sessions are created through the **detached** shell + claim flow
|
|
330
331
|
* (see {@link PaymentAPI.createDetachedSession}) and this method awaits the
|
|
331
|
-
* claim
|
|
332
|
-
*
|
|
332
|
+
* catalog claim. Callers still receive one catalog-populated session; when
|
|
333
|
+
* email is omitted it remains anonymous (`buyerIdentified: false`). The win
|
|
334
|
+
* here is server-side: the create no longer
|
|
333
335
|
* contends on buyer-identity advisory locks. Callers that want to render from
|
|
334
336
|
* the shell *before* the claim lands — mounting the card form early — should
|
|
335
337
|
* call {@link PaymentAPI.createDetachedSession} directly. Pass
|
|
@@ -360,17 +362,19 @@ declare class PaymentAPI {
|
|
|
360
362
|
* already carries the session id, nonce, `gateways` and the hosted `vault`
|
|
361
363
|
* block. The card form can mount from it immediately.
|
|
362
364
|
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
365
|
+
* Products and coupons are attached immediately by the stable
|
|
366
|
+
* {@link DetachedCheckoutSession.claimed} promise. With an email present that
|
|
367
|
+
* request also attaches the buyer. Without email it sends a catalog-only
|
|
368
|
+
* payload and returns a fully populated but anonymous session; the caller can
|
|
369
|
+
* later attach identity through the independent, replay-safe
|
|
370
|
+
* {@link DetachedCheckoutSession.claim} operation.
|
|
368
371
|
* **Nothing may be charged until it settles** — the billing API rejects
|
|
369
372
|
* process / intent / decline calls on an unclaimed session with
|
|
370
373
|
* `409 checkout_session_data_attachment_required`, and holds an unclaimed
|
|
371
374
|
* vault charge with a retryable `503`.
|
|
372
375
|
*
|
|
373
|
-
* Requires
|
|
376
|
+
* Requires billing API v1.7.12+ with the independent catalog/buyer
|
|
377
|
+
* `PATCH /v1/checkouts/sessions/{id}/claim` contract; there
|
|
374
378
|
* is no fallback to the one-shot create. Callers that want the original
|
|
375
379
|
* single-request behaviour should pass `deferDataAttachment: false` and use
|
|
376
380
|
* {@link PaymentAPI.createAndFetchSession}.
|
|
@@ -380,12 +384,12 @@ declare class PaymentAPI {
|
|
|
380
384
|
* `PATCH /v1/checkouts/sessions/{id}/claim` — attach buyer identity, address,
|
|
381
385
|
* products and coupons to a detached session shell.
|
|
382
386
|
*
|
|
383
|
-
* The backend fingerprints
|
|
384
|
-
* identical body returns the same
|
|
385
|
-
*
|
|
386
|
-
* which is surfaced without retrying. Invalid
|
|
387
|
-
* the same `422` the one-shot create would have
|
|
388
|
-
* but with identical semantics.
|
|
387
|
+
* The backend fingerprints each catalog or buyer-attachment operation, so a
|
|
388
|
+
* transport retry replaying the identical body returns the same session
|
|
389
|
+
* rather than conflicting. A materially different replay of the same
|
|
390
|
+
* operation returns `409`, which is surfaced without retrying. Invalid
|
|
391
|
+
* catalog data surfaces here as the same `422` the one-shot create would have
|
|
392
|
+
* returned — later in the flow, but with identical semantics.
|
|
389
393
|
*/
|
|
390
394
|
claimCheckoutSession(checkoutSessionId: string, nonce: string, payload: Record<string, unknown>, internal?: {
|
|
391
395
|
params: InlineSessionDraft;
|
|
@@ -91,6 +91,7 @@ interface RawCheckoutSession {
|
|
|
91
91
|
/** Final charge amount after coupon discount (cart-currency major units). */
|
|
92
92
|
totalAmount?: number;
|
|
93
93
|
checkoutMode?: CheckoutSessionMode;
|
|
94
|
+
buyerIdentified?: boolean;
|
|
94
95
|
captureMethod?: 'automatic' | 'manual';
|
|
95
96
|
paymentId?: string;
|
|
96
97
|
authorizationExpiresAt?: string;
|
|
@@ -105,10 +106,10 @@ interface RawCheckoutSession {
|
|
|
105
106
|
*/
|
|
106
107
|
providerPaymentMethodId?: string | null;
|
|
107
108
|
accountData: {
|
|
108
|
-
userId: string;
|
|
109
|
-
firstName: string;
|
|
110
|
-
lastName: string;
|
|
111
|
-
email: string;
|
|
109
|
+
userId: string | null;
|
|
110
|
+
firstName: string | null;
|
|
111
|
+
lastName: string | null;
|
|
112
|
+
email: string | null;
|
|
112
113
|
gender?: string | null;
|
|
113
114
|
city?: string | null;
|
|
114
115
|
state?: string | null;
|
|
@@ -328,8 +329,9 @@ declare class PaymentAPI {
|
|
|
328
329
|
*
|
|
329
330
|
* Eligible sessions are created through the **detached** shell + claim flow
|
|
330
331
|
* (see {@link PaymentAPI.createDetachedSession}) and this method awaits the
|
|
331
|
-
* claim
|
|
332
|
-
*
|
|
332
|
+
* catalog claim. Callers still receive one catalog-populated session; when
|
|
333
|
+
* email is omitted it remains anonymous (`buyerIdentified: false`). The win
|
|
334
|
+
* here is server-side: the create no longer
|
|
333
335
|
* contends on buyer-identity advisory locks. Callers that want to render from
|
|
334
336
|
* the shell *before* the claim lands — mounting the card form early — should
|
|
335
337
|
* call {@link PaymentAPI.createDetachedSession} directly. Pass
|
|
@@ -360,17 +362,19 @@ declare class PaymentAPI {
|
|
|
360
362
|
* already carries the session id, nonce, `gateways` and the hosted `vault`
|
|
361
363
|
* block. The card form can mount from it immediately.
|
|
362
364
|
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
365
|
+
* Products and coupons are attached immediately by the stable
|
|
366
|
+
* {@link DetachedCheckoutSession.claimed} promise. With an email present that
|
|
367
|
+
* request also attaches the buyer. Without email it sends a catalog-only
|
|
368
|
+
* payload and returns a fully populated but anonymous session; the caller can
|
|
369
|
+
* later attach identity through the independent, replay-safe
|
|
370
|
+
* {@link DetachedCheckoutSession.claim} operation.
|
|
368
371
|
* **Nothing may be charged until it settles** — the billing API rejects
|
|
369
372
|
* process / intent / decline calls on an unclaimed session with
|
|
370
373
|
* `409 checkout_session_data_attachment_required`, and holds an unclaimed
|
|
371
374
|
* vault charge with a retryable `503`.
|
|
372
375
|
*
|
|
373
|
-
* Requires
|
|
376
|
+
* Requires billing API v1.7.12+ with the independent catalog/buyer
|
|
377
|
+
* `PATCH /v1/checkouts/sessions/{id}/claim` contract; there
|
|
374
378
|
* is no fallback to the one-shot create. Callers that want the original
|
|
375
379
|
* single-request behaviour should pass `deferDataAttachment: false` and use
|
|
376
380
|
* {@link PaymentAPI.createAndFetchSession}.
|
|
@@ -380,12 +384,12 @@ declare class PaymentAPI {
|
|
|
380
384
|
* `PATCH /v1/checkouts/sessions/{id}/claim` — attach buyer identity, address,
|
|
381
385
|
* products and coupons to a detached session shell.
|
|
382
386
|
*
|
|
383
|
-
* The backend fingerprints
|
|
384
|
-
* identical body returns the same
|
|
385
|
-
*
|
|
386
|
-
* which is surfaced without retrying. Invalid
|
|
387
|
-
* the same `422` the one-shot create would have
|
|
388
|
-
* but with identical semantics.
|
|
387
|
+
* The backend fingerprints each catalog or buyer-attachment operation, so a
|
|
388
|
+
* transport retry replaying the identical body returns the same session
|
|
389
|
+
* rather than conflicting. A materially different replay of the same
|
|
390
|
+
* operation returns `409`, which is surfaced without retrying. Invalid
|
|
391
|
+
* catalog data surfaces here as the same `422` the one-shot create would have
|
|
392
|
+
* returned — later in the flow, but with identical semantics.
|
|
389
393
|
*/
|
|
390
394
|
claimCheckoutSession(checkoutSessionId: string, nonce: string, payload: Record<string, unknown>, internal?: {
|
|
391
395
|
params: InlineSessionDraft;
|
package/dist/card-setup.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var j=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var Te=(s,e)=>{for(var t in e)j(s,t,{get:e[t],enumerable:!0})},be=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ce(e))!ve.call(s,n)&&n!==t&&j(s,n,{get:()=>e[n],enumerable:!(r=fe(e,n))||r.enumerable});return s};var _e=s=>be(j({},"__esModule",{value:!0}),s);var Je={};Te(Je,{PaymentAPI:()=>U,PciVaultCardCapture:()=>N});module.exports=_e(Je);var a=require("@flopay/shared");function W(s){return typeof s=="string"&&s.trim()?s:void 0}function J(s){if(typeof s=="string")return s.trim()?s:void 0;if(Array.isArray(s))return s.filter(t=>typeof t=="string"&&t.trim().length>0).join("; ")||void 0}function R(s=12e3){let e=Number.isFinite(s)&&s>=0?s:12e3,t=new AbortController,r=setTimeout(()=>t.abort(),e);return{signal:t.signal,clear:()=>clearTimeout(r)}}function ke(){return Object.assign(new Error("The operation was aborted."),{name:"AbortError"})}function D(s,e){let t=150*2**s,r=Math.round(t*(.75+Math.random()*.5));return new Promise((n,o)=>{let i,c=()=>e.removeEventListener("abort",u),u=()=>{i!==void 0&&clearTimeout(i),c(),o(ke())};if(e.aborted){u();return}i=setTimeout(()=>{c(),n()},r),e.addEventListener("abort",u,{once:!0})})}var Se="flopay_session_display:";var x=new Map;function O(s){return`${Se}${s}`}function B(){if(typeof window>"u")return null;try{return window.sessionStorage}catch{return null}}function H(s,e,t){if(!s)return;let r=t?.ttlMs??36e5,n={data:e,expiresAt:Date.now()+r},o=B();if(o)try{o.setItem(O(s),JSON.stringify(n));return}catch{}x.set(s,n)}function Q(s){if(!s)return null;let e=B();if(e)try{let r=e.getItem(O(s));if(r){let n=JSON.parse(r);if(n&&typeof n.expiresAt=="number"&&n.expiresAt>Date.now())return n.data;e.removeItem(O(s))}}catch{}let t=x.get(s);if(t){if(t.expiresAt>Date.now())return t.data;x.delete(s)}return null}function X(s){if(!s)return;x.delete(s);let e=B();if(e)try{e.removeItem(O(s))}catch{}}var b=require("@flopay/shared"),Me="/v1/sdk-telemetry/events",K=16,Ae=64,Ee=1500,Z=1e3,we=64,Re="00000000-0000-4000-8000-000000000000",Ie={technical_error:8,lifecycle:32,expected_outcome:32,performance:24};function E(){try{return globalThis.crypto.randomUUID()}catch{let s=new Uint8Array(16);try{globalThis.crypto.getRandomValues(s)}catch{for(let t=0;t<s.length;t+=1)s[t]=Math.floor(Math.random()*256)}s[6]=s[6]&15|64,s[8]=s[8]&63|128;let e=[...s].map(t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}}function Pe(s){try{return new TextEncoder().encode(s).byteLength}catch{return s.length}}function De(s){return JSON.stringify([s.code,s.failureCategory,s.stage,s.provider,s.attempt,s.statusClass,s.requestCategory,s.paymentMethodCategory,s.checkoutMode,s.layout])}function k(){return globalThis.performance?.now()??0}var S=class{constructor(e){this.ingestionDisabled=!1;this.queue=[];this.sequence=0;this.flushTimer=null;this.flushInFlight=null;this.reportedFailures=new Map;this.checkoutContext={};this.checkoutStartedAt=null;this.destroyed=!1;this.observers=new Set;this.pageExitHandler=()=>{this.drainQueue()};this.visibilityHandler=()=>{document.visibilityState==="hidden"&&this.flush()};this.eventCounts={technical_error:0,lifecycle:0,expected_outcome:0,performance:0};this.endpoint=`${e.billingApiUrl.replace(/\/+$/,"")}${Me}`,this.sdkPackage=e.sdkPackage??"@flopay/js",this.sdkVersion=e.sdkVersion,this.correlationId=E(),this.merchantEnabled=e.enabled!==!1,this.clock=e.clock??k,this.browserTransportAvailable=typeof window<"u"&&typeof document<"u",this.browserTransportAvailable&&(window.addEventListener("pagehide",this.pageExitHandler),document.addEventListener("visibilitychange",this.visibilityHandler))}log(e){this.notify({...e,class:"lifecycle"}),this.canCollect()&&this.enqueue((0,b.buildTelemetryLogEvent)({...this.checkoutContext,...e,eventId:E(),sequence:this.sequence++}))}error(e){if(this.notify({...e,class:"technical_error"}),!this.canCollect())return;let t=(0,b.buildTelemetryErrorEvent)({...this.checkoutContext,...e,eventId:Re,sequence:0}),r=De(t),n=this.now();this.pruneReportedFailures(n);let o=this.reportedFailures.get(r);if(o!==void 0&&n>=o&&n-o<Z){this.log({name:"operation.deduplicated",stage:e.stage,provider:e.provider,paymentMethodCategory:e.paymentMethodCategory,attempt:e.attempt});return}this.rememberReportedFailure(r,n),this.enqueue((0,b.buildTelemetryErrorEvent)({...this.checkoutContext,...e,eventId:E(),sequence:this.sequence++}))}performance(e){this.canCollect()&&this.enqueue((0,b.buildTelemetryPerformanceEvent)({...this.checkoutContext,...e,eventId:E(),sequence:this.sequence++}))}terminal(e){if(this.canCollect()&&(this.enqueue((0,b.buildTelemetryTerminalEvent)({...this.checkoutContext,...e,eventId:E(),sequence:this.sequence++})),e.outcome!=="action_required"&&this.checkoutStartedAt!==null)){let t=this.checkoutStartedAt;this.checkoutStartedAt=null,this.performance({stage:"total_journey",durationMs:Math.max(0,this.now()-t),durationMode:"total",provider:e.provider,paymentMethodCategory:e.paymentMethodCategory})}}now(){try{return this.clock()}catch{return k()}}subscribe(e){return this.destroyed?()=>{}:(this.observers.add(e),()=>this.observers.delete(e))}notify(e){if(!this.destroyed)for(let t of this.observers)try{t(e)}catch{}}pruneReportedFailures(e){for(let[t,r]of this.reportedFailures)(e<r||e-r>=Z)&&this.reportedFailures.delete(t)}rememberReportedFailure(e,t){for(;this.reportedFailures.size>=we;){let r=this.reportedFailures.keys().next();if(r.done)break;this.reportedFailures.delete(r.value)}this.reportedFailures.set(e,t)}setCheckoutContext(e){this.checkoutContext={checkoutMode:e.checkoutMode,layout:e.layout}}beginCheckout(e={}){return this.canCollect()?(this.drainQueue(),this.setCheckoutContext(e),this.sequence=0,this.reportedFailures.clear(),this.eventCounts={technical_error:0,lifecycle:0,expected_outcome:0,performance:0},this.checkoutStartedAt=this.now(),this.checkoutStartedAt):0}enqueue(e){if(this.canCollect()&&!(this.queue.length>=Ae||this.eventCounts[e.class]>=Ie[e.class])){if(this.eventCounts[e.class]+=1,this.queue.push(e),this.queue.length>=K){this.flush();return}this.scheduleFlush()}}canCollect(){return this.browserTransportAvailable&&this.merchantEnabled&&!this.ingestionDisabled&&!this.destroyed}async flush(){if(this.flushInFlight)return this.flushInFlight;if(!this.browserTransportAvailable||this.destroyed||this.ingestionDisabled||this.queue.length===0)return;this.clearFlushTimer();let e=this.queue.splice(0,K);return this.flushInFlight=this.sendBatch(e).finally(()=>{this.flushInFlight=null,this.queue.length>0&&this.scheduleFlush()}),this.flushInFlight}destroy(){this.destroyed||(this.drainQueue(),this.destroyed=!0,this.clearFlushTimer(),this.browserTransportAvailable&&(window.removeEventListener("pagehide",this.pageExitHandler),document.removeEventListener("visibilitychange",this.visibilityHandler)),this.queue.splice(0),this.reportedFailures.clear(),this.observers.clear())}disable(){this.merchantEnabled=!1,this.queue.splice(0),this.reportedFailures.clear(),this.clearFlushTimer()}drainQueue(){if(!(!this.browserTransportAvailable||this.destroyed||this.ingestionDisabled||this.queue.length===0))for(this.clearFlushTimer();this.queue.length>0;){let e=this.queue.splice(0,K);this.sendBatch(e)}}async sendBatch(e){if(!this.browserTransportAvailable||this.ingestionDisabled)return;let t=(0,b.serializeTelemetryBatch)(e,{correlationId:this.correlationId,sdkPackage:this.sdkPackage,sdkVersion:this.sdkVersion,batchId:E()});if(Pe(t)>b.TELEMETRY_MAX_BATCH_BYTES)return;let r=typeof AbortController>"u"?null:new AbortController,n=null;try{let o=fetch(this.endpoint,{method:"POST",headers:{"content-type":"text/plain;charset=UTF-8"},body:t,credentials:"omit",keepalive:!0,referrerPolicy:"no-referrer",signal:r?.signal}).then(async u=>u.status!==202?null:(await u.json().catch(()=>null))?.status==="disabled"?"disabled":null).catch(()=>null),i=new Promise(u=>{n=setTimeout(()=>{r?.abort(),u(null)},Ee)});await Promise.race([o,i])==="disabled"&&this.disableFromIngestion()}catch{}finally{n&&clearTimeout(n)}}disableFromIngestion(){this.ingestionDisabled=!0,this.queue.splice(0),this.reportedFailures.clear(),this.clearFlushTimer()}scheduleFlush(){this.flushTimer||this.destroyed||this.ingestionDisabled||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush()},0))}clearFlushTimer(){this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)}},ee=Symbol.for("@flopay/js.telemetry.reporter-factory.v1"),te=globalThis;te[ee]===void 0&&Object.defineProperty(te,ee,{configurable:!0,enumerable:!1,writable:!1,value:s=>new S(s)});var re=1e3,xe=500,Oe=15e3,qe=3e3,Fe=1e4,Le=1e4;function Ue(s){return typeof s=="object"&&s!==null}function w(s,e){return W(s?.[e])}function se(s,e){return J(s?.[e])}function Ve(s,e){let t=s?.[e];return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ie(s){return new Promise(e=>setTimeout(e,s))}function F(){return new a.FloPayError("Checkout is still processing. Please try again shortly.","api_error",{code:"checkout_processing_timeout"})}async function M(s,e){let t=await s.json().catch(()=>null),r=Ue(t?.error)?t.error:null,n=se(t,"message")??se(r,"message")??e,o=w(t,"code")??w(t,"gatewayErrorCode")??w(r,"code")??`http_${s.status}`;return new a.FloPayError(n,"api_error",{code:o,statusCode:s.status})}async function Ne(s){let e=s.status===400?await s.clone().json().catch(()=>null):null;return(0,a.classifyPaymentRejection)(s.status,e)}function ne(s){return s===400||s===422}var L=2;async function $(s,e,t=L,r){let n;for(let o=0;;o++)try{return await fetch(s,e)}catch(i){if(e?.signal?.aborted||i instanceof Error&&i.name==="AbortError")throw i;if(n=i,o>=t)throw n;try{r?.(o+1)}catch{}await ie(150*2**o)}}var ze=Symbol.for("@flopay/js.session-create.telemetry.v1");function je(s){return s[ze]}function Be(s){return"now"in s||"onFirstByte"in s||"onSessionCreateFailure"in s||"onRetry"in s}function ae(s){return{userId:s.userId,firstName:s.firstName??null,lastName:s.lastName??null,email:s.email,country:s.country??null,gender:s.gender??null,city:s.city??null,state:s.state??null,zip:s.zip??null,addressLine1:s.addressLine1??null,addressLine2:s.addressLine2??null}}function ce(s,e){e.tagsData&&(s.tagsData=e.tagsData),e.utmMetadata?.length&&(s.utmMetadata=e.utmMetadata),e.avsCheck!==void 0&&(s.avsCheck=e.avsCheck),e.checkoutType&&(s.checkoutType=e.checkoutType),e.checkoutLayout&&(s.checkoutLayout=e.checkoutLayout),e.avsConfig&&(s.avsConfig=e.avsConfig)}function He(s,e){let t={clientId:s.clientId,checkoutVersion:a.SDK_VERSION,successUrl:s.successUrl,cancelUrl:s.cancelUrl,currency:e,checkoutMode:"full",deferDataAttachment:!0};return s.captureMethod==="manual"&&(t.captureMethod=s.captureMethod),s.account.country&&(t.accountData={country:s.account.country}),ce(t,s),t}function oe(s,e,t){return{currency:e,products:t.map(r=>(0,a.buildProductPayload)(r,e)),couponCodes:s.couponCodes??[],accountData:ae(s.account)}}var A=class A{constructor(e,t={}){this.baseUrl=e.replace(/\/+$/,"");let r=Be(t);this.telemetryHooks=r?t:void 0,this.directTelemetry=r||t.telemetry===!1?void 0:new S({billingApiUrl:this.baseUrl,sdkVersion:a.SDK_VERSION})}destroy(){this.directTelemetry?.destroy()}reportDirectFailure(e,t,r,n,o="unknown"){let i=(0,a.classifyTelemetryFailure)(e,t);this.directTelemetry?.error({...i,stage:r,requestCategory:n,paymentMethodCategory:o})}reportAccountSnapshotFailure(e,t){let r=(0,a.classifyTelemetryFailure)(e,"NETWORK_REQUEST_FAILED");if(t==="best_effort"&&r.errorCode==="REQUEST_TIMEOUT"){this.directTelemetry?.log({name:"operation.fallback",stage:"processing",requestCategory:"account_snapshot",statusClass:"timeout"});return}this.directTelemetry?.error({...r,stage:"processing",requestCategory:"account_snapshot",paymentMethodCategory:"unknown"})}telemetryTimestamp(){try{return this.telemetryHooks?.now?.()??this.directTelemetry?.now()??k()}catch{return k()}}beginDirectTelemetryCheckout(e){!this.directTelemetry||this.directTelemetryCheckoutId===e||(this.directTelemetryCheckoutId=e,this.directTelemetry.beginCheckout())}beginDirectTelemetryOperation(){this.directTelemetry&&(this.directTelemetryCheckoutId=void 0,this.directTelemetry.beginCheckout())}adoptDirectTelemetryCheckout(e){e&&(this.directTelemetryCheckoutId=e)}async getCheckoutSession(e,t){this.beginDirectTelemetryCheckout(e);let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"session.read.started",stage:"session_read",requestCategory:"session_read"});let n={[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION};t&&(n["x-checkout-session-token"]=t);try{let o=await $(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}`,{headers:n},L,l=>{this.telemetryHooks?.onRetry?.("session_read",l),this.directTelemetry?.log({name:"operation.retry",stage:"session_read",requestCategory:"session_read",attempt:l})}),i=Math.max(0,this.telemetryTimestamp()-r);try{this.telemetryHooks?.onFirstByte?.(i)}catch{}let c=`${Math.floor(o.status/100)}xx`;if(this.directTelemetry?.log({name:"session.request.first_byte",stage:"session_first_byte",requestCategory:"session_read",statusClass:c}),this.directTelemetry?.performance({stage:"session_first_byte",durationMs:i,durationMode:"machine",requestCategory:"session_read",statusClass:c}),!o.ok)throw await M(o,"Failed to get checkout session");let u=await o.json();return this.directTelemetry?.log({name:"session.request.completed",stage:"session_complete",requestCategory:"session_read",statusClass:c}),this.directTelemetry?.performance({stage:"session_complete",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_read",statusClass:c}),{...u,data:this.mergeCachedDisplayData(u.data)}}catch(o){throw this.directTelemetry?.error({...(0,a.classifyTelemetryFailure)(o,"NETWORK_REQUEST_FAILED"),stage:"session_read",requestCategory:"session_read"}),o}}cacheSessionDisplayData(e,t,r){H(e,t,r)}clearSessionDisplayData(e){X(e)}async getVaultCapture(e,t){let r=`${this.baseUrl}\0${e}\0${t??""}`,n=A.activeVaultCaptureRequests.get(r);if(n)return n;let o=this.requestVaultCapture(e,t);A.activeVaultCaptureRequests.set(r,o);try{return await o}finally{A.activeVaultCaptureRequests.get(r)===o&&A.activeVaultCaptureRequests.delete(r)}}async requestVaultCapture(e,t){let r=new AbortController,n=setTimeout(()=>r.abort(),Le);this.beginDirectTelemetryCheckout(e);let o=this.telemetryTimestamp();this.directTelemetry?.log({name:"vault.capture.requested",stage:"vault_request",requestCategory:"vault_capture",paymentMethodCategory:"card"});let i={"Content-Type":"application/json"};t&&(i["x-checkout-session-token"]=t);try{let c=await $(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/vault/capture`,{method:"POST",headers:i,signal:r.signal},L,l=>{this.telemetryHooks?.onRetry?.("vault_capture",l),this.directTelemetry?.log({name:"operation.retry",stage:"vault_request",requestCategory:"vault_capture",paymentMethodCategory:"card",attempt:l})});if(!c.ok)throw await M(c,"Failed to load the secure card form");let u=await c.json();return this.directTelemetry?.performance({stage:"vault_request",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"vault_capture",paymentMethodCategory:"card",statusClass:"2xx"}),this.toVaultBlock(u)}catch(c){let u=r.signal.aborted?new a.FloPayError("Timed out while loading the secure card form. Please try again.","api_error",{code:"vault_capture_timeout"}):c;throw this.reportDirectFailure(u,"VAULT_LOAD_FAILED","vault_request","vault_capture","card"),u}finally{clearTimeout(n)}}async getUnifiedCheckoutSession(e,t){let r=await this.getCheckoutSession(e,t),n=this.normalizeRawSession(r.data),o=r.vault;return o&&n.data.session&&(n.data.session.vault=this.toVaultBlock(o)),n}async processPayment(e,t,r){if(this.beginDirectTelemetryCheckout(t.sessionId),!t.nonce)throw this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"processing",requestCategory:"process_payment"}),new a.FloPayError("processPayment requires `nonce` \u2014 pass the value returned from session creation.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let n=this.telemetryTimestamp();this.directTelemetry?.log({name:"payment.processing.started",stage:"processing",requestCategory:"process_payment"});let{nonce:o,...i}=t,c;try{c=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(t.sessionId)}/process`,{method:"POST",headers:{"Content-Type":"application/json","x-checkout-session-token":o},body:JSON.stringify(i)})}catch(u){throw this.reportDirectFailure(u,"PAYMENT_PROCESSING_FAILED","processing","process_payment"),u}if(!c.ok&&c.status!==202){let u=await Ne(c);return u?this.directTelemetry?.terminal({outcome:u,stage:"processing",requestCategory:"process_payment",statusClass:"4xx"}):this.directTelemetry?.error({errorCode:"PAYMENT_PROCESSING_FAILED",stage:"processing",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(c.status),failureCategory:c.status>=500?"server_error":void 0}),c}try{let u=await this.resolveProcessResponse(c,t.sessionId,{...r,nonce:o});return this.directTelemetry?.log({name:"payment.processing.completed",stage:"processing",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(u.status)}),this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-n),durationMode:"machine",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(u.status)}),u}catch(u){throw u instanceof a.FloPayError&&u.code==="checkout_processing_timeout"||this.reportDirectFailure(u,"PAYMENT_PROCESSING_FAILED","processing","process_payment"),u}}async patchAccountSnapshot(e,t,r,n){this.beginDirectTelemetryCheckout(e);let o=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.state_transition",stage:"processing",requestCategory:"account_snapshot"});let i=n?.timeoutMs??Fe,c=new AbortController,u=()=>c.abort();n?.signal&&(n.signal.aborted?c.abort():n.signal.addEventListener("abort",u,{once:!0}));let l=setTimeout(()=>c.abort(),i);try{let d;try{d=await $(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/account`,{method:"PATCH",headers:{"Content-Type":"application/json","x-checkout-session-token":t},body:JSON.stringify(r),signal:c.signal},L,h=>{this.telemetryHooks?.onRetry?.("account_snapshot",h),this.directTelemetry?.log({name:"operation.retry",stage:"processing",requestCategory:"account_snapshot",attempt:h})})}finally{clearTimeout(l),n?.signal?.removeEventListener("abort",u)}if(!d.ok)throw await M(d,"Failed to persist account snapshot");this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"account_snapshot",statusClass:"2xx"})}catch(d){throw this.reportAccountSnapshotFailure(d,n?.telemetryMode??"blocking"),d}}async createSessionIntent(e,t,r,n){if(!t)throw new a.FloPayError("createSessionIntent requires the checkout session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let o=r,i=o.paymentMethodType,c=typeof i=="string"&&i.trim().toLowerCase()==="card",u=typeof i=="string"&&i.length>0&&!c&&(typeof o.paymentMethodId=="string"||o.paymentMethodId===null),l=o.provider==="stripe"&&(o.paymentMethodCategory==="wallet"||o.paymentMethodCategory==="apm")&&(o.intentKind==="payment"||o.intentKind==="setup"),d=o.provider==="paypal"&&o.paymentMethodCategory==="wallet"&&o.paymentMethodId===null&&(o.paymentMethodType==="paypal"&&o.intentKind==="payment"||o.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&(o.intentKind==="payment"||o.intentKind==="setup"));if(!u||!l&&!d)throw new a.FloPayError("Only wallet, APM, and PayPal session intents are supported.","validation_error",{code:"InvalidSessionIntentRequest"});let h=o.authorizationAttemptId;if(h!==void 0&&!(0,a.isUuidV4)(h))throw new a.FloPayError("authorizationAttemptId must be a v4 UUID identifying one buyer authorization attempt.","validation_error",{code:"InvalidAuthorizationAttemptId",param:"authorizationAttemptId"});let m=(0,a.isUuidV4)(h)?h:(0,a.randomUuidV4)();this.beginDirectTelemetryCheckout(e);let y=this.telemetryTimestamp();this.directTelemetry?.log({name:"payment.intent.started",stage:"processing",requestCategory:"intent_create"});let v={"Content-Type":"application/json","x-checkout-session-token":t,[a.IDEMPOTENCY_KEY_HEADER]:n?.idempotencyKey||m},C=!1;try{let T=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/intents`,{method:"POST",headers:v,body:JSON.stringify({...r,authorizationAttemptId:m}),signal:n?.signal});if(!T.ok){C=!0;let z=await M(T,"Failed to create checkout intent"),ge=(0,a.classifyTelemetryFailure)(z,"PAYMENT_PROCESSING_FAILED");throw ne(z.statusCode)?this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"processing",requestCategory:"intent_create",statusClass:"4xx"}):this.directTelemetry?.error({...ge,stage:"processing",requestCategory:"intent_create"}),z}let _=(await T.json()).data;if(!_||typeof _!="object")throw new a.FloPayError("Invalid checkout intent response.","api_error",{code:"InvalidSessionIntentResponse"});let p=_,Y=p.paymentMethodType,me=(p.paymentMethodCategory==="wallet"||p.paymentMethodCategory==="apm")&&typeof Y=="string"&&Y.trim().toLowerCase()!=="card"&&(typeof p.paymentMethodId=="string"||p.paymentMethodId===null)&&typeof p.providerObjectId=="string",pe=p.provider==="stripe"&&(p.intentKind==="payment"||p.intentKind==="setup")&&typeof p.clientSecret=="string",he=p.provider==="paypal"&&p.paymentMethodCategory==="wallet"&&p.paymentMethodId===null&&(p.paymentMethodType==="paypal"&&p.intentKind==="payment"&&(p.providerObjectType==="order"||p.providerObjectType==="subscription")||p.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&p.intentKind==="payment"&&p.providerObjectType==="order"||p.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&p.intentKind==="setup"&&p.providerObjectType==="setup_token")&&p.clientSecret===null,ye=p.provider===r.provider&&p.paymentMethodCategory===r.paymentMethodCategory&&p.paymentMethodType===r.paymentMethodType&&p.paymentMethodId===r.paymentMethodId&&p.intentKind===r.intentKind;if(!me||!pe&&!he||!ye)throw new a.FloPayError("Invalid checkout intent response.","api_error",{code:"InvalidSessionIntentResponse"});return this.directTelemetry?.log({name:"payment.intent.completed",stage:"processing",requestCategory:"intent_create",statusClass:(0,a.telemetryStatusClass)(T.status)}),this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-y),durationMode:"machine",requestCategory:"intent_create",statusClass:(0,a.telemetryStatusClass)(T.status)}),p}catch(T){throw C||this.reportDirectFailure(T,"PAYMENT_PROCESSING_FAILED","processing","intent_create"),T}}async reportSessionIntentDecline(e,t,r,n){if(!t)throw new a.FloPayError("reportSessionIntentDecline requires the checkout session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let o=r,i=o.providerDeclineReason,c=o.paymentMethodType,u=typeof i=="string"&&/^[a-z0-9][a-z0-9_.:-]{0,63}$/i.test(i)&&!/^(?:pm|pi|seti|tok|src|cus|sess|sk|pk)_/i.test(i),l=typeof c=="string"&&c.length>0&&c.trim().toLowerCase()!=="card"&&u,d=o.provider==="stripe"&&(o.paymentMethodCategory==="wallet"||o.paymentMethodCategory==="apm"),h=o.provider==="paypal"&&o.paymentMethodCategory==="wallet"&&o.paymentMethodType==="paypal";if(!l||!d&&!h)throw new a.FloPayError("Invalid non-card decline classification.","validation_error",{code:"InvalidSessionIntentDeclineRequest"});let m=h?{provider:"paypal",paymentMethodCategory:"wallet",paymentMethodType:"paypal",providerDeclineReason:i}:{provider:"stripe",paymentMethodCategory:o.paymentMethodCategory,paymentMethodType:o.paymentMethodType,providerDeclineReason:i},y=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/intents/decline`,{method:"POST",headers:{"Content-Type":"application/json","x-checkout-session-token":t},body:JSON.stringify(m),signal:n?.signal});if(!y.ok)throw await M(y,"Failed to report checkout decline")}async getPaymentsByEmail(e,t){this.beginDirectTelemetryOperation();let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.recovery.started",stage:"recovery",requestCategory:"other",paymentMethodCategory:"saved"});let n=t?.page??1,o=t?.limit??1,i=new URLSearchParams({email:e,page:String(n),limit:String(o),sortField:"createdAt",sortDirection:"DESC"});try{let c=await fetch(`${this.baseUrl}/v1/payments?${i.toString()}`,{method:"GET",signal:t?.signal,keepalive:!0});if(!c.ok)throw new a.FloPayError("Failed to fetch payments","api_error",{statusCode:c.status});let u=await c.json();return this.directTelemetry?.log({name:"operation.recovery.completed",stage:"recovery",requestCategory:"other",paymentMethodCategory:"saved",statusClass:"2xx"}),this.directTelemetry?.performance({stage:"recovery",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"other",paymentMethodCategory:"saved",statusClass:"2xx"}),u}catch(c){throw this.reportDirectFailure(c,"RECOVERY_FAILED","recovery","other","saved"),c}}async createAndFetchSession(e){if((0,a.isDetachedSessionEligible)(e)){if(!(0,a.isValidEmail)(e.account.email?.trim()))throw new a.FloPayError("createAndFetchSession requires a valid buyer email. Use createDetachedSession and call claim() after collecting a valid one.","validation_error",{code:"BuyerEmailCollectionRequired",param:"account.email"});return(await this.createDetachedSession(e)).claimed}this.beginDirectTelemetryOperation();let t=this.telemetryTimestamp(),r=R(e.timeoutMs??12e3),n={attempt:0,statusClass:"unknown"};this.directTelemetry?.log({name:"session.create.started",stage:"session_create",requestCategory:"session_create"});try{let o=await this.createAndFetchSessionRequest(e,t,r.signal,n);return this.adoptDirectTelemetryCheckout(o.data.session?.id),this.directTelemetry?.log({name:"session.request.completed",stage:"session_create",requestCategory:"session_create",statusClass:n.statusClass}),this.directTelemetry?.performance({stage:"session_create",durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:"session_create",statusClass:n.statusClass,attempt:n.attempt}),o}catch(o){throw this.reportSessionCreateFailure(o,t,n),o}finally{r.clear()}}async createAndFetchSessionRequest(e,t,r,n){let o=e.products??(0,a.foldIntoProducts)(e.items,e.subscriptions);(0,a.assertCaptureMethodEligible)({captureMethod:e.captureMethod,products:o});let i=(0,a.resolveSessionCurrency)(e.currency,e.items,e.subscriptions,o);if(!i)throw new a.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let c={clientId:e.clientId,checkoutVersion:a.SDK_VERSION,successUrl:e.successUrl,cancelUrl:e.cancelUrl,currency:i,checkoutMode:e.checkoutMode??"full",products:o.map(m=>(0,a.buildProductPayload)(m,i)),accountData:ae(e.account),couponCodes:e.couponCodes??[]};e.captureMethod==="manual"&&(c.captureMethod=e.captureMethod),e.tokenizedData&&(c.tokenizedData=e.tokenizedData),ce(c,e);let l=await(await this.postCheckoutSessionCreate(c,e,t,r,n)).json();if(l.data&&"gateways"in l.data){this.autoCacheDisplayData(l.data.uuid,e);let m=this.mergeCachedDisplayData(l.data),y=this.normalizeRawSession(m);return l.vault&&y.data.session&&(y.data.session.vault=this.toVaultBlock(l.vault)),{...y,autoProcessingError:l.autoProcessingError,autoProcessingAttempted:l.autoProcessingAttempted,autoProcessingPending:l.autoProcessingPending}}let d=l.data?.uuid;if(!d)throw new a.FloPayError("No session ID returned","api_error",{code:"InvalidCheckoutSessionResponse"});return this.autoCacheDisplayData(d,e),this.adoptDirectTelemetryCheckout(d),{...await this.getUnifiedCheckoutSession(d),autoProcessingError:l.autoProcessingError,autoProcessingAttempted:l.autoProcessingAttempted,autoProcessingPending:l.autoProcessingPending}}async postCheckoutSessionCreate(e,t,r,n,o){let i={"Content-Type":"application/json",[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION},c=(0,a.resolveIdempotencyKey)(t.idempotencyKey);c&&(i[a.IDEMPOTENCY_KEY_HEADER]=c);let u,l=!1,d=je(t),h=m=>{try{this.telemetryHooks?.onRetry?.("session_create",m),this.directTelemetry?.log({name:"operation.retry",stage:"session_create",requestCategory:"session_create",attempt:m})}catch{}};for(let m=0;m<3;m++){o.attempt=m;try{d?.onAttempt?.(m)}catch{}try{u=await fetch(`${this.baseUrl}/v1/checkouts/sessions?expand=true`,{method:"POST",headers:i,body:JSON.stringify(e),signal:n})}catch(C){if(o.statusClass=n.aborted||C instanceof Error&&C.name==="AbortError"?"timeout":"network_error",n.aborted||C instanceof Error&&C.name==="AbortError"||m>=2)throw C;let T=m+1;h(T),await D(m,n);continue}let y=(0,a.telemetryStatusClass)(u.status);if(o.statusClass=y,l||(l=!0,this.directTelemetry?.log({name:"session.request.first_byte",stage:"session_first_byte",requestCategory:"session_create",statusClass:y,attempt:m}),this.directTelemetry?.performance({stage:"session_first_byte",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_create",statusClass:y,attempt:m})),u.status===204)throw new a.FloPayError("Session auto-completed \u2014 payment method already on file","api_error",{code:"session_auto_completed"});if(u.ok)break;let v=await M(u,"Failed to create checkout session");if(v.code===a.IDEMPOTENCY_IN_PROGRESS_CODE&&m<2){h(m+1),await D(m,n);continue}throw v}if(!u)throw new TypeError("Checkout-session creation exhausted its retry budget.");return u}async createDetachedSession(e){this.beginDirectTelemetryOperation();let t=this.telemetryTimestamp(),r=R(e.timeoutMs??12e3),n={attempt:0,statusClass:"unknown"};this.directTelemetry?.log({name:"session.create.started",stage:"session_create",requestCategory:"session_create"});let o=e.products??(0,a.foldIntoProducts)(e.items,e.subscriptions);try{(0,a.assertCaptureMethodEligible)({captureMethod:e.captureMethod,products:o})}catch(g){throw r.clear(),this.reportSessionCreateFailure(g,t,n),g}let i=(0,a.resolveSessionCurrency)(e.currency,e.items,e.subscriptions,o);if(!i)throw r.clear(),this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"session_create",requestCategory:"session_create"}),new a.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});try{oe(e,i,o)}catch(g){throw r.clear(),this.reportSessionCreateFailure(g,t,n),g}let c,u;try{if(u=await(await this.postCheckoutSessionCreate(He(e,i),e,t,r.signal,n)).json(),!u.data||!("gateways"in u.data))throw new a.FloPayError("The billing API returned no session shell for a detached create. It must support `deferDataAttachment` (TeamFloPay/backend#1099).","api_error",{code:"InvalidCheckoutSessionResponse"});c=this.normalizeRawSession(this.mergeCachedDisplayData(u.data)),u.vault&&c.data.session&&(c.data.session.vault=this.toVaultBlock(u.vault))}catch(g){throw r.clear(),this.reportSessionCreateFailure(g,t,n),g}let l=c.data.session?.id??u.data.uuid??"",d=c.data.session?.clientSecret??u.data.nonce??"";if(!l||!d){r.clear();let g=new a.FloPayError("Checkout session shell was created without a session id or nonce.","api_error",{code:"InvalidCheckoutSessionResponse"});throw this.reportSessionCreateFailure(g,t,n),g}this.adoptDirectTelemetryCheckout(l),this.directTelemetry?.log({name:"session.shell.ready",stage:"session_shell",requestCategory:"session_create",statusClass:n.statusClass,paymentMethodCategory:"card"}),this.directTelemetry?.performance({stage:"session_shell",durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:"session_create",statusClass:n.statusClass,attempt:n.attempt,paymentMethodCategory:"card"});let h=!e.account.email?.trim();h&&r.clear();let m,y,v=new Promise((g,_)=>{m=g,y=_}),C=!1,T=(g={})=>{if(C)return v;let _={...e,account:{...e.account,...g,email:g.email?.trim()||e.account.email?.trim()}};if(!(0,a.isValidEmail)(_.account.email))return Promise.reject(new a.FloPayError("A valid buyer email is required before claiming checkout.","validation_error",{code:"BuyerEmailCollectionRequired",param:"account.email"}));C=!0;let p=h?R(e.timeoutMs??12e3):r;return this.claimCheckoutSession(l,d,oe(_,i,o),{params:_,startedAt:h?this.telemetryTimestamp():t,deadline:p,createAttempt:n.attempt}).then(m,y),v};return h||T(),v.catch(()=>{}),{shell:c,sessionId:l,nonce:d,claimed:v,claim:T}}async claimCheckoutSession(e,t,r,n){let o=n?.startedAt??this.telemetryTimestamp(),i=this.telemetryTimestamp(),c=n?.deadline??R(12e3),u=JSON.stringify(r),l="unknown",d=0;this.directTelemetry?.log({name:"session.claim.started",stage:"session_claim",requestCategory:"session_claim"});try{let h;for(d=0;d<3;d++){try{h=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/claim`,{method:"PATCH",headers:{"Content-Type":"application/json","x-checkout-session-token":t,[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION},body:u,signal:c.signal})}catch(v){let C=c.signal.aborted||v instanceof Error&&v.name==="AbortError";if(l=C?"timeout":"network_error",C||d>=2)throw v;try{this.telemetryHooks?.onRetry?.("session_claim",d+1),this.directTelemetry?.log({name:"operation.retry",stage:"session_claim",requestCategory:"session_claim",attempt:d+1})}catch{}await D(d,c.signal);continue}if(l=(0,a.telemetryStatusClass)(h.status),h.ok)break;throw await M(h,"Failed to attach checkout session data")}if(!h)throw new TypeError("Checkout-session claim exhausted its retry budget.");let m=await h.json();if(!m.data?.gateways)throw new a.FloPayError("The billing API returned no checkout session with gateways after claiming it.","api_error",{code:"InvalidCheckoutSessionResponse"});n?.params&&this.autoCacheDisplayData(m.data.uuid??e,n.params);let y=this.normalizeRawSession(this.mergeCachedDisplayData(m.data));return m.vault&&y.data.session&&(y.data.session.vault=this.toVaultBlock(m.vault)),this.directTelemetry?.log({name:"session.claim.completed",stage:"session_claim",requestCategory:"session_claim",statusClass:l}),this.directTelemetry?.performance({stage:"session_claim",durationMs:Math.max(0,this.telemetryTimestamp()-i),durationMode:"machine",requestCategory:"session_claim",statusClass:l,attempt:d}),this.directTelemetry?.log({name:"session.request.completed",stage:"session_create",requestCategory:"session_create",statusClass:l}),this.directTelemetry?.performance({stage:"session_create",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"session_create",statusClass:l,attempt:n?.createAttempt??d}),y}catch(h){throw this.reportSessionCreateFailure(h,o,{attempt:d,statusClass:l},"session_claim"),h}finally{c.clear()}}reportSessionCreateFailure(e,t,r,n="session_create"){if(!(e instanceof a.FloPayError&&e.code==="session_auto_completed"))try{this.telemetryHooks?.onSessionCreateFailure?.(e)}catch{}let o=(0,a.classifyTelemetryFailure)(e,"CHECKOUT_SESSION_CREATE_FAILED");if(this.directTelemetry?.performance({stage:n,durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:n==="session_claim"?"session_claim":"session_create",statusClass:o.statusClass,attempt:r.attempt}),e instanceof a.FloPayError&&e.type==="validation_error"||e instanceof a.FloPayError&&ne(e.statusCode)){this.directTelemetry?.terminal({outcome:"validation_rejected",stage:n,requestCategory:n==="session_claim"?"session_claim":"session_create",...e.type==="validation_error"?{}:{statusClass:"4xx"}});return}e instanceof a.FloPayError&&e.code==="session_auto_completed"||this.directTelemetry?.error({...o,stage:n,requestCategory:n==="session_claim"?"session_claim":"session_create"})}async waitForCheckoutSessionCompletion(e,t){this.beginDirectTelemetryCheckout(e);let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.recovery.started",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved"});let n=t?.timeoutMs??Oe,o=Date.now()+n,i=this.clampRetryAfterMs(t?.initialDelayMs??re),c=0;try{for(;;){let u=o-Date.now();if(u<=0)throw F();if(i>0){try{c+=1,this.telemetryHooks?.onRetry?.("session_read",c),this.directTelemetry?.log({name:"operation.retry",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved",attempt:c})}catch{}if(await ie(Math.min(i,u)),Date.now()>=o)throw F()}let l=await this.getUnifiedCheckoutSession(e,t?.nonce),d=l.data.session?.status;if(d==="authorized"||d==="complete"||d==="expired")return this.directTelemetry?.log({name:"operation.recovery.completed",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved"}),this.directTelemetry?.performance({stage:"recovery",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_read",paymentMethodCategory:"saved"}),l;if(Date.now()>=o)throw F();i=this.clampRetryAfterMs(Math.max(i*2,xe))}}catch(u){throw u instanceof a.FloPayError&&u.code==="checkout_processing_timeout"&&this.reportDirectFailure(u,"RECOVERY_FAILED","recovery","session_read","saved"),u}}normalizeRawSession(e){let t=e.gateways??{},r=[],n={session:this.toCheckoutSession(e)},o=t.stripe;if(o?.publishableKey){r.push("stripe");let u=[e.stripeClientSecret,o.stripeClientSecret].find(l=>typeof l=="string"&&l.length>0);n.stripe={clientSecret:u??"",publishableKey:o.publishableKey??void 0,paypalPublishableKey:o.paypalPublishableKey??void 0,environment:o.environment,enabledPaymentMethods:Array.isArray(o.enabledPaymentMethods)?o.enabledPaymentMethods.filter(l=>typeof l=="string"):void 0}}let i=t.paypal;return i?.publishableKey&&(r.push("paypal"),n.paypal={publishableKey:i.publishableKey,environment:i.environment,providerObjectType:i.providerObjectType}),{providers:r,mode:"tokenize",data:n,raw:{data:e}}}toCheckoutSession(e){let t=e.products??[],r=typeof e.totalAmount=="number"&&Number.isFinite(e.totalAmount),n=t.reduce((l,d)=>l+(d.overrideAmount??d.totalAmount??0),0),o=r?e.totalAmount:n,i=Math.round(o*100),c=e.currency??t[0]?.currency??"USD",u=e.checkoutMode==="setup"?"setup":t.some(l=>l.type==="subscription")?"subscription":"payment";return{id:e.uuid,clientSecret:e.nonce,mode:u,status:this.toCheckoutSessionStatus(e.status),amount:i,currency:c,captureMethod:e.captureMethod,paymentId:e.paymentId,authorizationExpiresAt:e.authorizationExpiresAt,failureOutcome:(0,a.normalizeCheckoutFailureOutcome)(e.outcome)??(0,a.normalizeCheckoutFailureOutcome)(e.failureReason)??(e.status==="expired"&&e.captureMethod==="manual"?"authorization_expired":void 0),customer:{id:e.accountData.userId,email:e.accountData.email,firstName:e.accountData.firstName,lastName:e.accountData.lastName,country:e.accountData.country??void 0,city:e.accountData.city??void 0,state:e.accountData.state??void 0,zip:e.accountData.zip??void 0,gender:e.accountData.gender??void 0,line1:e.accountData.addressLine1??void 0,line2:e.accountData.addressLine2??void 0},metadata:{},checkoutMode:e.checkoutMode,providerPaymentMethodId:typeof e.providerPaymentMethodId=="string"?e.providerPaymentMethodId:null,products:t.map(l=>({...l,totalAmount:typeof l.totalAmount=="number"?l.totalAmount:void 0,overrideAmount:typeof l.overrideAmount=="number"?l.overrideAmount:null,currency:typeof l.currency=="string"?l.currency:void 0,metadata:l.metadata??null})),successUrl:e.successUrl,cancelUrl:e.cancelUrl,coupons:e.coupons,subtotalAmount:e.subtotalAmount,discountAmount:e.discountAmount,totalAmount:e.totalAmount,createdAt:e.createdAt,gateways:e.gateways,accountData:e.accountData,tagsData:e.tagsData}}toVaultBlock(e){return{html:typeof e.html=="string"?e.html:void 0,url:typeof e.url=="string"?e.url:void 0,messageToken:typeof e.messageToken=="string"?e.messageToken:void 0,expectedOrigin:typeof e.expectedOrigin=="string"?e.expectedOrigin:void 0}}toCheckoutSessionStatus(e){return e==="completed"?"complete":e==="authorized"?"authorized":e==="expired"?"expired":"open"}async resolveProcessResponse(e,t,r){if(e.status!==202)return e;let n=await e.json().catch(()=>null),o=this.toCheckoutProcessingPending(n,e,t),i=await this.waitForCheckoutSessionCompletion(o.sessionId,{initialDelayMs:o.retryAfterMs,timeoutMs:r?.pollTimeoutMs,nonce:r?.nonce});if(i.data.session?.status==="complete")return new Response(null,{status:204,statusText:"No Content"});if(i.data.session?.status==="authorized"){let c=i.data.session;return new Response(JSON.stringify({status:"authorized",paymentId:c.paymentId,sessionId:c.id||t,authorizationExpiresAt:c.authorizationExpiresAt}),{status:200,headers:{"Content-Type":"application/json"}})}if(i.data.session?.status==="expired"){let c=i.data.session.failureOutcome==="authorization_expired"||i.data.session.captureMethod==="manual";throw new a.FloPayError(c?"Authorization has expired.":"Checkout session has expired.","api_error",{code:c?"authorization_expired":"checkout_session_expired"})}throw F()}toCheckoutProcessingPending(e,t,r){let n=t.headers.get("Retry-After"),o=n===null||n.trim()===""?void 0:Number(n),i=o!==void 0&&Number.isFinite(o)?o*1e3:void 0;return{type:"checkout_processing",sessionId:w(e,"sessionId")??r,retryAfterMs:this.clampRetryAfterMs(Ve(e,"retryAfterMs")??i??re),statusUrl:w(e,"statusUrl"),sessionUrl:w(e,"sessionUrl")}}clampRetryAfterMs(e){return Math.max(0,Math.min(e,qe))}autoCacheDisplayData(e,t){if(!e)return;let r=t.products??(0,a.foldIntoProducts)(t.items,t.subscriptions);if(r.length===0&&!t.currency)return;let n=t.products!==void 0,o=(0,a.resolveSessionCurrency)(t.currency,n?void 0:t.items,n?void 0:t.subscriptions,r);H(e,{currency:o??void 0,products:r.map(i=>({code:i.code??i.providerItemId??i.providerPlanId,type:i.type,name:i.name??i.itemName??i.providerItemName??i.subscriptionName??i.providerPlanName??null,totalAmount:i.totalAmount,overrideAmount:i.overrideAmount,currency:i.currency??o??void 0}))})}mergeCachedDisplayData(e){let t=Q(e.uuid),r=new Map,n=i=>i?`code:${i}`:void 0;for(let i of t?.products??[]){let c=n(i.code);c&&r.set(c,i)}let o=(e.products??[]).map(i=>{let c=n(i.code),u=c?r.get(c):void 0;return{...i,name:i.name??u?.name??null,totalAmount:i.totalAmount??u?.totalAmount,overrideAmount:i.overrideAmount??u?.overrideAmount,currency:i.currency??u?.currency}});return{...e,currency:e.currency??t?.currency,products:o}}};A.activeVaultCaptureRequests=new Map;var U=A;var f=require("@flopay/shared");var G="flopay-vault",ue={ready:["vault.widget.ready","vault_ready"],submitting:["vault.submission.started","vault_submit"],blocked:["operation.state_transition","vault_submit"],action_required:["vault.action.required","three_ds_handoff"]};function P(s){let e={class:s.class,stage:s.stage};"code"in s&&(e.code=s.code),"provider"in s&&s.provider&&(e.provider=s.provider),"paymentMethodCategory"in s&&s.paymentMethodCategory&&(e.paymentMethodCategory=s.paymentMethodCategory),"outcome"in s&&(e.outcome=s.outcome),"durationMs"in s&&s.durationMs!==void 0&&(e.durationMs=s.durationMs),"durationMode"in s&&s.durationMode&&(e.durationMode=s.durationMode);try{globalThis.Sentry?.addBreadcrumb?.({category:"flopay.telemetry",level:s.class==="technical_error"?"error":"info",message:s.class==="lifecycle"?s.name:s.class==="technical_error"?s.code:s.class==="expected_outcome"?s.outcome:"sdk.performance",data:e})}catch{}}function V(s,e){return(0,f.buildTelemetryLogEvent)({eventId:"11111111-1111-4111-8111-111111111111",name:s,stage:e,sequence:0,provider:"pcivault",paymentMethodCategory:"card"})}function le(s){return s?{errorCode:"VAULT_SUBMIT_FAILED",stage:"vault_submit",failureCategory:"provider_runtime"}:{errorCode:"VAULT_LOAD_FAILED",stage:"vault_mount",failureCategory:"provider_runtime"}}function de(s,e,t="checkout"){return t==="card_setup"?s.type==="decline"?"card_setup_declined":"card_setup_succeeded":s.type==="decline"?"payment_declined":s.outcome==="authorized"||e==="manual"?"payment_authorized":"payment_succeeded"}function Ke(s,e,t,r="checkout"){let{type:n}=s;if(n==="complete"||n==="decline")return(0,f.buildTelemetryTerminalEvent)({eventId:"22222222-2222-4222-8222-222222222222",outcome:de(s,t,r),sequence:0,provider:"pcivault",paymentMethodCategory:"card"});if(n==="error"){let c=le(e);return(0,f.buildTelemetryErrorEvent)({eventId:"33333333-3333-4333-8333-333333333333",...c,sequence:0,provider:"pcivault",paymentMethodCategory:"card"})}let[o,i]=ue[n];return V(o,i)}function $e(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===G&&(e.type==="ready"||e.type==="submitting"||e.type==="blocked"||e.type==="complete"||e.type==="decline"||e.type==="error"||e.type==="action_required")}function Ge(s){if(typeof s!="object"||s===null)return;let e=s,t=e.status;if(!(typeof e.id!="string"||e.id.trim()===""||typeof e.brand!="string"||e.brand.trim()===""||typeof e.lastFour!="string"||!/^\d{4}$/.test(e.lastFour)||typeof e.expiryMonth!="number"||!Number.isInteger(e.expiryMonth)||e.expiryMonth<1||e.expiryMonth>12||typeof e.expiryYear!="number"||!Number.isInteger(e.expiryYear)||e.expiryYear<1970||e.expiryYear>9999||t!=="pending"&&t!=="active"&&t!=="deleted"))return{id:e.id,brand:e.brand,lastFour:e.lastFour,expiryMonth:e.expiryMonth,expiryYear:e.expiryYear,status:t}}function Ye(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===G&&e.type==="validation"&&Array.isArray(e.messages)}function We(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===G&&e.type==="resize"&&typeof e.height=="number"&&Number.isFinite(e.height)}var N=class{constructor(e={},t){this.provider="pcivault";this.container=null;this.messageHandler=null;this.actionOverlay=null;this.threeDsReturnHandler=null;this.messageToken=null;this.expectedOrigin=null;this.theme=null;this.submitGateBlocked=!1;this.cardFieldOrder=null;this.cardAutoFocus=!0;this.mountStartedAt=0;this.vaultReadyReported=!1;this.submissionStarted=!1;this.submissionStartedAt=null;this.listeners=new Map;this.config=e,this.ownsTelemetryReporter=!t&&e.telemetry!==!1,this.telemetryReporter=t?.reporter??(this.ownsTelemetryReporter?new S({billingApiUrl:(0,f.resolveBillingApiUrl)(),sdkVersion:f.SDK_VERSION}):void 0)}async mount(e,t){this.ownsTelemetryReporter&&!this.telemetryReporter&&(this.telemetryReporter=new S({billingApiUrl:(0,f.resolveBillingApiUrl)(),sdkVersion:f.SDK_VERSION}));let r=this.telemetryReporter;if(this.config.operation==="card_setup"&&r&&this.setupTelemetryReporter!==r){this.setupTelemetryReporter=r;try{r.beginCheckout({checkoutMode:"setup"})}catch{}}if(this.mountStartedAt=this.telemetryReporter?.now?.()??k(),this.vaultReadyReported=!1,this.submissionStarted=!1,this.submissionStartedAt=null,typeof window>"u"||typeof document>"u")throw this.reportVaultLoadFailure(),new f.FloPayError("The vault card form is only available in the browser.","api_error",{code:"card_capture_no_window"});if(!t?.html?.trim())throw this.reportVaultLoadFailure(),new f.FloPayError("No vault capture widget HTML was provided to mount the secure card form.","api_error",{code:"card_capture_no_widget_html"});this.container=e,this.messageToken=t.messageToken??null,this.expectedOrigin=t.expectedOrigin??this.config.expectedOrigin??null,this.theme=t.theme??null;try{this.attachMessageListener(),this.injectWidget(e,t.html)}catch(n){throw this.reportVaultLoadFailure(),n}this.postTheme(),this.postSubmitGate(),this.postCardFieldOrder(),P(V("vault.widget.mounted","vault_mount")),this.telemetryReporter?.log({name:"vault.widget.mounted",stage:"vault_mount",provider:"pcivault",paymentMethodCategory:"card"}),this.emit("ready",{sessionId:this.config.sessionId})}reportVaultLoadFailure(){this.telemetryReporter?.error({errorCode:"VAULT_LOAD_FAILED",failureCategory:"provider_runtime",stage:"vault_mount",provider:"pcivault",paymentMethodCategory:"card"})}on(e,t){let r=this.listeners.get(e);return r||(r=new Set,this.listeners.set(e,r)),r.add(t),()=>{this.listeners.get(e)?.delete(t)}}unmount(){this.hideActionRequiredOverlay(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.container&&(this.container.replaceChildren(),this.container=null),this.messageToken=null,this.expectedOrigin=null,this.ownsTelemetryReporter&&(this.telemetryReporter?.destroy(),this.telemetryReporter=void 0)}injectWidget(e,t){e.innerHTML=t;let r=Array.from(e.querySelectorAll("script"));for(let n of r){let o=document.createElement("script");for(let i of Array.from(n.attributes))o.setAttribute(i.name,i.value);o.text=n.text,n.replaceWith(o)}}attachMessageListener(){if(this.messageHandler)return;let e=t=>{if(this.expectedOrigin&&t.origin!==this.expectedOrigin)return;let r=t.data;if(We(r)){if(this.messageToken&&r.messageToken!==this.messageToken)return;this.applyHeight(r.height);return}if(Ye(r)){if(this.messageToken&&r.messageToken!==this.messageToken)return;let u=r.messages.filter(l=>typeof l=="string"&&l.trim()).join(" ");this.emit("validation",{sessionId:this.config.sessionId,message:u||void 0});return}if(!$e(r)||this.messageToken&&r.messageToken!==this.messageToken)return;let n=this.config.sessionId,o=typeof r.sessionId=="string"?r.sessionId:void 0;if(n&&o&&o!==n||(r.type==="complete"||r.type==="decline")&&n&&o!==n)return;let i=Ge(r.paymentMethod),c={...r.sessionId??this.config.sessionId?{sessionId:r.sessionId??this.config.sessionId}:{},...r.outcome?{outcome:r.outcome}:{},...r.paymentId?{paymentId:r.paymentId}:{},...r.authorizationExpiresAt?{authorizationExpiresAt:r.authorizationExpiresAt}:{},...r.failureOutcome?{failureOutcome:r.failureOutcome}:{},...r.intentId?{intentId:r.intentId}:{},...r.declineReason?{declineReason:r.declineReason}:{},...r.message?{message:r.message}:{},...i?{paymentMethod:i}:{}};r.type==="submitting"&&(this.submissionStarted=!0,this.submissionStartedAt=this.telemetryReporter?.now?.()??k()),P(Ke(r,this.submissionStarted,this.config.captureMethod,this.config.operation)),this.reportOutcome(r),r.type==="ready"&&(this.postTheme(),this.postSubmitGate(),this.postCardFieldOrder()),r.type==="action_required"&&r.nextActionRedirectUrl&&this.showActionRequiredOverlay(r.nextActionRedirectUrl),(r.type==="complete"||r.type==="decline"||r.type==="error"||r.type==="submitting")&&this.hideActionRequiredOverlay(),r.type!=="action_required"&&this.emit(r.type,c)};this.messageHandler=e,window.addEventListener("message",e)}reportOutcome(e){let t=this.telemetryReporter;if(!t)return;let{type:r}=e;if(r==="ready"&&!this.vaultReadyReported&&(this.vaultReadyReported=!0,t.performance({stage:"vault_ready",durationMs:Math.max(0,t.now()-this.mountStartedAt),durationMode:"machine",provider:"pcivault",paymentMethodCategory:"card"})),r==="complete"||r==="decline"){t.log({name:"vault.terminal",stage:"completion",provider:"pcivault",paymentMethodCategory:"card"}),t.terminal({outcome:de(e,this.config.captureMethod,this.config.operation),provider:"pcivault",paymentMethodCategory:"card"});return}if(r==="error"){let i=le(this.submissionStarted);t.log({name:"vault.terminal",stage:i.stage,provider:"pcivault",paymentMethodCategory:"card"}),t.error({...i,provider:"pcivault",paymentMethodCategory:"card"});return}if(r==="action_required"){t.log({name:"vault.action.required",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"}),t.log({name:"vault.three_ds.handoff",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"});let i=this.submissionStartedAt;this.submissionStartedAt=null,i!==null&&t.performance({stage:"three_ds_handoff",durationMs:Math.max(0,t.now()-i),durationMode:"machine",provider:"pcivault",paymentMethodCategory:"card"}),t.terminal({outcome:"action_required",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"});return}let[n,o]=ue[r];t.log({name:n,stage:o,provider:"pcivault",paymentMethodCategory:"card"})}applyTheme(e){this.theme=e,this.postTheme()}postTheme(){if(!this.theme||!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"theme",theme:this.theme},"*")}catch{}}setSubmitGate(e){this.submitGateBlocked=e,this.postSubmitGate()}postSubmitGate(){if(!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"gate",blocked:this.submitGateBlocked},"*")}catch{}}setCardFieldOrder(e,t){this.cardFieldOrder=e,this.cardAutoFocus=t,this.postCardFieldOrder()}postCardFieldOrder(){if(!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"fieldOrder",order:this.cardFieldOrder,autoFocus:this.cardAutoFocus},"*")}catch{}}emit(e,t){for(let r of this.listeners.get(e)??[])r(t)}showActionRequiredOverlay(e){if(typeof document>"u")return;if(this.actionOverlay){let i=this.actionOverlay.querySelector("iframe");i instanceof HTMLIFrameElement&&(i.src=e);return}let t=document.createElement("div");t.setAttribute("data-flopay-action-required","1"),t.style.cssText=["position:fixed","inset:0","z-index:2147483647","background:rgba(15,23,42,0.6)","display:flex","align-items:center","justify-content:center","padding:16px"].join(";");let r=document.createElement("iframe");r.setAttribute("title","Card authentication"),r.setAttribute("allow","payment"),r.style.cssText=["width:min(100%,460px)","height:min(100%,640px)","border:0","border-radius:12px","background:#fff","box-shadow:0 12px 30px rgba(0,0,0,0.35)"].join(";"),r.src=e,t.appendChild(r);let n=document.createElement("button");n.type="button",n.setAttribute("aria-label","Close card authentication"),n.textContent="\xD7",n.style.cssText=["position:fixed","top:20px","right:20px","width:40px","height:40px","border:0","border-radius:9999px","background:#fff","color:#0f172a","font-size:28px","line-height:40px","cursor:pointer","box-shadow:0 4px 14px rgba(0,0,0,0.25)"].join(";"),n.addEventListener("click",()=>this.abandonActionRequiredOverlay()),t.appendChild(n),t.addEventListener("click",i=>{i.target===t&&this.abandonActionRequiredOverlay()});let o=i=>{if(i.source!==r.contentWindow)return;let c=i.data;if(!c||typeof c!="object")return;let u=c;u.source==="flopay-vault-3ds-return"&&(P(V("vault.three_ds.returned","three_ds_return")),this.telemetryReporter?.log({name:"vault.three_ds.returned",stage:"three_ds_return",provider:"pcivault",paymentMethodCategory:"card"}),this.hideActionRequiredOverlay(),this.postActionCompleted(u.status))};window.addEventListener("message",o),this.threeDsReturnHandler=o,document.body.appendChild(t),this.actionOverlay=t,P(V("vault.three_ds.handoff","three_ds_handoff"))}postActionCompleted(e){if(!this.container)return;let r=this.container.querySelector("iframe")?.contentWindow;if(r)try{r.postMessage({source:"flopay-vault-host",type:"action_completed",status:typeof e=="string"?e:"unknown"},"*")}catch{}}abandonActionRequiredOverlay(){if(!this.actionOverlay)return;let e=(0,f.buildTelemetryTerminalEvent)({eventId:"77777777-7777-4777-8777-777777777777",outcome:"customer_abandoned",stage:"three_ds_handoff",sequence:0,provider:"pcivault",paymentMethodCategory:"card"});P(e),this.telemetryReporter?.terminal({outcome:"customer_abandoned",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"}),this.hideActionRequiredOverlay(),this.postActionCompleted("abandoned")}hideActionRequiredOverlay(){this.threeDsReturnHandler&&(window.removeEventListener("message",this.threeDsReturnHandler),this.threeDsReturnHandler=null),this.actionOverlay&&(this.actionOverlay.parentNode?.removeChild(this.actionOverlay),this.actionOverlay=null)}applyHeight(e){let t=this.container?.querySelector("iframe");if(!t)return;let r=Math.max(0,Math.min(Math.ceil(e),2e3));t.style.height=`${r}px`}};0&&(module.exports={PaymentAPI,PciVaultCardCapture});
|
|
1
|
+
"use strict";var z=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var Te=(s,e)=>{for(var t in e)z(s,t,{get:e[t],enumerable:!0})},be=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ce(e))!ve.call(s,n)&&n!==t&&z(s,n,{get:()=>e[n],enumerable:!(r=fe(e,n))||r.enumerable});return s};var _e=s=>be(z({},"__esModule",{value:!0}),s);var Xe={};Te(Xe,{PaymentAPI:()=>F,PciVaultCardCapture:()=>U});module.exports=_e(Xe);var a=require("@flopay/shared");function W(s){return typeof s=="string"&&s.trim()?s:void 0}function J(s){if(typeof s=="string")return s.trim()?s:void 0;if(Array.isArray(s))return s.filter(t=>typeof t=="string"&&t.trim().length>0).join("; ")||void 0}function E(s=12e3){let e=Number.isFinite(s)&&s>=0?s:12e3,t=new AbortController,r=setTimeout(()=>t.abort(),e);return{signal:t.signal,clear:()=>clearTimeout(r)}}function ke(){return Object.assign(new Error("The operation was aborted."),{name:"AbortError"})}function I(s,e){let t=150*2**s,r=Math.round(t*(.75+Math.random()*.5));return new Promise((n,o)=>{let i,c=()=>e.removeEventListener("abort",u),u=()=>{i!==void 0&&clearTimeout(i),c(),o(ke())};if(e.aborted){u();return}i=setTimeout(()=>{c(),n()},r),e.addEventListener("abort",u,{once:!0})})}var Se="flopay_session_display:";var P=new Map;function D(s){return`${Se}${s}`}function B(){if(typeof window>"u")return null;try{return window.sessionStorage}catch{return null}}function j(s,e,t){if(!s)return;let r=t?.ttlMs??36e5,n={data:e,expiresAt:Date.now()+r},o=B();if(o)try{o.setItem(D(s),JSON.stringify(n));return}catch{}P.set(s,n)}function Q(s){if(!s)return null;let e=B();if(e)try{let r=e.getItem(D(s));if(r){let n=JSON.parse(r);if(n&&typeof n.expiresAt=="number"&&n.expiresAt>Date.now())return n.data;e.removeItem(D(s))}}catch{}let t=P.get(s);if(t){if(t.expiresAt>Date.now())return t.data;P.delete(s)}return null}function X(s){if(!s)return;P.delete(s);let e=B();if(e)try{e.removeItem(D(s))}catch{}}var v=require("@flopay/shared"),Me="/v1/sdk-telemetry/events",H=16,Ae=64,Ee=1500,Z=1e3,Re=64,we="00000000-0000-4000-8000-000000000000",Ie={technical_error:8,lifecycle:32,expected_outcome:32,performance:24};function M(){try{return globalThis.crypto.randomUUID()}catch{let s=new Uint8Array(16);try{globalThis.crypto.getRandomValues(s)}catch{for(let t=0;t<s.length;t+=1)s[t]=Math.floor(Math.random()*256)}s[6]=s[6]&15|64,s[8]=s[8]&63|128;let e=[...s].map(t=>t.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}}function Pe(s){try{return new TextEncoder().encode(s).byteLength}catch{return s.length}}function De(s){return JSON.stringify([s.code,s.failureCategory,s.stage,s.provider,s.attempt,s.statusClass,s.requestCategory,s.paymentMethodCategory,s.checkoutMode,s.layout])}function b(){return globalThis.performance?.now()??0}var _=class{constructor(e){this.ingestionDisabled=!1;this.queue=[];this.sequence=0;this.flushTimer=null;this.flushInFlight=null;this.reportedFailures=new Map;this.checkoutContext={};this.checkoutStartedAt=null;this.destroyed=!1;this.observers=new Set;this.pageExitHandler=()=>{this.drainQueue()};this.visibilityHandler=()=>{document.visibilityState==="hidden"&&this.flush()};this.eventCounts={technical_error:0,lifecycle:0,expected_outcome:0,performance:0};this.endpoint=`${e.billingApiUrl.replace(/\/+$/,"")}${Me}`,this.sdkPackage=e.sdkPackage??"@flopay/js",this.sdkVersion=e.sdkVersion,this.correlationId=M(),this.merchantEnabled=e.enabled!==!1,this.clock=e.clock??b,this.browserTransportAvailable=typeof window<"u"&&typeof document<"u",this.browserTransportAvailable&&(window.addEventListener("pagehide",this.pageExitHandler),document.addEventListener("visibilitychange",this.visibilityHandler))}log(e){this.notify({...e,class:"lifecycle"}),this.canCollect()&&this.enqueue((0,v.buildTelemetryLogEvent)({...this.checkoutContext,...e,eventId:M(),sequence:this.sequence++}))}error(e){if(this.notify({...e,class:"technical_error"}),!this.canCollect())return;let t=(0,v.buildTelemetryErrorEvent)({...this.checkoutContext,...e,eventId:we,sequence:0}),r=De(t),n=this.now();this.pruneReportedFailures(n);let o=this.reportedFailures.get(r);if(o!==void 0&&n>=o&&n-o<Z){this.log({name:"operation.deduplicated",stage:e.stage,provider:e.provider,paymentMethodCategory:e.paymentMethodCategory,attempt:e.attempt});return}this.rememberReportedFailure(r,n),this.enqueue((0,v.buildTelemetryErrorEvent)({...this.checkoutContext,...e,eventId:M(),sequence:this.sequence++}))}performance(e){this.canCollect()&&this.enqueue((0,v.buildTelemetryPerformanceEvent)({...this.checkoutContext,...e,eventId:M(),sequence:this.sequence++}))}terminal(e){if(this.canCollect()&&(this.enqueue((0,v.buildTelemetryTerminalEvent)({...this.checkoutContext,...e,eventId:M(),sequence:this.sequence++})),e.outcome!=="action_required"&&this.checkoutStartedAt!==null)){let t=this.checkoutStartedAt;this.checkoutStartedAt=null,this.performance({stage:"total_journey",durationMs:Math.max(0,this.now()-t),durationMode:"total",provider:e.provider,paymentMethodCategory:e.paymentMethodCategory})}}now(){try{return this.clock()}catch{return b()}}subscribe(e){return this.destroyed?()=>{}:(this.observers.add(e),()=>this.observers.delete(e))}notify(e){if(!this.destroyed)for(let t of this.observers)try{t(e)}catch{}}pruneReportedFailures(e){for(let[t,r]of this.reportedFailures)(e<r||e-r>=Z)&&this.reportedFailures.delete(t)}rememberReportedFailure(e,t){for(;this.reportedFailures.size>=Re;){let r=this.reportedFailures.keys().next();if(r.done)break;this.reportedFailures.delete(r.value)}this.reportedFailures.set(e,t)}setCheckoutContext(e){this.checkoutContext={checkoutMode:e.checkoutMode,layout:e.layout}}beginCheckout(e={}){return this.canCollect()?(this.drainQueue(),this.setCheckoutContext(e),this.sequence=0,this.reportedFailures.clear(),this.eventCounts={technical_error:0,lifecycle:0,expected_outcome:0,performance:0},this.checkoutStartedAt=this.now(),this.checkoutStartedAt):0}enqueue(e){if(this.canCollect()&&!(this.queue.length>=Ae||this.eventCounts[e.class]>=Ie[e.class])){if(this.eventCounts[e.class]+=1,this.queue.push(e),this.queue.length>=H){this.flush();return}this.scheduleFlush()}}canCollect(){return this.browserTransportAvailable&&this.merchantEnabled&&!this.ingestionDisabled&&!this.destroyed}async flush(){if(this.flushInFlight)return this.flushInFlight;if(!this.browserTransportAvailable||this.destroyed||this.ingestionDisabled||this.queue.length===0)return;this.clearFlushTimer();let e=this.queue.splice(0,H);return this.flushInFlight=this.sendBatch(e).finally(()=>{this.flushInFlight=null,this.queue.length>0&&this.scheduleFlush()}),this.flushInFlight}destroy(){this.destroyed||(this.drainQueue(),this.destroyed=!0,this.clearFlushTimer(),this.browserTransportAvailable&&(window.removeEventListener("pagehide",this.pageExitHandler),document.removeEventListener("visibilitychange",this.visibilityHandler)),this.queue.splice(0),this.reportedFailures.clear(),this.observers.clear())}disable(){this.merchantEnabled=!1,this.queue.splice(0),this.reportedFailures.clear(),this.clearFlushTimer()}drainQueue(){if(!(!this.browserTransportAvailable||this.destroyed||this.ingestionDisabled||this.queue.length===0))for(this.clearFlushTimer();this.queue.length>0;){let e=this.queue.splice(0,H);this.sendBatch(e)}}async sendBatch(e){if(!this.browserTransportAvailable||this.ingestionDisabled)return;let t=(0,v.serializeTelemetryBatch)(e,{correlationId:this.correlationId,sdkPackage:this.sdkPackage,sdkVersion:this.sdkVersion,batchId:M()});if(Pe(t)>v.TELEMETRY_MAX_BATCH_BYTES)return;let r=typeof AbortController>"u"?null:new AbortController,n=null;try{let o=fetch(this.endpoint,{method:"POST",headers:{"content-type":"text/plain;charset=UTF-8"},body:t,credentials:"omit",keepalive:!0,referrerPolicy:"no-referrer",signal:r?.signal}).then(async u=>u.status!==202?null:(await u.json().catch(()=>null))?.status==="disabled"?"disabled":null).catch(()=>null),i=new Promise(u=>{n=setTimeout(()=>{r?.abort(),u(null)},Ee)});await Promise.race([o,i])==="disabled"&&this.disableFromIngestion()}catch{}finally{n&&clearTimeout(n)}}disableFromIngestion(){this.ingestionDisabled=!0,this.queue.splice(0),this.reportedFailures.clear(),this.clearFlushTimer()}scheduleFlush(){this.flushTimer||this.destroyed||this.ingestionDisabled||(this.flushTimer=setTimeout(()=>{this.flushTimer=null,this.flush()},0))}clearFlushTimer(){this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)}},ee=Symbol.for("@flopay/js.telemetry.reporter-factory.v1"),te=globalThis;te[ee]===void 0&&Object.defineProperty(te,ee,{configurable:!0,enumerable:!1,writable:!1,value:s=>new _(s)});var re=1e3,xe=500,Oe=15e3,qe=3e3,Fe=1e4,Le=1e4;function Ue(s){return typeof s=="object"&&s!==null}function A(s,e){return W(s?.[e])}function se(s,e){return J(s?.[e])}function Ve(s,e){let t=s?.[e];return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ie(s){return new Promise(e=>setTimeout(e,s))}function O(){return new a.FloPayError("Checkout is still processing. Please try again shortly.","api_error",{code:"checkout_processing_timeout"})}async function k(s,e){let t=await s.json().catch(()=>null),r=Ue(t?.error)?t.error:null,n=se(t,"message")??se(r,"message")??e,o=A(t,"code")??A(t,"gatewayErrorCode")??A(r,"code")??`http_${s.status}`;return new a.FloPayError(n,"api_error",{code:o,statusCode:s.status})}async function Ne(s){let e=s.status===400?await s.clone().json().catch(()=>null):null;return(0,a.classifyPaymentRejection)(s.status,e)}function ne(s){return s===400||s===422}var q=2;async function K(s,e,t=q,r){let n;for(let o=0;;o++)try{return await fetch(s,e)}catch(i){if(e?.signal?.aborted||i instanceof Error&&i.name==="AbortError")throw i;if(n=i,o>=t)throw n;try{r?.(o+1)}catch{}await ie(150*2**o)}}var ze=Symbol.for("@flopay/js.session-create.telemetry.v1");function Be(s){return s[ze]}function je(s){return"now"in s||"onFirstByte"in s||"onSessionCreateFailure"in s||"onRetry"in s}function ae(s){return{userId:s.userId,firstName:s.firstName??null,lastName:s.lastName??null,email:s.email,country:s.country??null,gender:s.gender??null,city:s.city??null,state:s.state??null,zip:s.zip??null,addressLine1:s.addressLine1??null,addressLine2:s.addressLine2??null}}function ce(s,e){e.tagsData&&(s.tagsData=e.tagsData),e.utmMetadata?.length&&(s.utmMetadata=e.utmMetadata),e.avsCheck!==void 0&&(s.avsCheck=e.avsCheck),e.checkoutType&&(s.checkoutType=e.checkoutType),e.checkoutLayout&&(s.checkoutLayout=e.checkoutLayout),e.avsConfig&&(s.avsConfig=e.avsConfig)}function He(s,e){let t={clientId:s.clientId,checkoutVersion:a.SDK_VERSION,successUrl:s.successUrl,cancelUrl:s.cancelUrl,currency:e,checkoutMode:"full",deferDataAttachment:!0};return s.captureMethod==="manual"&&(t.captureMethod=s.captureMethod),s.account.country&&(t.accountData={country:s.account.country}),ce(t,s),t}function oe(s,e,t){return{currency:e,products:t.map(r=>(0,a.buildProductPayload)(r,e)),couponCodes:s.couponCodes??[],accountData:ae(s.account)}}function Ke(s,e,t){return{currency:e,products:t.map(r=>(0,a.buildProductPayload)(r,e)),couponCodes:s.couponCodes??[]}}function $e(s){let e={};for(let[t,r]of Object.entries(s)){if(typeof r!="string")continue;let n=r.trim();n&&(e[t]=n)}return{accountData:e}}var S=class S{constructor(e,t={}){this.baseUrl=e.replace(/\/+$/,"");let r=je(t);this.telemetryHooks=r?t:void 0,this.directTelemetry=r||t.telemetry===!1?void 0:new _({billingApiUrl:this.baseUrl,sdkVersion:a.SDK_VERSION})}destroy(){this.directTelemetry?.destroy()}reportDirectFailure(e,t,r,n,o="unknown"){let i=(0,a.classifyTelemetryFailure)(e,t);this.directTelemetry?.error({...i,stage:r,requestCategory:n,paymentMethodCategory:o})}reportAccountSnapshotFailure(e,t){let r=(0,a.classifyTelemetryFailure)(e,"NETWORK_REQUEST_FAILED");if(t==="best_effort"&&r.errorCode==="REQUEST_TIMEOUT"){this.directTelemetry?.log({name:"operation.fallback",stage:"processing",requestCategory:"account_snapshot",statusClass:"timeout"});return}this.directTelemetry?.error({...r,stage:"processing",requestCategory:"account_snapshot",paymentMethodCategory:"unknown"})}telemetryTimestamp(){try{return this.telemetryHooks?.now?.()??this.directTelemetry?.now()??b()}catch{return b()}}beginDirectTelemetryCheckout(e){!this.directTelemetry||this.directTelemetryCheckoutId===e||(this.directTelemetryCheckoutId=e,this.directTelemetry.beginCheckout())}beginDirectTelemetryOperation(){this.directTelemetry&&(this.directTelemetryCheckoutId=void 0,this.directTelemetry.beginCheckout())}adoptDirectTelemetryCheckout(e){e&&(this.directTelemetryCheckoutId=e)}async getCheckoutSession(e,t){this.beginDirectTelemetryCheckout(e);let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"session.read.started",stage:"session_read",requestCategory:"session_read"});let n={[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION};t&&(n["x-checkout-session-token"]=t);try{let o=await K(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}`,{headers:n},q,l=>{this.telemetryHooks?.onRetry?.("session_read",l),this.directTelemetry?.log({name:"operation.retry",stage:"session_read",requestCategory:"session_read",attempt:l})}),i=Math.max(0,this.telemetryTimestamp()-r);try{this.telemetryHooks?.onFirstByte?.(i)}catch{}let c=`${Math.floor(o.status/100)}xx`;if(this.directTelemetry?.log({name:"session.request.first_byte",stage:"session_first_byte",requestCategory:"session_read",statusClass:c}),this.directTelemetry?.performance({stage:"session_first_byte",durationMs:i,durationMode:"machine",requestCategory:"session_read",statusClass:c}),!o.ok)throw await k(o,"Failed to get checkout session");let u=await o.json();return this.directTelemetry?.log({name:"session.request.completed",stage:"session_complete",requestCategory:"session_read",statusClass:c}),this.directTelemetry?.performance({stage:"session_complete",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_read",statusClass:c}),{...u,data:this.mergeCachedDisplayData(u.data)}}catch(o){throw this.directTelemetry?.error({...(0,a.classifyTelemetryFailure)(o,"NETWORK_REQUEST_FAILED"),stage:"session_read",requestCategory:"session_read"}),o}}cacheSessionDisplayData(e,t,r){j(e,t,r)}clearSessionDisplayData(e){X(e)}async getVaultCapture(e,t){let r=`${this.baseUrl}\0${e}\0${t??""}`,n=S.activeVaultCaptureRequests.get(r);if(n)return n;let o=this.requestVaultCapture(e,t);S.activeVaultCaptureRequests.set(r,o);try{return await o}finally{S.activeVaultCaptureRequests.get(r)===o&&S.activeVaultCaptureRequests.delete(r)}}async requestVaultCapture(e,t){let r=new AbortController,n=setTimeout(()=>r.abort(),Le);this.beginDirectTelemetryCheckout(e);let o=this.telemetryTimestamp();this.directTelemetry?.log({name:"vault.capture.requested",stage:"vault_request",requestCategory:"vault_capture",paymentMethodCategory:"card"});let i={"Content-Type":"application/json"};t&&(i["x-checkout-session-token"]=t);try{let c=await K(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/vault/capture`,{method:"POST",headers:i,signal:r.signal},q,l=>{this.telemetryHooks?.onRetry?.("vault_capture",l),this.directTelemetry?.log({name:"operation.retry",stage:"vault_request",requestCategory:"vault_capture",paymentMethodCategory:"card",attempt:l})});if(!c.ok)throw await k(c,"Failed to load the secure card form");let u=await c.json();return this.directTelemetry?.performance({stage:"vault_request",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"vault_capture",paymentMethodCategory:"card",statusClass:"2xx"}),this.toVaultBlock(u)}catch(c){let u=r.signal.aborted?new a.FloPayError("Timed out while loading the secure card form. Please try again.","api_error",{code:"vault_capture_timeout"}):c;throw this.reportDirectFailure(u,"VAULT_LOAD_FAILED","vault_request","vault_capture","card"),u}finally{clearTimeout(n)}}async getUnifiedCheckoutSession(e,t){let r=await this.getCheckoutSession(e,t),n=this.normalizeRawSession(r.data),o=r.vault;return o&&n.data.session&&(n.data.session.vault=this.toVaultBlock(o)),n}async processPayment(e,t,r){if(this.beginDirectTelemetryCheckout(t.sessionId),!t.nonce)throw this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"processing",requestCategory:"process_payment"}),new a.FloPayError("processPayment requires `nonce` \u2014 pass the value returned from session creation.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let n=this.telemetryTimestamp();this.directTelemetry?.log({name:"payment.processing.started",stage:"processing",requestCategory:"process_payment"});let{nonce:o,...i}=t,c;try{c=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(t.sessionId)}/process`,{method:"POST",headers:{"Content-Type":"application/json","x-checkout-session-token":o},body:JSON.stringify(i)})}catch(u){throw this.reportDirectFailure(u,"PAYMENT_PROCESSING_FAILED","processing","process_payment"),u}if(!c.ok&&c.status!==202){let u=await Ne(c);return u?this.directTelemetry?.terminal({outcome:u,stage:"processing",requestCategory:"process_payment",statusClass:"4xx"}):this.directTelemetry?.error({errorCode:"PAYMENT_PROCESSING_FAILED",stage:"processing",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(c.status),failureCategory:c.status>=500?"server_error":void 0}),c}try{let u=await this.resolveProcessResponse(c,t.sessionId,{...r,nonce:o});return this.directTelemetry?.log({name:"payment.processing.completed",stage:"processing",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(u.status)}),this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-n),durationMode:"machine",requestCategory:"process_payment",statusClass:(0,a.telemetryStatusClass)(u.status)}),u}catch(u){throw u instanceof a.FloPayError&&u.code==="checkout_processing_timeout"||this.reportDirectFailure(u,"PAYMENT_PROCESSING_FAILED","processing","process_payment"),u}}async patchAccountSnapshot(e,t,r,n){this.beginDirectTelemetryCheckout(e);let o=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.state_transition",stage:"processing",requestCategory:"account_snapshot"});let i=n?.timeoutMs??Fe,c=new AbortController,u=()=>c.abort();n?.signal&&(n.signal.aborted?c.abort():n.signal.addEventListener("abort",u,{once:!0}));let l=setTimeout(()=>c.abort(),i);try{let d;try{d=await K(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/account`,{method:"PATCH",headers:{"Content-Type":"application/json","x-checkout-session-token":t},body:JSON.stringify(r),signal:c.signal},q,y=>{this.telemetryHooks?.onRetry?.("account_snapshot",y),this.directTelemetry?.log({name:"operation.retry",stage:"processing",requestCategory:"account_snapshot",attempt:y})})}finally{clearTimeout(l),n?.signal?.removeEventListener("abort",u)}if(!d.ok)throw await k(d,"Failed to persist account snapshot");this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"account_snapshot",statusClass:"2xx"})}catch(d){throw this.reportAccountSnapshotFailure(d,n?.telemetryMode??"blocking"),d}}async createSessionIntent(e,t,r,n){if(!t)throw new a.FloPayError("createSessionIntent requires the checkout session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let o=r,i=o.paymentMethodType,c=typeof i=="string"&&i.trim().toLowerCase()==="card",u=typeof i=="string"&&i.length>0&&!c&&(typeof o.paymentMethodId=="string"||o.paymentMethodId===null),l=o.provider==="stripe"&&(o.paymentMethodCategory==="wallet"||o.paymentMethodCategory==="apm")&&(o.intentKind==="payment"||o.intentKind==="setup"),d=o.provider==="paypal"&&o.paymentMethodCategory==="wallet"&&o.paymentMethodId===null&&(o.paymentMethodType==="paypal"&&o.intentKind==="payment"||o.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&(o.intentKind==="payment"||o.intentKind==="setup"));if(!u||!l&&!d)throw new a.FloPayError("Only wallet, APM, and PayPal session intents are supported.","validation_error",{code:"InvalidSessionIntentRequest"});let y=o.authorizationAttemptId;if(y!==void 0&&!(0,a.isUuidV4)(y))throw new a.FloPayError("authorizationAttemptId must be a v4 UUID identifying one buyer authorization attempt.","validation_error",{code:"InvalidAuthorizationAttemptId",param:"authorizationAttemptId"});let m=(0,a.isUuidV4)(y)?y:(0,a.randomUuidV4)();this.beginDirectTelemetryCheckout(e);let g=this.telemetryTimestamp();this.directTelemetry?.log({name:"payment.intent.started",stage:"processing",requestCategory:"intent_create"});let T={"Content-Type":"application/json","x-checkout-session-token":t,[a.IDEMPOTENCY_KEY_HEADER]:n?.idempotencyKey||m},h=!1;try{let C=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/intents`,{method:"POST",headers:T,body:JSON.stringify({...r,authorizationAttemptId:m}),signal:n?.signal});if(!C.ok){h=!0;let N=await k(C,"Failed to create checkout intent"),ge=(0,a.classifyTelemetryFailure)(N,"PAYMENT_PROCESSING_FAILED");throw ne(N.statusCode)?this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"processing",requestCategory:"intent_create",statusClass:"4xx"}):this.directTelemetry?.error({...ge,stage:"processing",requestCategory:"intent_create"}),N}let V=(await C.json()).data;if(!V||typeof V!="object")throw new a.FloPayError("Invalid checkout intent response.","api_error",{code:"InvalidSessionIntentResponse"});let p=V,Y=p.paymentMethodType,me=(p.paymentMethodCategory==="wallet"||p.paymentMethodCategory==="apm")&&typeof Y=="string"&&Y.trim().toLowerCase()!=="card"&&(typeof p.paymentMethodId=="string"||p.paymentMethodId===null)&&typeof p.providerObjectId=="string",pe=p.provider==="stripe"&&(p.intentKind==="payment"||p.intentKind==="setup")&&typeof p.clientSecret=="string",he=p.provider==="paypal"&&p.paymentMethodCategory==="wallet"&&p.paymentMethodId===null&&(p.paymentMethodType==="paypal"&&p.intentKind==="payment"&&(p.providerObjectType==="order"||p.providerObjectType==="subscription")||p.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&p.intentKind==="payment"&&p.providerObjectType==="order"||p.paymentMethodType===a.PAYPAL_VAULTED_PAYMENT_METHOD_TYPE&&p.intentKind==="setup"&&p.providerObjectType==="setup_token")&&p.clientSecret===null,ye=p.provider===r.provider&&p.paymentMethodCategory===r.paymentMethodCategory&&p.paymentMethodType===r.paymentMethodType&&p.paymentMethodId===r.paymentMethodId&&p.intentKind===r.intentKind;if(!me||!pe&&!he||!ye)throw new a.FloPayError("Invalid checkout intent response.","api_error",{code:"InvalidSessionIntentResponse"});return this.directTelemetry?.log({name:"payment.intent.completed",stage:"processing",requestCategory:"intent_create",statusClass:(0,a.telemetryStatusClass)(C.status)}),this.directTelemetry?.performance({stage:"processing",durationMs:Math.max(0,this.telemetryTimestamp()-g),durationMode:"machine",requestCategory:"intent_create",statusClass:(0,a.telemetryStatusClass)(C.status)}),p}catch(C){throw h||this.reportDirectFailure(C,"PAYMENT_PROCESSING_FAILED","processing","intent_create"),C}}async reportSessionIntentDecline(e,t,r,n){if(!t)throw new a.FloPayError("reportSessionIntentDecline requires the checkout session nonce.","validation_error",{code:"MissingCheckoutSessionToken",param:"nonce"});let o=r,i=o.providerDeclineReason,c=o.paymentMethodType,u=typeof i=="string"&&/^[a-z0-9][a-z0-9_.:-]{0,63}$/i.test(i)&&!/^(?:pm|pi|seti|tok|src|cus|sess|sk|pk)_/i.test(i),l=typeof c=="string"&&c.length>0&&c.trim().toLowerCase()!=="card"&&u,d=o.provider==="stripe"&&(o.paymentMethodCategory==="wallet"||o.paymentMethodCategory==="apm"),y=o.provider==="paypal"&&o.paymentMethodCategory==="wallet"&&o.paymentMethodType==="paypal";if(!l||!d&&!y)throw new a.FloPayError("Invalid non-card decline classification.","validation_error",{code:"InvalidSessionIntentDeclineRequest"});let m=y?{provider:"paypal",paymentMethodCategory:"wallet",paymentMethodType:"paypal",providerDeclineReason:i}:{provider:"stripe",paymentMethodCategory:o.paymentMethodCategory,paymentMethodType:o.paymentMethodType,providerDeclineReason:i},g=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/intents/decline`,{method:"POST",headers:{"Content-Type":"application/json","x-checkout-session-token":t},body:JSON.stringify(m),signal:n?.signal});if(!g.ok)throw await k(g,"Failed to report checkout decline")}async getPaymentsByEmail(e,t){this.beginDirectTelemetryOperation();let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.recovery.started",stage:"recovery",requestCategory:"other",paymentMethodCategory:"saved"});let n=t?.page??1,o=t?.limit??1,i=new URLSearchParams({email:e,page:String(n),limit:String(o),sortField:"createdAt",sortDirection:"DESC"});try{let c=await fetch(`${this.baseUrl}/v1/payments?${i.toString()}`,{method:"GET",signal:t?.signal,keepalive:!0});if(!c.ok)throw new a.FloPayError("Failed to fetch payments","api_error",{statusCode:c.status});let u=await c.json();return this.directTelemetry?.log({name:"operation.recovery.completed",stage:"recovery",requestCategory:"other",paymentMethodCategory:"saved",statusClass:"2xx"}),this.directTelemetry?.performance({stage:"recovery",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"other",paymentMethodCategory:"saved",statusClass:"2xx"}),u}catch(c){throw this.reportDirectFailure(c,"RECOVERY_FAILED","recovery","other","saved"),c}}async createAndFetchSession(e){if((0,a.isDetachedSessionEligible)(e)){let o=e.account.email?.trim();if(o&&!(0,a.isValidEmail)(o))throw new a.FloPayError("Buyer email must be valid when supplied.","validation_error",{code:"BuyerEmailCollectionRequired",param:"account.email"});return(await this.createDetachedSession(e)).claimed}this.beginDirectTelemetryOperation();let t=this.telemetryTimestamp(),r=E(e.timeoutMs??12e3),n={attempt:0,statusClass:"unknown"};this.directTelemetry?.log({name:"session.create.started",stage:"session_create",requestCategory:"session_create"});try{let o=await this.createAndFetchSessionRequest(e,t,r.signal,n);return this.adoptDirectTelemetryCheckout(o.data.session?.id),this.directTelemetry?.log({name:"session.request.completed",stage:"session_create",requestCategory:"session_create",statusClass:n.statusClass}),this.directTelemetry?.performance({stage:"session_create",durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:"session_create",statusClass:n.statusClass,attempt:n.attempt}),o}catch(o){throw this.reportSessionCreateFailure(o,t,n),o}finally{r.clear()}}async createAndFetchSessionRequest(e,t,r,n){let o=e.products??(0,a.foldIntoProducts)(e.items,e.subscriptions);(0,a.assertCaptureMethodEligible)({captureMethod:e.captureMethod,products:o});let i=(0,a.resolveSessionCurrency)(e.currency,e.items,e.subscriptions,o);if(!i)throw new a.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});let c={clientId:e.clientId,checkoutVersion:a.SDK_VERSION,successUrl:e.successUrl,cancelUrl:e.cancelUrl,currency:i,checkoutMode:e.checkoutMode??"full",products:o.map(m=>(0,a.buildProductPayload)(m,i)),accountData:ae(e.account),couponCodes:e.couponCodes??[]};e.captureMethod==="manual"&&(c.captureMethod=e.captureMethod),e.tokenizedData&&(c.tokenizedData=e.tokenizedData),ce(c,e);let l=await(await this.postCheckoutSessionCreate(c,e,t,r,n)).json();if(l.data&&"gateways"in l.data){this.autoCacheDisplayData(l.data.uuid,e);let m=this.mergeCachedDisplayData(l.data),g=this.normalizeRawSession(m);return l.vault&&g.data.session&&(g.data.session.vault=this.toVaultBlock(l.vault)),{...g,autoProcessingError:l.autoProcessingError,autoProcessingAttempted:l.autoProcessingAttempted,autoProcessingPending:l.autoProcessingPending}}let d=l.data?.uuid;if(!d)throw new a.FloPayError("No session ID returned","api_error",{code:"InvalidCheckoutSessionResponse"});return this.autoCacheDisplayData(d,e),this.adoptDirectTelemetryCheckout(d),{...await this.getUnifiedCheckoutSession(d),autoProcessingError:l.autoProcessingError,autoProcessingAttempted:l.autoProcessingAttempted,autoProcessingPending:l.autoProcessingPending}}async postCheckoutSessionCreate(e,t,r,n,o){let i={"Content-Type":"application/json",[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION},c=(0,a.resolveIdempotencyKey)(t.idempotencyKey);c&&(i[a.IDEMPOTENCY_KEY_HEADER]=c);let u,l=!1,d=Be(t),y=m=>{try{this.telemetryHooks?.onRetry?.("session_create",m),this.directTelemetry?.log({name:"operation.retry",stage:"session_create",requestCategory:"session_create",attempt:m})}catch{}};for(let m=0;m<3;m++){o.attempt=m;try{d?.onAttempt?.(m)}catch{}try{u=await fetch(`${this.baseUrl}/v1/checkouts/sessions?expand=true`,{method:"POST",headers:i,body:JSON.stringify(e),signal:n})}catch(h){if(o.statusClass=n.aborted||h instanceof Error&&h.name==="AbortError"?"timeout":"network_error",n.aborted||h instanceof Error&&h.name==="AbortError"||m>=2)throw h;let C=m+1;y(C),await I(m,n);continue}let g=(0,a.telemetryStatusClass)(u.status);if(o.statusClass=g,l||(l=!0,this.directTelemetry?.log({name:"session.request.first_byte",stage:"session_first_byte",requestCategory:"session_create",statusClass:g,attempt:m}),this.directTelemetry?.performance({stage:"session_first_byte",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_create",statusClass:g,attempt:m})),u.status===204)throw new a.FloPayError("Session auto-completed \u2014 payment method already on file","api_error",{code:"session_auto_completed"});if(u.ok)break;let T=await k(u,"Failed to create checkout session");if(T.code===a.IDEMPOTENCY_IN_PROGRESS_CODE&&m<2){y(m+1),await I(m,n);continue}throw T}if(!u)throw new TypeError("Checkout-session creation exhausted its retry budget.");return u}async createDetachedSession(e){this.beginDirectTelemetryOperation();let t=this.telemetryTimestamp(),r=E(e.timeoutMs??12e3),n={attempt:0,statusClass:"unknown"};this.directTelemetry?.log({name:"session.create.started",stage:"session_create",requestCategory:"session_create"});let o=e.products??(0,a.foldIntoProducts)(e.items,e.subscriptions);try{(0,a.assertCaptureMethodEligible)({captureMethod:e.captureMethod,products:o})}catch(h){throw r.clear(),this.reportSessionCreateFailure(h,t,n),h}let i=(0,a.resolveSessionCurrency)(e.currency,e.items,e.subscriptions,o);if(!i)throw r.clear(),this.directTelemetry?.terminal({outcome:"validation_rejected",stage:"session_create",requestCategory:"session_create"}),new a.FloPayError("currency is required: pass `currency` on the session, or include a `currency` on the first item/subscription/product.","validation_error",{code:"CurrencyRequired",param:"currency"});try{oe(e,i,o)}catch(h){throw r.clear(),this.reportSessionCreateFailure(h,t,n),h}let c,u;try{if(u=await(await this.postCheckoutSessionCreate(He(e,i),e,t,r.signal,n)).json(),!u.data||!("gateways"in u.data))throw new a.FloPayError("The billing API returned no session shell for a detached create. It must support `deferDataAttachment` (TeamFloPay/backend#1099).","api_error",{code:"InvalidCheckoutSessionResponse"});c=this.normalizeRawSession(this.mergeCachedDisplayData(u.data)),u.vault&&c.data.session&&(c.data.session.vault=this.toVaultBlock(u.vault))}catch(h){throw r.clear(),this.reportSessionCreateFailure(h,t,n),h}let l=c.data.session?.id??u.data.uuid??"",d=c.data.session?.clientSecret??u.data.nonce??"";if(!l||!d){r.clear();let h=new a.FloPayError("Checkout session shell was created without a session id or nonce.","api_error",{code:"InvalidCheckoutSessionResponse"});throw this.reportSessionCreateFailure(h,t,n),h}this.adoptDirectTelemetryCheckout(l),this.directTelemetry?.log({name:"session.shell.ready",stage:"session_shell",requestCategory:"session_create",statusClass:n.statusClass,paymentMethodCategory:"card"}),this.directTelemetry?.performance({stage:"session_shell",durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:"session_create",statusClass:n.statusClass,attempt:n.attempt,paymentMethodCategory:"card"});let y=!e.account.email?.trim(),m=this.claimCheckoutSession(l,d,y?Ke(e,i,o):oe(e,i,o),{params:e,startedAt:t,deadline:r,createAttempt:n.attempt}),g=y?void 0:m,T=(h={})=>{if(g)return g;let C={...e,account:{...e.account,...h,email:h.email?.trim()||e.account.email?.trim()}};return(0,a.isValidEmail)(C.account.email)?(g=m.then(()=>{let G=this.telemetryTimestamp();return this.claimCheckoutSession(l,d,$e(C.account),{params:C,startedAt:G,deadline:E(e.timeoutMs??12e3),createAttempt:0})}),g.catch(()=>{}),g):Promise.reject(new a.FloPayError("A valid buyer email is required before claiming checkout.","validation_error",{code:"BuyerEmailCollectionRequired",param:"account.email"}))};return m.catch(()=>{}),{shell:c,sessionId:l,nonce:d,claimed:m,claim:T}}async claimCheckoutSession(e,t,r,n){let o=n?.startedAt??this.telemetryTimestamp(),i=this.telemetryTimestamp(),c=n?.deadline??E(12e3),u=JSON.stringify(r),l="unknown",d=0;this.directTelemetry?.log({name:"session.claim.started",stage:"session_claim",requestCategory:"session_claim"});try{let y;for(d=0;d<3;d++){try{y=await fetch(`${this.baseUrl}/v1/checkouts/sessions/${encodeURIComponent(e)}/claim`,{method:"PATCH",headers:{"Content-Type":"application/json","x-checkout-session-token":t,[a.FLO_SDK_VERSION_HEADER]:a.SDK_VERSION},body:u,signal:c.signal})}catch(T){let h=c.signal.aborted||T instanceof Error&&T.name==="AbortError";if(l=h?"timeout":"network_error",h||d>=2)throw T;try{this.telemetryHooks?.onRetry?.("session_claim",d+1),this.directTelemetry?.log({name:"operation.retry",stage:"session_claim",requestCategory:"session_claim",attempt:d+1})}catch{}await I(d,c.signal);continue}if(l=(0,a.telemetryStatusClass)(y.status),y.ok)break;throw await k(y,"Failed to attach checkout session data")}if(!y)throw new TypeError("Checkout-session claim exhausted its retry budget.");let m=await y.json();if(!m.data?.gateways)throw new a.FloPayError("The billing API returned no checkout session with gateways after claiming it.","api_error",{code:"InvalidCheckoutSessionResponse"});n?.params&&this.autoCacheDisplayData(m.data.uuid??e,n.params);let g=this.normalizeRawSession(this.mergeCachedDisplayData(m.data));return m.vault&&g.data.session&&(g.data.session.vault=this.toVaultBlock(m.vault)),this.directTelemetry?.log({name:"session.claim.completed",stage:"session_claim",requestCategory:"session_claim",statusClass:l}),this.directTelemetry?.performance({stage:"session_claim",durationMs:Math.max(0,this.telemetryTimestamp()-i),durationMode:"machine",requestCategory:"session_claim",statusClass:l,attempt:d}),this.directTelemetry?.log({name:"session.request.completed",stage:"session_create",requestCategory:"session_create",statusClass:l}),this.directTelemetry?.performance({stage:"session_create",durationMs:Math.max(0,this.telemetryTimestamp()-o),durationMode:"machine",requestCategory:"session_create",statusClass:l,attempt:n?.createAttempt??d}),g}catch(y){throw this.reportSessionCreateFailure(y,o,{attempt:d,statusClass:l},"session_claim"),y}finally{c.clear()}}reportSessionCreateFailure(e,t,r,n="session_create"){if(!(e instanceof a.FloPayError&&e.code==="session_auto_completed"))try{this.telemetryHooks?.onSessionCreateFailure?.(e)}catch{}let o=(0,a.classifyTelemetryFailure)(e,"CHECKOUT_SESSION_CREATE_FAILED");if(this.directTelemetry?.performance({stage:n,durationMs:Math.max(0,this.telemetryTimestamp()-t),durationMode:"machine",requestCategory:n==="session_claim"?"session_claim":"session_create",statusClass:o.statusClass,attempt:r.attempt}),e instanceof a.FloPayError&&e.type==="validation_error"||e instanceof a.FloPayError&&ne(e.statusCode)){this.directTelemetry?.terminal({outcome:"validation_rejected",stage:n,requestCategory:n==="session_claim"?"session_claim":"session_create",...e.type==="validation_error"?{}:{statusClass:"4xx"}});return}e instanceof a.FloPayError&&e.code==="session_auto_completed"||this.directTelemetry?.error({...o,stage:n,requestCategory:n==="session_claim"?"session_claim":"session_create"})}async waitForCheckoutSessionCompletion(e,t){this.beginDirectTelemetryCheckout(e);let r=this.telemetryTimestamp();this.directTelemetry?.log({name:"operation.recovery.started",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved"});let n=t?.timeoutMs??Oe,o=Date.now()+n,i=this.clampRetryAfterMs(t?.initialDelayMs??re),c=0;try{for(;;){let u=o-Date.now();if(u<=0)throw O();if(i>0){try{c+=1,this.telemetryHooks?.onRetry?.("session_read",c),this.directTelemetry?.log({name:"operation.retry",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved",attempt:c})}catch{}if(await ie(Math.min(i,u)),Date.now()>=o)throw O()}let l=await this.getUnifiedCheckoutSession(e,t?.nonce),d=l.data.session?.status;if(d==="authorized"||d==="complete"||d==="expired")return this.directTelemetry?.log({name:"operation.recovery.completed",stage:"recovery",requestCategory:"session_read",paymentMethodCategory:"saved"}),this.directTelemetry?.performance({stage:"recovery",durationMs:Math.max(0,this.telemetryTimestamp()-r),durationMode:"machine",requestCategory:"session_read",paymentMethodCategory:"saved"}),l;if(Date.now()>=o)throw O();i=this.clampRetryAfterMs(Math.max(i*2,xe))}}catch(u){throw u instanceof a.FloPayError&&u.code==="checkout_processing_timeout"&&this.reportDirectFailure(u,"RECOVERY_FAILED","recovery","session_read","saved"),u}}normalizeRawSession(e){let t=e.gateways??{},r=[],n={session:this.toCheckoutSession(e)},o=t.stripe;if(o?.publishableKey){r.push("stripe");let u=[e.stripeClientSecret,o.stripeClientSecret].find(l=>typeof l=="string"&&l.length>0);n.stripe={clientSecret:u??"",publishableKey:o.publishableKey??void 0,paypalPublishableKey:o.paypalPublishableKey??void 0,environment:o.environment,enabledPaymentMethods:Array.isArray(o.enabledPaymentMethods)?o.enabledPaymentMethods.filter(l=>typeof l=="string"):void 0}}let i=t.paypal;return i?.publishableKey&&(r.push("paypal"),n.paypal={publishableKey:i.publishableKey,environment:i.environment,providerObjectType:i.providerObjectType}),{providers:r,mode:"tokenize",data:n,raw:{data:e}}}toCheckoutSession(e){let t=e.products??[],r=typeof e.totalAmount=="number"&&Number.isFinite(e.totalAmount),n=t.reduce((l,d)=>l+(d.overrideAmount??d.totalAmount??0),0),o=r?e.totalAmount:n,i=Math.round(o*100),c=e.currency??t[0]?.currency??"USD",u=e.checkoutMode==="setup"?"setup":t.some(l=>l.type==="subscription")?"subscription":"payment";return{id:e.uuid,clientSecret:e.nonce,mode:u,status:this.toCheckoutSessionStatus(e.status),amount:i,currency:c,captureMethod:e.captureMethod,paymentId:e.paymentId,authorizationExpiresAt:e.authorizationExpiresAt,failureOutcome:(0,a.normalizeCheckoutFailureOutcome)(e.outcome)??(0,a.normalizeCheckoutFailureOutcome)(e.failureReason)??(e.status==="expired"&&e.captureMethod==="manual"?"authorization_expired":void 0),customer:{id:e.accountData.userId??void 0,email:e.accountData.email??void 0,firstName:e.accountData.firstName??void 0,lastName:e.accountData.lastName??void 0,country:e.accountData.country??void 0,city:e.accountData.city??void 0,state:e.accountData.state??void 0,zip:e.accountData.zip??void 0,gender:e.accountData.gender??void 0,line1:e.accountData.addressLine1??void 0,line2:e.accountData.addressLine2??void 0},metadata:{},checkoutMode:e.checkoutMode,buyerIdentified:e.buyerIdentified,providerPaymentMethodId:typeof e.providerPaymentMethodId=="string"?e.providerPaymentMethodId:null,products:t.map(l=>({...l,totalAmount:typeof l.totalAmount=="number"?l.totalAmount:void 0,overrideAmount:typeof l.overrideAmount=="number"?l.overrideAmount:null,currency:typeof l.currency=="string"?l.currency:void 0,metadata:l.metadata??null})),successUrl:e.successUrl,cancelUrl:e.cancelUrl,coupons:e.coupons,subtotalAmount:e.subtotalAmount,discountAmount:e.discountAmount,totalAmount:e.totalAmount,createdAt:e.createdAt,gateways:e.gateways,accountData:e.accountData,tagsData:e.tagsData}}toVaultBlock(e){return{html:typeof e.html=="string"?e.html:void 0,url:typeof e.url=="string"?e.url:void 0,messageToken:typeof e.messageToken=="string"?e.messageToken:void 0,expectedOrigin:typeof e.expectedOrigin=="string"?e.expectedOrigin:void 0}}toCheckoutSessionStatus(e){return e==="completed"?"complete":e==="authorized"?"authorized":e==="expired"?"expired":"open"}async resolveProcessResponse(e,t,r){if(e.status!==202)return e;let n=await e.json().catch(()=>null),o=this.toCheckoutProcessingPending(n,e,t),i=await this.waitForCheckoutSessionCompletion(o.sessionId,{initialDelayMs:o.retryAfterMs,timeoutMs:r?.pollTimeoutMs,nonce:r?.nonce});if(i.data.session?.status==="complete")return new Response(null,{status:204,statusText:"No Content"});if(i.data.session?.status==="authorized"){let c=i.data.session;return new Response(JSON.stringify({status:"authorized",paymentId:c.paymentId,sessionId:c.id||t,authorizationExpiresAt:c.authorizationExpiresAt}),{status:200,headers:{"Content-Type":"application/json"}})}if(i.data.session?.status==="expired"){let c=i.data.session.failureOutcome==="authorization_expired"||i.data.session.captureMethod==="manual";throw new a.FloPayError(c?"Authorization has expired.":"Checkout session has expired.","api_error",{code:c?"authorization_expired":"checkout_session_expired"})}throw O()}toCheckoutProcessingPending(e,t,r){let n=t.headers.get("Retry-After"),o=n===null||n.trim()===""?void 0:Number(n),i=o!==void 0&&Number.isFinite(o)?o*1e3:void 0;return{type:"checkout_processing",sessionId:A(e,"sessionId")??r,retryAfterMs:this.clampRetryAfterMs(Ve(e,"retryAfterMs")??i??re),statusUrl:A(e,"statusUrl"),sessionUrl:A(e,"sessionUrl")}}clampRetryAfterMs(e){return Math.max(0,Math.min(e,qe))}autoCacheDisplayData(e,t){if(!e)return;let r=t.products??(0,a.foldIntoProducts)(t.items,t.subscriptions);if(r.length===0&&!t.currency)return;let n=t.products!==void 0,o=(0,a.resolveSessionCurrency)(t.currency,n?void 0:t.items,n?void 0:t.subscriptions,r);j(e,{currency:o??void 0,products:r.map(i=>({code:i.code??i.providerItemId??i.providerPlanId,type:i.type,name:i.name??i.itemName??i.providerItemName??i.subscriptionName??i.providerPlanName??null,totalAmount:i.totalAmount,overrideAmount:i.overrideAmount,currency:i.currency??o??void 0}))})}mergeCachedDisplayData(e){let t=Q(e.uuid),r=new Map,n=i=>i?`code:${i}`:void 0;for(let i of t?.products??[]){let c=n(i.code);c&&r.set(c,i)}let o=(e.products??[]).map(i=>{let c=n(i.code),u=c?r.get(c):void 0;return{...i,name:i.name??u?.name??null,totalAmount:i.totalAmount??u?.totalAmount,overrideAmount:i.overrideAmount??u?.overrideAmount,currency:i.currency??u?.currency}});return{...e,currency:e.currency??t?.currency,products:o}}};S.activeVaultCaptureRequests=new Map;var F=S;var f=require("@flopay/shared");var $="flopay-vault",ue={ready:["vault.widget.ready","vault_ready"],submitting:["vault.submission.started","vault_submit"],blocked:["operation.state_transition","vault_submit"],action_required:["vault.action.required","three_ds_handoff"]};function w(s){let e={class:s.class,stage:s.stage};"code"in s&&(e.code=s.code),"provider"in s&&s.provider&&(e.provider=s.provider),"paymentMethodCategory"in s&&s.paymentMethodCategory&&(e.paymentMethodCategory=s.paymentMethodCategory),"outcome"in s&&(e.outcome=s.outcome),"durationMs"in s&&s.durationMs!==void 0&&(e.durationMs=s.durationMs),"durationMode"in s&&s.durationMode&&(e.durationMode=s.durationMode);try{globalThis.Sentry?.addBreadcrumb?.({category:"flopay.telemetry",level:s.class==="technical_error"?"error":"info",message:s.class==="lifecycle"?s.name:s.class==="technical_error"?s.code:s.class==="expected_outcome"?s.outcome:"sdk.performance",data:e})}catch{}}function L(s,e){return(0,f.buildTelemetryLogEvent)({eventId:"11111111-1111-4111-8111-111111111111",name:s,stage:e,sequence:0,provider:"pcivault",paymentMethodCategory:"card"})}function le(s){return s?{errorCode:"VAULT_SUBMIT_FAILED",stage:"vault_submit",failureCategory:"provider_runtime"}:{errorCode:"VAULT_LOAD_FAILED",stage:"vault_mount",failureCategory:"provider_runtime"}}function de(s,e,t="checkout"){return t==="card_setup"?s.type==="decline"?"card_setup_declined":"card_setup_succeeded":s.type==="decline"?"payment_declined":s.outcome==="authorized"||e==="manual"?"payment_authorized":"payment_succeeded"}function Ge(s,e,t,r="checkout"){let{type:n}=s;if(n==="complete"||n==="decline")return(0,f.buildTelemetryTerminalEvent)({eventId:"22222222-2222-4222-8222-222222222222",outcome:de(s,t,r),sequence:0,provider:"pcivault",paymentMethodCategory:"card"});if(n==="error"){let c=le(e);return(0,f.buildTelemetryErrorEvent)({eventId:"33333333-3333-4333-8333-333333333333",...c,sequence:0,provider:"pcivault",paymentMethodCategory:"card"})}let[o,i]=ue[n];return L(o,i)}function Ye(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===$&&(e.type==="ready"||e.type==="submitting"||e.type==="blocked"||e.type==="complete"||e.type==="decline"||e.type==="error"||e.type==="action_required")}function We(s){if(typeof s!="object"||s===null)return;let e=s,t=e.status;if(!(typeof e.id!="string"||e.id.trim()===""||typeof e.brand!="string"||e.brand.trim()===""||typeof e.lastFour!="string"||!/^\d{4}$/.test(e.lastFour)||typeof e.expiryMonth!="number"||!Number.isInteger(e.expiryMonth)||e.expiryMonth<1||e.expiryMonth>12||typeof e.expiryYear!="number"||!Number.isInteger(e.expiryYear)||e.expiryYear<1970||e.expiryYear>9999||t!=="pending"&&t!=="active"&&t!=="deleted"))return{id:e.id,brand:e.brand,lastFour:e.lastFour,expiryMonth:e.expiryMonth,expiryYear:e.expiryYear,status:t}}function Je(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===$&&e.type==="validation"&&Array.isArray(e.messages)}function Qe(s){if(typeof s!="object"||s===null)return!1;let e=s;return e.source===$&&e.type==="resize"&&typeof e.height=="number"&&Number.isFinite(e.height)}var U=class{constructor(e={},t){this.provider="pcivault";this.container=null;this.messageHandler=null;this.actionOverlay=null;this.threeDsReturnHandler=null;this.messageToken=null;this.expectedOrigin=null;this.theme=null;this.submitGateBlocked=!1;this.cardFieldOrder=null;this.cardAutoFocus=!0;this.mountStartedAt=0;this.vaultReadyReported=!1;this.submissionStarted=!1;this.submissionStartedAt=null;this.listeners=new Map;this.config=e,this.ownsTelemetryReporter=!t&&e.telemetry!==!1,this.telemetryReporter=t?.reporter??(this.ownsTelemetryReporter?new _({billingApiUrl:(0,f.resolveBillingApiUrl)(),sdkVersion:f.SDK_VERSION}):void 0)}async mount(e,t){this.ownsTelemetryReporter&&!this.telemetryReporter&&(this.telemetryReporter=new _({billingApiUrl:(0,f.resolveBillingApiUrl)(),sdkVersion:f.SDK_VERSION}));let r=this.telemetryReporter;if(this.config.operation==="card_setup"&&r&&this.setupTelemetryReporter!==r){this.setupTelemetryReporter=r;try{r.beginCheckout({checkoutMode:"setup"})}catch{}}if(this.mountStartedAt=this.telemetryReporter?.now?.()??b(),this.vaultReadyReported=!1,this.submissionStarted=!1,this.submissionStartedAt=null,typeof window>"u"||typeof document>"u")throw this.reportVaultLoadFailure(),new f.FloPayError("The vault card form is only available in the browser.","api_error",{code:"card_capture_no_window"});if(!t?.html?.trim())throw this.reportVaultLoadFailure(),new f.FloPayError("No vault capture widget HTML was provided to mount the secure card form.","api_error",{code:"card_capture_no_widget_html"});this.container=e,this.messageToken=t.messageToken??null,this.expectedOrigin=t.expectedOrigin??this.config.expectedOrigin??null,this.theme=t.theme??null;try{this.attachMessageListener(),this.injectWidget(e,t.html)}catch(n){throw this.reportVaultLoadFailure(),n}this.postTheme(),this.postSubmitGate(),this.postCardFieldOrder(),w(L("vault.widget.mounted","vault_mount")),this.telemetryReporter?.log({name:"vault.widget.mounted",stage:"vault_mount",provider:"pcivault",paymentMethodCategory:"card"}),this.emit("ready",{sessionId:this.config.sessionId})}reportVaultLoadFailure(){this.telemetryReporter?.error({errorCode:"VAULT_LOAD_FAILED",failureCategory:"provider_runtime",stage:"vault_mount",provider:"pcivault",paymentMethodCategory:"card"})}on(e,t){let r=this.listeners.get(e);return r||(r=new Set,this.listeners.set(e,r)),r.add(t),()=>{this.listeners.get(e)?.delete(t)}}unmount(){this.hideActionRequiredOverlay(),this.messageHandler&&(window.removeEventListener("message",this.messageHandler),this.messageHandler=null),this.container&&(this.container.replaceChildren(),this.container=null),this.messageToken=null,this.expectedOrigin=null,this.ownsTelemetryReporter&&(this.telemetryReporter?.destroy(),this.telemetryReporter=void 0)}injectWidget(e,t){e.innerHTML=t;let r=Array.from(e.querySelectorAll("script"));for(let n of r){let o=document.createElement("script");for(let i of Array.from(n.attributes))o.setAttribute(i.name,i.value);o.text=n.text,n.replaceWith(o)}}attachMessageListener(){if(this.messageHandler)return;let e=t=>{if(this.expectedOrigin&&t.origin!==this.expectedOrigin)return;let r=t.data;if(Qe(r)){if(this.messageToken&&r.messageToken!==this.messageToken)return;this.applyHeight(r.height);return}if(Je(r)){if(this.messageToken&&r.messageToken!==this.messageToken)return;let u=r.messages.filter(l=>typeof l=="string"&&l.trim()).join(" ");this.emit("validation",{sessionId:this.config.sessionId,message:u||void 0});return}if(!Ye(r)||this.messageToken&&r.messageToken!==this.messageToken)return;let n=this.config.sessionId,o=typeof r.sessionId=="string"?r.sessionId:void 0;if(n&&o&&o!==n||(r.type==="complete"||r.type==="decline")&&n&&o!==n)return;let i=We(r.paymentMethod),c={...r.sessionId??this.config.sessionId?{sessionId:r.sessionId??this.config.sessionId}:{},...r.outcome?{outcome:r.outcome}:{},...r.paymentId?{paymentId:r.paymentId}:{},...r.authorizationExpiresAt?{authorizationExpiresAt:r.authorizationExpiresAt}:{},...r.failureOutcome?{failureOutcome:r.failureOutcome}:{},...r.intentId?{intentId:r.intentId}:{},...r.declineReason?{declineReason:r.declineReason}:{},...r.message?{message:r.message}:{},...i?{paymentMethod:i}:{}};r.type==="submitting"&&(this.submissionStarted=!0,this.submissionStartedAt=this.telemetryReporter?.now?.()??b()),w(Ge(r,this.submissionStarted,this.config.captureMethod,this.config.operation)),this.reportOutcome(r),r.type==="ready"&&(this.postTheme(),this.postSubmitGate(),this.postCardFieldOrder()),r.type==="action_required"&&r.nextActionRedirectUrl&&this.showActionRequiredOverlay(r.nextActionRedirectUrl),(r.type==="complete"||r.type==="decline"||r.type==="error"||r.type==="submitting")&&this.hideActionRequiredOverlay(),r.type!=="action_required"&&this.emit(r.type,c)};this.messageHandler=e,window.addEventListener("message",e)}reportOutcome(e){let t=this.telemetryReporter;if(!t)return;let{type:r}=e;if(r==="ready"&&!this.vaultReadyReported&&(this.vaultReadyReported=!0,t.performance({stage:"vault_ready",durationMs:Math.max(0,t.now()-this.mountStartedAt),durationMode:"machine",provider:"pcivault",paymentMethodCategory:"card"})),r==="complete"||r==="decline"){t.log({name:"vault.terminal",stage:"completion",provider:"pcivault",paymentMethodCategory:"card"}),t.terminal({outcome:de(e,this.config.captureMethod,this.config.operation),provider:"pcivault",paymentMethodCategory:"card"});return}if(r==="error"){let i=le(this.submissionStarted);t.log({name:"vault.terminal",stage:i.stage,provider:"pcivault",paymentMethodCategory:"card"}),t.error({...i,provider:"pcivault",paymentMethodCategory:"card"});return}if(r==="action_required"){t.log({name:"vault.action.required",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"}),t.log({name:"vault.three_ds.handoff",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"});let i=this.submissionStartedAt;this.submissionStartedAt=null,i!==null&&t.performance({stage:"three_ds_handoff",durationMs:Math.max(0,t.now()-i),durationMode:"machine",provider:"pcivault",paymentMethodCategory:"card"}),t.terminal({outcome:"action_required",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"});return}let[n,o]=ue[r];t.log({name:n,stage:o,provider:"pcivault",paymentMethodCategory:"card"})}applyTheme(e){this.theme=e,this.postTheme()}postTheme(){if(!this.theme||!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"theme",theme:this.theme},"*")}catch{}}setSubmitGate(e){this.submitGateBlocked=e,this.postSubmitGate()}postSubmitGate(){if(!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"gate",blocked:this.submitGateBlocked},"*")}catch{}}setCardFieldOrder(e,t){this.cardFieldOrder=e,this.cardAutoFocus=t,this.postCardFieldOrder()}postCardFieldOrder(){if(!this.container)return;let t=this.container.querySelector("iframe")?.contentWindow;if(t)try{t.postMessage({source:"flopay-vault-host",type:"fieldOrder",order:this.cardFieldOrder,autoFocus:this.cardAutoFocus},"*")}catch{}}emit(e,t){for(let r of this.listeners.get(e)??[])r(t)}showActionRequiredOverlay(e){if(typeof document>"u")return;if(this.actionOverlay){let i=this.actionOverlay.querySelector("iframe");i instanceof HTMLIFrameElement&&(i.src=e);return}let t=document.createElement("div");t.setAttribute("data-flopay-action-required","1"),t.style.cssText=["position:fixed","inset:0","z-index:2147483647","background:rgba(15,23,42,0.6)","display:flex","align-items:center","justify-content:center","padding:16px"].join(";");let r=document.createElement("iframe");r.setAttribute("title","Card authentication"),r.setAttribute("allow","payment"),r.style.cssText=["width:min(100%,460px)","height:min(100%,640px)","border:0","border-radius:12px","background:#fff","box-shadow:0 12px 30px rgba(0,0,0,0.35)"].join(";"),r.src=e,t.appendChild(r);let n=document.createElement("button");n.type="button",n.setAttribute("aria-label","Close card authentication"),n.textContent="\xD7",n.style.cssText=["position:fixed","top:20px","right:20px","width:40px","height:40px","border:0","border-radius:9999px","background:#fff","color:#0f172a","font-size:28px","line-height:40px","cursor:pointer","box-shadow:0 4px 14px rgba(0,0,0,0.25)"].join(";"),n.addEventListener("click",()=>this.abandonActionRequiredOverlay()),t.appendChild(n),t.addEventListener("click",i=>{i.target===t&&this.abandonActionRequiredOverlay()});let o=i=>{if(i.source!==r.contentWindow)return;let c=i.data;if(!c||typeof c!="object")return;let u=c;u.source==="flopay-vault-3ds-return"&&(w(L("vault.three_ds.returned","three_ds_return")),this.telemetryReporter?.log({name:"vault.three_ds.returned",stage:"three_ds_return",provider:"pcivault",paymentMethodCategory:"card"}),this.hideActionRequiredOverlay(),this.postActionCompleted(u.status))};window.addEventListener("message",o),this.threeDsReturnHandler=o,document.body.appendChild(t),this.actionOverlay=t,w(L("vault.three_ds.handoff","three_ds_handoff"))}postActionCompleted(e){if(!this.container)return;let r=this.container.querySelector("iframe")?.contentWindow;if(r)try{r.postMessage({source:"flopay-vault-host",type:"action_completed",status:typeof e=="string"?e:"unknown"},"*")}catch{}}abandonActionRequiredOverlay(){if(!this.actionOverlay)return;let e=(0,f.buildTelemetryTerminalEvent)({eventId:"77777777-7777-4777-8777-777777777777",outcome:"customer_abandoned",stage:"three_ds_handoff",sequence:0,provider:"pcivault",paymentMethodCategory:"card"});w(e),this.telemetryReporter?.terminal({outcome:"customer_abandoned",stage:"three_ds_handoff",provider:"pcivault",paymentMethodCategory:"card"}),this.hideActionRequiredOverlay(),this.postActionCompleted("abandoned")}hideActionRequiredOverlay(){this.threeDsReturnHandler&&(window.removeEventListener("message",this.threeDsReturnHandler),this.threeDsReturnHandler=null),this.actionOverlay&&(this.actionOverlay.parentNode?.removeChild(this.actionOverlay),this.actionOverlay=null)}applyHeight(e){let t=this.container?.querySelector("iframe");if(!t)return;let r=Math.max(0,Math.min(Math.ceil(e),2e3));t.style.height=`${r}px`}};0&&(module.exports={PaymentAPI,PciVaultCardCapture});
|
package/dist/card-setup.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as CardCaptureOperation, P as PaymentAPI, a as PciVaultCardCapture, b as PciVaultCardCaptureConfig } from './card-setup-
|
|
1
|
+
export { C as CardCaptureOperation, P as PaymentAPI, a as PciVaultCardCapture, b as PciVaultCardCaptureConfig } from './card-setup-B-_Bnluz.cjs';
|
|
2
2
|
import '@flopay/shared';
|
package/dist/card-setup.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { C as CardCaptureOperation, P as PaymentAPI, a as PciVaultCardCapture, b as PciVaultCardCaptureConfig } from './card-setup-
|
|
1
|
+
export { C as CardCaptureOperation, P as PaymentAPI, a as PciVaultCardCapture, b as PciVaultCardCaptureConfig } from './card-setup-B-_Bnluz.js';
|
|
2
2
|
import '@flopay/shared';
|
package/dist/card-setup.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as r,l as a}from"./chunk-
|
|
1
|
+
import{j as r,l as a}from"./chunk-UOFQ6V54.mjs";export{r as PaymentAPI,a as PciVaultCardCapture};
|