@solvapay/react 1.3.0 → 1.4.0-preview-ecd61384a4e849717e13d47ab2daa086cdcd91c5

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,3224 @@
1
+ import {
2
+ AmountPicker,
3
+ MandateText,
4
+ MissingProductRefError,
5
+ MissingProviderError,
6
+ PaymentForm,
7
+ PlanSelector,
8
+ Slot,
9
+ SolvaPayContext,
10
+ Spinner,
11
+ TopupForm,
12
+ buildDefaultCheckoutPlanFilter,
13
+ composeEventHandlers,
14
+ createHttpTransport,
15
+ createTransportCacheKey,
16
+ formatContinueLabel,
17
+ formatPrice,
18
+ getMinorUnitsPerMajor,
19
+ interpolate,
20
+ isPaygPlan,
21
+ planSortByPaygFirstThenAsc,
22
+ shortCycle,
23
+ useActivation,
24
+ useAmountPicker,
25
+ useAmountPickerCopy,
26
+ useBalance,
27
+ useCheckoutFlow,
28
+ useCopy,
29
+ useLocale,
30
+ usePlan,
31
+ usePlanSelection,
32
+ usePlans,
33
+ useProduct,
34
+ usePurchase,
35
+ useSolvaPay,
36
+ useTopupAmountSelector,
37
+ withPaymentElementDefaults
38
+ } from "./chunk-6RR4J74H.js";
39
+
40
+ // src/TopupForm.tsx
41
+ import { jsx, jsxs } from "react/jsx-runtime";
42
+ var TopupForm2 = (props) => {
43
+ const { className, buttonClassName, submitButtonText, ...rootProps } = props;
44
+ const rootClass = ["solvapay-topup-form", className].filter(Boolean).join(" ");
45
+ const buttonClass = ["solvapay-topup-form-submit", buttonClassName].filter(Boolean).join(" ");
46
+ return /* @__PURE__ */ jsxs(TopupForm.Root, { ...rootProps, className: rootClass, children: [
47
+ /* @__PURE__ */ jsx(TopupForm.PaymentElement, {}),
48
+ /* @__PURE__ */ jsx(TopupForm.Error, { className: "solvapay-topup-form-error" }),
49
+ /* @__PURE__ */ jsx(TopupForm.Loading, { className: "solvapay-topup-form-loading" }),
50
+ /* @__PURE__ */ jsx(TopupForm.SubmitButton, { className: buttonClass, children: submitButtonText })
51
+ ] });
52
+ };
53
+
54
+ // src/primitives/ProductBadge.tsx
55
+ import { forwardRef, useContext, useEffect, useState } from "react";
56
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
57
+ var ProductBadgeImpl = forwardRef(function ProductBadge({ asChild, children, ...rest }, forwardedRef) {
58
+ const solva = useContext(SolvaPayContext);
59
+ if (!solva) throw new MissingProviderError("ProductBadge");
60
+ const { purchases, loading, hasPaidPurchase, activePurchase } = usePurchase();
61
+ const copy = useCopy();
62
+ const [hasLoadedOnce, setHasLoadedOnce] = useState(false);
63
+ useEffect(() => {
64
+ if (!loading) setHasLoadedOnce(true);
65
+ }, [loading]);
66
+ const planToDisplay = activePurchase?.productName ?? null;
67
+ const shouldShow = planToDisplay !== null && (!loading || hasLoadedOnce);
68
+ if (!shouldShow) return null;
69
+ const commonProps = {
70
+ "data-solvapay-product-badge": "",
71
+ "data-loading": loading ? "" : void 0,
72
+ "data-has-purchase": activePurchase ? "" : void 0,
73
+ "data-has-paid-purchase": hasPaidPurchase ? "" : void 0,
74
+ role: "status",
75
+ "aria-live": "polite",
76
+ "aria-busy": loading,
77
+ "aria-label": interpolate(copy.product.currentProductLabel, { name: planToDisplay }),
78
+ ...rest
79
+ };
80
+ if (asChild) {
81
+ return (
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ /* @__PURE__ */ jsx2(Slot, { ref: forwardedRef, ...commonProps, children: children ?? /* @__PURE__ */ jsx2(Fragment, { children: planToDisplay }) })
84
+ );
85
+ }
86
+ void purchases;
87
+ return (
88
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
+ /* @__PURE__ */ jsx2("div", { ref: forwardedRef, ...commonProps, children: children ?? planToDisplay })
90
+ );
91
+ });
92
+ var ProductBadge2 = ProductBadgeImpl;
93
+ var PlanBadge = ProductBadgeImpl;
94
+
95
+ // src/primitives/PurchaseGate.tsx
96
+ import {
97
+ createContext,
98
+ forwardRef as forwardRef2,
99
+ useContext as useContext2,
100
+ useMemo
101
+ } from "react";
102
+ import { jsx as jsx3 } from "react/jsx-runtime";
103
+ var PurchaseGateContext = createContext(null);
104
+ function useGateCtx(part) {
105
+ const ctx = useContext2(PurchaseGateContext);
106
+ if (!ctx) {
107
+ throw new Error(`PurchaseGate.${part} must be rendered inside <PurchaseGate.Root>.`);
108
+ }
109
+ return ctx;
110
+ }
111
+ var Root = forwardRef2(function PurchaseGateRoot({ requirePlan, requireProduct, asChild, children, ...rest }, forwardedRef) {
112
+ const solva = useContext2(SolvaPayContext);
113
+ if (!solva) throw new MissingProviderError("PurchaseGate");
114
+ const { purchases, loading, hasProduct, error } = usePurchase();
115
+ const productToCheck = requireProduct || requirePlan;
116
+ const hasAccess = productToCheck ? hasProduct(productToCheck) : purchases.some((p) => p.status === "active");
117
+ const state = loading ? "loading" : hasAccess ? "allowed" : "blocked";
118
+ const ctx = useMemo(
119
+ () => ({ state, loading, hasAccess, error }),
120
+ [state, loading, hasAccess, error]
121
+ );
122
+ const Comp = asChild ? Slot : "div";
123
+ return /* @__PURE__ */ jsx3(PurchaseGateContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx3(
124
+ Comp,
125
+ {
126
+ ref: forwardedRef,
127
+ "data-solvapay-purchase-gate": "",
128
+ "data-state": state,
129
+ ...rest,
130
+ children
131
+ }
132
+ ) });
133
+ });
134
+ var Allowed = forwardRef2(function PurchaseGateAllowed({ asChild, children, ...rest }, forwardedRef) {
135
+ const ctx = useGateCtx("Allowed");
136
+ if (ctx.state !== "allowed") return null;
137
+ const Comp = asChild ? Slot : "div";
138
+ return /* @__PURE__ */ jsx3(Comp, { ref: forwardedRef, "data-solvapay-purchase-gate-allowed": "", ...rest, children });
139
+ });
140
+ var Blocked = forwardRef2(function PurchaseGateBlocked({ asChild, children, ...rest }, forwardedRef) {
141
+ const ctx = useGateCtx("Blocked");
142
+ if (ctx.state !== "blocked") return null;
143
+ const Comp = asChild ? Slot : "div";
144
+ return /* @__PURE__ */ jsx3(Comp, { ref: forwardedRef, "data-solvapay-purchase-gate-blocked": "", ...rest, children });
145
+ });
146
+ var Loading = forwardRef2(function PurchaseGateLoading({ asChild, children, ...rest }, forwardedRef) {
147
+ const ctx = useGateCtx("Loading");
148
+ if (ctx.state !== "loading") return null;
149
+ const Comp = asChild ? Slot : "div";
150
+ return /* @__PURE__ */ jsx3(Comp, { ref: forwardedRef, "data-solvapay-purchase-gate-loading": "", ...rest, children });
151
+ });
152
+ var ErrorSlot = forwardRef2(function PurchaseGateError({ asChild, children, ...rest }, forwardedRef) {
153
+ const ctx = useGateCtx("Error");
154
+ if (!ctx.error) return null;
155
+ const Comp = asChild ? Slot : "div";
156
+ return /* @__PURE__ */ jsx3(Comp, { ref: forwardedRef, "data-solvapay-purchase-gate-error": "", role: "alert", ...rest, children: children ?? ctx.error.message });
157
+ });
158
+ var PurchaseGateRoot2 = Root;
159
+ var PurchaseGateAllowed2 = Allowed;
160
+ var PurchaseGateBlocked2 = Blocked;
161
+ var PurchaseGateLoading2 = Loading;
162
+ var PurchaseGateError2 = ErrorSlot;
163
+ var PurchaseGate = {
164
+ Root,
165
+ Allowed,
166
+ Blocked,
167
+ Loading,
168
+ Error: ErrorSlot
169
+ };
170
+ function usePurchaseGate() {
171
+ return useGateCtx("usePurchaseGate");
172
+ }
173
+
174
+ // src/primitives/ActivationFlow.tsx
175
+ import {
176
+ createContext as createContext2,
177
+ forwardRef as forwardRef3,
178
+ useCallback,
179
+ useContext as useContext3,
180
+ useEffect as useEffect2,
181
+ useMemo as useMemo2,
182
+ useRef,
183
+ useState as useState2
184
+ } from "react";
185
+ import { Fragment as Fragment2, jsx as jsx4 } from "react/jsx-runtime";
186
+ var ActivationFlowContext = createContext2(null);
187
+ function useFlowCtx(part) {
188
+ const ctx = useContext3(ActivationFlowContext);
189
+ if (!ctx) {
190
+ throw new Error(`ActivationFlow.${part} must be rendered inside <ActivationFlow.Root>.`);
191
+ }
192
+ return ctx;
193
+ }
194
+ var Root2 = forwardRef3(function ActivationFlowRoot({
195
+ productRef,
196
+ planRef: planRefProp,
197
+ onSuccess,
198
+ onError,
199
+ retryDelayMs = 1500,
200
+ retryBackoffMs = 2e3,
201
+ asChild,
202
+ children,
203
+ ...rest
204
+ }, forwardedRef) {
205
+ const solva = useContext3(SolvaPayContext);
206
+ if (!solva) throw new MissingProviderError("ActivationFlow");
207
+ if (!productRef) throw new MissingProductRefError("ActivationFlow");
208
+ const planSelection = usePlanSelection();
209
+ const resolvedPlanRef = planRefProp ?? planSelection?.selectedPlanRef ?? void 0;
210
+ const { plan } = usePlan({ planRef: resolvedPlanRef, productRef });
211
+ const { activate, state, error, result, reset } = useActivation();
212
+ const currency = plan?.currency ?? "USD";
213
+ const amountSelector = useTopupAmountSelector({ currency });
214
+ const { adjustBalance, creditsPerMinorUnit, displayExchangeRate } = useBalance();
215
+ const [step, setStep] = useState2("summary");
216
+ const calledSuccessRef = useRef(false);
217
+ const retryTimeoutRef = useRef(null);
218
+ useEffect2(() => {
219
+ if (state === "activated" && !calledSuccessRef.current) {
220
+ calledSuccessRef.current = true;
221
+ setStep("activated");
222
+ if (result) {
223
+ const activationResult = { kind: "activated", result };
224
+ onSuccess?.(activationResult);
225
+ }
226
+ }
227
+ }, [state, result, onSuccess]);
228
+ useEffect2(() => {
229
+ if (state === "topup_required" && (step === "summary" || step === "activating")) {
230
+ setStep("selectAmount");
231
+ }
232
+ }, [state, step]);
233
+ useEffect2(() => {
234
+ if ((state === "error" || state === "payment_required") && error) {
235
+ setStep("error");
236
+ if (state === "error") onError?.(new Error(error));
237
+ }
238
+ }, [state, error, onError]);
239
+ const handleActivate = useCallback(async () => {
240
+ if (!resolvedPlanRef) return;
241
+ setStep("activating");
242
+ await activate({ productRef, planRef: resolvedPlanRef });
243
+ }, [activate, productRef, resolvedPlanRef]);
244
+ const goToTopupPayment = useCallback(() => {
245
+ if (amountSelector.validate()) setStep("topupPayment");
246
+ }, [amountSelector]);
247
+ const backToSelectAmount = useCallback(() => {
248
+ setStep("selectAmount");
249
+ }, []);
250
+ const retryActivation = useCallback(async () => {
251
+ if (!resolvedPlanRef) return;
252
+ setStep("retrying");
253
+ const amountMinor2 = Math.round(
254
+ (amountSelector.resolvedAmount || 0) * getMinorUnitsPerMajor(currency)
255
+ );
256
+ const rate = displayExchangeRate ?? 1;
257
+ if (creditsPerMinorUnit) {
258
+ adjustBalance(Math.floor(amountMinor2 / rate * creditsPerMinorUnit));
259
+ }
260
+ await new Promise((r) => setTimeout(r, retryDelayMs));
261
+ await activate({ productRef, planRef: resolvedPlanRef });
262
+ }, [
263
+ resolvedPlanRef,
264
+ amountSelector.resolvedAmount,
265
+ currency,
266
+ displayExchangeRate,
267
+ creditsPerMinorUnit,
268
+ adjustBalance,
269
+ retryDelayMs,
270
+ activate,
271
+ productRef
272
+ ]);
273
+ const handleTopupSuccess = useCallback(async () => {
274
+ await retryActivation();
275
+ }, [retryActivation]);
276
+ useEffect2(() => {
277
+ if (step !== "retrying") return;
278
+ if (state !== "topup_required") return;
279
+ if (!resolvedPlanRef) return;
280
+ retryTimeoutRef.current = setTimeout(async () => {
281
+ await activate({ productRef, planRef: resolvedPlanRef });
282
+ }, retryBackoffMs);
283
+ return () => {
284
+ if (retryTimeoutRef.current) clearTimeout(retryTimeoutRef.current);
285
+ };
286
+ }, [step, state, resolvedPlanRef, retryBackoffMs, activate, productRef]);
287
+ const resetFlow = useCallback(() => {
288
+ reset();
289
+ calledSuccessRef.current = false;
290
+ setStep("summary");
291
+ }, [reset]);
292
+ const amountMinor = Math.round(
293
+ (amountSelector.resolvedAmount || 0) * getMinorUnitsPerMajor(currency)
294
+ );
295
+ const ctx = useMemo2(
296
+ () => ({
297
+ step,
298
+ plan,
299
+ productRef,
300
+ planRef: resolvedPlanRef ?? "",
301
+ amountSelector,
302
+ amountMinor,
303
+ // Deprecated alias — same value as amountMinor so legacy consumers
304
+ // keep working after the zero-decimal fix (previously this was
305
+ // `resolvedAmount * 100`, which over-billed JPY/KRW by 100x).
306
+ amountCents: amountMinor,
307
+ currency,
308
+ activate: handleActivate,
309
+ reset: resetFlow,
310
+ goToTopupPayment,
311
+ backToSelectAmount,
312
+ onTopupSuccess: handleTopupSuccess,
313
+ error,
314
+ onError
315
+ }),
316
+ [
317
+ step,
318
+ plan,
319
+ productRef,
320
+ resolvedPlanRef,
321
+ amountSelector,
322
+ amountMinor,
323
+ currency,
324
+ handleActivate,
325
+ resetFlow,
326
+ goToTopupPayment,
327
+ backToSelectAmount,
328
+ handleTopupSuccess,
329
+ error,
330
+ onError
331
+ ]
332
+ );
333
+ const Comp = asChild ? Slot : "div";
334
+ return /* @__PURE__ */ jsx4(ActivationFlowContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx4(
335
+ Comp,
336
+ {
337
+ ref: forwardedRef,
338
+ "data-solvapay-activation-flow": "",
339
+ "data-state": step,
340
+ ...rest,
341
+ children
342
+ }
343
+ ) });
344
+ });
345
+ function matchStep(step, allowed) {
346
+ return allowed.includes(step);
347
+ }
348
+ var Summary = forwardRef3(function ActivationFlowSummary({ asChild, children, ...rest }, forwardedRef) {
349
+ const ctx = useFlowCtx("Summary");
350
+ if (!matchStep(ctx.step, ["summary", "activating"])) return null;
351
+ const Comp = asChild ? Slot : "div";
352
+ return /* @__PURE__ */ jsx4(Comp, { ref: forwardedRef, "data-solvapay-activation-flow-summary": "", ...rest, children });
353
+ });
354
+ var ActivateButton = forwardRef3(
355
+ function ActivationFlowActivateButton({ asChild, onClick, children, ...rest }, forwardedRef) {
356
+ const ctx = useFlowCtx("ActivateButton");
357
+ const copy = useCopy();
358
+ if (!matchStep(ctx.step, ["summary", "activating"])) return null;
359
+ const isActivating = ctx.step === "activating";
360
+ const disabled = isActivating;
361
+ const commonProps = {
362
+ "data-solvapay-activation-flow-activate": "",
363
+ "data-state": isActivating ? "activating" : "idle",
364
+ "aria-busy": isActivating,
365
+ disabled,
366
+ onClick: composeEventHandlers(onClick, () => {
367
+ void ctx.activate();
368
+ }),
369
+ ...rest
370
+ };
371
+ const label = isActivating ? copy.activationFlow.activatingLabel : copy.activationFlow.activateButton;
372
+ if (asChild) {
373
+ return (
374
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
375
+ /* @__PURE__ */ jsx4(Slot, { ref: forwardedRef, ...commonProps, children: children ?? /* @__PURE__ */ jsx4(Fragment2, { children: label }) })
376
+ );
377
+ }
378
+ return /* @__PURE__ */ jsx4("button", { ref: forwardedRef, type: "button", ...commonProps, children: children ?? label });
379
+ }
380
+ );
381
+ var AmountPickerMount = ({ children }) => {
382
+ const ctx = useFlowCtx("AmountPicker");
383
+ if (ctx.step !== "selectAmount") return null;
384
+ return /* @__PURE__ */ jsx4("div", { "data-solvapay-activation-flow-amount-picker": "", children: /* @__PURE__ */ jsx4(AmountPicker.Root, { currency: ctx.currency, selector: ctx.amountSelector, children }) });
385
+ };
386
+ var ContinueButton = forwardRef3(
387
+ function ActivationFlowContinueButton({ asChild, onClick, children, ...rest }, forwardedRef) {
388
+ const ctx = useFlowCtx("ContinueButton");
389
+ const copy = useCopy();
390
+ if (ctx.step !== "selectAmount") return null;
391
+ const disabled = !ctx.amountSelector.resolvedAmount;
392
+ const commonProps = {
393
+ "data-solvapay-activation-flow-continue": "",
394
+ "data-state": disabled ? "disabled" : "idle",
395
+ disabled,
396
+ "aria-disabled": disabled || void 0,
397
+ onClick: composeEventHandlers(onClick, () => {
398
+ ctx.goToTopupPayment();
399
+ }),
400
+ ...rest
401
+ };
402
+ if (asChild) {
403
+ return (
404
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405
+ /* @__PURE__ */ jsx4(Slot, { ref: forwardedRef, ...commonProps, children: children ?? /* @__PURE__ */ jsx4(Fragment2, { children: copy.activationFlow.continueToPayment }) })
406
+ );
407
+ }
408
+ return /* @__PURE__ */ jsx4("button", { ref: forwardedRef, type: "button", ...commonProps, children: children ?? copy.activationFlow.continueToPayment });
409
+ }
410
+ );
411
+ var Retrying = forwardRef3(function ActivationFlowRetrying({ asChild, children, ...rest }, forwardedRef) {
412
+ const ctx = useFlowCtx("Retrying");
413
+ if (ctx.step !== "retrying") return null;
414
+ const Comp = asChild ? Slot : "div";
415
+ return /* @__PURE__ */ jsx4(Comp, { ref: forwardedRef, "data-solvapay-activation-flow-retrying": "", ...rest, children });
416
+ });
417
+ var Activated = forwardRef3(function ActivationFlowActivated({ asChild, children, ...rest }, forwardedRef) {
418
+ const ctx = useFlowCtx("Activated");
419
+ if (ctx.step !== "activated") return null;
420
+ const Comp = asChild ? Slot : "div";
421
+ return /* @__PURE__ */ jsx4(Comp, { ref: forwardedRef, "data-solvapay-activation-flow-activated": "", ...rest, children });
422
+ });
423
+ var Loading2 = forwardRef3(function ActivationFlowLoading({ asChild, children, ...rest }, forwardedRef) {
424
+ const ctx = useFlowCtx("Loading");
425
+ if (ctx.plan) return null;
426
+ const Comp = asChild ? Slot : "div";
427
+ return /* @__PURE__ */ jsx4(Comp, { ref: forwardedRef, "data-solvapay-activation-flow-loading": "", ...rest, children });
428
+ });
429
+ var ErrorSlot2 = forwardRef3(function ActivationFlowError({ asChild, children, ...rest }, forwardedRef) {
430
+ const ctx = useFlowCtx("Error");
431
+ if (ctx.step !== "error") return null;
432
+ const Comp = asChild ? Slot : "div";
433
+ return /* @__PURE__ */ jsx4(
434
+ Comp,
435
+ {
436
+ ref: forwardedRef,
437
+ role: "alert",
438
+ "data-solvapay-activation-flow-error": "",
439
+ ...rest,
440
+ children: children ?? ctx.error
441
+ }
442
+ );
443
+ });
444
+ var ActivationFlowRoot2 = Root2;
445
+ var ActivationFlowSummary2 = Summary;
446
+ var ActivationFlowActivateButton2 = ActivateButton;
447
+ var ActivationFlowAmountPicker = AmountPickerMount;
448
+ var ActivationFlowContinueButton2 = ContinueButton;
449
+ var ActivationFlowRetrying2 = Retrying;
450
+ var ActivationFlowActivated2 = Activated;
451
+ var ActivationFlowLoading2 = Loading2;
452
+ var ActivationFlowError2 = ErrorSlot2;
453
+ var ActivationFlow = {
454
+ Root: Root2,
455
+ Summary,
456
+ ActivateButton,
457
+ AmountPicker: AmountPickerMount,
458
+ ContinueButton,
459
+ Retrying,
460
+ Activated,
461
+ Loading: Loading2,
462
+ Error: ErrorSlot2
463
+ };
464
+ function useActivationFlow() {
465
+ return useFlowCtx("useActivationFlow");
466
+ }
467
+
468
+ // src/primitives/CreditGate.tsx
469
+ import {
470
+ createContext as createContext3,
471
+ forwardRef as forwardRef4,
472
+ useContext as useContext4,
473
+ useMemo as useMemo3
474
+ } from "react";
475
+ import { jsx as jsx5 } from "react/jsx-runtime";
476
+ var CreditGateContext = createContext3(null);
477
+ function useGateCtx2(part) {
478
+ const ctx = useContext4(CreditGateContext);
479
+ if (!ctx) {
480
+ throw new Error(`CreditGate.${part} must be rendered inside <CreditGate.Root>.`);
481
+ }
482
+ return ctx;
483
+ }
484
+ var Root3 = forwardRef4(function CreditGateRoot({
485
+ minCredits = 1,
486
+ productRef,
487
+ topupAmount = 1e3,
488
+ topupCurrency = "usd",
489
+ asChild,
490
+ children,
491
+ ...rest
492
+ }, forwardedRef) {
493
+ const solva = useContext4(SolvaPayContext);
494
+ if (!solva) throw new MissingProviderError("CreditGate");
495
+ const { credits, loading } = useBalance();
496
+ const { product } = useProduct(productRef);
497
+ const hasCredits = credits != null && credits >= minCredits;
498
+ const state = loading && credits == null ? "loading" : hasCredits ? "allowed" : "blocked";
499
+ const ctx = useMemo3(
500
+ () => ({
501
+ state,
502
+ loading,
503
+ hasCredits,
504
+ balance: credits,
505
+ productName: product?.name ?? null,
506
+ topupAmount,
507
+ topupCurrency
508
+ }),
509
+ [state, loading, hasCredits, credits, product?.name, topupAmount, topupCurrency]
510
+ );
511
+ const Comp = asChild ? Slot : "div";
512
+ return /* @__PURE__ */ jsx5(CreditGateContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx5(
513
+ Comp,
514
+ {
515
+ ref: forwardedRef,
516
+ "data-solvapay-credit-gate": "",
517
+ "data-state": state,
518
+ ...rest,
519
+ children
520
+ }
521
+ ) });
522
+ });
523
+ var Heading = forwardRef4(function CreditGateHeading({ asChild, children, ...rest }, forwardedRef) {
524
+ const ctx = useGateCtx2("Heading");
525
+ const copy = useCopy();
526
+ if (ctx.state !== "blocked") return null;
527
+ const Comp = asChild ? Slot : "h3";
528
+ return /* @__PURE__ */ jsx5(Comp, { ref: forwardedRef, "data-solvapay-credit-gate-heading": "", ...rest, children: children ?? copy.creditGate.lowBalanceHeading });
529
+ });
530
+ var Subheading = forwardRef4(function CreditGateSubheading({ asChild, children, ...rest }, forwardedRef) {
531
+ const ctx = useGateCtx2("Subheading");
532
+ const copy = useCopy();
533
+ if (ctx.state !== "blocked") return null;
534
+ const text = interpolate(copy.creditGate.lowBalanceSubheading, {
535
+ product: ctx.productName ?? "this product"
536
+ });
537
+ const Comp = asChild ? Slot : "p";
538
+ return /* @__PURE__ */ jsx5(Comp, { ref: forwardedRef, "data-solvapay-credit-gate-subheading": "", ...rest, children: children ?? text });
539
+ });
540
+ var Topup = ({ amount, currency }) => {
541
+ const ctx = useGateCtx2("Topup");
542
+ if (ctx.state !== "blocked") return null;
543
+ return /* @__PURE__ */ jsx5(
544
+ TopupForm2,
545
+ {
546
+ amount: amount ?? ctx.topupAmount,
547
+ currency: currency ?? ctx.topupCurrency
548
+ }
549
+ );
550
+ };
551
+ var Loading3 = forwardRef4(function CreditGateLoading({ asChild, children, ...rest }, forwardedRef) {
552
+ const ctx = useGateCtx2("Loading");
553
+ if (ctx.state !== "loading") return null;
554
+ const Comp = asChild ? Slot : "div";
555
+ return (
556
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
557
+ /* @__PURE__ */ jsx5(Comp, { ref: forwardedRef, "data-solvapay-credit-gate-loading": "", ...rest, children })
558
+ );
559
+ });
560
+ var ErrorSlot3 = forwardRef4(function CreditGateError({ asChild, children, ...rest }, forwardedRef) {
561
+ if (!children) return null;
562
+ const Comp = asChild ? Slot : "div";
563
+ return (
564
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
565
+ /* @__PURE__ */ jsx5(Comp, { ref: forwardedRef, "data-solvapay-credit-gate-error": "", role: "alert", ...rest, children })
566
+ );
567
+ });
568
+ var CreditGateRoot2 = Root3;
569
+ var CreditGateHeading2 = Heading;
570
+ var CreditGateSubheading2 = Subheading;
571
+ var CreditGateTopup = Topup;
572
+ var CreditGateLoading2 = Loading3;
573
+ var CreditGateError2 = ErrorSlot3;
574
+ var CreditGate = {
575
+ Root: Root3,
576
+ Heading,
577
+ Subheading,
578
+ Topup,
579
+ Loading: Loading3,
580
+ Error: ErrorSlot3
581
+ };
582
+ function useCreditGate() {
583
+ return useGateCtx2("useCreditGate");
584
+ }
585
+
586
+ // src/hooks/useAutoRecharge.ts
587
+ import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
588
+
589
+ // src/hooks/autoRechargeCache.ts
590
+ var autoRechargeCache = /* @__PURE__ */ new Map();
591
+ var CACHE_DURATION = 5 * 60 * 1e3;
592
+ function autoRechargeCacheKeyFor(config) {
593
+ return createTransportCacheKey(config, config?.api?.autoRecharge || "/api/auto-recharge");
594
+ }
595
+
596
+ // src/hooks/useAutoRecharge.ts
597
+ function mergeAutoRechargeConfig(config, display) {
598
+ return display ? { ...config, display } : config;
599
+ }
600
+ async function fetchAutoRecharge(config) {
601
+ const transport = config?.transport ?? createHttpTransport(config);
602
+ if (!transport.getAutoRecharge) return null;
603
+ const response = await transport.getAutoRecharge();
604
+ if (!response.config) return null;
605
+ return mergeAutoRechargeConfig(response.config, response.display);
606
+ }
607
+ function useAutoRecharge() {
608
+ const { _config } = useSolvaPay();
609
+ const key = autoRechargeCacheKeyFor(_config);
610
+ const [config, setConfig] = useState3(
611
+ () => autoRechargeCache.get(key)?.config ?? null
612
+ );
613
+ const [loading, setLoading] = useState3(() => {
614
+ const cached = autoRechargeCache.get(key);
615
+ return !cached || !cached.config && !cached.promise;
616
+ });
617
+ const [saving, setSaving] = useState3(false);
618
+ const [disabling, setDisabling] = useState3(false);
619
+ const [error, setError] = useState3(null);
620
+ const requestSeq = useRef2(0);
621
+ const load = useCallback2(
622
+ async (force = false) => {
623
+ const seq = requestSeq.current;
624
+ const cached = autoRechargeCache.get(key);
625
+ const now = Date.now();
626
+ if (!force && cached?.config && now - cached.timestamp < CACHE_DURATION) {
627
+ if (seq !== requestSeq.current) return;
628
+ setConfig(cached.config);
629
+ setLoading(false);
630
+ setError(null);
631
+ return;
632
+ }
633
+ if (!force && cached?.promise) {
634
+ setLoading(true);
635
+ try {
636
+ const value = await cached.promise;
637
+ if (seq !== requestSeq.current) return;
638
+ setConfig(value);
639
+ setError(null);
640
+ } catch (caught) {
641
+ if (seq !== requestSeq.current) return;
642
+ setError(caught instanceof Error ? caught : new Error(String(caught)));
643
+ } finally {
644
+ if (seq === requestSeq.current) {
645
+ setLoading(false);
646
+ }
647
+ }
648
+ return;
649
+ }
650
+ setLoading(true);
651
+ setError(null);
652
+ const promise = fetchAutoRecharge(_config);
653
+ autoRechargeCache.set(key, {
654
+ config: cached?.config ?? null,
655
+ promise,
656
+ timestamp: now
657
+ });
658
+ try {
659
+ const value = await promise;
660
+ if (seq !== requestSeq.current) return;
661
+ autoRechargeCache.set(key, { config: value, promise: null, timestamp: Date.now() });
662
+ setConfig(value);
663
+ } catch (caught) {
664
+ if (seq !== requestSeq.current) return;
665
+ const err = caught instanceof Error ? caught : new Error(String(caught));
666
+ autoRechargeCache.set(key, { config: null, promise: null, timestamp: Date.now() });
667
+ setError(err);
668
+ } finally {
669
+ if (seq === requestSeq.current) {
670
+ setLoading(false);
671
+ }
672
+ }
673
+ },
674
+ [_config, key]
675
+ );
676
+ useEffect3(() => {
677
+ void load();
678
+ }, [load]);
679
+ const refresh = useCallback2(
680
+ async (force = true) => {
681
+ await load(force);
682
+ },
683
+ [load]
684
+ );
685
+ const save = useCallback2(
686
+ async (input) => {
687
+ const transport = _config?.transport ?? createHttpTransport(_config);
688
+ if (!transport.saveAutoRecharge) {
689
+ throw new Error("saveAutoRecharge is not available on this transport");
690
+ }
691
+ setSaving(true);
692
+ setError(null);
693
+ const seq = ++requestSeq.current;
694
+ try {
695
+ const result = await transport.saveAutoRecharge(input);
696
+ if (seq !== requestSeq.current) return result;
697
+ const nextConfig = mergeAutoRechargeConfig(result.config, result.display);
698
+ autoRechargeCache.set(key, {
699
+ config: nextConfig,
700
+ promise: null,
701
+ timestamp: Date.now()
702
+ });
703
+ setConfig(nextConfig);
704
+ return result;
705
+ } catch (caught) {
706
+ const err = caught instanceof Error ? caught : new Error(String(caught));
707
+ setError(err);
708
+ throw err;
709
+ } finally {
710
+ setSaving(false);
711
+ }
712
+ },
713
+ [_config, key]
714
+ );
715
+ const disable = useCallback2(async () => {
716
+ const transport = _config?.transport ?? createHttpTransport(_config);
717
+ if (!transport.disableAutoRecharge) {
718
+ throw new Error("disableAutoRecharge is not available on this transport");
719
+ }
720
+ setDisabling(true);
721
+ setError(null);
722
+ const seq = ++requestSeq.current;
723
+ try {
724
+ const result = await transport.disableAutoRecharge();
725
+ if (seq === requestSeq.current) {
726
+ setConfig((current) => {
727
+ const disabledConfig = current ? { ...current, enabled: false } : null;
728
+ autoRechargeCache.set(key, {
729
+ config: disabledConfig,
730
+ promise: null,
731
+ timestamp: Date.now()
732
+ });
733
+ return disabledConfig;
734
+ });
735
+ await refresh(true);
736
+ setConfig((current) => {
737
+ const disabledConfig = current ? { ...current, enabled: false } : null;
738
+ autoRechargeCache.set(key, {
739
+ config: disabledConfig,
740
+ promise: null,
741
+ timestamp: Date.now()
742
+ });
743
+ return disabledConfig;
744
+ });
745
+ }
746
+ return result;
747
+ } catch (caught) {
748
+ const err = caught instanceof Error ? caught : new Error(String(caught));
749
+ setError(err);
750
+ throw err;
751
+ } finally {
752
+ setDisabling(false);
753
+ }
754
+ }, [_config, key, refresh]);
755
+ return { config, loading, saving, disabling, error, refresh, save, disable };
756
+ }
757
+
758
+ // src/utils/credit-estimation.ts
759
+ import { creditsToDisplayMinorUnits } from "@solvapay/core";
760
+ function estimateCredits(resolvedAmountMajor, currency, creditsPerMinorUnit, displayExchangeRate) {
761
+ if (resolvedAmountMajor == null || resolvedAmountMajor <= 0) return null;
762
+ if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
763
+ const rate = displayExchangeRate ?? 1;
764
+ const resolvedAmountMinor = Math.round(resolvedAmountMajor * getMinorUnitsPerMajor(currency));
765
+ return Math.round(resolvedAmountMinor / rate * creditsPerMinorUnit);
766
+ }
767
+ function estimateCurrencyMajorFromCredits(credits, currency, creditsPerMinorUnit, displayExchangeRate) {
768
+ if (credits == null || credits <= 0) return null;
769
+ if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
770
+ const rate = displayExchangeRate ?? 1;
771
+ const displayMinor = creditsToDisplayMinorUnits({
772
+ credits,
773
+ creditsPerMinorUnit,
774
+ displayExchangeRate: rate,
775
+ displayCurrency: currency
776
+ });
777
+ if (displayMinor === null) return null;
778
+ return displayMinor / getMinorUnitsPerMajor(currency);
779
+ }
780
+
781
+ // src/helpers/stripe-minimums.ts
782
+ var STRIPE_MINIMUM_MINOR = {
783
+ USD: 50,
784
+ EUR: 50,
785
+ GBP: 30,
786
+ SEK: 300,
787
+ NOK: 300,
788
+ DKK: 250,
789
+ CHF: 50,
790
+ CAD: 50,
791
+ AUD: 50,
792
+ JPY: 50,
793
+ KRW: 500
794
+ };
795
+ var DEFAULT_MINIMUM_MINOR = 50;
796
+ function getStripeMinimumMinor(currency) {
797
+ return STRIPE_MINIMUM_MINOR[currency.toUpperCase()] ?? DEFAULT_MINIMUM_MINOR;
798
+ }
799
+
800
+ // src/helpers/auto-recharge-form.ts
801
+ var DEFAULT_VALIDATION_MESSAGES = {
802
+ invalidThreshold: "Enter a valid balance threshold.",
803
+ thresholdTooLow: "Balance threshold must be greater than zero.",
804
+ minTopupAmount: "Top-up amount must be at least {amount}.",
805
+ topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount})."
806
+ };
807
+ function amountAnchors(thresholdValue, topupValue, unit = "currency") {
808
+ return {
809
+ thresholdBaseValue: thresholdValue,
810
+ thresholdBaseUnit: unit,
811
+ topupBaseValue: topupValue,
812
+ topupBaseUnit: unit
813
+ };
814
+ }
815
+ function createDefaultAutoRechargeForm(currency, defaultTopupMajor, defaultThresholdMajor) {
816
+ const topup = defaultTopupMajor != null && defaultTopupMajor > 0 ? String(defaultTopupMajor) : "10";
817
+ const threshold = defaultThresholdMajor != null && defaultThresholdMajor >= 0 ? String(defaultThresholdMajor) : "5";
818
+ return {
819
+ enabled: false,
820
+ thresholdAmountMajor: threshold,
821
+ thresholdUnit: "currency",
822
+ topupAmountMajor: topup,
823
+ topupUnit: "currency",
824
+ ...amountAnchors(threshold, topup, "currency")
825
+ };
826
+ }
827
+ function parsePositiveNumber(value) {
828
+ const trimmed = value.trim();
829
+ if (trimmed.length === 0) return null;
830
+ const parsed = Number(trimmed);
831
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
832
+ return parsed;
833
+ }
834
+ function parseNonNegativeNumber(value) {
835
+ const trimmed = value.trim();
836
+ if (trimmed.length === 0) return null;
837
+ const parsed = Number(trimmed);
838
+ if (!Number.isFinite(parsed) || parsed < 0) return null;
839
+ return parsed;
840
+ }
841
+ function validateAutoRechargeForm(form, currency, conversion, messages = DEFAULT_VALIDATION_MESSAGES) {
842
+ if (!form.enabled) {
843
+ return {
844
+ ok: true,
845
+ payload: {
846
+ enabled: false,
847
+ triggerType: "balance",
848
+ currency: currency.toUpperCase()
849
+ }
850
+ };
851
+ }
852
+ const payload = {
853
+ enabled: true,
854
+ triggerType: "balance",
855
+ currency: currency.toUpperCase()
856
+ };
857
+ const minorPerMajor = getMinorUnitsPerMajor(currency);
858
+ const minMinor = getStripeMinimumMinor(currency);
859
+ const thresholdRaw = parseNonNegativeNumber(form.thresholdAmountMajor);
860
+ if (thresholdRaw == null) {
861
+ return { ok: false, error: messages.invalidThreshold };
862
+ }
863
+ if (form.thresholdUnit === "credits") {
864
+ const major = estimateCurrencyMajorFromCredits(
865
+ thresholdRaw,
866
+ currency,
867
+ conversion?.creditsPerMinorUnit,
868
+ conversion?.displayExchangeRate
869
+ );
870
+ if (major == null) {
871
+ return { ok: false, error: messages.invalidThreshold };
872
+ }
873
+ payload.thresholdAmountMajor = major;
874
+ } else {
875
+ payload.thresholdAmountMajor = thresholdRaw;
876
+ }
877
+ if (payload.thresholdAmountMajor == null || payload.thresholdAmountMajor <= 0) {
878
+ return { ok: false, error: messages.thresholdTooLow };
879
+ }
880
+ const amountRaw = parsePositiveNumber(form.topupAmountMajor);
881
+ if (amountRaw == null) {
882
+ return {
883
+ ok: false,
884
+ error: interpolate(messages.minTopupAmount, {
885
+ amount: formatPrice(minMinor, currency, { free: "" })
886
+ })
887
+ };
888
+ }
889
+ const amountMajor = form.topupUnit === "credits" ? estimateCurrencyMajorFromCredits(
890
+ amountRaw,
891
+ currency,
892
+ conversion?.creditsPerMinorUnit,
893
+ conversion?.displayExchangeRate
894
+ ) : amountRaw;
895
+ if (amountMajor == null || Math.round(amountMajor * minorPerMajor) < minMinor) {
896
+ return {
897
+ ok: false,
898
+ error: interpolate(messages.minTopupAmount, {
899
+ amount: formatPrice(minMinor, currency, { free: "" })
900
+ })
901
+ };
902
+ }
903
+ payload.topupAmountMajor = amountMajor;
904
+ if (amountMajor < payload.thresholdAmountMajor) {
905
+ return {
906
+ ok: false,
907
+ error: interpolate(messages.topupBelowThreshold, {
908
+ amount: formatPrice(
909
+ Math.round(payload.thresholdAmountMajor * minorPerMajor),
910
+ currency,
911
+ { free: "" }
912
+ )
913
+ })
914
+ };
915
+ }
916
+ return { ok: true, payload };
917
+ }
918
+ function triggerAmountMajorFromConfig(config) {
919
+ const topupCurrency = config.topup.currency.toUpperCase();
920
+ const minorPerMajor = getMinorUnitsPerMajor(topupCurrency);
921
+ const { thresholdAmountMinor } = config.trigger;
922
+ if (!Number.isFinite(thresholdAmountMinor) || thresholdAmountMinor < 0) {
923
+ return null;
924
+ }
925
+ return thresholdAmountMinor / minorPerMajor;
926
+ }
927
+ function configToAutoRechargeInput(config, options) {
928
+ if (!config.enabled) return null;
929
+ const display = options?.display ?? config.display;
930
+ const currency = (display?.currency ?? config.topup.currency ?? options?.currency ?? "USD").toUpperCase();
931
+ if (display?.thresholdAmountMajor != null && display.topupAmountMajor != null) {
932
+ return {
933
+ enabled: true,
934
+ triggerType: "balance",
935
+ thresholdAmountMajor: display.thresholdAmountMajor,
936
+ topupAmountMajor: display.topupAmountMajor,
937
+ currency
938
+ };
939
+ }
940
+ const thresholdMajor = triggerAmountMajorFromConfig(config);
941
+ const topupAmountMajor = config.topup.amountMinor / getMinorUnitsPerMajor(currency);
942
+ if (thresholdMajor == null || !Number.isFinite(topupAmountMajor) || topupAmountMajor <= 0) {
943
+ return null;
944
+ }
945
+ return {
946
+ enabled: true,
947
+ triggerType: "balance",
948
+ thresholdAmountMajor: Math.max(0, thresholdMajor),
949
+ topupAmountMajor,
950
+ currency
951
+ };
952
+ }
953
+ function configToForm(config, currency) {
954
+ const base = createDefaultAutoRechargeForm(currency);
955
+ const display = config.display;
956
+ if (display?.thresholdAmountMajor != null && display.topupAmountMajor != null) {
957
+ const thresholdStr2 = String(Math.max(0, display.thresholdAmountMajor));
958
+ const topupStr2 = String(display.topupAmountMajor);
959
+ return {
960
+ ...base,
961
+ enabled: config.enabled,
962
+ thresholdAmountMajor: thresholdStr2,
963
+ topupAmountMajor: topupStr2,
964
+ ...amountAnchors(thresholdStr2, topupStr2, "currency")
965
+ };
966
+ }
967
+ const thresholdMajor = triggerAmountMajorFromConfig(config);
968
+ const thresholdStr = thresholdMajor != null ? String(Math.max(0, thresholdMajor)) : "0";
969
+ const topupStr = String(config.topup.amountMinor / getMinorUnitsPerMajor(currency));
970
+ return {
971
+ ...base,
972
+ enabled: config.enabled,
973
+ thresholdAmountMajor: thresholdStr,
974
+ topupAmountMajor: topupStr,
975
+ ...amountAnchors(thresholdStr, topupStr, "currency")
976
+ };
977
+ }
978
+ function formatAmountWithUnit(value, unit, currency) {
979
+ const num = Number(value);
980
+ if (!value || !Number.isFinite(num)) return "\u2014";
981
+ if (unit === "credits") {
982
+ return `${new Intl.NumberFormat().format(num)} credits`;
983
+ }
984
+ return formatPrice(Math.round(num * getMinorUnitsPerMajor(currency)), currency, { free: "" });
985
+ }
986
+ function buildSummaryLine(form, currency) {
987
+ if (!form.enabled) return null;
988
+ const thresholdDisplay = formatAmountWithUnit(
989
+ form.thresholdAmountMajor,
990
+ form.thresholdUnit,
991
+ currency
992
+ );
993
+ const fixedDisplay = formatAmountWithUnit(form.topupAmountMajor, form.topupUnit, currency);
994
+ return `When my balance falls below ${thresholdDisplay}, add ${fixedDisplay}.`;
995
+ }
996
+ function convertAmountForUnitFlip(value, fromUnit, toUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
997
+ if (fromUnit === toUnit) return value;
998
+ const parsed = Number(value);
999
+ if (!Number.isFinite(parsed) || parsed <= 0) return value;
1000
+ if (fromUnit === "currency" && toUnit === "credits") {
1001
+ const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
1002
+ return credits != null ? String(credits) : value;
1003
+ }
1004
+ const major = estimateCurrencyMajorFromCredits(
1005
+ parsed,
1006
+ currency,
1007
+ creditsPerMinorUnit,
1008
+ displayExchangeRate
1009
+ );
1010
+ return major != null ? String(major) : value;
1011
+ }
1012
+ function flipUnitValue(anchor, targetUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
1013
+ if (targetUnit === anchor.unit) {
1014
+ return { value: anchor.value, unit: anchor.unit };
1015
+ }
1016
+ const converted = convertAmountForUnitFlip(
1017
+ anchor.value,
1018
+ anchor.unit,
1019
+ targetUnit,
1020
+ currency,
1021
+ creditsPerMinorUnit,
1022
+ displayExchangeRate
1023
+ );
1024
+ return { value: converted, unit: targetUnit };
1025
+ }
1026
+
1027
+ // src/primitives/AutoRecharge.tsx
1028
+ import {
1029
+ createContext as createContext4,
1030
+ forwardRef as forwardRef5,
1031
+ useCallback as useCallback3,
1032
+ useContext as useContext5,
1033
+ useEffect as useEffect4,
1034
+ useId,
1035
+ useMemo as useMemo4,
1036
+ useRef as useRef3,
1037
+ useState as useState4
1038
+ } from "react";
1039
+ import { createPortal } from "react-dom";
1040
+ import {
1041
+ Elements,
1042
+ PaymentElement as StripePaymentElement,
1043
+ useElements,
1044
+ useStripe
1045
+ } from "@stripe/react-stripe-js";
1046
+ import { loadStripe } from "@stripe/stripe-js";
1047
+
1048
+ // src/primitives/autoRechargeActivation.ts
1049
+ var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1050
+ async function waitForAutoRechargeActivation({
1051
+ refresh,
1052
+ getStatus,
1053
+ attempts = 5,
1054
+ delayMs = 800,
1055
+ sleep = defaultSleep
1056
+ }) {
1057
+ for (let attempt = 0; attempt < attempts; attempt++) {
1058
+ await refresh(true);
1059
+ if (getStatus() === "active") return true;
1060
+ if (attempt < attempts - 1) await sleep(delayMs);
1061
+ }
1062
+ return getStatus() === "active";
1063
+ }
1064
+
1065
+ // src/primitives/setupIntentReturn.ts
1066
+ var SETUP_INTENT_PARAMS = ["setup_intent", "setup_intent_client_secret", "redirect_status"];
1067
+ function readSetupIntentClientSecret(search) {
1068
+ return new URLSearchParams(search).get("setup_intent_client_secret");
1069
+ }
1070
+ function stripSetupIntentParams() {
1071
+ if (typeof window === "undefined") return;
1072
+ const url = new URL(window.location.href);
1073
+ let changed = false;
1074
+ for (const param of SETUP_INTENT_PARAMS) {
1075
+ if (url.searchParams.has(param)) {
1076
+ url.searchParams.delete(param);
1077
+ changed = true;
1078
+ }
1079
+ }
1080
+ if (!changed) return;
1081
+ const query = url.searchParams.toString();
1082
+ window.history.replaceState({}, "", `${url.pathname}${query ? `?${query}` : ""}${url.hash}`);
1083
+ }
1084
+
1085
+ // src/primitives/AutoRecharge.tsx
1086
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
1087
+ var AutoRechargeContext = createContext4(null);
1088
+ function useAutoRechargeCtx(part) {
1089
+ const ctx = useContext5(AutoRechargeContext);
1090
+ if (!ctx) {
1091
+ throw new Error(`AutoRecharge.${part} must be rendered inside <AutoRecharge.Root>.`);
1092
+ }
1093
+ return ctx;
1094
+ }
1095
+ function getCurrencySymbol(currency) {
1096
+ try {
1097
+ const parts = new Intl.NumberFormat("en", { style: "currency", currency }).formatToParts(0);
1098
+ const sym = parts.find((p) => p.type === "currency");
1099
+ return sym?.value ?? currency.toUpperCase();
1100
+ } catch {
1101
+ return currency.toUpperCase();
1102
+ }
1103
+ }
1104
+ var stripePromiseCache = /* @__PURE__ */ new Map();
1105
+ function getStripeCacheKey(publishableKey, accountId) {
1106
+ return accountId ? `${publishableKey}:${accountId}` : publishableKey;
1107
+ }
1108
+ var Root4 = forwardRef5(function AutoRechargeRoot({
1109
+ currency = "USD",
1110
+ defaultThresholdAmountMajor,
1111
+ defaultTopupAmountMajor,
1112
+ open: openProp,
1113
+ defaultOpen = false,
1114
+ onOpenChange,
1115
+ onSetupRequired,
1116
+ onSaved,
1117
+ onDisabled,
1118
+ deferCardSetup = false,
1119
+ onPendingConfig,
1120
+ asChild,
1121
+ children,
1122
+ className,
1123
+ ...rest
1124
+ }, forwardedRef) {
1125
+ const solva = useContext5(SolvaPayContext);
1126
+ if (!solva) throw new MissingProviderError("AutoRecharge");
1127
+ const autoRecharge = useAutoRecharge();
1128
+ const { creditsPerMinorUnit, displayExchangeRate } = useBalance();
1129
+ const copy = useCopy();
1130
+ const titleId = useId();
1131
+ const triggerRef = useRef3(null);
1132
+ const defaultTopup = defaultTopupAmountMajor ?? defaultThresholdAmountMajor ?? void 0;
1133
+ const [uncontrolledOpen, setUncontrolledOpen] = useState4(defaultOpen);
1134
+ const isControlled = openProp !== void 0;
1135
+ const open = isControlled ? openProp : uncontrolledOpen;
1136
+ const setOpen = useCallback3(
1137
+ (next) => {
1138
+ if (!isControlled) {
1139
+ setUncontrolledOpen(next);
1140
+ }
1141
+ onOpenChange?.(next);
1142
+ },
1143
+ [isControlled, onOpenChange]
1144
+ );
1145
+ const registerTriggerRef = useCallback3((node) => {
1146
+ triggerRef.current = node;
1147
+ }, []);
1148
+ const focusTrigger = useCallback3(() => {
1149
+ triggerRef.current?.focus();
1150
+ }, []);
1151
+ const [form, setForm] = useState4(
1152
+ () => autoRecharge.config ? configToForm(autoRecharge.config, currency) : createDefaultAutoRechargeForm(currency, defaultTopup)
1153
+ );
1154
+ const [validationError, setValidationError] = useState4(null);
1155
+ const [statusMessage, setStatusMessage] = useState4(null);
1156
+ const [setup, setSetup] = useState4(null);
1157
+ const latestConfigRef = useRef3(autoRecharge.config);
1158
+ useEffect4(() => {
1159
+ latestConfigRef.current = autoRecharge.config;
1160
+ }, [autoRecharge.config]);
1161
+ useEffect4(() => {
1162
+ if (autoRecharge.config) {
1163
+ setForm(configToForm(autoRecharge.config, currency));
1164
+ }
1165
+ }, [autoRecharge.config, currency]);
1166
+ const canToggleUnits = creditsPerMinorUnit != null && creditsPerMinorUnit > 0;
1167
+ const rate = displayExchangeRate ?? 1;
1168
+ const isApproximate = rate !== 1;
1169
+ const emitValidation = useCallback3(
1170
+ (next) => {
1171
+ const result = validateAutoRechargeForm(
1172
+ next,
1173
+ currency,
1174
+ { creditsPerMinorUnit, displayExchangeRate },
1175
+ copy.autoRecharge
1176
+ );
1177
+ if (!result.ok) {
1178
+ setValidationError(result.error);
1179
+ return null;
1180
+ }
1181
+ setValidationError(null);
1182
+ return result.payload;
1183
+ },
1184
+ [currency, creditsPerMinorUnit, displayExchangeRate, copy.autoRecharge]
1185
+ );
1186
+ const updateForm = useCallback3(
1187
+ (patch) => {
1188
+ setForm((prev) => {
1189
+ const next = { ...prev, ...patch };
1190
+ emitValidation(next);
1191
+ return next;
1192
+ });
1193
+ },
1194
+ [emitValidation]
1195
+ );
1196
+ const resetForm = useCallback3(() => {
1197
+ if (autoRecharge.config) {
1198
+ setForm(configToForm(autoRecharge.config, currency));
1199
+ } else {
1200
+ setForm(createDefaultAutoRechargeForm(currency, defaultTopup));
1201
+ }
1202
+ setValidationError(null);
1203
+ }, [autoRecharge.config, currency, defaultTopup]);
1204
+ const flipUnit = useCallback3(
1205
+ (valueKey, unitKey, baseValueKey, baseUnitKey, currentUnit) => {
1206
+ const nextUnit = currentUnit === "currency" ? "credits" : "currency";
1207
+ setForm((prev) => {
1208
+ const anchor = { value: prev[baseValueKey], unit: prev[baseUnitKey] };
1209
+ const flipped = flipUnitValue(
1210
+ anchor,
1211
+ nextUnit,
1212
+ currency,
1213
+ creditsPerMinorUnit,
1214
+ displayExchangeRate
1215
+ );
1216
+ const next = {
1217
+ ...prev,
1218
+ [unitKey]: flipped.unit,
1219
+ [valueKey]: flipped.value
1220
+ };
1221
+ emitValidation(next);
1222
+ return next;
1223
+ });
1224
+ },
1225
+ [currency, creditsPerMinorUnit, displayExchangeRate, emitValidation]
1226
+ );
1227
+ const fixedTopupHint = useMemo4(() => {
1228
+ const parsed = Number(form.topupAmountMajor);
1229
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
1230
+ if (form.topupUnit === "currency") {
1231
+ const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
1232
+ if (credits == null) return null;
1233
+ return { credits, approximate: isApproximate };
1234
+ }
1235
+ const major = estimateCurrencyMajorFromCredits(
1236
+ parsed,
1237
+ currency,
1238
+ creditsPerMinorUnit,
1239
+ displayExchangeRate
1240
+ );
1241
+ if (major == null) return null;
1242
+ return { major, approximate: isApproximate };
1243
+ }, [
1244
+ form.topupAmountMajor,
1245
+ form.topupUnit,
1246
+ currency,
1247
+ creditsPerMinorUnit,
1248
+ displayExchangeRate,
1249
+ isApproximate
1250
+ ]);
1251
+ const summaryLine = useMemo4(() => buildSummaryLine(form, currency), [form, currency]);
1252
+ const savedSummaryLine = useMemo4(() => {
1253
+ if (!autoRecharge.config?.enabled) return null;
1254
+ return buildSummaryLine(
1255
+ configToForm(autoRecharge.config, currency),
1256
+ currency
1257
+ );
1258
+ }, [autoRecharge.config, currency]);
1259
+ const save = useCallback3(async () => {
1260
+ const payload = emitValidation(form);
1261
+ if (!payload) return;
1262
+ const saveInput = deferCardSetup ? { ...payload, deferSetupIntent: true } : payload;
1263
+ const result = await autoRecharge.save(saveInput);
1264
+ if (result.setupClientSecret) {
1265
+ setSetup(result);
1266
+ setStatusMessage(copy.autoRecharge.setupRequiredMessage);
1267
+ await onSetupRequired?.(result);
1268
+ return;
1269
+ }
1270
+ setSetup(null);
1271
+ if (deferCardSetup) {
1272
+ await onPendingConfig?.(payload);
1273
+ }
1274
+ setStatusMessage(
1275
+ payload.enabled ? copy.autoRecharge.savedMessage : copy.autoRecharge.disabledMessage
1276
+ );
1277
+ setOpen(false);
1278
+ await onSaved?.(result);
1279
+ }, [
1280
+ autoRecharge,
1281
+ copy.autoRecharge,
1282
+ deferCardSetup,
1283
+ emitValidation,
1284
+ form,
1285
+ onPendingConfig,
1286
+ onSaved,
1287
+ onSetupRequired,
1288
+ setOpen
1289
+ ]);
1290
+ const disable = useCallback3(async () => {
1291
+ await autoRecharge.disable();
1292
+ setStatusMessage(copy.autoRecharge.disabledMessage);
1293
+ setSetup(null);
1294
+ await onDisabled?.();
1295
+ }, [autoRecharge, copy.autoRecharge, onDisabled]);
1296
+ const completeSetup = useCallback3(async () => {
1297
+ const activated = await waitForAutoRechargeActivation({
1298
+ refresh: autoRecharge.refresh,
1299
+ getStatus: () => latestConfigRef.current?.status
1300
+ });
1301
+ setSetup(null);
1302
+ if (!form.enabled) return;
1303
+ if (activated) {
1304
+ setStatusMessage(copy.autoRecharge.savedMessage);
1305
+ setOpen(false);
1306
+ } else {
1307
+ setStatusMessage(copy.autoRecharge.setupAwaitingConfirmation);
1308
+ }
1309
+ }, [autoRecharge, copy.autoRecharge, form.enabled, setOpen]);
1310
+ const dataState = setup ? "setup" : autoRecharge.error ? "error" : autoRecharge.loading ? "loading" : autoRecharge.saving ? "saving" : autoRecharge.disabling ? "disabling" : "idle";
1311
+ const ctx = useMemo4(
1312
+ () => ({
1313
+ form,
1314
+ updateForm,
1315
+ resetForm,
1316
+ validationError,
1317
+ currency,
1318
+ config: autoRecharge.config,
1319
+ loading: autoRecharge.loading,
1320
+ saving: autoRecharge.saving,
1321
+ disabling: autoRecharge.disabling,
1322
+ error: autoRecharge.error,
1323
+ statusMessage,
1324
+ setup,
1325
+ dataState,
1326
+ creditsPerMinorUnit,
1327
+ displayExchangeRate,
1328
+ canToggleUnits,
1329
+ isApproximate,
1330
+ summaryLine,
1331
+ savedSummaryLine,
1332
+ deferCardSetup,
1333
+ fixedTopupHint: fixedTopupHint && "credits" in fixedTopupHint ? String(fixedTopupHint.credits) : fixedTopupHint && "major" in fixedTopupHint ? formatPrice(
1334
+ Math.round(fixedTopupHint.major * getMinorUnitsPerMajor(currency)),
1335
+ currency,
1336
+ { free: "" }
1337
+ ) : null,
1338
+ open,
1339
+ setOpen,
1340
+ titleId,
1341
+ registerTriggerRef,
1342
+ focusTrigger,
1343
+ save,
1344
+ disable,
1345
+ completeSetup,
1346
+ flipUnit
1347
+ }),
1348
+ [
1349
+ form,
1350
+ updateForm,
1351
+ resetForm,
1352
+ validationError,
1353
+ currency,
1354
+ autoRecharge.config,
1355
+ autoRecharge.loading,
1356
+ autoRecharge.saving,
1357
+ autoRecharge.disabling,
1358
+ autoRecharge.error,
1359
+ statusMessage,
1360
+ setup,
1361
+ dataState,
1362
+ creditsPerMinorUnit,
1363
+ displayExchangeRate,
1364
+ canToggleUnits,
1365
+ isApproximate,
1366
+ summaryLine,
1367
+ savedSummaryLine,
1368
+ deferCardSetup,
1369
+ fixedTopupHint,
1370
+ open,
1371
+ setOpen,
1372
+ titleId,
1373
+ registerTriggerRef,
1374
+ focusTrigger,
1375
+ save,
1376
+ disable,
1377
+ completeSetup,
1378
+ flipUnit
1379
+ ]
1380
+ );
1381
+ const Comp = asChild ? Slot : "section";
1382
+ return /* @__PURE__ */ jsx6(AutoRechargeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx6(
1383
+ Comp,
1384
+ {
1385
+ ref: forwardedRef,
1386
+ className,
1387
+ "aria-label": "Automatic credit top-up",
1388
+ "data-solvapay-auto-recharge": "",
1389
+ "data-state": dataState,
1390
+ ...rest,
1391
+ children
1392
+ }
1393
+ ) });
1394
+ });
1395
+ var Loading4 = forwardRef5(
1396
+ function AutoRechargeLoading({ className, children, ...rest }, forwardedRef) {
1397
+ const ctx = useAutoRechargeCtx("Loading");
1398
+ if (!ctx.loading) return null;
1399
+ return /* @__PURE__ */ jsx6("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-loading": "", ...rest, children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1400
+ /* @__PURE__ */ jsx6(Spinner, { size: "sm" }),
1401
+ " Loading auto-recharge settings\u2026"
1402
+ ] }) });
1403
+ }
1404
+ );
1405
+ var Card = forwardRef5(function AutoRechargeCard({ className, children, ...rest }, forwardedRef) {
1406
+ return /* @__PURE__ */ jsx6(
1407
+ "section",
1408
+ {
1409
+ ref: forwardedRef,
1410
+ className,
1411
+ "data-solvapay-auto-recharge-card": "",
1412
+ ...rest,
1413
+ children
1414
+ }
1415
+ );
1416
+ });
1417
+ var CardHeading = forwardRef5(
1418
+ function AutoRechargeCardHeading({ className, children, ...rest }, forwardedRef) {
1419
+ const copy = useCopy();
1420
+ return /* @__PURE__ */ jsx6(
1421
+ "h3",
1422
+ {
1423
+ ref: forwardedRef,
1424
+ className,
1425
+ "data-solvapay-auto-recharge-card-heading": "",
1426
+ ...rest,
1427
+ children: children ?? copy.autoRecharge.heading
1428
+ }
1429
+ );
1430
+ }
1431
+ );
1432
+ var CardSummary = forwardRef5(
1433
+ function AutoRechargeCardSummary({ className, children, ...rest }, forwardedRef) {
1434
+ const ctx = useAutoRechargeCtx("CardSummary");
1435
+ const copy = useCopy();
1436
+ const text = ctx.savedSummaryLine ?? copy.autoRecharge.notConfiguredHint;
1437
+ return /* @__PURE__ */ jsx6(
1438
+ "p",
1439
+ {
1440
+ ref: forwardedRef,
1441
+ className,
1442
+ "data-solvapay-auto-recharge-card-summary": "",
1443
+ ...rest,
1444
+ children: children ?? text
1445
+ }
1446
+ );
1447
+ }
1448
+ );
1449
+ var Trigger = forwardRef5(function AutoRechargeTrigger({ asChild, onClick, children, className, ...rest }, forwardedRef) {
1450
+ const ctx = useAutoRechargeCtx("Trigger");
1451
+ const copy = useCopy();
1452
+ const hasExistingConfig = Boolean(ctx.config?.enabled);
1453
+ const label = hasExistingConfig ? copy.autoRecharge.modifyTriggerLabel : copy.autoRecharge.setupTriggerLabel;
1454
+ const setRefs = (node) => {
1455
+ ctx.registerTriggerRef(node);
1456
+ if (typeof forwardedRef === "function") {
1457
+ forwardedRef(node);
1458
+ } else if (forwardedRef) {
1459
+ forwardedRef.current = node;
1460
+ }
1461
+ };
1462
+ const commonProps = {
1463
+ "data-solvapay-auto-recharge-trigger": "",
1464
+ type: "button",
1465
+ "aria-haspopup": "dialog",
1466
+ "aria-expanded": ctx.open,
1467
+ disabled: ctx.loading,
1468
+ onClick: composeEventHandlers(onClick, (event) => {
1469
+ event.preventDefault();
1470
+ ctx.resetForm();
1471
+ ctx.setOpen(true);
1472
+ }),
1473
+ className,
1474
+ ...rest
1475
+ };
1476
+ if (asChild) {
1477
+ return /* @__PURE__ */ jsx6(Slot, { ref: setRefs, ...commonProps, children: children ?? label });
1478
+ }
1479
+ return /* @__PURE__ */ jsx6("button", { ref: setRefs, ...commonProps, children: children ?? label });
1480
+ });
1481
+ var Overlay = forwardRef5(
1482
+ function AutoRechargeOverlay({ onClick, className, ...rest }, forwardedRef) {
1483
+ const ctx = useAutoRechargeCtx("Overlay");
1484
+ return /* @__PURE__ */ jsx6(
1485
+ "div",
1486
+ {
1487
+ ref: forwardedRef,
1488
+ className,
1489
+ "data-solvapay-auto-recharge-overlay": "",
1490
+ "aria-hidden": "true",
1491
+ onClick: composeEventHandlers(onClick, () => {
1492
+ ctx.resetForm();
1493
+ ctx.setOpen(false);
1494
+ ctx.focusTrigger();
1495
+ }),
1496
+ ...rest
1497
+ }
1498
+ );
1499
+ }
1500
+ );
1501
+ var Content = forwardRef5(function AutoRechargeContent({ className, children, ...rest }, forwardedRef) {
1502
+ const ctx = useAutoRechargeCtx("Content");
1503
+ const panelRef = useRef3(null);
1504
+ useEffect4(() => {
1505
+ if (!ctx.open) return;
1506
+ const handleKeyDown = (event) => {
1507
+ if (event.key === "Escape") {
1508
+ ctx.resetForm();
1509
+ ctx.setOpen(false);
1510
+ ctx.focusTrigger();
1511
+ }
1512
+ };
1513
+ document.addEventListener("keydown", handleKeyDown);
1514
+ const focusTarget = panelRef.current?.querySelector(
1515
+ 'button:not([disabled]), input:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'
1516
+ );
1517
+ focusTarget?.focus();
1518
+ return () => {
1519
+ document.removeEventListener("keydown", handleKeyDown);
1520
+ };
1521
+ }, [ctx.open, ctx.resetForm, ctx.setOpen, ctx.focusTrigger]);
1522
+ if (!ctx.open || typeof document === "undefined") return null;
1523
+ return createPortal(
1524
+ /* @__PURE__ */ jsxs2("div", { "data-solvapay-auto-recharge-portal": "", children: [
1525
+ /* @__PURE__ */ jsx6(Overlay, {}),
1526
+ /* @__PURE__ */ jsx6(
1527
+ "div",
1528
+ {
1529
+ ref: (node) => {
1530
+ panelRef.current = node;
1531
+ if (typeof forwardedRef === "function") {
1532
+ forwardedRef(node);
1533
+ } else if (forwardedRef) {
1534
+ forwardedRef.current = node;
1535
+ }
1536
+ },
1537
+ role: "dialog",
1538
+ "aria-modal": "true",
1539
+ "aria-labelledby": ctx.titleId,
1540
+ className,
1541
+ "data-solvapay-auto-recharge-content": "",
1542
+ ...rest,
1543
+ children
1544
+ }
1545
+ )
1546
+ ] }),
1547
+ document.body
1548
+ );
1549
+ });
1550
+ var Title = forwardRef5(
1551
+ function AutoRechargeTitle({ className, children, ...rest }, forwardedRef) {
1552
+ const ctx = useAutoRechargeCtx("Title");
1553
+ const copy = useCopy();
1554
+ return /* @__PURE__ */ jsx6(
1555
+ "h2",
1556
+ {
1557
+ ref: forwardedRef,
1558
+ id: ctx.titleId,
1559
+ className,
1560
+ "data-solvapay-auto-recharge-title": "",
1561
+ ...rest,
1562
+ children: children ?? copy.autoRecharge.settingsHeading
1563
+ }
1564
+ );
1565
+ }
1566
+ );
1567
+ var EnableQuestion = forwardRef5(
1568
+ function AutoRechargeEnableQuestion({ className, children, ...rest }, forwardedRef) {
1569
+ const copy = useCopy();
1570
+ return /* @__PURE__ */ jsx6("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-question": "", ...rest, children: children ?? copy.autoRecharge.enableQuestion });
1571
+ }
1572
+ );
1573
+ var EnableSentence = forwardRef5(
1574
+ function AutoRechargeEnableSentence({ className, children, ...rest }, forwardedRef) {
1575
+ const copy = useCopy();
1576
+ return /* @__PURE__ */ jsx6(
1577
+ "label",
1578
+ {
1579
+ ref: forwardedRef,
1580
+ className,
1581
+ "data-solvapay-auto-recharge-enable-sentence": "",
1582
+ ...rest,
1583
+ children: children ?? copy.autoRecharge.enableSentence
1584
+ }
1585
+ );
1586
+ }
1587
+ );
1588
+ var EnableRow = forwardRef5(
1589
+ function AutoRechargeEnableRow({ className, children, ...rest }, forwardedRef) {
1590
+ const enableId = useId();
1591
+ return /* @__PURE__ */ jsx6(
1592
+ "div",
1593
+ {
1594
+ ref: forwardedRef,
1595
+ className,
1596
+ "data-solvapay-auto-recharge-enable-row": "",
1597
+ ...rest,
1598
+ children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1599
+ /* @__PURE__ */ jsx6(EnableSwitch, { appearance: "checkbox", id: enableId }),
1600
+ /* @__PURE__ */ jsx6(EnableSentence, { htmlFor: enableId })
1601
+ ] })
1602
+ }
1603
+ );
1604
+ }
1605
+ );
1606
+ var CancelButton = forwardRef5(
1607
+ function AutoRechargeCancelButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
1608
+ const ctx = useAutoRechargeCtx("CancelButton");
1609
+ const copy = useCopy();
1610
+ const commonProps = {
1611
+ "data-solvapay-auto-recharge-cancel": "",
1612
+ type: "button",
1613
+ onClick: composeEventHandlers(onClick, (event) => {
1614
+ event.preventDefault();
1615
+ ctx.resetForm();
1616
+ ctx.setOpen(false);
1617
+ ctx.focusTrigger();
1618
+ }),
1619
+ className,
1620
+ ...rest
1621
+ };
1622
+ if (asChild) {
1623
+ return /* @__PURE__ */ jsx6(
1624
+ Slot,
1625
+ {
1626
+ ref: forwardedRef,
1627
+ ...commonProps,
1628
+ children: children ?? copy.autoRecharge.cancelButton
1629
+ }
1630
+ );
1631
+ }
1632
+ return /* @__PURE__ */ jsx6("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.cancelButton });
1633
+ }
1634
+ );
1635
+ var Header = forwardRef5(
1636
+ function AutoRechargeHeader({ className, ...rest }, forwardedRef) {
1637
+ const copy = useCopy();
1638
+ const headingId = useId();
1639
+ return /* @__PURE__ */ jsxs2(
1640
+ "header",
1641
+ {
1642
+ ref: forwardedRef,
1643
+ className,
1644
+ "data-solvapay-auto-recharge-header": "",
1645
+ ...rest,
1646
+ children: [
1647
+ /* @__PURE__ */ jsxs2("section", { "data-solvapay-auto-recharge-heading-group": "", children: [
1648
+ /* @__PURE__ */ jsx6("h3", { id: headingId, "data-solvapay-auto-recharge-heading": "", children: copy.autoRecharge.heading }),
1649
+ /* @__PURE__ */ jsx6(Description, {})
1650
+ ] }),
1651
+ /* @__PURE__ */ jsx6(EnableSwitch, { "aria-labelledby": headingId })
1652
+ ]
1653
+ }
1654
+ );
1655
+ }
1656
+ );
1657
+ var Description = forwardRef5(
1658
+ function AutoRechargeDescription({ className, children, ...rest }, forwardedRef) {
1659
+ const copy = useCopy();
1660
+ return /* @__PURE__ */ jsx6(
1661
+ "p",
1662
+ {
1663
+ ref: forwardedRef,
1664
+ className,
1665
+ "data-solvapay-auto-recharge-description": "",
1666
+ ...rest,
1667
+ children: children ?? copy.autoRecharge.description
1668
+ }
1669
+ );
1670
+ }
1671
+ );
1672
+ var EnableSwitch = forwardRef5(
1673
+ function AutoRechargeEnableSwitch({ asChild, appearance = "switch", onChange, className, ...rest }, forwardedRef) {
1674
+ const ctx = useAutoRechargeCtx("EnableSwitch");
1675
+ const copy = useCopy();
1676
+ const commonProps = {
1677
+ "data-solvapay-auto-recharge-enable": "",
1678
+ "data-appearance": appearance,
1679
+ type: "checkbox",
1680
+ ...appearance === "switch" ? { role: "switch", "aria-checked": ctx.form.enabled } : {},
1681
+ checked: ctx.form.enabled,
1682
+ "aria-label": copy.autoRecharge.enableLabel,
1683
+ disabled: ctx.loading || ctx.saving || ctx.disabling || !!ctx.setup,
1684
+ onChange: composeEventHandlers(onChange, (event) => {
1685
+ ctx.updateForm({ enabled: event.currentTarget.checked });
1686
+ }),
1687
+ className,
1688
+ ...rest
1689
+ };
1690
+ if (asChild) {
1691
+ return /* @__PURE__ */ jsx6(
1692
+ Slot,
1693
+ {
1694
+ ref: forwardedRef,
1695
+ ...commonProps
1696
+ }
1697
+ );
1698
+ }
1699
+ return /* @__PURE__ */ jsx6("input", { ref: forwardedRef, ...commonProps });
1700
+ }
1701
+ );
1702
+ var Fields = forwardRef5(
1703
+ function AutoRechargeFields({ className, children, ...rest }, forwardedRef) {
1704
+ const ctx = useAutoRechargeCtx("Fields");
1705
+ const copy = useCopy();
1706
+ if (!ctx.form.enabled) return null;
1707
+ return /* @__PURE__ */ jsxs2(
1708
+ "fieldset",
1709
+ {
1710
+ ref: forwardedRef,
1711
+ className,
1712
+ disabled: ctx.saving || ctx.disabling,
1713
+ "data-solvapay-auto-recharge-fields": "",
1714
+ "data-solvapay-auto-recharge-body": "",
1715
+ "data-state": "open",
1716
+ ...rest,
1717
+ children: [
1718
+ /* @__PURE__ */ jsx6("legend", { className: "sr-only", children: copy.autoRecharge.heading }),
1719
+ children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1720
+ /* @__PURE__ */ jsx6(Summary2, {}),
1721
+ /* @__PURE__ */ jsx6(ThresholdField, {}),
1722
+ /* @__PURE__ */ jsx6(TopupField, {}),
1723
+ /* @__PURE__ */ jsx6(ValidationError, {})
1724
+ ] })
1725
+ ]
1726
+ }
1727
+ );
1728
+ }
1729
+ );
1730
+ var Setup = forwardRef5(
1731
+ function AutoRechargeSetup({ className, children, ...rest }, forwardedRef) {
1732
+ const ctx = useAutoRechargeCtx("Setup");
1733
+ if (!ctx.setup?.setupClientSecret) return null;
1734
+ return /* @__PURE__ */ jsx6(
1735
+ "div",
1736
+ {
1737
+ ref: forwardedRef,
1738
+ className,
1739
+ "data-solvapay-auto-recharge-setup-panel": "",
1740
+ ...rest,
1741
+ children: children ?? /* @__PURE__ */ jsx6(CardSetup, { setup: ctx.setup, onComplete: ctx.completeSetup })
1742
+ }
1743
+ );
1744
+ }
1745
+ );
1746
+ var Body = forwardRef5(
1747
+ function AutoRechargeBody({ className, children, ...rest }, forwardedRef) {
1748
+ const ctx = useAutoRechargeCtx("Body");
1749
+ if (ctx.setup?.setupClientSecret) {
1750
+ return /* @__PURE__ */ jsx6(Setup, { className });
1751
+ }
1752
+ if (!ctx.form.enabled) return null;
1753
+ return /* @__PURE__ */ jsx6(Fields, { ref: forwardedRef, className, ...rest, children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1754
+ /* @__PURE__ */ jsx6(Summary2, {}),
1755
+ /* @__PURE__ */ jsx6(ThresholdField, {}),
1756
+ /* @__PURE__ */ jsx6(TopupField, {}),
1757
+ /* @__PURE__ */ jsx6(ValidationError, {}),
1758
+ /* @__PURE__ */ jsx6(Actions, {})
1759
+ ] }) });
1760
+ }
1761
+ );
1762
+ var Summary2 = forwardRef5(
1763
+ function AutoRechargeSummary({ className, children, ...rest }, forwardedRef) {
1764
+ const ctx = useAutoRechargeCtx("Summary");
1765
+ if (!ctx.summaryLine) return null;
1766
+ return /* @__PURE__ */ jsx6("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-summary": "", ...rest, children: children ?? ctx.summaryLine });
1767
+ }
1768
+ );
1769
+ var AmountField = forwardRef5(function AutoRechargeAmountField({ field, showLabel = true, asChild, onChange, className, ...rest }, forwardedRef) {
1770
+ const ctx = useAutoRechargeCtx("AmountField");
1771
+ const copy = useCopy();
1772
+ const fieldConfig = {
1773
+ threshold: {
1774
+ label: copy.autoRecharge.thresholdLabel,
1775
+ ariaLabel: copy.autoRecharge.thresholdAriaLabel,
1776
+ unitToggleLabel: "balance threshold",
1777
+ value: ctx.form.thresholdAmountMajor,
1778
+ unit: ctx.form.thresholdUnit,
1779
+ unitKey: "thresholdUnit",
1780
+ valueKey: "thresholdAmountMajor",
1781
+ baseValueKey: "thresholdBaseValue",
1782
+ baseUnitKey: "thresholdBaseUnit",
1783
+ mode: ctx.form.thresholdUnit === "currency" ? "currency" : "number",
1784
+ onValue: (value) => ctx.updateForm({
1785
+ thresholdAmountMajor: value,
1786
+ thresholdBaseValue: value,
1787
+ thresholdBaseUnit: ctx.form.thresholdUnit
1788
+ })
1789
+ },
1790
+ fixed: {
1791
+ label: copy.autoRecharge.fixedAmountLabel,
1792
+ ariaLabel: copy.autoRecharge.fixedAmountAriaLabel,
1793
+ unitToggleLabel: "fixed top-up amount",
1794
+ value: ctx.form.topupAmountMajor,
1795
+ unit: ctx.form.topupUnit,
1796
+ unitKey: "topupUnit",
1797
+ valueKey: "topupAmountMajor",
1798
+ baseValueKey: "topupBaseValue",
1799
+ baseUnitKey: "topupBaseUnit",
1800
+ mode: ctx.form.topupUnit === "currency" ? "currency" : "number",
1801
+ onValue: (value) => ctx.updateForm({
1802
+ topupAmountMajor: value,
1803
+ topupBaseValue: value,
1804
+ topupBaseUnit: ctx.form.topupUnit
1805
+ })
1806
+ }
1807
+ }[field];
1808
+ const inputId = useId();
1809
+ const prefix = fieldConfig.mode === "currency" ? getCurrencySymbol(ctx.currency) : void 0;
1810
+ const handleChange = (event) => {
1811
+ const raw = event.target.value;
1812
+ const next = fieldConfig.mode === "currency" ? raw.replace(/[^0-9.]/g, "") : raw.replace(/[^0-9]/g, "");
1813
+ fieldConfig.onValue(next);
1814
+ };
1815
+ const inputProps = {
1816
+ id: inputId,
1817
+ "data-solvapay-auto-recharge-amount": "",
1818
+ "data-field": field,
1819
+ type: "text",
1820
+ inputMode: fieldConfig.mode === "currency" ? "decimal" : "numeric",
1821
+ placeholder: fieldConfig.mode === "currency" ? "0.00" : "0",
1822
+ value: fieldConfig.value,
1823
+ "aria-label": fieldConfig.ariaLabel,
1824
+ onChange: composeEventHandlers(onChange, handleChange),
1825
+ className,
1826
+ ...rest
1827
+ };
1828
+ const slotRef = forwardedRef;
1829
+ return /* @__PURE__ */ jsxs2("p", { "data-solvapay-auto-recharge-field": "", "data-field": field, children: [
1830
+ showLabel ? /* @__PURE__ */ jsx6("label", { htmlFor: inputId, children: fieldConfig.label }) : null,
1831
+ /* @__PURE__ */ jsxs2("span", { "data-solvapay-auto-recharge-amount-row": "", children: [
1832
+ prefix ? /* @__PURE__ */ jsx6("span", { "data-solvapay-auto-recharge-currency-prefix": "", "aria-hidden": "true", children: prefix }) : null,
1833
+ asChild ? /* @__PURE__ */ jsx6(Slot, { ref: slotRef, ...inputProps }) : /* @__PURE__ */ jsx6("input", { ref: forwardedRef, ...inputProps }),
1834
+ ctx.canToggleUnits ? /* @__PURE__ */ jsx6(
1835
+ UnitToggle,
1836
+ {
1837
+ unit: fieldConfig.unit,
1838
+ fieldLabel: fieldConfig.unitToggleLabel,
1839
+ onToggle: () => ctx.flipUnit(
1840
+ fieldConfig.valueKey,
1841
+ fieldConfig.unitKey,
1842
+ fieldConfig.baseValueKey,
1843
+ fieldConfig.baseUnitKey,
1844
+ fieldConfig.unit
1845
+ )
1846
+ }
1847
+ ) : null
1848
+ ] })
1849
+ ] });
1850
+ });
1851
+ var ThresholdField = forwardRef5(
1852
+ function AutoRechargeThresholdField({ className, ...rest }, ref) {
1853
+ return /* @__PURE__ */ jsx6("section", { ref, className, ...rest, children: /* @__PURE__ */ jsx6(AmountField, { field: "threshold" }) });
1854
+ }
1855
+ );
1856
+ var TopupField = forwardRef5(
1857
+ function AutoRechargeTopupField({ className, ...rest }, ref) {
1858
+ return /* @__PURE__ */ jsxs2(
1859
+ "section",
1860
+ {
1861
+ ref,
1862
+ className,
1863
+ "data-solvapay-auto-recharge-topup-field": "",
1864
+ ...rest,
1865
+ children: [
1866
+ /* @__PURE__ */ jsx6(AmountField, { field: "fixed" }),
1867
+ /* @__PURE__ */ jsx6(Hint, {})
1868
+ ]
1869
+ }
1870
+ );
1871
+ }
1872
+ );
1873
+ var UnitToggle = forwardRef5(function AutoRechargeUnitToggle({ unit, fieldLabel, onToggle, className, ...rest }, forwardedRef) {
1874
+ const ctx = useAutoRechargeCtx("UnitToggle");
1875
+ const targetUnitLabel = unit === "currency" ? "credits" : "currency";
1876
+ return /* @__PURE__ */ jsx6(
1877
+ "button",
1878
+ {
1879
+ ref: forwardedRef,
1880
+ type: "button",
1881
+ className,
1882
+ "data-solvapay-auto-recharge-unit-toggle": "",
1883
+ "aria-label": `Switch ${fieldLabel} to ${targetUnitLabel}`,
1884
+ onClick: onToggle,
1885
+ ...rest,
1886
+ children: unit === "currency" ? ctx.currency.toUpperCase() : "credits"
1887
+ }
1888
+ );
1889
+ });
1890
+ var Hint = forwardRef5(
1891
+ function AutoRechargeHint({ className, ...rest }, forwardedRef) {
1892
+ const ctx = useAutoRechargeCtx("Hint");
1893
+ const copy = useCopy();
1894
+ const hint = ctx.fixedTopupHint;
1895
+ if (!hint) return null;
1896
+ const isCreditsHint = ctx.form.topupUnit === "currency";
1897
+ const text = isCreditsHint ? interpolate(
1898
+ ctx.isApproximate ? copy.autoRecharge.creditsPerRechargeApprox : copy.autoRecharge.creditsPerRecharge,
1899
+ { credits: new Intl.NumberFormat().format(Number(hint)) }
1900
+ ) : interpolate(
1901
+ ctx.isApproximate ? copy.autoRecharge.currencyPerRechargeApprox : copy.autoRecharge.currencyPerRecharge,
1902
+ { amount: hint }
1903
+ );
1904
+ return /* @__PURE__ */ jsx6("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-hint": "", ...rest, children: text });
1905
+ }
1906
+ );
1907
+ var ValidationError = forwardRef5(function AutoRechargeValidationError({ className, ...rest }, forwardedRef) {
1908
+ const ctx = useAutoRechargeCtx("ValidationError");
1909
+ if (!ctx.validationError) return null;
1910
+ return /* @__PURE__ */ jsx6(
1911
+ "p",
1912
+ {
1913
+ ref: forwardedRef,
1914
+ role: "alert",
1915
+ "aria-live": "polite",
1916
+ className,
1917
+ "data-solvapay-auto-recharge-validation-error": "",
1918
+ ...rest,
1919
+ children: ctx.validationError
1920
+ }
1921
+ );
1922
+ });
1923
+ var Actions = forwardRef5(
1924
+ function AutoRechargeActions({ className, children, ...rest }, forwardedRef) {
1925
+ return /* @__PURE__ */ jsx6(
1926
+ "menu",
1927
+ {
1928
+ ref: forwardedRef,
1929
+ className,
1930
+ "data-solvapay-auto-recharge-actions": "",
1931
+ ...rest,
1932
+ children: children ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1933
+ /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsx6(CancelButton, {}) }),
1934
+ /* @__PURE__ */ jsx6("li", { children: /* @__PURE__ */ jsx6(SaveButton, {}) })
1935
+ ] })
1936
+ }
1937
+ );
1938
+ }
1939
+ );
1940
+ var SaveButton = forwardRef5(function AutoRechargeSaveButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
1941
+ const ctx = useAutoRechargeCtx("SaveButton");
1942
+ const copy = useCopy();
1943
+ const dataState = ctx.saving ? "processing" : ctx.validationError ? "disabled" : "idle";
1944
+ const commonProps = {
1945
+ "data-solvapay-auto-recharge-save": "",
1946
+ "data-state": dataState,
1947
+ type: "button",
1948
+ disabled: ctx.saving || ctx.disabling || !!ctx.validationError,
1949
+ "aria-busy": ctx.saving,
1950
+ onClick: composeEventHandlers(onClick, (event) => {
1951
+ event.preventDefault();
1952
+ void ctx.save();
1953
+ }),
1954
+ className,
1955
+ ...rest
1956
+ };
1957
+ const content = ctx.saving ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1958
+ /* @__PURE__ */ jsx6(Spinner, { size: "sm" }),
1959
+ " ",
1960
+ copy.cta.processing
1961
+ ] }) : children ?? copy.autoRecharge.saveButton;
1962
+ if (asChild) {
1963
+ return /* @__PURE__ */ jsx6(
1964
+ Slot,
1965
+ {
1966
+ ref: forwardedRef,
1967
+ ...commonProps,
1968
+ children: content
1969
+ }
1970
+ );
1971
+ }
1972
+ return /* @__PURE__ */ jsx6("button", { ref: forwardedRef, ...commonProps, children: content });
1973
+ });
1974
+ var DisableButton = forwardRef5(
1975
+ function AutoRechargeDisableButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
1976
+ const ctx = useAutoRechargeCtx("DisableButton");
1977
+ const copy = useCopy();
1978
+ if (!ctx.config) return null;
1979
+ const commonProps = {
1980
+ "data-solvapay-auto-recharge-disable": "",
1981
+ type: "button",
1982
+ disabled: ctx.saving || ctx.disabling,
1983
+ "aria-busy": ctx.disabling,
1984
+ onClick: composeEventHandlers(onClick, (event) => {
1985
+ event.preventDefault();
1986
+ void ctx.disable();
1987
+ }),
1988
+ className,
1989
+ ...rest
1990
+ };
1991
+ if (asChild) {
1992
+ return /* @__PURE__ */ jsx6(
1993
+ Slot,
1994
+ {
1995
+ ref: forwardedRef,
1996
+ ...commonProps,
1997
+ children: children ?? copy.autoRecharge.disableButton
1998
+ }
1999
+ );
2000
+ }
2001
+ return /* @__PURE__ */ jsx6("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.disableButton });
2002
+ }
2003
+ );
2004
+ var ErrorSlot4 = forwardRef5(
2005
+ function AutoRechargeError({ className, children, ...rest }, forwardedRef) {
2006
+ const ctx = useAutoRechargeCtx("Error");
2007
+ if (!ctx.error) return null;
2008
+ return /* @__PURE__ */ jsx6(
2009
+ "p",
2010
+ {
2011
+ ref: forwardedRef,
2012
+ role: "alert",
2013
+ "aria-live": "polite",
2014
+ className,
2015
+ "data-solvapay-auto-recharge-error": "",
2016
+ ...rest,
2017
+ children: children ?? ctx.error.message
2018
+ }
2019
+ );
2020
+ }
2021
+ );
2022
+ var StatusMessage = forwardRef5(
2023
+ function AutoRechargeStatusMessage({ className, children, ...rest }, forwardedRef) {
2024
+ const ctx = useAutoRechargeCtx("StatusMessage");
2025
+ if (!ctx.statusMessage) return null;
2026
+ return /* @__PURE__ */ jsx6(
2027
+ "p",
2028
+ {
2029
+ ref: forwardedRef,
2030
+ "aria-live": "polite",
2031
+ className,
2032
+ "data-solvapay-auto-recharge-status-message": "",
2033
+ ...rest,
2034
+ children: children ?? ctx.statusMessage
2035
+ }
2036
+ );
2037
+ }
2038
+ );
2039
+ var Status = forwardRef5(
2040
+ function AutoRechargeStatus({ className, ...rest }, forwardedRef) {
2041
+ const ctx = useAutoRechargeCtx("Status");
2042
+ const copy = useCopy();
2043
+ const status = ctx.config?.status;
2044
+ if (!status || status === "active" || status === "disabled" || status === "pending_setup") {
2045
+ return null;
2046
+ }
2047
+ const label = status === "failed" ? copy.autoRecharge.statusFailed : null;
2048
+ if (!label) return null;
2049
+ return /* @__PURE__ */ jsx6(
2050
+ "span",
2051
+ {
2052
+ ref: forwardedRef,
2053
+ className,
2054
+ "data-solvapay-auto-recharge-status": "",
2055
+ "data-status": status,
2056
+ ...rest,
2057
+ children: label
2058
+ }
2059
+ );
2060
+ }
2061
+ );
2062
+ function CardSetupInner({ onComplete }) {
2063
+ const copy = useCopy();
2064
+ const stripe = useStripe();
2065
+ const elements = useElements();
2066
+ const [processing, setProcessing] = useState4(false);
2067
+ const [error, setError] = useState4(null);
2068
+ useEffect4(() => {
2069
+ if (!stripe) return;
2070
+ const clientSecret = readSetupIntentClientSecret(window.location.search);
2071
+ if (!clientSecret) return;
2072
+ let cancelled = false;
2073
+ void (async () => {
2074
+ setProcessing(true);
2075
+ const { setupIntent, error: retrieveError } = await stripe.retrieveSetupIntent(clientSecret);
2076
+ if (cancelled) return;
2077
+ stripSetupIntentParams();
2078
+ if (retrieveError || !setupIntent) {
2079
+ setError(copy.autoRecharge.setupAuthFailed);
2080
+ setProcessing(false);
2081
+ return;
2082
+ }
2083
+ if (setupIntent.status === "succeeded" || setupIntent.status === "processing") {
2084
+ await onComplete();
2085
+ } else {
2086
+ setError(copy.autoRecharge.setupAuthFailed);
2087
+ }
2088
+ if (!cancelled) setProcessing(false);
2089
+ })();
2090
+ return () => {
2091
+ cancelled = true;
2092
+ };
2093
+ }, [stripe, onComplete, copy.autoRecharge]);
2094
+ const handleSubmit = async (event) => {
2095
+ event.preventDefault();
2096
+ if (!stripe || !elements) {
2097
+ setError("Stripe is still loading. Please wait.");
2098
+ return;
2099
+ }
2100
+ setProcessing(true);
2101
+ setError(null);
2102
+ const { error: submitError } = await elements.submit();
2103
+ if (submitError) {
2104
+ setError(submitError.message ?? "Card authorization failed");
2105
+ setProcessing(false);
2106
+ return;
2107
+ }
2108
+ const { error: confirmError } = await stripe.confirmSetup({
2109
+ elements,
2110
+ confirmParams: {
2111
+ return_url: typeof window !== "undefined" ? window.location.href : "/"
2112
+ },
2113
+ redirect: "if_required"
2114
+ });
2115
+ if (confirmError) {
2116
+ setError(confirmError.message ?? "Card authorization failed");
2117
+ setProcessing(false);
2118
+ return;
2119
+ }
2120
+ await onComplete();
2121
+ setProcessing(false);
2122
+ };
2123
+ return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit, "data-solvapay-auto-recharge-setup": "", children: [
2124
+ /* @__PURE__ */ jsx6("h4", { children: copy.autoRecharge.setupHeading }),
2125
+ /* @__PURE__ */ jsx6("p", { children: copy.autoRecharge.setupDescription }),
2126
+ /* @__PURE__ */ jsx6(StripePaymentElement, { options: withPaymentElementDefaults() }),
2127
+ error ? /* @__PURE__ */ jsx6("p", { role: "alert", "aria-live": "polite", "data-solvapay-auto-recharge-setup-error": "", children: error }) : null,
2128
+ /* @__PURE__ */ jsx6(
2129
+ "button",
2130
+ {
2131
+ type: "submit",
2132
+ disabled: processing || !stripe,
2133
+ "data-solvapay-auto-recharge-setup-submit": "",
2134
+ children: processing ? copy.autoRecharge.setupProcessing : copy.autoRecharge.setupSubmit
2135
+ }
2136
+ )
2137
+ ] });
2138
+ }
2139
+ function CardSetup({ setup, onComplete }) {
2140
+ const stripePromise = useMemo4(() => {
2141
+ if (!setup.publishableKey || !setup.setupClientSecret) return null;
2142
+ const options = {
2143
+ ...setup.stripeAccountId ? { stripeAccount: setup.stripeAccountId } : {},
2144
+ developerTools: { assistant: { enabled: false } }
2145
+ };
2146
+ const cacheKey = getStripeCacheKey(setup.publishableKey, setup.stripeAccountId);
2147
+ const cached = stripePromiseCache.get(cacheKey);
2148
+ if (cached) return cached;
2149
+ const promise = loadStripe(setup.publishableKey, options);
2150
+ stripePromiseCache.set(cacheKey, promise);
2151
+ return promise;
2152
+ }, [setup.publishableKey, setup.setupClientSecret, setup.stripeAccountId]);
2153
+ if (!stripePromise || !setup.setupClientSecret) {
2154
+ return /* @__PURE__ */ jsxs2("p", { "data-solvapay-auto-recharge-setup-loading": "", children: [
2155
+ /* @__PURE__ */ jsx6(Spinner, { size: "sm" }),
2156
+ " Loading card form\u2026"
2157
+ ] });
2158
+ }
2159
+ return /* @__PURE__ */ jsx6(
2160
+ Elements,
2161
+ {
2162
+ stripe: stripePromise,
2163
+ options: { clientSecret: setup.setupClientSecret },
2164
+ children: /* @__PURE__ */ jsx6(CardSetupInner, { onComplete })
2165
+ },
2166
+ setup.setupClientSecret
2167
+ );
2168
+ }
2169
+ var AutoRechargeRoot2 = Root4;
2170
+ var AutoRechargeLoading2 = Loading4;
2171
+ var AutoRechargeCard2 = Card;
2172
+ var AutoRechargeCardHeading2 = CardHeading;
2173
+ var AutoRechargeCardSummary2 = CardSummary;
2174
+ var AutoRechargeTrigger2 = Trigger;
2175
+ var AutoRechargeOverlay2 = Overlay;
2176
+ var AutoRechargeContent2 = Content;
2177
+ var AutoRechargeTitle2 = Title;
2178
+ var AutoRechargeEnableQuestion2 = EnableQuestion;
2179
+ var AutoRechargeEnableSentence2 = EnableSentence;
2180
+ var AutoRechargeEnableRow2 = EnableRow;
2181
+ var AutoRechargeCancelButton2 = CancelButton;
2182
+ var AutoRechargeHeader2 = Header;
2183
+ var AutoRechargeDescription2 = Description;
2184
+ var AutoRechargeEnableSwitch2 = EnableSwitch;
2185
+ var AutoRechargeFields2 = Fields;
2186
+ var AutoRechargeSetup2 = Setup;
2187
+ var AutoRechargeBody2 = Body;
2188
+ var AutoRechargeSummary2 = Summary2;
2189
+ var AutoRechargeThresholdField2 = ThresholdField;
2190
+ var AutoRechargeTopupField2 = TopupField;
2191
+ var AutoRechargeAmountField2 = AmountField;
2192
+ var AutoRechargeUnitToggle2 = UnitToggle;
2193
+ var AutoRechargeHint2 = Hint;
2194
+ var AutoRechargeValidationError2 = ValidationError;
2195
+ var AutoRechargeActions2 = Actions;
2196
+ var AutoRechargeSaveButton2 = SaveButton;
2197
+ var AutoRechargeDisableButton2 = DisableButton;
2198
+ var AutoRechargeError2 = ErrorSlot4;
2199
+ var AutoRechargeStatusMessage2 = StatusMessage;
2200
+ var AutoRechargeStatus2 = Status;
2201
+ var AutoRechargeCardSetup = CardSetup;
2202
+ var AutoRecharge = {
2203
+ Root: Root4,
2204
+ Loading: Loading4,
2205
+ Card,
2206
+ CardHeading,
2207
+ CardSummary,
2208
+ Trigger,
2209
+ Overlay,
2210
+ Content,
2211
+ Title,
2212
+ EnableQuestion,
2213
+ EnableSentence,
2214
+ EnableRow,
2215
+ CancelButton,
2216
+ Header,
2217
+ Description,
2218
+ EnableSwitch,
2219
+ Fields,
2220
+ Setup,
2221
+ Body,
2222
+ Summary: Summary2,
2223
+ ThresholdField,
2224
+ TopupField,
2225
+ AmountField,
2226
+ UnitToggle,
2227
+ Hint,
2228
+ ValidationError,
2229
+ Actions,
2230
+ SaveButton,
2231
+ DisableButton,
2232
+ Error: ErrorSlot4,
2233
+ StatusMessage,
2234
+ Status,
2235
+ CardSetup
2236
+ };
2237
+ function useAutoRechargeForm() {
2238
+ return useAutoRechargeCtx("useAutoRechargeForm");
2239
+ }
2240
+
2241
+ // src/hooks/usePaywallResolver.ts
2242
+ import { useCallback as useCallback4, useMemo as useMemo5 } from "react";
2243
+ function balanceCoversNextUnit(balance, credits) {
2244
+ if (!balance) return false;
2245
+ if (typeof balance.remainingUnits === "number" && balance.remainingUnits > 0) {
2246
+ return true;
2247
+ }
2248
+ if (credits != null && balance.creditsPerUnit && credits >= balance.creditsPerUnit) {
2249
+ return true;
2250
+ }
2251
+ return false;
2252
+ }
2253
+ function usePaywallResolver(content) {
2254
+ const { activePurchase, hasPaidPurchase, refetch: refetchPurchase } = usePurchase();
2255
+ const { credits, refetch: refetchBalance } = useBalance();
2256
+ const resolved = useMemo5(() => {
2257
+ if (!content) return false;
2258
+ const productMatches = !content.product || activePurchase?.productRef === content.product || activePurchase?.productName === content.product;
2259
+ if (content.kind === "payment_required") {
2260
+ if (hasPaidPurchase && productMatches) return true;
2261
+ return balanceCoversNextUnit(content.balance, credits);
2262
+ }
2263
+ if (balanceCoversNextUnit(content.balance, credits)) return true;
2264
+ return Boolean(productMatches && activePurchase?.status === "active");
2265
+ }, [content, hasPaidPurchase, activePurchase, credits]);
2266
+ const refetch = useCallback4(async () => {
2267
+ await Promise.all([
2268
+ refetchPurchase().catch(() => void 0),
2269
+ refetchBalance().catch(() => void 0)
2270
+ ]);
2271
+ }, [refetchPurchase, refetchBalance]);
2272
+ return { resolved, refetch };
2273
+ }
2274
+
2275
+ // src/primitives/PaywallNotice.tsx
2276
+ import {
2277
+ createContext as createContext6,
2278
+ forwardRef as forwardRef7,
2279
+ useCallback as useCallback5,
2280
+ useContext as useContext7,
2281
+ useEffect as useEffect5,
2282
+ useMemo as useMemo7,
2283
+ useRef as useRef4
2284
+ } from "react";
2285
+
2286
+ // src/primitives/checkout/index.tsx
2287
+ import { createContext as createContext5, forwardRef as forwardRef6, useContext as useContext6, useMemo as useMemo6 } from "react";
2288
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
2289
+ var CheckoutContext = createContext5(null);
2290
+ function useCheckoutContext(part) {
2291
+ const ctx = useContext6(CheckoutContext);
2292
+ if (!ctx) {
2293
+ throw new Error(`CheckoutSteps.${part} must be rendered inside <CheckoutSteps.Root>.`);
2294
+ }
2295
+ return ctx;
2296
+ }
2297
+ function useCheckoutSteps() {
2298
+ return useCheckoutContext("useCheckoutSteps");
2299
+ }
2300
+ var Root5 = forwardRef6(function CheckoutStepsRoot(props, forwardedRef) {
2301
+ const {
2302
+ productRef,
2303
+ returnUrl: _returnUrl,
2304
+ flow: externalFlow,
2305
+ initialStep,
2306
+ initialPlanRef,
2307
+ initialAmountMinor,
2308
+ autoSelectFirstPaid = false,
2309
+ topupCurrency,
2310
+ filter,
2311
+ sortBy = planSortByPaygFirstThenAsc,
2312
+ popularPlanRef,
2313
+ currentPlanRef,
2314
+ onPlanSelect,
2315
+ onAmountSelect,
2316
+ onPurchaseSuccess,
2317
+ onError,
2318
+ className,
2319
+ children
2320
+ } = props;
2321
+ if (externalFlow) {
2322
+ return /* @__PURE__ */ jsx7("div", { ref: forwardedRef, "data-solvapay-checkout": "", className, children: /* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: externalFlow, children }) });
2323
+ }
2324
+ return /* @__PURE__ */ jsx7(
2325
+ RootWithPlanSelector,
2326
+ {
2327
+ productRef,
2328
+ filter,
2329
+ sortBy,
2330
+ popularPlanRef,
2331
+ currentPlanRef,
2332
+ autoSelectFirstPaid,
2333
+ initialPlanRef,
2334
+ forwardedRef,
2335
+ className,
2336
+ initialStep,
2337
+ initialAmountMinor,
2338
+ topupCurrency,
2339
+ onPlanSelect,
2340
+ onAmountSelect,
2341
+ onPurchaseSuccess,
2342
+ onError,
2343
+ children
2344
+ }
2345
+ );
2346
+ });
2347
+ function RootWithPlanSelector({
2348
+ productRef,
2349
+ filter,
2350
+ sortBy,
2351
+ popularPlanRef,
2352
+ currentPlanRef,
2353
+ autoSelectFirstPaid,
2354
+ initialPlanRef,
2355
+ forwardedRef,
2356
+ className,
2357
+ initialStep,
2358
+ initialAmountMinor,
2359
+ topupCurrency,
2360
+ onPlanSelect,
2361
+ onAmountSelect,
2362
+ onPurchaseSuccess,
2363
+ onError,
2364
+ children
2365
+ }) {
2366
+ const { plans } = usePlans({ productRef });
2367
+ const resolvedFilter = useMemo6(
2368
+ () => filter ?? buildDefaultCheckoutPlanFilter(plans),
2369
+ [filter, plans]
2370
+ );
2371
+ return /* @__PURE__ */ jsx7(
2372
+ PlanSelector.Root,
2373
+ {
2374
+ productRef,
2375
+ filter: resolvedFilter,
2376
+ sortBy,
2377
+ popularPlanRef,
2378
+ currentPlanRef,
2379
+ autoSelectFirstPaid,
2380
+ initialPlanRef,
2381
+ children: /* @__PURE__ */ jsx7(
2382
+ FlowProvider,
2383
+ {
2384
+ productRef,
2385
+ forwardedRef,
2386
+ className,
2387
+ initialStep,
2388
+ initialAmountMinor,
2389
+ topupCurrency,
2390
+ onPlanSelect,
2391
+ onAmountSelect,
2392
+ onPurchaseSuccess,
2393
+ onError,
2394
+ children
2395
+ }
2396
+ )
2397
+ }
2398
+ );
2399
+ }
2400
+ function FlowProvider({
2401
+ productRef,
2402
+ initialStep,
2403
+ initialAmountMinor,
2404
+ topupCurrency,
2405
+ onPlanSelect,
2406
+ onAmountSelect,
2407
+ onPurchaseSuccess,
2408
+ onError,
2409
+ className,
2410
+ forwardedRef,
2411
+ children
2412
+ }) {
2413
+ const flow = useCheckoutFlow({
2414
+ productRef,
2415
+ initialStep,
2416
+ initialAmountMinor,
2417
+ topupCurrency,
2418
+ onPlanSelect,
2419
+ onAmountSelect,
2420
+ onPurchaseSuccess,
2421
+ onError
2422
+ });
2423
+ return /* @__PURE__ */ jsx7("div", { ref: forwardedRef, "data-solvapay-checkout": "", "data-step": flow.step, className, children: /* @__PURE__ */ jsx7(CheckoutContext.Provider, { value: flow, children }) });
2424
+ }
2425
+ function IfStep({ step, children }) {
2426
+ const flow = useCheckoutContext("IfStep");
2427
+ const matches = Array.isArray(step) ? step.includes(flow.step) : flow.step === step;
2428
+ if (!matches) return null;
2429
+ return /* @__PURE__ */ jsx7(Fragment4, { children });
2430
+ }
2431
+ var StepHeading = forwardRef6(function CheckoutStepsStepHeading({ asChild, children, className, ...rest }, forwardedRef) {
2432
+ const flow = useCheckoutContext("StepHeading");
2433
+ const copy = useCopy();
2434
+ const paywallCtx = usePaywallNoticeOptional();
2435
+ if (flow.step === "success") return null;
2436
+ const defaultText = resolveStepHeading(flow.step, copy, paywallCtx?.content ?? null);
2437
+ const Comp = asChild ? Slot : "h3";
2438
+ return /* @__PURE__ */ jsx7(
2439
+ Comp,
2440
+ {
2441
+ ref: forwardedRef,
2442
+ "data-solvapay-checkout-step-heading": "",
2443
+ "data-step": flow.step,
2444
+ className: className ?? "solvapay-checkout-step-heading",
2445
+ ...rest,
2446
+ children: children ?? defaultText
2447
+ }
2448
+ );
2449
+ });
2450
+ var StepMessage = forwardRef6(function CheckoutStepsStepMessage({ asChild, children, className, ...rest }, forwardedRef) {
2451
+ const flow = useCheckoutContext("StepMessage");
2452
+ const copy = useCopy();
2453
+ const paywallCtx = usePaywallNoticeOptional();
2454
+ if (flow.step === "success") return null;
2455
+ const defaultText = resolveStepMessage(flow, copy, paywallCtx?.content ?? null);
2456
+ if (!defaultText && children == null) return null;
2457
+ const Comp = asChild ? Slot : "p";
2458
+ return /* @__PURE__ */ jsx7(
2459
+ Comp,
2460
+ {
2461
+ ref: forwardedRef,
2462
+ "data-solvapay-checkout-step-message": "",
2463
+ "data-step": flow.step,
2464
+ className: className ?? "solvapay-checkout-step-message",
2465
+ ...rest,
2466
+ children: children ?? defaultText
2467
+ }
2468
+ );
2469
+ });
2470
+ function resolveStepHeading(step, copy, content) {
2471
+ if (step === "amount") return copy.checkout.stepHeading.amount;
2472
+ if (step === "payment") return copy.checkout.stepHeading.payment;
2473
+ if (step === "plan") {
2474
+ if (content) {
2475
+ if (content.kind === "payment_required") return copy.paywall.paymentRequiredHeading;
2476
+ if (content.kind === "activation_required") {
2477
+ return isTopupGate(content) ? copy.paywall.topupRequiredHeading : copy.paywall.activationRequiredHeading;
2478
+ }
2479
+ }
2480
+ return copy.checkout.stepHeading.plan;
2481
+ }
2482
+ return "";
2483
+ }
2484
+ function resolveStepMessage(flow, copy, content) {
2485
+ if (flow.step === "plan") {
2486
+ if (content) return resolvePaywallMessage(content, copy.paywall);
2487
+ return copy.checkout.stepMessage.plan;
2488
+ }
2489
+ if (flow.step === "amount") return copy.checkout.stepMessage.amount;
2490
+ if (flow.step === "payment") {
2491
+ if (flow.branch === "payg") return copy.checkout.stepMessage.paymentPayg;
2492
+ const plan = flow.selectedPlan;
2493
+ if (flow.branch === "recurring" && plan) {
2494
+ const planName = plan.name ?? "your";
2495
+ if (plan.billingCycle) {
2496
+ return interpolate(copy.checkout.stepMessage.paymentRecurring, { planName });
2497
+ }
2498
+ return copy.checkout.stepMessage.paymentOneTime;
2499
+ }
2500
+ return copy.checkout.stepMessage.paymentOneTime;
2501
+ }
2502
+ return "";
2503
+ }
2504
+ function PlanGrid({ className, children }) {
2505
+ return /* @__PURE__ */ jsx7(PlanSelector.Grid, { className: className ?? "solvapay-checkout-plan-grid", children: children ?? /* @__PURE__ */ jsxs3(PlanSelector.Card, { className: "solvapay-checkout-plan-card", children: [
2506
+ /* @__PURE__ */ jsx7(PlanSelector.CardBadge, { className: "solvapay-checkout-plan-card-badge" }),
2507
+ /* @__PURE__ */ jsx7(PlanSelector.CardName, { className: "solvapay-checkout-plan-card-name" }),
2508
+ /* @__PURE__ */ jsx7(PlanSelector.CardPrice, { className: "solvapay-checkout-plan-card-price" }),
2509
+ /* @__PURE__ */ jsx7(PlanSelector.CardInterval, { className: "solvapay-checkout-plan-card-interval" })
2510
+ ] }) });
2511
+ }
2512
+ var PlanContinueButton = forwardRef6(
2513
+ function PlanContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
2514
+ const flow = useCheckoutContext("PlanContinueButton");
2515
+ const locale = useLocale();
2516
+ const selectedPlanShape = flow.selectedPlan;
2517
+ const isDisabled = disabled || !flow.selectedPlanRef || flow.status === "activating";
2518
+ const label = children ?? formatContinueLabel(selectedPlanShape, locale);
2519
+ return /* @__PURE__ */ jsx7(
2520
+ "button",
2521
+ {
2522
+ ref,
2523
+ type: "button",
2524
+ className: className ?? "solvapay-checkout-continue-button",
2525
+ disabled: isDisabled,
2526
+ "aria-disabled": isDisabled || void 0,
2527
+ "data-solvapay-checkout-continue": "",
2528
+ onClick: (e) => {
2529
+ onClick?.(e);
2530
+ if (e.defaultPrevented) return;
2531
+ void flow.advance();
2532
+ },
2533
+ ...rest,
2534
+ children: label
2535
+ }
2536
+ );
2537
+ }
2538
+ );
2539
+ function AmountPicker2({ className, children }) {
2540
+ const flow = useCheckoutContext("AmountPicker");
2541
+ if (!flow.topupCurrencyReady || flow.topupCurrency == null) {
2542
+ return /* @__PURE__ */ jsx7(
2543
+ "div",
2544
+ {
2545
+ className: className ?? "solvapay-amount-picker",
2546
+ "data-state": "loading",
2547
+ "aria-busy": "true",
2548
+ children: /* @__PURE__ */ jsx7("div", { className: "solvapay-amount-picker-pills", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ jsx7(
2549
+ "span",
2550
+ {
2551
+ className: "solvapay-amount-picker-pill",
2552
+ "data-state": "disabled",
2553
+ "aria-hidden": "true"
2554
+ },
2555
+ i
2556
+ )) })
2557
+ }
2558
+ );
2559
+ }
2560
+ return /* @__PURE__ */ jsx7(
2561
+ AmountPicker.Root,
2562
+ {
2563
+ currency: flow.topupCurrency,
2564
+ emit: "minor",
2565
+ className: className ?? "solvapay-amount-picker",
2566
+ onChange: (value) => {
2567
+ if (typeof value === "number") {
2568
+ flow.selectAmount(value);
2569
+ }
2570
+ },
2571
+ children: children ?? /* @__PURE__ */ jsx7(DefaultAmountTree, {})
2572
+ }
2573
+ );
2574
+ }
2575
+ function DefaultAmountTree() {
2576
+ const ctx = useAmountPicker();
2577
+ const { selectAmountLabel, customAmountLabel, creditEstimate } = useAmountPickerCopy();
2578
+ return /* @__PURE__ */ jsxs3(Fragment4, { children: [
2579
+ /* @__PURE__ */ jsx7("p", { className: "solvapay-amount-picker-label", children: selectAmountLabel }),
2580
+ /* @__PURE__ */ jsx7("div", { className: "solvapay-amount-picker-pills", children: ctx.quickAmounts.map((amount) => /* @__PURE__ */ jsx7(
2581
+ AmountPicker.Option,
2582
+ {
2583
+ amount,
2584
+ className: "solvapay-amount-picker-pill"
2585
+ },
2586
+ amount
2587
+ )) }),
2588
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-amount-picker-custom-wrapper", children: [
2589
+ /* @__PURE__ */ jsx7("p", { className: "solvapay-amount-picker-custom-label", children: customAmountLabel }),
2590
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-amount-picker-custom-row", children: [
2591
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-amount-picker-currency-symbol", children: ctx.currencySymbol }),
2592
+ /* @__PURE__ */ jsx7(
2593
+ AmountPicker.Custom,
2594
+ {
2595
+ className: "solvapay-amount-picker-custom-input",
2596
+ placeholder: "0.00"
2597
+ }
2598
+ )
2599
+ ] })
2600
+ ] }),
2601
+ /* @__PURE__ */ jsx7(
2602
+ "p",
2603
+ {
2604
+ className: "solvapay-amount-picker-credit-estimate",
2605
+ "aria-hidden": ctx.estimatedCredits == null || void 0,
2606
+ children: ctx.estimatedCredits != null ? creditEstimate(ctx.estimatedCredits) : "\xA0"
2607
+ }
2608
+ )
2609
+ ] });
2610
+ }
2611
+ var AmountContinueButton = forwardRef6(
2612
+ function AmountContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
2613
+ const flow = useCheckoutContext("AmountContinueButton");
2614
+ const locale = useLocale();
2615
+ const currency = flow.topupCurrency;
2616
+ const amountMinor = flow.selectedAmountMinor;
2617
+ const ready = flow.topupCurrencyReady && currency != null;
2618
+ const isDisabled = disabled || !ready || amountMinor == null;
2619
+ const label = children ?? (ready && currency != null && amountMinor != null ? `Continue \u2014 ${formatPrice(amountMinor, currency, { locale })}` : "Continue");
2620
+ return /* @__PURE__ */ jsx7(
2621
+ "button",
2622
+ {
2623
+ ref,
2624
+ type: "button",
2625
+ className: className ?? "solvapay-checkout-continue-button",
2626
+ disabled: isDisabled,
2627
+ "aria-disabled": isDisabled || void 0,
2628
+ "data-solvapay-checkout-continue": "",
2629
+ onClick: (e) => {
2630
+ onClick?.(e);
2631
+ if (e.defaultPrevented) return;
2632
+ void flow.advance();
2633
+ },
2634
+ ...rest,
2635
+ children: label
2636
+ }
2637
+ );
2638
+ }
2639
+ );
2640
+ function Payment({ className }) {
2641
+ const flow = useCheckoutContext("Payment");
2642
+ if (flow.branch === "payg") {
2643
+ return /* @__PURE__ */ jsx7(PaygPayment, { className });
2644
+ }
2645
+ if (flow.branch === "recurring") {
2646
+ return /* @__PURE__ */ jsx7(RecurringPayment, { className });
2647
+ }
2648
+ return null;
2649
+ }
2650
+ function PaygPayment({ className }) {
2651
+ const flow = useCheckoutContext("Payment");
2652
+ const locale = useLocale();
2653
+ const { creditsPerMinorUnit, displayExchangeRate } = useBalance();
2654
+ const returnUrl = useReturnUrl();
2655
+ const selectedPlanShape = flow.selectedPlan;
2656
+ const amountMinor = flow.selectedAmountMinor;
2657
+ const currency = flow.topupCurrency;
2658
+ if (!selectedPlanShape || amountMinor == null || currency == null) return null;
2659
+ const creditsAdded = creditsPerMinorUnit != null && creditsPerMinorUnit > 0 ? Math.floor(amountMinor / (displayExchangeRate ?? 1) * creditsPerMinorUnit) : null;
2660
+ return /* @__PURE__ */ jsxs3("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "payg", children: [
2661
+ /* @__PURE__ */ jsx7("div", { className: "solvapay-checkout-order-summary", "data-variant": "payg", children: /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-order-summary-row", children: [
2662
+ /* @__PURE__ */ jsx7("span", { children: creditsAdded != null ? `${creditsAdded.toLocaleString(locale)} credits` : formatPrice(amountMinor, currency, { locale }) }),
2663
+ creditsAdded != null ? /* @__PURE__ */ jsx7("span", { children: formatPrice(amountMinor, currency, { locale }) }) : null
2664
+ ] }) }),
2665
+ /* @__PURE__ */ jsxs3(
2666
+ TopupForm.Root,
2667
+ {
2668
+ amount: amountMinor,
2669
+ currency,
2670
+ returnUrl,
2671
+ className: "solvapay-checkout-topup-form",
2672
+ onSuccess: (intent, extras) => flow.notifyPaymentSuccess(intent, extras),
2673
+ children: [
2674
+ /* @__PURE__ */ jsx7(TopupForm.Loading, {}),
2675
+ /* @__PURE__ */ jsx7(TopupForm.PaymentElement, {}),
2676
+ /* @__PURE__ */ jsx7(TopupForm.Error, { className: "solvapay-checkout-error" }),
2677
+ /* @__PURE__ */ jsx7(MandateText, { mode: "topup", amountMinor, currency }),
2678
+ /* @__PURE__ */ jsxs3(TopupForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: [
2679
+ "Pay ",
2680
+ formatPrice(amountMinor, currency, { locale })
2681
+ ] })
2682
+ ]
2683
+ }
2684
+ )
2685
+ ] });
2686
+ }
2687
+ function RecurringPayment({ className }) {
2688
+ const flow = useCheckoutContext("Payment");
2689
+ const locale = useLocale();
2690
+ const returnUrl = useReturnUrl();
2691
+ const productRef = useProductRef();
2692
+ const selectedPlanShape = flow.selectedPlan;
2693
+ if (!selectedPlanShape || !flow.selectedPlanRef) return null;
2694
+ const currency = (selectedPlanShape.currency ?? "USD").toUpperCase();
2695
+ const amountMinor = selectedPlanShape.price ?? 0;
2696
+ const cycle = selectedPlanShape.billingCycle;
2697
+ const planName = selectedPlanShape.name ?? "Plan";
2698
+ const isRecurring = !!cycle;
2699
+ const formattedAmount = formatPrice(amountMinor, currency, { locale });
2700
+ const priceLine = isRecurring ? `${formattedAmount}/${shortCycle(cycle)}` : formattedAmount;
2701
+ return /* @__PURE__ */ jsxs3("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "recurring", children: [
2702
+ /* @__PURE__ */ jsx7("div", { className: "solvapay-checkout-order-summary", "data-variant": "recurring", children: /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-order-summary-row", children: [
2703
+ /* @__PURE__ */ jsx7("span", { children: planName }),
2704
+ /* @__PURE__ */ jsx7("span", { children: priceLine })
2705
+ ] }) }),
2706
+ /* @__PURE__ */ jsxs3(
2707
+ PaymentForm.Root,
2708
+ {
2709
+ planRef: flow.selectedPlanRef,
2710
+ productRef,
2711
+ returnUrl,
2712
+ requireTermsAcceptance: false,
2713
+ onSuccess: (intent) => flow.notifyPaymentSuccess(intent),
2714
+ children: [
2715
+ /* @__PURE__ */ jsx7(PaymentForm.Loading, {}),
2716
+ /* @__PURE__ */ jsx7(PaymentForm.PaymentElement, {}),
2717
+ /* @__PURE__ */ jsx7(PaymentForm.Error, { className: "solvapay-checkout-error" }),
2718
+ /* @__PURE__ */ jsx7(PaymentForm.MandateText, {}),
2719
+ /* @__PURE__ */ jsx7(PaymentForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: isRecurring ? `Subscribe \u2014 ${priceLine}` : `Pay ${formattedAmount}` })
2720
+ ]
2721
+ }
2722
+ )
2723
+ ] });
2724
+ }
2725
+ var CheckoutEnvContext = createContext5(null);
2726
+ function useReturnUrl() {
2727
+ return useContext6(CheckoutEnvContext)?.returnUrl ?? "";
2728
+ }
2729
+ function useProductRef() {
2730
+ return useContext6(CheckoutEnvContext)?.productRef ?? "";
2731
+ }
2732
+ var BackLink = forwardRef6(function CheckoutStepsBackLink({ label, glyph = "\u2190", className, onClick, ...rest }, ref) {
2733
+ const flow = useCheckoutContext("BackLink");
2734
+ if (!flow.canGoBack) return null;
2735
+ const resolvedLabel = label ?? (flow.step === "payment" && flow.branch === "payg" ? "Change amount" : flow.step === "payment" && flow.branch === "recurring" ? "Change plan" : "Back");
2736
+ return /* @__PURE__ */ jsxs3(
2737
+ "button",
2738
+ {
2739
+ ref,
2740
+ type: "button",
2741
+ className: ["solvapay-checkout-back-link", className].filter(Boolean).join(" "),
2742
+ "data-solvapay-checkout-back": "",
2743
+ onClick: (e) => {
2744
+ onClick?.(e);
2745
+ if (e.defaultPrevented) return;
2746
+ flow.back();
2747
+ },
2748
+ ...rest,
2749
+ children: [
2750
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-checkout-back-link-glyph", "aria-hidden": "true", children: glyph }),
2751
+ /* @__PURE__ */ jsx7("span", { className: "solvapay-checkout-back-link-label", children: resolvedLabel })
2752
+ ]
2753
+ }
2754
+ );
2755
+ });
2756
+ function Success({ className, children }) {
2757
+ const flow = useCheckoutContext("Success");
2758
+ const locale = useLocale();
2759
+ if (flow.step !== "success" || !flow.successMeta) return null;
2760
+ if (children) {
2761
+ return /* @__PURE__ */ jsx7("div", { className: className ?? "solvapay-checkout-success", children });
2762
+ }
2763
+ const meta = flow.successMeta;
2764
+ if (meta.branch === "payg") {
2765
+ return /* @__PURE__ */ jsxs3("div", { className: className ?? "solvapay-checkout-success", "data-branch": "payg", children: [
2766
+ /* @__PURE__ */ jsx7("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
2767
+ /* @__PURE__ */ jsx7("h2", { className: "solvapay-checkout-success-heading", children: "Credits added" }),
2768
+ /* @__PURE__ */ jsx7("p", { className: "solvapay-checkout-success-subheading", children: "Pay as you go plan is active." }),
2769
+ /* @__PURE__ */ jsxs3("dl", { className: "solvapay-checkout-receipt", "data-variant": "payg", children: [
2770
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2771
+ /* @__PURE__ */ jsx7("dt", { children: "Amount" }),
2772
+ /* @__PURE__ */ jsx7("dd", { children: formatPrice(meta.amountMinor, meta.currency, { locale }) })
2773
+ ] }),
2774
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2775
+ /* @__PURE__ */ jsx7("dt", { children: "Credits" }),
2776
+ /* @__PURE__ */ jsxs3("dd", { children: [
2777
+ "+",
2778
+ meta.creditsAdded.toLocaleString(locale)
2779
+ ] })
2780
+ ] }),
2781
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2782
+ /* @__PURE__ */ jsx7("dt", { children: "Plan" }),
2783
+ /* @__PURE__ */ jsx7("dd", { children: meta.plan.name ?? "Pay as you go" })
2784
+ ] }),
2785
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2786
+ /* @__PURE__ */ jsx7("dt", { children: "Rate" }),
2787
+ /* @__PURE__ */ jsx7("dd", { children: meta.rateLabel })
2788
+ ] })
2789
+ ] })
2790
+ ] });
2791
+ }
2792
+ return /* @__PURE__ */ jsxs3("div", { className: className ?? "solvapay-checkout-success", "data-branch": "recurring", children: [
2793
+ /* @__PURE__ */ jsx7("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
2794
+ /* @__PURE__ */ jsxs3("h2", { className: "solvapay-checkout-success-heading", children: [
2795
+ meta.plan.name ?? "Plan",
2796
+ " active"
2797
+ ] }),
2798
+ /* @__PURE__ */ jsx7("p", { className: "solvapay-checkout-success-subheading", children: "Subscription is live and credits are ready." }),
2799
+ /* @__PURE__ */ jsxs3("dl", { className: "solvapay-checkout-receipt", "data-variant": "recurring", children: [
2800
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2801
+ /* @__PURE__ */ jsx7("dt", { children: "Plan" }),
2802
+ /* @__PURE__ */ jsx7("dd", { children: meta.plan.name ?? "Plan" })
2803
+ ] }),
2804
+ meta.creditsIncluded > 0 ? /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2805
+ /* @__PURE__ */ jsx7("dt", { children: "Credits" }),
2806
+ /* @__PURE__ */ jsxs3("dd", { children: [
2807
+ "+",
2808
+ meta.creditsIncluded.toLocaleString(locale)
2809
+ ] })
2810
+ ] }) : null,
2811
+ /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2812
+ /* @__PURE__ */ jsx7("dt", { children: "Charged today" }),
2813
+ /* @__PURE__ */ jsx7("dd", { children: formatPrice(meta.chargedTodayMinor, meta.currency, { locale }) })
2814
+ ] }),
2815
+ meta.nextRenewalLabel ? /* @__PURE__ */ jsxs3("div", { className: "solvapay-checkout-receipt-row", children: [
2816
+ /* @__PURE__ */ jsx7("dt", { children: "Next renewal" }),
2817
+ /* @__PURE__ */ jsx7("dd", { children: meta.nextRenewalLabel })
2818
+ ] }) : null
2819
+ ] })
2820
+ ] });
2821
+ }
2822
+ var RootWithEnv = forwardRef6(
2823
+ function CheckoutStepsRootWithEnv(props, forwardedRef) {
2824
+ const env = useMemo6(
2825
+ () => ({ returnUrl: props.returnUrl, productRef: props.productRef }),
2826
+ [props.returnUrl, props.productRef]
2827
+ );
2828
+ return /* @__PURE__ */ jsx7(CheckoutEnvContext.Provider, { value: env, children: /* @__PURE__ */ jsx7(Root5, { ...props, ref: forwardedRef }) });
2829
+ }
2830
+ );
2831
+ var CheckoutSteps = {
2832
+ Root: RootWithEnv,
2833
+ IfStep,
2834
+ StepHeading,
2835
+ StepMessage,
2836
+ PlanGrid,
2837
+ PlanContinueButton,
2838
+ AmountPicker: AmountPicker2,
2839
+ AmountContinueButton,
2840
+ Payment,
2841
+ BackLink,
2842
+ Success
2843
+ };
2844
+ var CheckoutStepsRoot2 = RootWithEnv;
2845
+ var CheckoutStepsIfStep = IfStep;
2846
+ var CheckoutStepsStepHeading2 = StepHeading;
2847
+ var CheckoutStepsStepMessage2 = StepMessage;
2848
+ var CheckoutStepsPlanGrid = PlanGrid;
2849
+ var CheckoutStepsPlanContinueButton = PlanContinueButton;
2850
+ var CheckoutStepsAmountPicker = AmountPicker2;
2851
+ var CheckoutStepsAmountContinueButton = AmountContinueButton;
2852
+ var CheckoutStepsPayment = Payment;
2853
+ var CheckoutStepsBackLink2 = BackLink;
2854
+ var CheckoutStepsSuccess = Success;
2855
+
2856
+ // src/primitives/PaywallNotice.tsx
2857
+ import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
2858
+ var PaywallNoticeContext = createContext6(null);
2859
+ function usePaywallNoticeCtx(part) {
2860
+ const ctx = useContext7(PaywallNoticeContext);
2861
+ if (!ctx) {
2862
+ throw new Error(`PaywallNotice.${part} must be rendered inside <PaywallNotice.Root>.`);
2863
+ }
2864
+ return ctx;
2865
+ }
2866
+ var Root6 = forwardRef7(function PaywallNoticeRoot({ content, onResolved, classNames, asChild, children, ...rest }, forwardedRef) {
2867
+ const { resolved, refetch } = usePaywallResolver(content);
2868
+ const classNamesResolved = useMemo7(() => classNames ?? {}, [classNames]);
2869
+ const onResolvedRef = useRef4(onResolved);
2870
+ useEffect5(() => {
2871
+ onResolvedRef.current = onResolved;
2872
+ }, [onResolved]);
2873
+ const hasResolvedRef = useRef4(false);
2874
+ const signalResolved = useCallback5(() => {
2875
+ if (hasResolvedRef.current) return;
2876
+ hasResolvedRef.current = true;
2877
+ onResolvedRef.current?.();
2878
+ }, []);
2879
+ useEffect5(() => {
2880
+ if (resolved) signalResolved();
2881
+ }, [resolved, signalResolved]);
2882
+ const ctx = useMemo7(
2883
+ () => ({
2884
+ content,
2885
+ resolved,
2886
+ refetch,
2887
+ onResolved: signalResolved,
2888
+ classNames: classNamesResolved
2889
+ }),
2890
+ [content, resolved, refetch, signalResolved, classNamesResolved]
2891
+ );
2892
+ const Comp = asChild ? Slot : "div";
2893
+ return /* @__PURE__ */ jsx8(PaywallNoticeContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx8(
2894
+ Comp,
2895
+ {
2896
+ ref: forwardedRef,
2897
+ "data-solvapay-paywall-notice": "",
2898
+ "data-kind": content.kind,
2899
+ "data-state": resolved ? "resolved" : "pending",
2900
+ className: classNamesResolved.root,
2901
+ ...rest,
2902
+ children
2903
+ }
2904
+ ) });
2905
+ });
2906
+ var Heading2 = forwardRef7(function PaywallNoticeHeading({ asChild, children, className, ...rest }, forwardedRef) {
2907
+ const ctx = usePaywallNoticeCtx("Heading");
2908
+ const copy = useCopy();
2909
+ const defaultText = ctx.resolved ? copy.paywall.resolvedHeading : ctx.content.kind === "payment_required" ? copy.paywall.paymentRequiredHeading : isTopupGate(ctx.content) ? copy.paywall.topupRequiredHeading : copy.paywall.activationRequiredHeading;
2910
+ const Comp = asChild ? Slot : "h2";
2911
+ return /* @__PURE__ */ jsx8(
2912
+ Comp,
2913
+ {
2914
+ ref: forwardedRef,
2915
+ "data-solvapay-paywall-heading": "",
2916
+ className: className ?? ctx.classNames.heading,
2917
+ ...rest,
2918
+ children: children ?? defaultText
2919
+ }
2920
+ );
2921
+ });
2922
+ var Message = forwardRef7(function PaywallNoticeMessage({ asChild, children, className, ...rest }, forwardedRef) {
2923
+ const ctx = usePaywallNoticeCtx("Message");
2924
+ const copy = useCopy();
2925
+ const Comp = asChild ? Slot : "p";
2926
+ const defaultText = resolvePaywallMessage(ctx.content, copy.paywall);
2927
+ return /* @__PURE__ */ jsx8(
2928
+ Comp,
2929
+ {
2930
+ ref: forwardedRef,
2931
+ "data-solvapay-paywall-message": "",
2932
+ className: className ?? ctx.classNames.message,
2933
+ ...rest,
2934
+ children: children ?? defaultText
2935
+ }
2936
+ );
2937
+ });
2938
+ function isTopupGate(content) {
2939
+ if (content.kind !== "activation_required") return false;
2940
+ const plans = content.plans;
2941
+ if (!plans || plans.length === 0) return false;
2942
+ return plans.every((p) => isPaygPlan(p));
2943
+ }
2944
+ function resolvePaywallMessage(content, paywallCopy) {
2945
+ const productName = content.kind === "payment_required" || content.kind === "activation_required" ? content.productDetails?.name : void 0;
2946
+ const forProduct = productName ? interpolate(paywallCopy.paymentRequiredProductSuffix, { product: productName }) : "";
2947
+ if (content.kind === "payment_required") {
2948
+ const balance = content.balance;
2949
+ if (!balance) {
2950
+ return interpolate(paywallCopy.paymentRequiredMessageNoBalance, { forProduct });
2951
+ }
2952
+ const remaining = balance.remainingUnits ?? 0;
2953
+ if (remaining <= 0) {
2954
+ return interpolate(paywallCopy.paymentRequiredMessage, { forProduct });
2955
+ }
2956
+ return interpolate(paywallCopy.paymentRequiredMessageRemaining, {
2957
+ remaining: String(remaining),
2958
+ pluralSuffix: remaining === 1 ? "" : "s",
2959
+ forProduct
2960
+ });
2961
+ }
2962
+ if (content.kind === "activation_required") {
2963
+ if (isTopupGate(content)) {
2964
+ return interpolate(paywallCopy.topupRequiredMessage, { forProduct });
2965
+ }
2966
+ return interpolate(paywallCopy.activationRequiredMessage, { forProduct });
2967
+ }
2968
+ return content.message ?? "";
2969
+ }
2970
+ var ProductContext = forwardRef7(function PaywallNoticeProductContext({ asChild, children, className, ...rest }, forwardedRef) {
2971
+ const ctx = usePaywallNoticeCtx("ProductContext");
2972
+ const copy = useCopy();
2973
+ const product = ctx.content.kind === "activation_required" ? ctx.content.productDetails : void 0;
2974
+ if (!product?.name) return null;
2975
+ const label = interpolate(copy.paywall.productContext, { product: product.name });
2976
+ const Comp = asChild ? Slot : "div";
2977
+ return /* @__PURE__ */ jsx8(
2978
+ Comp,
2979
+ {
2980
+ ref: forwardedRef,
2981
+ "data-solvapay-paywall-product-context": "",
2982
+ className: className ?? ctx.classNames.productContext,
2983
+ ...rest,
2984
+ children: children ?? label
2985
+ }
2986
+ );
2987
+ });
2988
+ var Balance = forwardRef7(function PaywallNoticeBalance({ asChild, children, className, ...rest }, forwardedRef) {
2989
+ const ctx = usePaywallNoticeCtx("Balance");
2990
+ const copy = useCopy();
2991
+ const balance = ctx.content.balance;
2992
+ if (ctx.content.kind !== "activation_required" || !balance) return null;
2993
+ const label = interpolate(copy.paywall.balanceLine, {
2994
+ available: String(balance.remainingUnits ?? 0),
2995
+ required: String(balance.creditsPerUnit ?? 1)
2996
+ });
2997
+ const Comp = asChild ? Slot : "div";
2998
+ return /* @__PURE__ */ jsx8(
2999
+ Comp,
3000
+ {
3001
+ ref: forwardedRef,
3002
+ "data-solvapay-paywall-balance": "",
3003
+ className: className ?? ctx.classNames.balance,
3004
+ ...rest,
3005
+ children: children ?? label
3006
+ }
3007
+ );
3008
+ });
3009
+ function Plans({ className, children }) {
3010
+ const ctx = usePaywallNoticeCtx("Plans");
3011
+ if (ctx.content.kind !== "activation_required") return null;
3012
+ if (!ctx.content.product) return null;
3013
+ const defaultClass = className ?? ctx.classNames.plans ?? "solvapay-paywall-plans";
3014
+ return /* @__PURE__ */ jsx8("div", { "data-solvapay-paywall-plans": "", className: defaultClass, children: /* @__PURE__ */ jsx8(PlanSelector.Root, { productRef: ctx.content.product, filter: hidesFreePlan, children: children ?? /* @__PURE__ */ jsxs4(Fragment5, { children: [
3015
+ /* @__PURE__ */ jsx8(PlanSelector.Grid, { children: /* @__PURE__ */ jsxs4(PlanSelector.Card, { children: [
3016
+ /* @__PURE__ */ jsx8(PlanSelector.CardBadge, {}),
3017
+ /* @__PURE__ */ jsx8(PlanSelector.CardName, {}),
3018
+ /* @__PURE__ */ jsx8(PlanSelector.CardPrice, {}),
3019
+ /* @__PURE__ */ jsx8(PlanSelector.CardInterval, {})
3020
+ ] }) }),
3021
+ /* @__PURE__ */ jsx8(PlanSelector.Loading, {}),
3022
+ /* @__PURE__ */ jsx8(PlanSelector.Error, {})
3023
+ ] }) }) });
3024
+ }
3025
+ function hidesFreePlan(plan) {
3026
+ return plan.requiresPayment !== false;
3027
+ }
3028
+ var HostedCheckoutLink = forwardRef7(function PaywallNoticeHostedCheckoutLink({ asChild, children, className, ...rest }, forwardedRef) {
3029
+ const ctx = usePaywallNoticeCtx("HostedCheckoutLink");
3030
+ const copy = useCopy();
3031
+ const href = ctx.content.checkoutUrl;
3032
+ if (!href) return null;
3033
+ const Comp = asChild ? Slot : "a";
3034
+ return /* @__PURE__ */ jsx8(
3035
+ Comp,
3036
+ {
3037
+ ref: forwardedRef,
3038
+ href,
3039
+ target: "_blank",
3040
+ rel: "noopener noreferrer",
3041
+ "data-solvapay-paywall-hosted-link": "",
3042
+ className: className ?? ctx.classNames.hostedLink,
3043
+ ...rest,
3044
+ children: children ?? copy.paywall.hostedCheckoutButton
3045
+ }
3046
+ );
3047
+ });
3048
+ function EmbeddedCheckout({ returnUrl, topupCurrency, className }) {
3049
+ const ctx = usePaywallNoticeCtx("EmbeddedCheckout");
3050
+ const productRef = ctx.content.product;
3051
+ const { plans } = usePlans({ productRef: productRef ?? void 0 });
3052
+ const filter = useMemo7(() => buildDefaultCheckoutPlanFilter(plans), [plans]);
3053
+ if (!productRef) return null;
3054
+ const resolvedClassName = className ?? ctx.classNames.embeddedCheckout ?? "solvapay-paywall-embedded-checkout";
3055
+ const headingClassName = ctx.classNames.heading ?? "solvapay-paywall-step-heading";
3056
+ const messageClassName = ctx.classNames.message ?? "solvapay-paywall-step-message";
3057
+ return /* @__PURE__ */ jsxs4(
3058
+ CheckoutSteps.Root,
3059
+ {
3060
+ productRef,
3061
+ returnUrl,
3062
+ filter,
3063
+ topupCurrency,
3064
+ onPurchaseSuccess: () => {
3065
+ void ctx.refetch();
3066
+ ctx.onResolved?.();
3067
+ },
3068
+ className: resolvedClassName,
3069
+ children: [
3070
+ /* @__PURE__ */ jsx8(CheckoutSteps.StepHeading, { className: headingClassName }),
3071
+ /* @__PURE__ */ jsx8(CheckoutSteps.StepMessage, { className: messageClassName }),
3072
+ /* @__PURE__ */ jsxs4(CheckoutSteps.IfStep, { step: "plan", children: [
3073
+ /* @__PURE__ */ jsx8(CheckoutSteps.PlanGrid, {}),
3074
+ /* @__PURE__ */ jsx8(PlanSelector.Loading, {}),
3075
+ /* @__PURE__ */ jsx8(PlanSelector.Error, {}),
3076
+ /* @__PURE__ */ jsx8(CheckoutSteps.PlanContinueButton, {})
3077
+ ] }),
3078
+ /* @__PURE__ */ jsxs4(CheckoutSteps.IfStep, { step: "amount", children: [
3079
+ /* @__PURE__ */ jsx8(CheckoutSteps.BackLink, {}),
3080
+ /* @__PURE__ */ jsx8(CheckoutSteps.AmountPicker, {}),
3081
+ /* @__PURE__ */ jsx8(CheckoutSteps.AmountContinueButton, {})
3082
+ ] }),
3083
+ /* @__PURE__ */ jsxs4(CheckoutSteps.IfStep, { step: "payment", children: [
3084
+ /* @__PURE__ */ jsx8(CheckoutSteps.BackLink, {}),
3085
+ /* @__PURE__ */ jsx8(CheckoutSteps.Payment, {})
3086
+ ] }),
3087
+ /* @__PURE__ */ jsx8(CheckoutSteps.IfStep, { step: "success", children: /* @__PURE__ */ jsx8(CheckoutSteps.Success, {}) })
3088
+ ]
3089
+ }
3090
+ );
3091
+ }
3092
+ var Retry = forwardRef7(function PaywallNoticeRetry({ asChild, children, className, onClick, ...rest }, forwardedRef) {
3093
+ const ctx = usePaywallNoticeCtx("Retry");
3094
+ const copy = useCopy();
3095
+ const Comp = asChild ? Slot : "button";
3096
+ return /* @__PURE__ */ jsx8(
3097
+ Comp,
3098
+ {
3099
+ ref: forwardedRef,
3100
+ type: "button",
3101
+ disabled: !ctx.resolved,
3102
+ "data-solvapay-paywall-retry": "",
3103
+ "data-state": ctx.resolved ? "ready" : "waiting",
3104
+ className: className ?? ctx.classNames.retryButton,
3105
+ onClick: (e) => {
3106
+ onClick?.(e);
3107
+ if (!e.defaultPrevented && ctx.resolved) ctx.onResolved?.();
3108
+ },
3109
+ ...rest,
3110
+ children: children ?? copy.paywall.retryButton
3111
+ }
3112
+ );
3113
+ });
3114
+ var PaywallNotice = Object.assign(Root6, {
3115
+ Root: Root6,
3116
+ Heading: Heading2,
3117
+ Message,
3118
+ ProductContext,
3119
+ Plans,
3120
+ Balance,
3121
+ HostedCheckoutLink,
3122
+ EmbeddedCheckout,
3123
+ Retry
3124
+ });
3125
+ function usePaywallNotice() {
3126
+ return usePaywallNoticeCtx("usePaywallNotice");
3127
+ }
3128
+ function usePaywallNoticeOptional() {
3129
+ return useContext7(PaywallNoticeContext);
3130
+ }
3131
+
3132
+ export {
3133
+ TopupForm2 as TopupForm,
3134
+ ProductBadge2 as ProductBadge,
3135
+ PlanBadge,
3136
+ PurchaseGateRoot2 as PurchaseGateRoot,
3137
+ PurchaseGateAllowed2 as PurchaseGateAllowed,
3138
+ PurchaseGateBlocked2 as PurchaseGateBlocked,
3139
+ PurchaseGateLoading2 as PurchaseGateLoading,
3140
+ PurchaseGateError2 as PurchaseGateError,
3141
+ PurchaseGate,
3142
+ usePurchaseGate,
3143
+ ActivationFlowRoot2 as ActivationFlowRoot,
3144
+ ActivationFlowSummary2 as ActivationFlowSummary,
3145
+ ActivationFlowActivateButton2 as ActivationFlowActivateButton,
3146
+ ActivationFlowAmountPicker,
3147
+ ActivationFlowContinueButton2 as ActivationFlowContinueButton,
3148
+ ActivationFlowRetrying2 as ActivationFlowRetrying,
3149
+ ActivationFlowActivated2 as ActivationFlowActivated,
3150
+ ActivationFlowLoading2 as ActivationFlowLoading,
3151
+ ActivationFlowError2 as ActivationFlowError,
3152
+ ActivationFlow,
3153
+ useActivationFlow,
3154
+ CreditGateRoot2 as CreditGateRoot,
3155
+ CreditGateHeading2 as CreditGateHeading,
3156
+ CreditGateSubheading2 as CreditGateSubheading,
3157
+ CreditGateTopup,
3158
+ CreditGateLoading2 as CreditGateLoading,
3159
+ CreditGateError2 as CreditGateError,
3160
+ CreditGate,
3161
+ useCreditGate,
3162
+ useAutoRecharge,
3163
+ configToAutoRechargeInput,
3164
+ AutoRechargeRoot2 as AutoRechargeRoot,
3165
+ AutoRechargeLoading2 as AutoRechargeLoading,
3166
+ AutoRechargeCard2 as AutoRechargeCard,
3167
+ AutoRechargeCardHeading2 as AutoRechargeCardHeading,
3168
+ AutoRechargeCardSummary2 as AutoRechargeCardSummary,
3169
+ AutoRechargeTrigger2 as AutoRechargeTrigger,
3170
+ AutoRechargeOverlay2 as AutoRechargeOverlay,
3171
+ AutoRechargeContent2 as AutoRechargeContent,
3172
+ AutoRechargeTitle2 as AutoRechargeTitle,
3173
+ AutoRechargeEnableQuestion2 as AutoRechargeEnableQuestion,
3174
+ AutoRechargeEnableSentence2 as AutoRechargeEnableSentence,
3175
+ AutoRechargeEnableRow2 as AutoRechargeEnableRow,
3176
+ AutoRechargeCancelButton2 as AutoRechargeCancelButton,
3177
+ AutoRechargeHeader2 as AutoRechargeHeader,
3178
+ AutoRechargeDescription2 as AutoRechargeDescription,
3179
+ AutoRechargeEnableSwitch2 as AutoRechargeEnableSwitch,
3180
+ AutoRechargeFields2 as AutoRechargeFields,
3181
+ AutoRechargeSetup2 as AutoRechargeSetup,
3182
+ AutoRechargeBody2 as AutoRechargeBody,
3183
+ AutoRechargeSummary2 as AutoRechargeSummary,
3184
+ AutoRechargeThresholdField2 as AutoRechargeThresholdField,
3185
+ AutoRechargeTopupField2 as AutoRechargeTopupField,
3186
+ AutoRechargeAmountField2 as AutoRechargeAmountField,
3187
+ AutoRechargeUnitToggle2 as AutoRechargeUnitToggle,
3188
+ AutoRechargeHint2 as AutoRechargeHint,
3189
+ AutoRechargeValidationError2 as AutoRechargeValidationError,
3190
+ AutoRechargeActions2 as AutoRechargeActions,
3191
+ AutoRechargeSaveButton2 as AutoRechargeSaveButton,
3192
+ AutoRechargeDisableButton2 as AutoRechargeDisableButton,
3193
+ AutoRechargeError2 as AutoRechargeError,
3194
+ AutoRechargeStatusMessage2 as AutoRechargeStatusMessage,
3195
+ AutoRechargeStatus2 as AutoRechargeStatus,
3196
+ AutoRechargeCardSetup,
3197
+ AutoRecharge,
3198
+ useAutoRechargeForm,
3199
+ usePaywallResolver,
3200
+ Root6 as Root,
3201
+ Heading2 as Heading,
3202
+ Message,
3203
+ ProductContext,
3204
+ Balance,
3205
+ Plans,
3206
+ HostedCheckoutLink,
3207
+ EmbeddedCheckout,
3208
+ Retry,
3209
+ PaywallNotice,
3210
+ usePaywallNotice,
3211
+ useCheckoutSteps,
3212
+ CheckoutSteps,
3213
+ CheckoutStepsRoot2 as CheckoutStepsRoot,
3214
+ CheckoutStepsIfStep,
3215
+ CheckoutStepsStepHeading2 as CheckoutStepsStepHeading,
3216
+ CheckoutStepsStepMessage2 as CheckoutStepsStepMessage,
3217
+ CheckoutStepsPlanGrid,
3218
+ CheckoutStepsPlanContinueButton,
3219
+ CheckoutStepsAmountPicker,
3220
+ CheckoutStepsAmountContinueButton,
3221
+ CheckoutStepsPayment,
3222
+ CheckoutStepsBackLink2 as CheckoutStepsBackLink,
3223
+ CheckoutStepsSuccess
3224
+ };