@flopay/vue 0.0.0-stage → 1.13.2

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.
@@ -0,0 +1,614 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/card-setup-entry.ts
21
+ var card_setup_entry_exports = {};
22
+ __export(card_setup_entry_exports, {
23
+ FloPayCardSetup: () => FloPayCardSetup,
24
+ FloPayCardSetupError: () => FloPayCardSetupError
25
+ });
26
+ module.exports = __toCommonJS(card_setup_entry_exports);
27
+
28
+ // src/flopay-card-setup.ts
29
+ var import_shared3 = require("@flopay/shared");
30
+ var import_vue4 = require("vue");
31
+
32
+ // src/hosted-setup.ts
33
+ var import_card_setup = require("@flopay/js/card-setup");
34
+ var import_shared = require("@flopay/shared");
35
+ var import_vue2 = require("vue");
36
+
37
+ // src/processing-overlay.ts
38
+ var import_vue = require("vue");
39
+ var PROCESSING_OVERLAY_SUCCESS_DELAY_MS = 600;
40
+ var PROCESSING_OVERLAY_ERROR_DELAY_MS = 400;
41
+ var NEUTRAL_THEME = {
42
+ panel: { background: "white" },
43
+ spinnerTrackColor: "#e5e7eb",
44
+ spinnerAccentColor: "#4A49FF",
45
+ labelColors: { processing: "#374151", success: "#16a34a", error: "#dc2626" },
46
+ noteColor: "#6b7280"
47
+ };
48
+ var KEYFRAMES_ID = "flopay-processing-overlay-keyframes";
49
+ var KEYFRAMES = [
50
+ "@keyframes flopay-spin { to { transform: rotate(360deg); } }",
51
+ "@keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }",
52
+ "@keyframes flopay-draw { to { stroke-dashoffset: 0; } }",
53
+ "@keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }"
54
+ ].join("\n");
55
+ function ensureKeyframes() {
56
+ if (typeof document === "undefined" || document.getElementById(KEYFRAMES_ID)) return;
57
+ const style = document.createElement("style");
58
+ style.id = KEYFRAMES_ID;
59
+ style.textContent = KEYFRAMES;
60
+ document.head.appendChild(style);
61
+ }
62
+ var SVG = {
63
+ "aria-hidden": "true",
64
+ width: "48",
65
+ height: "48",
66
+ viewBox: "0 0 24 24",
67
+ fill: "none"
68
+ };
69
+ function statusIcon(status, theme) {
70
+ if (status === "processing") {
71
+ return (0, import_vue.h)("svg", { ...SVG, style: { animation: "flopay-spin 0.8s linear infinite" } }, [
72
+ (0, import_vue.h)("circle", {
73
+ cx: "12",
74
+ cy: "12",
75
+ r: "10",
76
+ stroke: theme.spinnerTrackColor,
77
+ "stroke-width": "3"
78
+ }),
79
+ (0, import_vue.h)("path", { d: "M4 12a8 8 0 018-8v3a5 5 0 00-5 5H4z", fill: theme.spinnerAccentColor })
80
+ ]);
81
+ }
82
+ if (status === "success") {
83
+ return (0, import_vue.h)("div", { style: { animation: "flopay-pop 0.4s cubic-bezier(0.34,1.56,0.64,1)" } }, [
84
+ (0, import_vue.h)("svg", SVG, [
85
+ (0, import_vue.h)("circle", { cx: "12", cy: "12", r: "11", fill: "#22c55e" }),
86
+ (0, import_vue.h)("path", {
87
+ d: "M7 12.5l3 3 7-7",
88
+ stroke: "white",
89
+ "stroke-width": "2.5",
90
+ "stroke-linecap": "round",
91
+ "stroke-linejoin": "round",
92
+ style: {
93
+ strokeDasharray: 20,
94
+ strokeDashoffset: 20,
95
+ animation: "flopay-draw 0.4s 0.15s ease forwards"
96
+ }
97
+ })
98
+ ])
99
+ ]);
100
+ }
101
+ return (0, import_vue.h)("div", { style: { animation: "flopay-shake 0.4s ease" } }, [
102
+ (0, import_vue.h)("svg", SVG, [
103
+ (0, import_vue.h)("circle", { cx: "12", cy: "12", r: "11", fill: "#ef4444" }),
104
+ (0, import_vue.h)("path", {
105
+ d: "M8 8l8 8M16 8l-8 8",
106
+ stroke: "white",
107
+ "stroke-width": "2.5",
108
+ "stroke-linecap": "round",
109
+ style: {
110
+ strokeDasharray: 12,
111
+ strokeDashoffset: 12,
112
+ animation: "flopay-draw 0.3s 0.1s ease forwards"
113
+ }
114
+ })
115
+ ])
116
+ ]);
117
+ }
118
+ var ProcessingOverlay = (0, import_vue.defineComponent)({
119
+ name: "FloPayProcessingOverlay",
120
+ props: {
121
+ status: { type: String, required: true },
122
+ errorMessage: { type: String, default: null },
123
+ processingLabel: { type: String, default: "PROCESSING..." },
124
+ successLabel: { type: String, default: "PAYMENT SUCCESSFUL" },
125
+ errorLabel: { type: String, default: "PAYMENT FAILED" },
126
+ /** Success sub-note; `null` omits it (surfaces that do not redirect). */
127
+ successNote: {
128
+ type: String,
129
+ default: "You will be automatically redirected, do not close or navigate away from this window."
130
+ },
131
+ theme: { type: Object, default: void 0 }
132
+ },
133
+ setup(props) {
134
+ (0, import_vue.onMounted)(ensureKeyframes);
135
+ return () => {
136
+ const theme = props.theme ?? NEUTRAL_THEME;
137
+ const noteStyle = {
138
+ fontSize: "13px",
139
+ color: theme.noteColor,
140
+ fontWeight: 400,
141
+ maxWidth: "260px",
142
+ lineHeight: 1.4,
143
+ margin: 0
144
+ };
145
+ const label = {
146
+ processing: props.processingLabel,
147
+ success: props.successLabel,
148
+ error: props.errorLabel
149
+ }[props.status];
150
+ const note = { processing: null, success: props.successNote, error: props.errorMessage }[props.status];
151
+ return (0, import_vue.h)(
152
+ "div",
153
+ {
154
+ "data-testid": "flopay-processing-overlay",
155
+ "data-status": props.status,
156
+ // The attribute the Vue setup surfaces' overlay already carried.
157
+ "data-state": props.status,
158
+ role: "dialog",
159
+ "aria-modal": "true",
160
+ style: {
161
+ position: "fixed",
162
+ inset: 0,
163
+ background: "rgba(0,0,0,0.35)",
164
+ display: "flex",
165
+ alignItems: "center",
166
+ justifyContent: "center",
167
+ zIndex: 1e3,
168
+ backdropFilter: "blur(2px)"
169
+ }
170
+ },
171
+ [
172
+ (0, import_vue.h)(
173
+ "div",
174
+ {
175
+ "data-testid": "flopay-processing-overlay-panel",
176
+ style: {
177
+ borderRadius: "12px",
178
+ boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
179
+ ...theme.panel,
180
+ padding: "2rem 2.5rem",
181
+ textAlign: "center",
182
+ minWidth: "240px",
183
+ display: "flex",
184
+ flexDirection: "column",
185
+ alignItems: "center",
186
+ gap: "16px"
187
+ }
188
+ },
189
+ [
190
+ (0, import_vue.h)("div", { style: { width: "48px", height: "48px", position: "relative" } }, [
191
+ statusIcon(props.status, theme)
192
+ ]),
193
+ (0, import_vue.h)(
194
+ "span",
195
+ {
196
+ "data-testid": "flopay-processing-overlay-label",
197
+ style: {
198
+ fontSize: "14px",
199
+ fontWeight: 600,
200
+ letterSpacing: "0.05em",
201
+ color: theme.labelColors[props.status]
202
+ }
203
+ },
204
+ label
205
+ ),
206
+ note ? (0, import_vue.h)("p", { style: noteStyle }, note) : null
207
+ ]
208
+ )
209
+ ]
210
+ );
211
+ };
212
+ }
213
+ });
214
+
215
+ // src/hosted-setup.ts
216
+ var FloPayCardSetupError = class extends import_shared.FloPayError {
217
+ constructor(message, type, options) {
218
+ super(message, type, options);
219
+ this.name = "FloPayCardSetupError";
220
+ this.retryable = options.retryable;
221
+ }
222
+ };
223
+ function asCardSetupError(error, overrides = {}) {
224
+ const source = error instanceof import_shared.FloPayError ? error : void 0;
225
+ const statusCode = source?.statusCode;
226
+ const retryable = overrides.retryable ?? (source?.type === "network_error" || source?.type === "rate_limit_error" || typeof statusCode === "number" && statusCode >= 500 || source?.code === "vault_capture_timeout" || !source);
227
+ return new FloPayCardSetupError(
228
+ source?.message ?? (error instanceof Error ? error.message : "Failed to load the secure card form."),
229
+ source?.type ?? "api_error",
230
+ {
231
+ code: overrides.code ?? source?.code ?? "card_setup_load_failed",
232
+ retryable,
233
+ ...source?.param ? { param: source.param } : {},
234
+ ...statusCode === void 0 ? {} : { statusCode }
235
+ }
236
+ );
237
+ }
238
+ function useCardSetupTheme(source) {
239
+ const resolved = (0, import_vue2.computed)(
240
+ () => (0, import_shared.resolveCardSetupTheme)({
241
+ theme: source.theme ?? "modern-light",
242
+ appearance: source.appearance,
243
+ buttonsStyles: source.buttonsStyles
244
+ })
245
+ );
246
+ const vaultTheme = (0, import_vue2.computed)(() => resolved.value.vaultTheme);
247
+ const surfaceStyle = (0, import_vue2.computed)(
248
+ () => (0, import_shared.mergeCardSetupSurface)(resolved.value.surface, source.containerStyle)
249
+ );
250
+ const overlayTheme = (0, import_vue2.computed)(() => resolved.value.overlayTheme);
251
+ const appearance = (0, import_vue2.computed)(() => resolved.value.appearance);
252
+ return { vaultTheme, surfaceStyle, overlayTheme, appearance };
253
+ }
254
+ function useHostedSetup(props, emitters, options) {
255
+ const capture = (0, import_vue2.shallowRef)(null);
256
+ const vault = (0, import_vue2.shallowRef)(null);
257
+ const session = (0, import_vue2.shallowRef)(null);
258
+ const loadError = (0, import_vue2.ref)(null);
259
+ let active = true;
260
+ let terminal = false;
261
+ let completed = false;
262
+ let submissionInFlight = false;
263
+ let clearTimer = null;
264
+ const offs = [];
265
+ const sessionId = () => props.sessionId ?? "";
266
+ const showOverlay = (state) => {
267
+ if (clearTimer) clearTimeout(clearTimer);
268
+ clearTimer = null;
269
+ emitters.overlay(state);
270
+ };
271
+ const holdFailure = (message) => {
272
+ showOverlay({ status: "error", message });
273
+ clearTimer = setTimeout(() => {
274
+ clearTimer = null;
275
+ if (active) emitters.overlay(null);
276
+ }, PROCESSING_OVERLAY_ERROR_DELAY_MS);
277
+ };
278
+ const bind = (adapter) => {
279
+ submissionInFlight = false;
280
+ offs.push(
281
+ adapter.on("submitting", () => {
282
+ submissionInFlight = true;
283
+ showOverlay({ status: "processing", message: null });
284
+ }),
285
+ adapter.on("complete", (event) => {
286
+ terminal = true;
287
+ submissionInFlight = false;
288
+ showOverlay({ status: "success", message: null });
289
+ setTimeout(() => {
290
+ if (completed) return;
291
+ completed = true;
292
+ (0, import_shared.invokeMerchantCallback)(
293
+ () => emitters.complete({
294
+ status: "succeeded",
295
+ sessionId: sessionId(),
296
+ ...event.paymentMethod ? { paymentMethod: event.paymentMethod } : {}
297
+ })
298
+ );
299
+ if (active) emitters.overlay(null);
300
+ }, PROCESSING_OVERLAY_SUCCESS_DELAY_MS);
301
+ }),
302
+ adapter.on("decline", (event) => {
303
+ terminal = true;
304
+ submissionInFlight = false;
305
+ holdFailure(event.message ?? null);
306
+ (0, import_shared.invokeMerchantCallback)(
307
+ () => emitters.decline({
308
+ status: "declined",
309
+ sessionId: sessionId(),
310
+ ...event.declineReason ? { reason: event.declineReason } : {},
311
+ ...event.message ? { message: event.message } : {}
312
+ })
313
+ );
314
+ }),
315
+ // Closing the bank's authentication window is not an outcome: the hosted
316
+ // form keeps polling and may still report one. Drop the overlay but keep
317
+ // the submission in flight, so a late failure still shows "CARD NOT SAVED".
318
+ adapter.on("challenge_dismissed", () => {
319
+ showOverlay(null);
320
+ })
321
+ );
322
+ };
323
+ (0, import_vue2.onMounted)(async () => {
324
+ const billingApiUrl = (0, import_shared.resolveBillingApiUrl)(props.billingApiUrl);
325
+ const api = new import_card_setup.PaymentAPI(billingApiUrl, { telemetry: props.telemetry });
326
+ try {
327
+ if (!sessionId().trim()) {
328
+ throw new import_shared.FloPayError("A setup surface requires a sessionId.", "validation_error", {
329
+ code: "MissingCheckoutSessionId",
330
+ param: "sessionId"
331
+ });
332
+ }
333
+ if (!props.nonce?.trim()) {
334
+ throw new import_shared.FloPayError("A setup surface requires a session nonce.", "validation_error", {
335
+ code: "MissingCheckoutSessionToken",
336
+ param: "nonce"
337
+ });
338
+ }
339
+ const result = await api.getUnifiedCheckoutSession(sessionId(), props.nonce);
340
+ const read = result.data.session;
341
+ if (!read || !(0, import_shared.isCardSetupCheckoutSession)(read)) {
342
+ throw new import_shared.FloPayError(
343
+ "Only a zero-amount, productless setup session is accepted.",
344
+ "validation_error",
345
+ { code: "InvalidCardSetupSession", param: "sessionId" }
346
+ );
347
+ }
348
+ if (!active) return;
349
+ session.value = result;
350
+ if (!options.requireVault(result)) return;
351
+ let block = read.vault;
352
+ if (!(0, import_shared.isMountableVaultBlock)(block))
353
+ block = await api.getVaultCapture(sessionId(), props.nonce);
354
+ const mount = (0, import_shared.resolveVaultMountOptions)(block, {
355
+ billingApiUrl,
356
+ sessionId: sessionId(),
357
+ nonce: props.nonce
358
+ });
359
+ if (!mount) {
360
+ throw new import_shared.FloPayError(
361
+ "FloPay: this setup session has no vault card capability. Upgrade the billing backend integration.",
362
+ "api_error",
363
+ { code: "UnsupportedBackendVaultCapability" }
364
+ );
365
+ }
366
+ if (!active) return;
367
+ const adapter = new import_card_setup.PciVaultCardCapture({
368
+ sessionId: sessionId(),
369
+ operation: "card_setup",
370
+ telemetry: props.telemetry
371
+ });
372
+ bind(adapter);
373
+ vault.value = mount;
374
+ capture.value = adapter;
375
+ } catch (error) {
376
+ if (!active) return;
377
+ terminal = true;
378
+ const failure = asCardSetupError(error);
379
+ loadError.value = failure;
380
+ (0, import_shared.invokeMerchantCallback)(() => emitters.error(failure));
381
+ } finally {
382
+ api.destroy();
383
+ }
384
+ });
385
+ (0, import_vue2.onBeforeUnmount)(() => {
386
+ active = false;
387
+ if (clearTimer) clearTimeout(clearTimer);
388
+ clearTimer = null;
389
+ for (const off of offs.splice(0)) off();
390
+ if (!terminal && sessionId()) {
391
+ (0, import_shared.invokeMerchantCallback)(
392
+ () => emitters.cancel({ status: "cancelled", sessionId: sessionId() })
393
+ );
394
+ }
395
+ });
396
+ return {
397
+ capture,
398
+ vault,
399
+ session,
400
+ loadError,
401
+ settle: () => {
402
+ terminal = true;
403
+ },
404
+ widgetFailed: (message) => {
405
+ if (!submissionInFlight) return;
406
+ submissionInFlight = false;
407
+ holdFailure(message);
408
+ }
409
+ };
410
+ }
411
+
412
+ // src/vault-card-fields.ts
413
+ var import_shared2 = require("@flopay/shared");
414
+ var import_vue3 = require("vue");
415
+ var labelledCaptures = /* @__PURE__ */ new WeakSet();
416
+ var VaultCardFields = (0, import_vue3.defineComponent)({
417
+ name: "VaultCardFields",
418
+ props: {
419
+ capture: { type: Object, default: void 0 },
420
+ html: { type: String, default: void 0 },
421
+ messageToken: { type: String, default: void 0 },
422
+ expectedOrigin: { type: String, default: void 0 },
423
+ verificationRequired: { type: Boolean, default: void 0 },
424
+ theme: { type: Object, default: void 0 },
425
+ submitLabel: { type: String, default: void 0 },
426
+ containerStyle: { type: Object, default: void 0 }
427
+ },
428
+ emits: {
429
+ ready: () => true,
430
+ error: (_message) => true,
431
+ validation: (_message) => true
432
+ },
433
+ setup(props, { emit }) {
434
+ const container = (0, import_vue3.ref)(null);
435
+ let teardown = null;
436
+ let appliedLabel;
437
+ let appliedTheme = null;
438
+ const mountWidget = () => {
439
+ teardown?.();
440
+ teardown = null;
441
+ const el = container.value;
442
+ const { capture, html } = props;
443
+ if (!el || !capture || !html) return;
444
+ let active = true;
445
+ let readyEmitted = false;
446
+ const emitReadyOnce = () => {
447
+ if (!active || readyEmitted) return;
448
+ readyEmitted = true;
449
+ (0, import_shared2.invokeMerchantCallback)(() => emit("ready"));
450
+ };
451
+ const offReady = capture.on("ready", emitReadyOnce);
452
+ const offError = capture.on("error", (event) => {
453
+ const message = event.message ?? "There was a problem loading the secure card form.";
454
+ (0, import_shared2.invokeMerchantCallback)(() => emit("error", message));
455
+ });
456
+ const offValidation = capture.on("validation", (event) => {
457
+ (0, import_shared2.invokeMerchantCallback)(() => emit("validation", event.message ?? null));
458
+ });
459
+ const label = props.submitLabel ?? void 0;
460
+ const labelDirective = label ?? (labelledCaptures.has(capture) ? null : void 0);
461
+ appliedLabel = label;
462
+ appliedTheme = props.theme ?? null;
463
+ if (label !== void 0) labelledCaptures.add(capture);
464
+ capture.mount(el, {
465
+ html,
466
+ ...props.messageToken ? { messageToken: props.messageToken } : {},
467
+ ...props.expectedOrigin ? { expectedOrigin: props.expectedOrigin } : {},
468
+ ...props.verificationRequired ? { verificationRequired: true } : {},
469
+ ...props.theme ? { theme: props.theme } : {},
470
+ ...labelDirective === void 0 ? {} : { submitLabel: labelDirective }
471
+ }).then(emitReadyOnce).catch((error) => {
472
+ if (!active) return;
473
+ const message = error instanceof Error ? error.message : "Failed to load the secure card form.";
474
+ (0, import_shared2.invokeMerchantCallback)(() => emit("error", message));
475
+ });
476
+ teardown = () => {
477
+ active = false;
478
+ offReady();
479
+ offError();
480
+ offValidation();
481
+ capture.unmount();
482
+ };
483
+ };
484
+ (0, import_vue3.onMounted)(() => {
485
+ mountWidget();
486
+ (0, import_vue3.watch)(
487
+ () => [
488
+ props.capture,
489
+ props.html,
490
+ props.messageToken,
491
+ props.expectedOrigin,
492
+ props.verificationRequired
493
+ ],
494
+ mountWidget
495
+ );
496
+ (0, import_vue3.watch)(
497
+ () => props.theme,
498
+ (theme) => {
499
+ if (theme === void 0) return;
500
+ if (theme === null && appliedTheme === null) return;
501
+ appliedTheme = theme;
502
+ props.capture?.applyTheme?.(theme);
503
+ }
504
+ );
505
+ (0, import_vue3.watch)(
506
+ () => props.submitLabel ?? void 0,
507
+ (label) => {
508
+ if (!props.capture || label === appliedLabel) return;
509
+ appliedLabel = label;
510
+ if (label !== void 0) labelledCaptures.add(props.capture);
511
+ props.capture.setSubmitLabel?.(label ?? null);
512
+ }
513
+ );
514
+ });
515
+ (0, import_vue3.onBeforeUnmount)(() => {
516
+ teardown?.();
517
+ teardown = null;
518
+ });
519
+ return () => (0, import_vue3.h)("div", {
520
+ ref: container,
521
+ "data-testid": "flopay-vault-card-fields",
522
+ style: props.containerStyle
523
+ });
524
+ }
525
+ });
526
+
527
+ // src/flopay-card-setup.ts
528
+ var FloPayCardSetup = (0, import_vue4.defineComponent)({
529
+ name: "FloPayCardSetup",
530
+ props: {
531
+ sessionId: { type: String, default: void 0 },
532
+ nonce: { type: String, default: void 0 },
533
+ billingApiUrl: { type: String, default: void 0 },
534
+ telemetry: { type: Boolean, default: void 0 },
535
+ theme: {
536
+ type: [String, Object],
537
+ default: "modern-light"
538
+ },
539
+ containerStyle: {
540
+ type: Object,
541
+ default: void 0
542
+ },
543
+ appearance: { type: Object, default: void 0 },
544
+ buttonsStyles: { type: Object, default: void 0 }
545
+ },
546
+ emits: {
547
+ ready: () => true,
548
+ complete: (_event) => true,
549
+ cancel: (_event) => true,
550
+ decline: (_event) => true,
551
+ validation: (_message) => true,
552
+ error: (_error) => true
553
+ },
554
+ setup(props, { emit, slots }) {
555
+ const overlay = (0, import_vue4.shallowRef)(null);
556
+ const setup = useHostedSetup(
557
+ props,
558
+ {
559
+ complete: (event) => emit("complete", event),
560
+ decline: (event) => emit("decline", event),
561
+ cancel: (event) => emit("cancel", event),
562
+ error: (error) => emit("error", error),
563
+ overlay: (state) => {
564
+ overlay.value = state;
565
+ }
566
+ },
567
+ { requireVault: () => true }
568
+ );
569
+ const theme = useCardSetupTheme(props);
570
+ return () => {
571
+ if (setup.loadError.value) {
572
+ return (0, import_vue4.h)("div", { role: "alert" }, setup.loadError.value.message);
573
+ }
574
+ const capture = setup.capture.value;
575
+ const vault = setup.vault.value;
576
+ if (!capture || !vault?.html) return slots.loading?.() ?? null;
577
+ const state = overlay.value;
578
+ return [
579
+ state ? (0, import_vue4.h)(ProcessingOverlay, {
580
+ status: state.status,
581
+ errorMessage: state.message,
582
+ ...(0, import_shared3.setupOverlayLabels)("card"),
583
+ successNote: null,
584
+ ...theme.overlayTheme.value ? { theme: theme.overlayTheme.value } : {}
585
+ }) : null,
586
+ (0, import_vue4.h)(VaultCardFields, {
587
+ capture,
588
+ html: vault.html,
589
+ messageToken: vault.messageToken,
590
+ expectedOrigin: vault.expectedOrigin,
591
+ verificationRequired: vault.verificationRequired,
592
+ theme: theme.vaultTheme.value,
593
+ containerStyle: theme.surfaceStyle.value,
594
+ onReady: () => (0, import_shared3.invokeMerchantCallback)(() => emit("ready")),
595
+ onValidation: (message) => (0, import_shared3.invokeMerchantCallback)(() => emit("validation", message)),
596
+ onError: (message) => {
597
+ if (!message) return;
598
+ setup.widgetFailed(message);
599
+ const error = asCardSetupError(new Error(message), {
600
+ code: "card_setup_widget_failed",
601
+ retryable: true
602
+ });
603
+ (0, import_shared3.invokeMerchantCallback)(() => emit("error", error));
604
+ }
605
+ })
606
+ ];
607
+ };
608
+ }
609
+ });
610
+ // Annotate the CommonJS export names for ESM import in node:
611
+ 0 && (module.exports = {
612
+ FloPayCardSetup,
613
+ FloPayCardSetupError
614
+ });