@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.
@@ -45,6 +45,40 @@ __export(primitives_exports, {
45
45
  AmountPickerCustom: () => AmountPickerCustom2,
46
46
  AmountPickerOption: () => AmountPickerOption2,
47
47
  AmountPickerRoot: () => AmountPickerRoot2,
48
+ AutoRecharge: () => AutoRecharge,
49
+ AutoRechargeActions: () => AutoRechargeActions2,
50
+ AutoRechargeAmountField: () => AutoRechargeAmountField2,
51
+ AutoRechargeBody: () => AutoRechargeBody2,
52
+ AutoRechargeCancelButton: () => AutoRechargeCancelButton2,
53
+ AutoRechargeCard: () => AutoRechargeCard2,
54
+ AutoRechargeCardHeading: () => AutoRechargeCardHeading2,
55
+ AutoRechargeCardSetup: () => AutoRechargeCardSetup,
56
+ AutoRechargeCardSummary: () => AutoRechargeCardSummary2,
57
+ AutoRechargeContent: () => AutoRechargeContent2,
58
+ AutoRechargeDescription: () => AutoRechargeDescription2,
59
+ AutoRechargeDisableButton: () => AutoRechargeDisableButton2,
60
+ AutoRechargeEnableQuestion: () => AutoRechargeEnableQuestion2,
61
+ AutoRechargeEnableRow: () => AutoRechargeEnableRow2,
62
+ AutoRechargeEnableSentence: () => AutoRechargeEnableSentence2,
63
+ AutoRechargeEnableSwitch: () => AutoRechargeEnableSwitch2,
64
+ AutoRechargeError: () => AutoRechargeError2,
65
+ AutoRechargeFields: () => AutoRechargeFields2,
66
+ AutoRechargeHeader: () => AutoRechargeHeader2,
67
+ AutoRechargeHint: () => AutoRechargeHint2,
68
+ AutoRechargeLoading: () => AutoRechargeLoading2,
69
+ AutoRechargeOverlay: () => AutoRechargeOverlay2,
70
+ AutoRechargeRoot: () => AutoRechargeRoot2,
71
+ AutoRechargeSaveButton: () => AutoRechargeSaveButton2,
72
+ AutoRechargeSetup: () => AutoRechargeSetup2,
73
+ AutoRechargeStatus: () => AutoRechargeStatus2,
74
+ AutoRechargeStatusMessage: () => AutoRechargeStatusMessage2,
75
+ AutoRechargeSummary: () => AutoRechargeSummary2,
76
+ AutoRechargeThresholdField: () => AutoRechargeThresholdField2,
77
+ AutoRechargeTitle: () => AutoRechargeTitle2,
78
+ AutoRechargeTopupField: () => AutoRechargeTopupField2,
79
+ AutoRechargeTrigger: () => AutoRechargeTrigger2,
80
+ AutoRechargeUnitToggle: () => AutoRechargeUnitToggle2,
81
+ AutoRechargeValidationError: () => AutoRechargeValidationError2,
48
82
  BalanceBadge: () => BalanceBadge,
49
83
  CancelPlanButton: () => CancelPlanButton,
50
84
  CancelledPlanNotice: () => CancelledPlanNotice,
@@ -105,7 +139,7 @@ __export(primitives_exports, {
105
139
  PaywallNoticePlans: () => Plans,
106
140
  PaywallNoticeProductContext: () => ProductContext,
107
141
  PaywallNoticeRetry: () => Retry,
108
- PaywallNoticeRoot: () => Root11,
142
+ PaywallNoticeRoot: () => Root12,
109
143
  PlanBadge: () => PlanBadge,
110
144
  PlanSelector: () => PlanSelector,
111
145
  PlanSelectorCard: () => PlanSelectorCard2,
@@ -140,16 +174,17 @@ __export(primitives_exports, {
140
174
  UsageMeterBar: () => Bar,
141
175
  UsageMeterEmpty: () => Empty,
142
176
  UsageMeterLabel: () => Label,
143
- UsageMeterLoading: () => Loading7,
177
+ UsageMeterLoading: () => Loading8,
144
178
  UsageMeterPercentage: () => Percentage,
145
179
  UsageMeterResetsIn: () => ResetsIn,
146
- UsageMeterRoot: () => Root12,
180
+ UsageMeterRoot: () => Root13,
147
181
  composeEventHandlers: () => composeEventHandlers,
148
182
  composeRefs: () => composeRefs,
149
183
  setRef: () => setRef,
150
184
  useActivationFlow: () => useActivationFlow,
151
185
  useAmountPicker: () => useAmountPicker,
152
186
  useAmountPickerCopy: () => useAmountPickerCopy,
187
+ useAutoRechargeForm: () => useAutoRechargeForm,
153
188
  useCancelledPlanNotice: () => useCancelledPlanNotice,
154
189
  useCheckoutStepsContext: () => useCheckoutSteps,
155
190
  useCheckoutSummary: () => useCheckoutSummary,
@@ -417,6 +452,7 @@ var DEFAULT_ROUTES = {
417
452
  getProduct: "/api/get-product",
418
453
  listPlans: "/api/list-plans",
419
454
  getPaymentMethod: "/api/payment-method",
455
+ autoRecharge: "/api/auto-recharge",
420
456
  getUsage: "/api/usage",
421
457
  getLimits: "/api/limits"
422
458
  };
@@ -454,7 +490,11 @@ function createHttpTransport(config) {
454
490
  }),
455
491
  createTopupPayment: (params) => request(config, routeFor(config, "createTopupPayment"), {
456
492
  method: "POST",
457
- body: { amount: params.amount, currency: params.currency },
493
+ body: {
494
+ amount: params.amount,
495
+ currency: params.currency,
496
+ ...params.autoRecharge ? { autoRecharge: params.autoRecharge } : {}
497
+ },
458
498
  onErrorContext: "createTopupPayment",
459
499
  errorPrefix: "Failed to create topup payment"
460
500
  }),
@@ -503,16 +543,12 @@ function createHttpTransport(config) {
503
543
  }
504
544
  );
505
545
  },
506
- createCustomerSession: () => request(
507
- config,
508
- routeFor(config, "createCustomerSession"),
509
- {
510
- method: "POST",
511
- body: {},
512
- onErrorContext: "createCustomerSession",
513
- errorPrefix: "Failed to create customer session"
514
- }
515
- ),
546
+ createCustomerSession: () => request(config, routeFor(config, "createCustomerSession"), {
547
+ method: "POST",
548
+ body: {},
549
+ onErrorContext: "createCustomerSession",
550
+ errorPrefix: "Failed to create customer session"
551
+ }),
516
552
  getMerchant: () => request(config, routeFor(config, "getMerchant"), {
517
553
  method: "GET",
518
554
  onErrorContext: "getMerchant",
@@ -542,6 +578,22 @@ function createHttpTransport(config) {
542
578
  onErrorContext: "getPaymentMethod",
543
579
  errorPrefix: "Failed to load payment method"
544
580
  }),
581
+ getAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
582
+ method: "GET",
583
+ onErrorContext: "getAutoRecharge",
584
+ errorPrefix: "Failed to load auto-recharge"
585
+ }),
586
+ saveAutoRecharge: (input) => request(config, routeFor(config, "autoRecharge"), {
587
+ method: "PUT",
588
+ body: input,
589
+ onErrorContext: "saveAutoRecharge",
590
+ errorPrefix: "Failed to save auto-recharge"
591
+ }),
592
+ disableAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
593
+ method: "DELETE",
594
+ onErrorContext: "disableAutoRecharge",
595
+ errorPrefix: "Failed to disable auto-recharge"
596
+ }),
545
597
  getUsage: () => request(config, routeFor(config, "getUsage"), {
546
598
  method: "GET",
547
599
  onErrorContext: "getUsage",
@@ -680,6 +732,42 @@ var enCopy = {
680
732
  creditEstimateExact: "= {credits} credits",
681
733
  creditEstimateApprox: "~ {credits} credits"
682
734
  },
735
+ autoRecharge: {
736
+ heading: "Auto recharge",
737
+ description: "Automatically top up so you never run out \u2014 recommended for production. You can turn this off anytime.",
738
+ settingsHeading: "Auto recharge settings",
739
+ setupTriggerLabel: "Set up auto-recharge",
740
+ modifyTriggerLabel: "Modify",
741
+ notConfiguredHint: "Automatic top-ups are off. Set up auto-recharge if you want credits added when your balance runs low.",
742
+ enableLabel: "Enable auto-recharge",
743
+ enableQuestion: "Would you like to set up automatic recharge?",
744
+ enableSentence: "Yes, automatically recharge my card when my credit balance falls below a threshold",
745
+ thresholdLabel: "When balance falls below",
746
+ thresholdAriaLabel: "Balance threshold",
747
+ fixedAmountLabel: "Add this amount",
748
+ fixedAmountAriaLabel: "Fixed top-up amount",
749
+ saveButton: "Save settings",
750
+ cancelButton: "Cancel",
751
+ disableButton: "Disable automatic top-up",
752
+ savedMessage: "Automatic top-up settings saved.",
753
+ disabledMessage: "Automatic top-ups disabled.",
754
+ setupRequiredMessage: "Confirm your card to activate automatic top-ups.",
755
+ setupHeading: "Authorize card",
756
+ setupDescription: "Authorize a card for automatic top-ups. You will not be charged now.",
757
+ setupSubmit: "Save card for auto-recharge",
758
+ setupProcessing: "Authorizing...",
759
+ setupAwaitingConfirmation: "Card authorized. Finishing activation \u2014 this can take a moment.",
760
+ setupAuthFailed: "Card authentication failed. Please try a different card.",
761
+ invalidThreshold: "Enter a valid balance threshold.",
762
+ thresholdTooLow: "Balance threshold must be greater than zero.",
763
+ minTopupAmount: "Top-up amount must be at least {amount}.",
764
+ topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount}).",
765
+ creditsPerRecharge: "\u2248 {credits} credits per recharge",
766
+ creditsPerRechargeApprox: "~ {credits} credits per recharge",
767
+ currencyPerRecharge: "\u2248 {amount} per recharge",
768
+ currencyPerRechargeApprox: "~ {amount} per recharge",
769
+ statusFailed: "Payment failed \u2014 update your card to resume"
770
+ },
683
771
  activationFlow: {
684
772
  heading: "Confirm your plan",
685
773
  activateButton: "Activate",
@@ -4306,7 +4394,7 @@ function getStripeCacheKey2(publishableKey, accountId) {
4306
4394
  return accountId ? `${publishableKey}:${accountId}` : publishableKey;
4307
4395
  }
4308
4396
  function useTopup(options) {
4309
- const { amount, currency } = options;
4397
+ const { amount, currency, autoRecharge } = options;
4310
4398
  const { createTopupPayment, customerRef, updateCustomerRef } = useSolvaPay();
4311
4399
  const [loading, setLoading] = (0, import_react27.useState)(false);
4312
4400
  const [error, setError] = (0, import_react27.useState)(null);
@@ -4325,7 +4413,7 @@ function useTopup(options) {
4325
4413
  setLoading(true);
4326
4414
  setError(null);
4327
4415
  try {
4328
- const result = await createTopupPayment({ amount, currency });
4416
+ const result = await createTopupPayment({ amount, currency, autoRecharge });
4329
4417
  if (!result || typeof result !== "object") {
4330
4418
  throw new Error("Invalid topup payment intent response from server");
4331
4419
  }
@@ -4357,7 +4445,7 @@ function useTopup(options) {
4357
4445
  setLoading(false);
4358
4446
  isStartingRef.current = false;
4359
4447
  }
4360
- }, [amount, currency, createTopupPayment, customerRef, updateCustomerRef, loading]);
4448
+ }, [amount, currency, autoRecharge, createTopupPayment, customerRef, updateCustomerRef, loading]);
4361
4449
  const reset = (0, import_react27.useCallback)(() => {
4362
4450
  isStartingRef.current = false;
4363
4451
  setLoading(false);
@@ -4389,6 +4477,7 @@ var Root7 = (0, import_react28.forwardRef)(function TopupFormRoot(props, forward
4389
4477
  const {
4390
4478
  amount,
4391
4479
  currency,
4480
+ autoRecharge,
4392
4481
  onSuccess,
4393
4482
  onError,
4394
4483
  returnUrl,
@@ -4412,7 +4501,8 @@ var Root7 = (0, import_react28.forwardRef)(function TopupFormRoot(props, forward
4412
4501
  stripePromise
4413
4502
  } = useTopup({
4414
4503
  amount,
4415
- currency
4504
+ currency,
4505
+ autoRecharge
4416
4506
  });
4417
4507
  const hasInitializedRef = (0, import_react28.useRef)(false);
4418
4508
  const hasAmount = amount > 0;
@@ -4901,170 +4991,1784 @@ function usePurchaseGate() {
4901
4991
  return useGateCtx2("usePurchaseGate");
4902
4992
  }
4903
4993
 
4904
- // src/primitives/ProductBadge.tsx
4994
+ // src/primitives/AutoRecharge.tsx
4995
+ var import_react32 = require("react");
4996
+ var import_react_dom = require("react-dom");
4997
+ var import_react_stripe_js3 = require("@stripe/react-stripe-js");
4998
+ var import_stripe_js3 = require("@stripe/stripe-js");
4999
+
5000
+ // src/hooks/useAutoRecharge.ts
4905
5001
  var import_react31 = require("react");
4906
- var import_jsx_runtime22 = require("react/jsx-runtime");
4907
- var ProductBadgeImpl = (0, import_react31.forwardRef)(function ProductBadge({ asChild, children, ...rest }, forwardedRef) {
4908
- const solva = (0, import_react31.useContext)(SolvaPayContext);
4909
- if (!solva) throw new MissingProviderError("ProductBadge");
4910
- const { purchases, loading, hasPaidPurchase, activePurchase } = usePurchase();
4911
- const copy = useCopy();
4912
- const [hasLoadedOnce, setHasLoadedOnce] = (0, import_react31.useState)(false);
5002
+
5003
+ // src/hooks/autoRechargeCache.ts
5004
+ var autoRechargeCache = /* @__PURE__ */ new Map();
5005
+ var CACHE_DURATION5 = 5 * 60 * 1e3;
5006
+ function autoRechargeCacheKeyFor(config) {
5007
+ return createTransportCacheKey(config, config?.api?.autoRecharge || "/api/auto-recharge");
5008
+ }
5009
+
5010
+ // src/hooks/useAutoRecharge.ts
5011
+ function mergeAutoRechargeConfig(config, display) {
5012
+ return display ? { ...config, display } : config;
5013
+ }
5014
+ async function fetchAutoRecharge(config) {
5015
+ const transport = config?.transport ?? createHttpTransport(config);
5016
+ if (!transport.getAutoRecharge) return null;
5017
+ const response = await transport.getAutoRecharge();
5018
+ if (!response.config) return null;
5019
+ return mergeAutoRechargeConfig(response.config, response.display);
5020
+ }
5021
+ function useAutoRecharge() {
5022
+ const { _config } = useSolvaPay();
5023
+ const key = autoRechargeCacheKeyFor(_config);
5024
+ const [config, setConfig] = (0, import_react31.useState)(
5025
+ () => autoRechargeCache.get(key)?.config ?? null
5026
+ );
5027
+ const [loading, setLoading] = (0, import_react31.useState)(() => {
5028
+ const cached = autoRechargeCache.get(key);
5029
+ return !cached || !cached.config && !cached.promise;
5030
+ });
5031
+ const [saving, setSaving] = (0, import_react31.useState)(false);
5032
+ const [disabling, setDisabling] = (0, import_react31.useState)(false);
5033
+ const [error, setError] = (0, import_react31.useState)(null);
5034
+ const requestSeq = (0, import_react31.useRef)(0);
5035
+ const load = (0, import_react31.useCallback)(
5036
+ async (force = false) => {
5037
+ const seq = requestSeq.current;
5038
+ const cached = autoRechargeCache.get(key);
5039
+ const now = Date.now();
5040
+ if (!force && cached?.config && now - cached.timestamp < CACHE_DURATION5) {
5041
+ if (seq !== requestSeq.current) return;
5042
+ setConfig(cached.config);
5043
+ setLoading(false);
5044
+ setError(null);
5045
+ return;
5046
+ }
5047
+ if (!force && cached?.promise) {
5048
+ setLoading(true);
5049
+ try {
5050
+ const value = await cached.promise;
5051
+ if (seq !== requestSeq.current) return;
5052
+ setConfig(value);
5053
+ setError(null);
5054
+ } catch (caught) {
5055
+ if (seq !== requestSeq.current) return;
5056
+ setError(caught instanceof Error ? caught : new Error(String(caught)));
5057
+ } finally {
5058
+ if (seq === requestSeq.current) {
5059
+ setLoading(false);
5060
+ }
5061
+ }
5062
+ return;
5063
+ }
5064
+ setLoading(true);
5065
+ setError(null);
5066
+ const promise = fetchAutoRecharge(_config);
5067
+ autoRechargeCache.set(key, {
5068
+ config: cached?.config ?? null,
5069
+ promise,
5070
+ timestamp: now
5071
+ });
5072
+ try {
5073
+ const value = await promise;
5074
+ if (seq !== requestSeq.current) return;
5075
+ autoRechargeCache.set(key, { config: value, promise: null, timestamp: Date.now() });
5076
+ setConfig(value);
5077
+ } catch (caught) {
5078
+ if (seq !== requestSeq.current) return;
5079
+ const err = caught instanceof Error ? caught : new Error(String(caught));
5080
+ autoRechargeCache.set(key, { config: null, promise: null, timestamp: Date.now() });
5081
+ setError(err);
5082
+ } finally {
5083
+ if (seq === requestSeq.current) {
5084
+ setLoading(false);
5085
+ }
5086
+ }
5087
+ },
5088
+ [_config, key]
5089
+ );
4913
5090
  (0, import_react31.useEffect)(() => {
4914
- if (!loading) setHasLoadedOnce(true);
4915
- }, [loading]);
4916
- const planToDisplay = activePurchase?.productName ?? null;
4917
- const shouldShow = planToDisplay !== null && (!loading || hasLoadedOnce);
4918
- if (!shouldShow) return null;
4919
- const commonProps = {
4920
- "data-solvapay-product-badge": "",
4921
- "data-loading": loading ? "" : void 0,
4922
- "data-has-purchase": activePurchase ? "" : void 0,
4923
- "data-has-paid-purchase": hasPaidPurchase ? "" : void 0,
4924
- role: "status",
4925
- "aria-live": "polite",
4926
- "aria-busy": loading,
4927
- "aria-label": interpolate(copy.product.currentProductLabel, { name: planToDisplay }),
4928
- ...rest
4929
- };
4930
- if (asChild) {
4931
- return (
4932
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4933
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Slot, { ref: forwardedRef, ...commonProps, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children: planToDisplay }) })
4934
- );
4935
- }
4936
- void purchases;
4937
- return (
4938
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
4939
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ref: forwardedRef, ...commonProps, children: children ?? planToDisplay })
5091
+ void load();
5092
+ }, [load]);
5093
+ const refresh = (0, import_react31.useCallback)(
5094
+ async (force = true) => {
5095
+ await load(force);
5096
+ },
5097
+ [load]
4940
5098
  );
4941
- });
4942
- var ProductBadge2 = ProductBadgeImpl;
4943
- var PlanBadge = ProductBadgeImpl;
5099
+ const save = (0, import_react31.useCallback)(
5100
+ async (input) => {
5101
+ const transport = _config?.transport ?? createHttpTransport(_config);
5102
+ if (!transport.saveAutoRecharge) {
5103
+ throw new Error("saveAutoRecharge is not available on this transport");
5104
+ }
5105
+ setSaving(true);
5106
+ setError(null);
5107
+ const seq = ++requestSeq.current;
5108
+ try {
5109
+ const result = await transport.saveAutoRecharge(input);
5110
+ if (seq !== requestSeq.current) return result;
5111
+ const nextConfig = mergeAutoRechargeConfig(result.config, result.display);
5112
+ autoRechargeCache.set(key, {
5113
+ config: nextConfig,
5114
+ promise: null,
5115
+ timestamp: Date.now()
5116
+ });
5117
+ setConfig(nextConfig);
5118
+ return result;
5119
+ } catch (caught) {
5120
+ const err = caught instanceof Error ? caught : new Error(String(caught));
5121
+ setError(err);
5122
+ throw err;
5123
+ } finally {
5124
+ setSaving(false);
5125
+ }
5126
+ },
5127
+ [_config, key]
5128
+ );
5129
+ const disable = (0, import_react31.useCallback)(async () => {
5130
+ const transport = _config?.transport ?? createHttpTransport(_config);
5131
+ if (!transport.disableAutoRecharge) {
5132
+ throw new Error("disableAutoRecharge is not available on this transport");
5133
+ }
5134
+ setDisabling(true);
5135
+ setError(null);
5136
+ const seq = ++requestSeq.current;
5137
+ try {
5138
+ const result = await transport.disableAutoRecharge();
5139
+ if (seq === requestSeq.current) {
5140
+ setConfig((current) => {
5141
+ const disabledConfig = current ? { ...current, enabled: false } : null;
5142
+ autoRechargeCache.set(key, {
5143
+ config: disabledConfig,
5144
+ promise: null,
5145
+ timestamp: Date.now()
5146
+ });
5147
+ return disabledConfig;
5148
+ });
5149
+ await refresh(true);
5150
+ setConfig((current) => {
5151
+ const disabledConfig = current ? { ...current, enabled: false } : null;
5152
+ autoRechargeCache.set(key, {
5153
+ config: disabledConfig,
5154
+ promise: null,
5155
+ timestamp: Date.now()
5156
+ });
5157
+ return disabledConfig;
5158
+ });
5159
+ }
5160
+ return result;
5161
+ } catch (caught) {
5162
+ const err = caught instanceof Error ? caught : new Error(String(caught));
5163
+ setError(err);
5164
+ throw err;
5165
+ } finally {
5166
+ setDisabling(false);
5167
+ }
5168
+ }, [_config, key, refresh]);
5169
+ return { config, loading, saving, disabling, error, refresh, save, disable };
5170
+ }
4944
5171
 
4945
- // src/primitives/PaywallNotice.tsx
4946
- var import_react36 = require("react");
5172
+ // src/primitives/autoRechargeActivation.ts
5173
+ var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
5174
+ async function waitForAutoRechargeActivation({
5175
+ refresh,
5176
+ getStatus,
5177
+ attempts = 5,
5178
+ delayMs = 800,
5179
+ sleep = defaultSleep
5180
+ }) {
5181
+ for (let attempt = 0; attempt < attempts; attempt++) {
5182
+ await refresh(true);
5183
+ if (getStatus() === "active") return true;
5184
+ if (attempt < attempts - 1) await sleep(delayMs);
5185
+ }
5186
+ return getStatus() === "active";
5187
+ }
4947
5188
 
4948
- // src/primitives/checkout/index.tsx
4949
- var import_react34 = require("react");
5189
+ // src/primitives/setupIntentReturn.ts
5190
+ var SETUP_INTENT_PARAMS = ["setup_intent", "setup_intent_client_secret", "redirect_status"];
5191
+ function readSetupIntentClientSecret(search) {
5192
+ return new URLSearchParams(search).get("setup_intent_client_secret");
5193
+ }
5194
+ function stripSetupIntentParams() {
5195
+ if (typeof window === "undefined") return;
5196
+ const url = new URL(window.location.href);
5197
+ let changed = false;
5198
+ for (const param of SETUP_INTENT_PARAMS) {
5199
+ if (url.searchParams.has(param)) {
5200
+ url.searchParams.delete(param);
5201
+ changed = true;
5202
+ }
5203
+ }
5204
+ if (!changed) return;
5205
+ const query = url.searchParams.toString();
5206
+ window.history.replaceState({}, "", `${url.pathname}${query ? `?${query}` : ""}${url.hash}`);
5207
+ }
4950
5208
 
4951
- // src/hooks/useCheckoutFlow.ts
4952
- var import_react33 = require("react");
5209
+ // src/utils/credit-estimation.ts
5210
+ var import_core2 = require("@solvapay/core");
5211
+ function estimateCredits(resolvedAmountMajor, currency, creditsPerMinorUnit, displayExchangeRate) {
5212
+ if (resolvedAmountMajor == null || resolvedAmountMajor <= 0) return null;
5213
+ if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
5214
+ const rate = displayExchangeRate ?? 1;
5215
+ const resolvedAmountMinor = Math.round(resolvedAmountMajor * getMinorUnitsPerMajor(currency));
5216
+ return Math.round(resolvedAmountMinor / rate * creditsPerMinorUnit);
5217
+ }
5218
+ function estimateCurrencyMajorFromCredits(credits, currency, creditsPerMinorUnit, displayExchangeRate) {
5219
+ if (credits == null || credits <= 0) return null;
5220
+ if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
5221
+ const rate = displayExchangeRate ?? 1;
5222
+ const displayMinor = (0, import_core2.creditsToDisplayMinorUnits)({
5223
+ credits,
5224
+ creditsPerMinorUnit,
5225
+ displayExchangeRate: rate,
5226
+ displayCurrency: currency
5227
+ });
5228
+ if (displayMinor === null) return null;
5229
+ return displayMinor / getMinorUnitsPerMajor(currency);
5230
+ }
4953
5231
 
4954
- // src/hooks/useTransport.ts
4955
- var import_react32 = require("react");
4956
- function useTransport() {
4957
- const { _config } = useSolvaPay();
4958
- return (0, import_react32.useMemo)(() => _config?.transport ?? createHttpTransport(_config), [_config]);
5232
+ // src/helpers/stripe-minimums.ts
5233
+ var STRIPE_MINIMUM_MINOR = {
5234
+ USD: 50,
5235
+ EUR: 50,
5236
+ GBP: 30,
5237
+ SEK: 300,
5238
+ NOK: 300,
5239
+ DKK: 250,
5240
+ CHF: 50,
5241
+ CAD: 50,
5242
+ AUD: 50,
5243
+ JPY: 50,
5244
+ KRW: 500
5245
+ };
5246
+ var DEFAULT_MINIMUM_MINOR = 50;
5247
+ function getStripeMinimumMinor(currency) {
5248
+ return STRIPE_MINIMUM_MINOR[currency.toUpperCase()] ?? DEFAULT_MINIMUM_MINOR;
4959
5249
  }
4960
5250
 
4961
- // src/primitives/checkout/shared.ts
4962
- function isPayg(plan) {
4963
- return isPaygPlan(plan ?? null);
5251
+ // src/helpers/auto-recharge-form.ts
5252
+ var DEFAULT_VALIDATION_MESSAGES = {
5253
+ invalidThreshold: "Enter a valid balance threshold.",
5254
+ thresholdTooLow: "Balance threshold must be greater than zero.",
5255
+ minTopupAmount: "Top-up amount must be at least {amount}.",
5256
+ topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount})."
5257
+ };
5258
+ function amountAnchors(thresholdValue, topupValue, unit = "currency") {
5259
+ return {
5260
+ thresholdBaseValue: thresholdValue,
5261
+ thresholdBaseUnit: unit,
5262
+ topupBaseValue: topupValue,
5263
+ topupBaseUnit: unit
5264
+ };
4964
5265
  }
4965
- function planSortByPaygFirstThenAsc(a, b) {
4966
- const aPayg = isPayg(a);
4967
- const bPayg = isPayg(b);
4968
- if (aPayg && !bPayg) return -1;
4969
- if (!aPayg && bPayg) return 1;
4970
- return (a.price ?? 0) - (b.price ?? 0);
5266
+ function createDefaultAutoRechargeForm(currency, defaultTopupMajor, defaultThresholdMajor) {
5267
+ const topup = defaultTopupMajor != null && defaultTopupMajor > 0 ? String(defaultTopupMajor) : "10";
5268
+ const threshold = defaultThresholdMajor != null && defaultThresholdMajor >= 0 ? String(defaultThresholdMajor) : "5";
5269
+ return {
5270
+ enabled: false,
5271
+ thresholdAmountMajor: threshold,
5272
+ thresholdUnit: "currency",
5273
+ topupAmountMajor: topup,
5274
+ topupUnit: "currency",
5275
+ ...amountAnchors(threshold, topup, "currency")
5276
+ };
4971
5277
  }
4972
- function buildDefaultCheckoutPlanFilter(allPlans) {
4973
- const hasNonPaygPaid = allPlans.some(
4974
- (p) => p.requiresPayment !== false && !isPayg(p)
4975
- );
4976
- return (plan) => {
4977
- if (plan.requiresPayment === false) return false;
4978
- if (hasNonPaygPaid && isPayg(plan)) return false;
4979
- return true;
5278
+ function parsePositiveNumber(value) {
5279
+ const trimmed = value.trim();
5280
+ if (trimmed.length === 0) return null;
5281
+ const parsed = Number(trimmed);
5282
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
5283
+ return parsed;
5284
+ }
5285
+ function parseNonNegativeNumber(value) {
5286
+ const trimmed = value.trim();
5287
+ if (trimmed.length === 0) return null;
5288
+ const parsed = Number(trimmed);
5289
+ if (!Number.isFinite(parsed) || parsed < 0) return null;
5290
+ return parsed;
5291
+ }
5292
+ function validateAutoRechargeForm(form, currency, conversion, messages = DEFAULT_VALIDATION_MESSAGES) {
5293
+ if (!form.enabled) {
5294
+ return {
5295
+ ok: true,
5296
+ payload: {
5297
+ enabled: false,
5298
+ triggerType: "balance",
5299
+ currency: currency.toUpperCase()
5300
+ }
5301
+ };
5302
+ }
5303
+ const payload = {
5304
+ enabled: true,
5305
+ triggerType: "balance",
5306
+ currency: currency.toUpperCase()
4980
5307
  };
5308
+ const minorPerMajor = getMinorUnitsPerMajor(currency);
5309
+ const minMinor = getStripeMinimumMinor(currency);
5310
+ const thresholdRaw = parseNonNegativeNumber(form.thresholdAmountMajor);
5311
+ if (thresholdRaw == null) {
5312
+ return { ok: false, error: messages.invalidThreshold };
5313
+ }
5314
+ if (form.thresholdUnit === "credits") {
5315
+ const major = estimateCurrencyMajorFromCredits(
5316
+ thresholdRaw,
5317
+ currency,
5318
+ conversion?.creditsPerMinorUnit,
5319
+ conversion?.displayExchangeRate
5320
+ );
5321
+ if (major == null) {
5322
+ return { ok: false, error: messages.invalidThreshold };
5323
+ }
5324
+ payload.thresholdAmountMajor = major;
5325
+ } else {
5326
+ payload.thresholdAmountMajor = thresholdRaw;
5327
+ }
5328
+ if (payload.thresholdAmountMajor == null || payload.thresholdAmountMajor <= 0) {
5329
+ return { ok: false, error: messages.thresholdTooLow };
5330
+ }
5331
+ const amountRaw = parsePositiveNumber(form.topupAmountMajor);
5332
+ if (amountRaw == null) {
5333
+ return {
5334
+ ok: false,
5335
+ error: interpolate(messages.minTopupAmount, {
5336
+ amount: formatPrice(minMinor, currency, { free: "" })
5337
+ })
5338
+ };
5339
+ }
5340
+ const amountMajor = form.topupUnit === "credits" ? estimateCurrencyMajorFromCredits(
5341
+ amountRaw,
5342
+ currency,
5343
+ conversion?.creditsPerMinorUnit,
5344
+ conversion?.displayExchangeRate
5345
+ ) : amountRaw;
5346
+ if (amountMajor == null || Math.round(amountMajor * minorPerMajor) < minMinor) {
5347
+ return {
5348
+ ok: false,
5349
+ error: interpolate(messages.minTopupAmount, {
5350
+ amount: formatPrice(minMinor, currency, { free: "" })
5351
+ })
5352
+ };
5353
+ }
5354
+ payload.topupAmountMajor = amountMajor;
5355
+ if (amountMajor < payload.thresholdAmountMajor) {
5356
+ return {
5357
+ ok: false,
5358
+ error: interpolate(messages.topupBelowThreshold, {
5359
+ amount: formatPrice(
5360
+ Math.round(payload.thresholdAmountMajor * minorPerMajor),
5361
+ currency,
5362
+ { free: "" }
5363
+ )
5364
+ })
5365
+ };
5366
+ }
5367
+ return { ok: true, payload };
4981
5368
  }
4982
- function formatContinueLabel(plan, locale, pricingOption) {
4983
- if (!plan) return "Continue";
4984
- if (isPayg(plan)) {
4985
- return `Continue with ${plan.name ?? "Pay as you go"}`;
5369
+ function triggerAmountMajorFromConfig(config) {
5370
+ const topupCurrency = config.topup.currency.toUpperCase();
5371
+ const minorPerMajor = getMinorUnitsPerMajor(topupCurrency);
5372
+ const { thresholdAmountMinor } = config.trigger;
5373
+ if (!Number.isFinite(thresholdAmountMinor) || thresholdAmountMinor < 0) {
5374
+ return null;
4986
5375
  }
4987
- const option = pricingOption ?? resolvePlanPricingOption(plan, null);
4988
- const currency = option.currency.toUpperCase();
4989
- const priceLabel = formatPrice(option.price ?? 0, currency, { locale });
4990
- const cycle = plan.billingCycle ? `/${shortCycle(plan.billingCycle)}` : "";
4991
- return `Continue with ${plan.name ?? "Plan"} \u2014 ${priceLabel}${cycle}`;
5376
+ return thresholdAmountMinor / minorPerMajor;
5377
+ }
5378
+ function configToForm(config, currency) {
5379
+ const base = createDefaultAutoRechargeForm(currency);
5380
+ const display = config.display;
5381
+ if (display?.thresholdAmountMajor != null && display.topupAmountMajor != null) {
5382
+ const thresholdStr2 = String(Math.max(0, display.thresholdAmountMajor));
5383
+ const topupStr2 = String(display.topupAmountMajor);
5384
+ return {
5385
+ ...base,
5386
+ enabled: config.enabled,
5387
+ thresholdAmountMajor: thresholdStr2,
5388
+ topupAmountMajor: topupStr2,
5389
+ ...amountAnchors(thresholdStr2, topupStr2, "currency")
5390
+ };
5391
+ }
5392
+ const thresholdMajor = triggerAmountMajorFromConfig(config);
5393
+ const thresholdStr = thresholdMajor != null ? String(Math.max(0, thresholdMajor)) : "0";
5394
+ const topupStr = String(config.topup.amountMinor / getMinorUnitsPerMajor(currency));
5395
+ return {
5396
+ ...base,
5397
+ enabled: config.enabled,
5398
+ thresholdAmountMajor: thresholdStr,
5399
+ topupAmountMajor: topupStr,
5400
+ ...amountAnchors(thresholdStr, topupStr, "currency")
5401
+ };
4992
5402
  }
4993
- function formatPaygRate(plan, locale) {
4994
- const creditsPerUnit = plan.creditsPerUnit ?? 1;
4995
- const creditLabel = creditsPerUnit === 1 ? "credit" : "credits";
4996
- return `${creditsPerUnit.toLocaleString(locale)} ${creditLabel} / call`;
5403
+ function formatAmountWithUnit(value, unit, currency) {
5404
+ const num = Number(value);
5405
+ if (!value || !Number.isFinite(num)) return "\u2014";
5406
+ if (unit === "credits") {
5407
+ return `${new Intl.NumberFormat().format(num)} credits`;
5408
+ }
5409
+ return formatPrice(Math.round(num * getMinorUnitsPerMajor(currency)), currency, { free: "" });
4997
5410
  }
4998
- function inferIncludedCredits(plan) {
4999
- const price = plan.price ?? 0;
5000
- const creditsPerUnit = plan.creditsPerUnit ?? 0;
5001
- if (price > 0 && creditsPerUnit > 0) {
5002
- return Math.round(price * creditsPerUnit);
5411
+ function buildSummaryLine(form, currency) {
5412
+ if (!form.enabled) return null;
5413
+ const thresholdDisplay = formatAmountWithUnit(
5414
+ form.thresholdAmountMajor,
5415
+ form.thresholdUnit,
5416
+ currency
5417
+ );
5418
+ const fixedDisplay = formatAmountWithUnit(form.topupAmountMajor, form.topupUnit, currency);
5419
+ return `When my balance falls below ${thresholdDisplay}, add ${fixedDisplay}.`;
5420
+ }
5421
+ function convertAmountForUnitFlip(value, fromUnit, toUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
5422
+ if (fromUnit === toUnit) return value;
5423
+ const parsed = Number(value);
5424
+ if (!Number.isFinite(parsed) || parsed <= 0) return value;
5425
+ if (fromUnit === "currency" && toUnit === "credits") {
5426
+ const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
5427
+ return credits != null ? String(credits) : value;
5003
5428
  }
5004
- return 0;
5429
+ const major = estimateCurrencyMajorFromCredits(
5430
+ parsed,
5431
+ currency,
5432
+ creditsPerMinorUnit,
5433
+ displayExchangeRate
5434
+ );
5435
+ return major != null ? String(major) : value;
5005
5436
  }
5006
- function shortCycle(cycle) {
5007
- if (!cycle) return "mo";
5008
- const lc = cycle.toLowerCase();
5009
- if (lc.startsWith("year") || lc === "annually" || lc === "annual") return "yr";
5010
- if (lc.startsWith("week")) return "wk";
5011
- if (lc.startsWith("day")) return "d";
5012
- return "mo";
5437
+ function flipUnitValue(anchor, targetUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
5438
+ if (targetUnit === anchor.unit) {
5439
+ return { value: anchor.value, unit: anchor.unit };
5440
+ }
5441
+ const converted = convertAmountForUnitFlip(
5442
+ anchor.value,
5443
+ anchor.unit,
5444
+ targetUnit,
5445
+ currency,
5446
+ creditsPerMinorUnit,
5447
+ displayExchangeRate
5448
+ );
5449
+ return { value: converted, unit: targetUnit };
5013
5450
  }
5014
5451
 
5015
- // src/hooks/useCheckoutFlow.ts
5016
- function useCheckoutFlow(opts) {
5017
- const {
5018
- productRef,
5019
- initialStep = "plan",
5020
- initialAmountMinor = null
5021
- } = opts;
5022
- const onPlanSelectRef = (0, import_react33.useRef)(opts.onPlanSelect);
5023
- const onAmountSelectRef = (0, import_react33.useRef)(opts.onAmountSelect);
5024
- const onPurchaseSuccessRef = (0, import_react33.useRef)(opts.onPurchaseSuccess);
5025
- const onErrorRef = (0, import_react33.useRef)(opts.onError);
5026
- onPlanSelectRef.current = opts.onPlanSelect;
5027
- onAmountSelectRef.current = opts.onAmountSelect;
5028
- onPurchaseSuccessRef.current = opts.onPurchaseSuccess;
5029
- onErrorRef.current = opts.onError;
5030
- const planCtx = usePlanSelector();
5031
- const planSelection = usePlanSelection();
5032
- const transport = useTransport();
5033
- const locale = useLocale();
5034
- const balance = useBalance();
5035
- const { creditsPerMinorUnit, displayExchangeRate, adjustBalance } = balance;
5036
- const { refetchPurchase } = useSolvaPay();
5037
- const { merchant } = useMerchant();
5038
- const [topupCurrencyOverride, setTopupCurrencyOverride] = (0, import_react33.useState)(null);
5039
- const topupCurrencies = (0, import_react33.useMemo)(() => {
5040
- const fromMerchant = (merchant?.supportedTopupCurrencies ?? []).map((code) => code.toUpperCase()).filter(Boolean);
5041
- const fallback = opts.topupCurrency?.toUpperCase() ?? merchant?.defaultCurrency?.toUpperCase() ?? null;
5042
- const list = fromMerchant.length > 0 ? fromMerchant : fallback ? [fallback] : [];
5043
- return Array.from(new Set(list));
5044
- }, [merchant?.supportedTopupCurrencies, merchant?.defaultCurrency, opts.topupCurrency]);
5045
- const resolvedDefaultTopupCurrency = opts.topupCurrency?.toUpperCase() ?? merchant?.defaultCurrency?.toUpperCase() ?? null;
5046
- const planPickerCurrency = planCtx.preferredCurrency?.toUpperCase() ?? null;
5047
- const topupCurrency = (topupCurrencyOverride && topupCurrencies.includes(topupCurrencyOverride) ? topupCurrencyOverride : null) ?? (planPickerCurrency && topupCurrencies.includes(planPickerCurrency) ? planPickerCurrency : null) ?? resolvedDefaultTopupCurrency;
5048
- const topupCurrencyReady = topupCurrency != null;
5049
- const setTopupCurrency = (0, import_react33.useCallback)(
5050
- (code) => {
5051
- const normalized = code.toUpperCase();
5052
- setTopupCurrencyOverride(normalized);
5053
- },
5054
- []
5055
- );
5056
- const [step, setStep] = (0, import_react33.useState)(initialStep);
5057
- const [status, setStatus] = (0, import_react33.useState)("idle");
5058
- const [selectedAmountMinor, setSelectedAmountMinor] = (0, import_react33.useState)(initialAmountMinor);
5059
- const [successMeta, setSuccessMeta] = (0, import_react33.useState)(null);
5060
- const [error, setError] = (0, import_react33.useState)(null);
5061
- const selectedAmountMinorRef = (0, import_react33.useRef)(initialAmountMinor);
5062
- const selectedPlan = planCtx.selectedPlan;
5063
- const selectedPlanRef = planCtx.selectedPlanRef;
5064
- const selectedPlanShape = selectedPlan;
5065
- const branch = selectedPlanShape ? isPayg(selectedPlanShape) ? "payg" : "recurring" : null;
5066
- const canGoBack = step === "amount" || step === "payment";
5067
- const selectPlan = (0, import_react33.useCallback)(
5452
+ // src/primitives/AutoRecharge.tsx
5453
+ var import_jsx_runtime22 = require("react/jsx-runtime");
5454
+ var AutoRechargeContext = (0, import_react32.createContext)(null);
5455
+ function useAutoRechargeCtx(part) {
5456
+ const ctx = (0, import_react32.useContext)(AutoRechargeContext);
5457
+ if (!ctx) {
5458
+ throw new Error(`AutoRecharge.${part} must be rendered inside <AutoRecharge.Root>.`);
5459
+ }
5460
+ return ctx;
5461
+ }
5462
+ function getCurrencySymbol2(currency) {
5463
+ try {
5464
+ const parts = new Intl.NumberFormat("en", { style: "currency", currency }).formatToParts(0);
5465
+ const sym = parts.find((p) => p.type === "currency");
5466
+ return sym?.value ?? currency.toUpperCase();
5467
+ } catch {
5468
+ return currency.toUpperCase();
5469
+ }
5470
+ }
5471
+ var stripePromiseCache3 = /* @__PURE__ */ new Map();
5472
+ function getStripeCacheKey3(publishableKey, accountId) {
5473
+ return accountId ? `${publishableKey}:${accountId}` : publishableKey;
5474
+ }
5475
+ var Root10 = (0, import_react32.forwardRef)(function AutoRechargeRoot({
5476
+ currency = "USD",
5477
+ defaultThresholdAmountMajor,
5478
+ defaultTopupAmountMajor,
5479
+ open: openProp,
5480
+ defaultOpen = false,
5481
+ onOpenChange,
5482
+ onSetupRequired,
5483
+ onSaved,
5484
+ onDisabled,
5485
+ deferCardSetup = false,
5486
+ onPendingConfig,
5487
+ asChild,
5488
+ children,
5489
+ className,
5490
+ ...rest
5491
+ }, forwardedRef) {
5492
+ const solva = (0, import_react32.useContext)(SolvaPayContext);
5493
+ if (!solva) throw new MissingProviderError("AutoRecharge");
5494
+ const autoRecharge = useAutoRecharge();
5495
+ const { creditsPerMinorUnit, displayExchangeRate } = useBalance();
5496
+ const copy = useCopy();
5497
+ const titleId = (0, import_react32.useId)();
5498
+ const triggerRef = (0, import_react32.useRef)(null);
5499
+ const defaultTopup = defaultTopupAmountMajor ?? defaultThresholdAmountMajor ?? void 0;
5500
+ const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react32.useState)(defaultOpen);
5501
+ const isControlled = openProp !== void 0;
5502
+ const open = isControlled ? openProp : uncontrolledOpen;
5503
+ const setOpen = (0, import_react32.useCallback)(
5504
+ (next) => {
5505
+ if (!isControlled) {
5506
+ setUncontrolledOpen(next);
5507
+ }
5508
+ onOpenChange?.(next);
5509
+ },
5510
+ [isControlled, onOpenChange]
5511
+ );
5512
+ const registerTriggerRef = (0, import_react32.useCallback)((node) => {
5513
+ triggerRef.current = node;
5514
+ }, []);
5515
+ const focusTrigger = (0, import_react32.useCallback)(() => {
5516
+ triggerRef.current?.focus();
5517
+ }, []);
5518
+ const [form, setForm] = (0, import_react32.useState)(
5519
+ () => autoRecharge.config ? configToForm(autoRecharge.config, currency) : createDefaultAutoRechargeForm(currency, defaultTopup)
5520
+ );
5521
+ const [validationError, setValidationError] = (0, import_react32.useState)(null);
5522
+ const [statusMessage, setStatusMessage] = (0, import_react32.useState)(null);
5523
+ const [setup, setSetup] = (0, import_react32.useState)(null);
5524
+ const latestConfigRef = (0, import_react32.useRef)(autoRecharge.config);
5525
+ (0, import_react32.useEffect)(() => {
5526
+ latestConfigRef.current = autoRecharge.config;
5527
+ }, [autoRecharge.config]);
5528
+ (0, import_react32.useEffect)(() => {
5529
+ if (autoRecharge.config) {
5530
+ setForm(configToForm(autoRecharge.config, currency));
5531
+ }
5532
+ }, [autoRecharge.config, currency]);
5533
+ const canToggleUnits = creditsPerMinorUnit != null && creditsPerMinorUnit > 0;
5534
+ const rate = displayExchangeRate ?? 1;
5535
+ const isApproximate = rate !== 1;
5536
+ const emitValidation = (0, import_react32.useCallback)(
5537
+ (next) => {
5538
+ const result = validateAutoRechargeForm(
5539
+ next,
5540
+ currency,
5541
+ { creditsPerMinorUnit, displayExchangeRate },
5542
+ copy.autoRecharge
5543
+ );
5544
+ if (!result.ok) {
5545
+ setValidationError(result.error);
5546
+ return null;
5547
+ }
5548
+ setValidationError(null);
5549
+ return result.payload;
5550
+ },
5551
+ [currency, creditsPerMinorUnit, displayExchangeRate, copy.autoRecharge]
5552
+ );
5553
+ const updateForm = (0, import_react32.useCallback)(
5554
+ (patch) => {
5555
+ setForm((prev) => {
5556
+ const next = { ...prev, ...patch };
5557
+ emitValidation(next);
5558
+ return next;
5559
+ });
5560
+ },
5561
+ [emitValidation]
5562
+ );
5563
+ const resetForm = (0, import_react32.useCallback)(() => {
5564
+ if (autoRecharge.config) {
5565
+ setForm(configToForm(autoRecharge.config, currency));
5566
+ } else {
5567
+ setForm(createDefaultAutoRechargeForm(currency, defaultTopup));
5568
+ }
5569
+ setValidationError(null);
5570
+ }, [autoRecharge.config, currency, defaultTopup]);
5571
+ const flipUnit = (0, import_react32.useCallback)(
5572
+ (valueKey, unitKey, baseValueKey, baseUnitKey, currentUnit) => {
5573
+ const nextUnit = currentUnit === "currency" ? "credits" : "currency";
5574
+ setForm((prev) => {
5575
+ const anchor = { value: prev[baseValueKey], unit: prev[baseUnitKey] };
5576
+ const flipped = flipUnitValue(
5577
+ anchor,
5578
+ nextUnit,
5579
+ currency,
5580
+ creditsPerMinorUnit,
5581
+ displayExchangeRate
5582
+ );
5583
+ const next = {
5584
+ ...prev,
5585
+ [unitKey]: flipped.unit,
5586
+ [valueKey]: flipped.value
5587
+ };
5588
+ emitValidation(next);
5589
+ return next;
5590
+ });
5591
+ },
5592
+ [currency, creditsPerMinorUnit, displayExchangeRate, emitValidation]
5593
+ );
5594
+ const fixedTopupHint = (0, import_react32.useMemo)(() => {
5595
+ const parsed = Number(form.topupAmountMajor);
5596
+ if (!Number.isFinite(parsed) || parsed <= 0) return null;
5597
+ if (form.topupUnit === "currency") {
5598
+ const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
5599
+ if (credits == null) return null;
5600
+ return { credits, approximate: isApproximate };
5601
+ }
5602
+ const major = estimateCurrencyMajorFromCredits(
5603
+ parsed,
5604
+ currency,
5605
+ creditsPerMinorUnit,
5606
+ displayExchangeRate
5607
+ );
5608
+ if (major == null) return null;
5609
+ return { major, approximate: isApproximate };
5610
+ }, [
5611
+ form.topupAmountMajor,
5612
+ form.topupUnit,
5613
+ currency,
5614
+ creditsPerMinorUnit,
5615
+ displayExchangeRate,
5616
+ isApproximate
5617
+ ]);
5618
+ const summaryLine = (0, import_react32.useMemo)(() => buildSummaryLine(form, currency), [form, currency]);
5619
+ const savedSummaryLine = (0, import_react32.useMemo)(() => {
5620
+ if (!autoRecharge.config?.enabled) return null;
5621
+ return buildSummaryLine(
5622
+ configToForm(autoRecharge.config, currency),
5623
+ currency
5624
+ );
5625
+ }, [autoRecharge.config, currency]);
5626
+ const save = (0, import_react32.useCallback)(async () => {
5627
+ const payload = emitValidation(form);
5628
+ if (!payload) return;
5629
+ const saveInput = deferCardSetup ? { ...payload, deferSetupIntent: true } : payload;
5630
+ const result = await autoRecharge.save(saveInput);
5631
+ if (result.setupClientSecret) {
5632
+ setSetup(result);
5633
+ setStatusMessage(copy.autoRecharge.setupRequiredMessage);
5634
+ await onSetupRequired?.(result);
5635
+ return;
5636
+ }
5637
+ setSetup(null);
5638
+ if (deferCardSetup) {
5639
+ await onPendingConfig?.(payload);
5640
+ }
5641
+ setStatusMessage(
5642
+ payload.enabled ? copy.autoRecharge.savedMessage : copy.autoRecharge.disabledMessage
5643
+ );
5644
+ setOpen(false);
5645
+ await onSaved?.(result);
5646
+ }, [
5647
+ autoRecharge,
5648
+ copy.autoRecharge,
5649
+ deferCardSetup,
5650
+ emitValidation,
5651
+ form,
5652
+ onPendingConfig,
5653
+ onSaved,
5654
+ onSetupRequired,
5655
+ setOpen
5656
+ ]);
5657
+ const disable = (0, import_react32.useCallback)(async () => {
5658
+ await autoRecharge.disable();
5659
+ setStatusMessage(copy.autoRecharge.disabledMessage);
5660
+ setSetup(null);
5661
+ await onDisabled?.();
5662
+ }, [autoRecharge, copy.autoRecharge, onDisabled]);
5663
+ const completeSetup = (0, import_react32.useCallback)(async () => {
5664
+ const activated = await waitForAutoRechargeActivation({
5665
+ refresh: autoRecharge.refresh,
5666
+ getStatus: () => latestConfigRef.current?.status
5667
+ });
5668
+ setSetup(null);
5669
+ if (!form.enabled) return;
5670
+ if (activated) {
5671
+ setStatusMessage(copy.autoRecharge.savedMessage);
5672
+ setOpen(false);
5673
+ } else {
5674
+ setStatusMessage(copy.autoRecharge.setupAwaitingConfirmation);
5675
+ }
5676
+ }, [autoRecharge, copy.autoRecharge, form.enabled, setOpen]);
5677
+ const dataState = setup ? "setup" : autoRecharge.error ? "error" : autoRecharge.loading ? "loading" : autoRecharge.saving ? "saving" : autoRecharge.disabling ? "disabling" : "idle";
5678
+ const ctx = (0, import_react32.useMemo)(
5679
+ () => ({
5680
+ form,
5681
+ updateForm,
5682
+ resetForm,
5683
+ validationError,
5684
+ currency,
5685
+ config: autoRecharge.config,
5686
+ loading: autoRecharge.loading,
5687
+ saving: autoRecharge.saving,
5688
+ disabling: autoRecharge.disabling,
5689
+ error: autoRecharge.error,
5690
+ statusMessage,
5691
+ setup,
5692
+ dataState,
5693
+ creditsPerMinorUnit,
5694
+ displayExchangeRate,
5695
+ canToggleUnits,
5696
+ isApproximate,
5697
+ summaryLine,
5698
+ savedSummaryLine,
5699
+ deferCardSetup,
5700
+ fixedTopupHint: fixedTopupHint && "credits" in fixedTopupHint ? String(fixedTopupHint.credits) : fixedTopupHint && "major" in fixedTopupHint ? formatPrice(
5701
+ Math.round(fixedTopupHint.major * getMinorUnitsPerMajor(currency)),
5702
+ currency,
5703
+ { free: "" }
5704
+ ) : null,
5705
+ open,
5706
+ setOpen,
5707
+ titleId,
5708
+ registerTriggerRef,
5709
+ focusTrigger,
5710
+ save,
5711
+ disable,
5712
+ completeSetup,
5713
+ flipUnit
5714
+ }),
5715
+ [
5716
+ form,
5717
+ updateForm,
5718
+ resetForm,
5719
+ validationError,
5720
+ currency,
5721
+ autoRecharge.config,
5722
+ autoRecharge.loading,
5723
+ autoRecharge.saving,
5724
+ autoRecharge.disabling,
5725
+ autoRecharge.error,
5726
+ statusMessage,
5727
+ setup,
5728
+ dataState,
5729
+ creditsPerMinorUnit,
5730
+ displayExchangeRate,
5731
+ canToggleUnits,
5732
+ isApproximate,
5733
+ summaryLine,
5734
+ savedSummaryLine,
5735
+ deferCardSetup,
5736
+ fixedTopupHint,
5737
+ open,
5738
+ setOpen,
5739
+ titleId,
5740
+ registerTriggerRef,
5741
+ focusTrigger,
5742
+ save,
5743
+ disable,
5744
+ completeSetup,
5745
+ flipUnit
5746
+ ]
5747
+ );
5748
+ const Comp = asChild ? Slot : "section";
5749
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AutoRechargeContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5750
+ Comp,
5751
+ {
5752
+ ref: forwardedRef,
5753
+ className,
5754
+ "aria-label": "Automatic credit top-up",
5755
+ "data-solvapay-auto-recharge": "",
5756
+ "data-state": dataState,
5757
+ ...rest,
5758
+ children
5759
+ }
5760
+ ) });
5761
+ });
5762
+ var Loading7 = (0, import_react32.forwardRef)(
5763
+ function AutoRechargeLoading({ className, children, ...rest }, forwardedRef) {
5764
+ const ctx = useAutoRechargeCtx("Loading");
5765
+ if (!ctx.loading) return null;
5766
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-loading": "", ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
5767
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Spinner, { size: "sm" }),
5768
+ " Loading auto-recharge settings\u2026"
5769
+ ] }) });
5770
+ }
5771
+ );
5772
+ var Card2 = (0, import_react32.forwardRef)(function AutoRechargeCard({ className, children, ...rest }, forwardedRef) {
5773
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5774
+ "section",
5775
+ {
5776
+ ref: forwardedRef,
5777
+ className,
5778
+ "data-solvapay-auto-recharge-card": "",
5779
+ ...rest,
5780
+ children
5781
+ }
5782
+ );
5783
+ });
5784
+ var CardHeading = (0, import_react32.forwardRef)(
5785
+ function AutoRechargeCardHeading({ className, children, ...rest }, forwardedRef) {
5786
+ const copy = useCopy();
5787
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5788
+ "h3",
5789
+ {
5790
+ ref: forwardedRef,
5791
+ className,
5792
+ "data-solvapay-auto-recharge-card-heading": "",
5793
+ ...rest,
5794
+ children: children ?? copy.autoRecharge.heading
5795
+ }
5796
+ );
5797
+ }
5798
+ );
5799
+ var CardSummary = (0, import_react32.forwardRef)(
5800
+ function AutoRechargeCardSummary({ className, children, ...rest }, forwardedRef) {
5801
+ const ctx = useAutoRechargeCtx("CardSummary");
5802
+ const copy = useCopy();
5803
+ const text = ctx.savedSummaryLine ?? copy.autoRecharge.notConfiguredHint;
5804
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5805
+ "p",
5806
+ {
5807
+ ref: forwardedRef,
5808
+ className,
5809
+ "data-solvapay-auto-recharge-card-summary": "",
5810
+ ...rest,
5811
+ children: children ?? text
5812
+ }
5813
+ );
5814
+ }
5815
+ );
5816
+ var Trigger = (0, import_react32.forwardRef)(function AutoRechargeTrigger({ asChild, onClick, children, className, ...rest }, forwardedRef) {
5817
+ const ctx = useAutoRechargeCtx("Trigger");
5818
+ const copy = useCopy();
5819
+ const hasExistingConfig = Boolean(ctx.config?.enabled);
5820
+ const label = hasExistingConfig ? copy.autoRecharge.modifyTriggerLabel : copy.autoRecharge.setupTriggerLabel;
5821
+ const setRefs = (node) => {
5822
+ ctx.registerTriggerRef(node);
5823
+ if (typeof forwardedRef === "function") {
5824
+ forwardedRef(node);
5825
+ } else if (forwardedRef) {
5826
+ forwardedRef.current = node;
5827
+ }
5828
+ };
5829
+ const commonProps = {
5830
+ "data-solvapay-auto-recharge-trigger": "",
5831
+ type: "button",
5832
+ "aria-haspopup": "dialog",
5833
+ "aria-expanded": ctx.open,
5834
+ disabled: ctx.loading,
5835
+ onClick: composeEventHandlers(onClick, (event) => {
5836
+ event.preventDefault();
5837
+ ctx.resetForm();
5838
+ ctx.setOpen(true);
5839
+ }),
5840
+ className,
5841
+ ...rest
5842
+ };
5843
+ if (asChild) {
5844
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Slot, { ref: setRefs, ...commonProps, children: children ?? label });
5845
+ }
5846
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { ref: setRefs, ...commonProps, children: children ?? label });
5847
+ });
5848
+ var Overlay = (0, import_react32.forwardRef)(
5849
+ function AutoRechargeOverlay({ onClick, className, ...rest }, forwardedRef) {
5850
+ const ctx = useAutoRechargeCtx("Overlay");
5851
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5852
+ "div",
5853
+ {
5854
+ ref: forwardedRef,
5855
+ className,
5856
+ "data-solvapay-auto-recharge-overlay": "",
5857
+ "aria-hidden": "true",
5858
+ onClick: composeEventHandlers(onClick, () => {
5859
+ ctx.resetForm();
5860
+ ctx.setOpen(false);
5861
+ ctx.focusTrigger();
5862
+ }),
5863
+ ...rest
5864
+ }
5865
+ );
5866
+ }
5867
+ );
5868
+ var Content = (0, import_react32.forwardRef)(function AutoRechargeContent({ className, children, ...rest }, forwardedRef) {
5869
+ const ctx = useAutoRechargeCtx("Content");
5870
+ const panelRef = (0, import_react32.useRef)(null);
5871
+ (0, import_react32.useEffect)(() => {
5872
+ if (!ctx.open) return;
5873
+ const handleKeyDown = (event) => {
5874
+ if (event.key === "Escape") {
5875
+ ctx.resetForm();
5876
+ ctx.setOpen(false);
5877
+ ctx.focusTrigger();
5878
+ }
5879
+ };
5880
+ document.addEventListener("keydown", handleKeyDown);
5881
+ const focusTarget = panelRef.current?.querySelector(
5882
+ 'button:not([disabled]), input:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'
5883
+ );
5884
+ focusTarget?.focus();
5885
+ return () => {
5886
+ document.removeEventListener("keydown", handleKeyDown);
5887
+ };
5888
+ }, [ctx.open, ctx.resetForm, ctx.setOpen, ctx.focusTrigger]);
5889
+ if (!ctx.open || typeof document === "undefined") return null;
5890
+ return (0, import_react_dom.createPortal)(
5891
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { "data-solvapay-auto-recharge-portal": "", children: [
5892
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Overlay, {}),
5893
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5894
+ "div",
5895
+ {
5896
+ ref: (node) => {
5897
+ panelRef.current = node;
5898
+ if (typeof forwardedRef === "function") {
5899
+ forwardedRef(node);
5900
+ } else if (forwardedRef) {
5901
+ forwardedRef.current = node;
5902
+ }
5903
+ },
5904
+ role: "dialog",
5905
+ "aria-modal": "true",
5906
+ "aria-labelledby": ctx.titleId,
5907
+ className,
5908
+ "data-solvapay-auto-recharge-content": "",
5909
+ ...rest,
5910
+ children
5911
+ }
5912
+ )
5913
+ ] }),
5914
+ document.body
5915
+ );
5916
+ });
5917
+ var Title = (0, import_react32.forwardRef)(
5918
+ function AutoRechargeTitle({ className, children, ...rest }, forwardedRef) {
5919
+ const ctx = useAutoRechargeCtx("Title");
5920
+ const copy = useCopy();
5921
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5922
+ "h2",
5923
+ {
5924
+ ref: forwardedRef,
5925
+ id: ctx.titleId,
5926
+ className,
5927
+ "data-solvapay-auto-recharge-title": "",
5928
+ ...rest,
5929
+ children: children ?? copy.autoRecharge.settingsHeading
5930
+ }
5931
+ );
5932
+ }
5933
+ );
5934
+ var EnableQuestion = (0, import_react32.forwardRef)(
5935
+ function AutoRechargeEnableQuestion({ className, children, ...rest }, forwardedRef) {
5936
+ const copy = useCopy();
5937
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-question": "", ...rest, children: children ?? copy.autoRecharge.enableQuestion });
5938
+ }
5939
+ );
5940
+ var EnableSentence = (0, import_react32.forwardRef)(
5941
+ function AutoRechargeEnableSentence({ className, children, ...rest }, forwardedRef) {
5942
+ const copy = useCopy();
5943
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5944
+ "label",
5945
+ {
5946
+ ref: forwardedRef,
5947
+ className,
5948
+ "data-solvapay-auto-recharge-enable-sentence": "",
5949
+ ...rest,
5950
+ children: children ?? copy.autoRecharge.enableSentence
5951
+ }
5952
+ );
5953
+ }
5954
+ );
5955
+ var EnableRow = (0, import_react32.forwardRef)(
5956
+ function AutoRechargeEnableRow({ className, children, ...rest }, forwardedRef) {
5957
+ const enableId = (0, import_react32.useId)();
5958
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5959
+ "div",
5960
+ {
5961
+ ref: forwardedRef,
5962
+ className,
5963
+ "data-solvapay-auto-recharge-enable-row": "",
5964
+ ...rest,
5965
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
5966
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EnableSwitch, { appearance: "checkbox", id: enableId }),
5967
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EnableSentence, { htmlFor: enableId })
5968
+ ] })
5969
+ }
5970
+ );
5971
+ }
5972
+ );
5973
+ var CancelButton = (0, import_react32.forwardRef)(
5974
+ function AutoRechargeCancelButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
5975
+ const ctx = useAutoRechargeCtx("CancelButton");
5976
+ const copy = useCopy();
5977
+ const commonProps = {
5978
+ "data-solvapay-auto-recharge-cancel": "",
5979
+ type: "button",
5980
+ onClick: composeEventHandlers(onClick, (event) => {
5981
+ event.preventDefault();
5982
+ ctx.resetForm();
5983
+ ctx.setOpen(false);
5984
+ ctx.focusTrigger();
5985
+ }),
5986
+ className,
5987
+ ...rest
5988
+ };
5989
+ if (asChild) {
5990
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5991
+ Slot,
5992
+ {
5993
+ ref: forwardedRef,
5994
+ ...commonProps,
5995
+ children: children ?? copy.autoRecharge.cancelButton
5996
+ }
5997
+ );
5998
+ }
5999
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.cancelButton });
6000
+ }
6001
+ );
6002
+ var Header = (0, import_react32.forwardRef)(
6003
+ function AutoRechargeHeader({ className, ...rest }, forwardedRef) {
6004
+ const copy = useCopy();
6005
+ const headingId = (0, import_react32.useId)();
6006
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6007
+ "header",
6008
+ {
6009
+ ref: forwardedRef,
6010
+ className,
6011
+ "data-solvapay-auto-recharge-header": "",
6012
+ ...rest,
6013
+ children: [
6014
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("section", { "data-solvapay-auto-recharge-heading-group": "", children: [
6015
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { id: headingId, "data-solvapay-auto-recharge-heading": "", children: copy.autoRecharge.heading }),
6016
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Description, {})
6017
+ ] }),
6018
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(EnableSwitch, { "aria-labelledby": headingId })
6019
+ ]
6020
+ }
6021
+ );
6022
+ }
6023
+ );
6024
+ var Description = (0, import_react32.forwardRef)(
6025
+ function AutoRechargeDescription({ className, children, ...rest }, forwardedRef) {
6026
+ const copy = useCopy();
6027
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6028
+ "p",
6029
+ {
6030
+ ref: forwardedRef,
6031
+ className,
6032
+ "data-solvapay-auto-recharge-description": "",
6033
+ ...rest,
6034
+ children: children ?? copy.autoRecharge.description
6035
+ }
6036
+ );
6037
+ }
6038
+ );
6039
+ var EnableSwitch = (0, import_react32.forwardRef)(
6040
+ function AutoRechargeEnableSwitch({ asChild, appearance = "switch", onChange, className, ...rest }, forwardedRef) {
6041
+ const ctx = useAutoRechargeCtx("EnableSwitch");
6042
+ const copy = useCopy();
6043
+ const commonProps = {
6044
+ "data-solvapay-auto-recharge-enable": "",
6045
+ "data-appearance": appearance,
6046
+ type: "checkbox",
6047
+ ...appearance === "switch" ? { role: "switch", "aria-checked": ctx.form.enabled } : {},
6048
+ checked: ctx.form.enabled,
6049
+ "aria-label": copy.autoRecharge.enableLabel,
6050
+ disabled: ctx.loading || ctx.saving || ctx.disabling || !!ctx.setup,
6051
+ onChange: composeEventHandlers(onChange, (event) => {
6052
+ ctx.updateForm({ enabled: event.currentTarget.checked });
6053
+ }),
6054
+ className,
6055
+ ...rest
6056
+ };
6057
+ if (asChild) {
6058
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6059
+ Slot,
6060
+ {
6061
+ ref: forwardedRef,
6062
+ ...commonProps
6063
+ }
6064
+ );
6065
+ }
6066
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("input", { ref: forwardedRef, ...commonProps });
6067
+ }
6068
+ );
6069
+ var Fields = (0, import_react32.forwardRef)(
6070
+ function AutoRechargeFields({ className, children, ...rest }, forwardedRef) {
6071
+ const ctx = useAutoRechargeCtx("Fields");
6072
+ const copy = useCopy();
6073
+ if (!ctx.form.enabled) return null;
6074
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6075
+ "fieldset",
6076
+ {
6077
+ ref: forwardedRef,
6078
+ className,
6079
+ disabled: ctx.saving || ctx.disabling,
6080
+ "data-solvapay-auto-recharge-fields": "",
6081
+ "data-solvapay-auto-recharge-body": "",
6082
+ "data-state": "open",
6083
+ ...rest,
6084
+ children: [
6085
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("legend", { className: "sr-only", children: copy.autoRecharge.heading }),
6086
+ children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6087
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Summary3, {}),
6088
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThresholdField, {}),
6089
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TopupField, {}),
6090
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ValidationError, {})
6091
+ ] })
6092
+ ]
6093
+ }
6094
+ );
6095
+ }
6096
+ );
6097
+ var Setup = (0, import_react32.forwardRef)(
6098
+ function AutoRechargeSetup({ className, children, ...rest }, forwardedRef) {
6099
+ const ctx = useAutoRechargeCtx("Setup");
6100
+ if (!ctx.setup?.setupClientSecret) return null;
6101
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6102
+ "div",
6103
+ {
6104
+ ref: forwardedRef,
6105
+ className,
6106
+ "data-solvapay-auto-recharge-setup-panel": "",
6107
+ ...rest,
6108
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardSetup, { setup: ctx.setup, onComplete: ctx.completeSetup })
6109
+ }
6110
+ );
6111
+ }
6112
+ );
6113
+ var Body = (0, import_react32.forwardRef)(
6114
+ function AutoRechargeBody({ className, children, ...rest }, forwardedRef) {
6115
+ const ctx = useAutoRechargeCtx("Body");
6116
+ if (ctx.setup?.setupClientSecret) {
6117
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Setup, { className });
6118
+ }
6119
+ if (!ctx.form.enabled) return null;
6120
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Fields, { ref: forwardedRef, className, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6121
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Summary3, {}),
6122
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ThresholdField, {}),
6123
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TopupField, {}),
6124
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ValidationError, {}),
6125
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Actions, {})
6126
+ ] }) });
6127
+ }
6128
+ );
6129
+ var Summary3 = (0, import_react32.forwardRef)(
6130
+ function AutoRechargeSummary({ className, children, ...rest }, forwardedRef) {
6131
+ const ctx = useAutoRechargeCtx("Summary");
6132
+ if (!ctx.summaryLine) return null;
6133
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-summary": "", ...rest, children: children ?? ctx.summaryLine });
6134
+ }
6135
+ );
6136
+ var AmountField = (0, import_react32.forwardRef)(function AutoRechargeAmountField({ field, showLabel = true, asChild, onChange, className, ...rest }, forwardedRef) {
6137
+ const ctx = useAutoRechargeCtx("AmountField");
6138
+ const copy = useCopy();
6139
+ const fieldConfig = {
6140
+ threshold: {
6141
+ label: copy.autoRecharge.thresholdLabel,
6142
+ ariaLabel: copy.autoRecharge.thresholdAriaLabel,
6143
+ unitToggleLabel: "balance threshold",
6144
+ value: ctx.form.thresholdAmountMajor,
6145
+ unit: ctx.form.thresholdUnit,
6146
+ unitKey: "thresholdUnit",
6147
+ valueKey: "thresholdAmountMajor",
6148
+ baseValueKey: "thresholdBaseValue",
6149
+ baseUnitKey: "thresholdBaseUnit",
6150
+ mode: ctx.form.thresholdUnit === "currency" ? "currency" : "number",
6151
+ onValue: (value) => ctx.updateForm({
6152
+ thresholdAmountMajor: value,
6153
+ thresholdBaseValue: value,
6154
+ thresholdBaseUnit: ctx.form.thresholdUnit
6155
+ })
6156
+ },
6157
+ fixed: {
6158
+ label: copy.autoRecharge.fixedAmountLabel,
6159
+ ariaLabel: copy.autoRecharge.fixedAmountAriaLabel,
6160
+ unitToggleLabel: "fixed top-up amount",
6161
+ value: ctx.form.topupAmountMajor,
6162
+ unit: ctx.form.topupUnit,
6163
+ unitKey: "topupUnit",
6164
+ valueKey: "topupAmountMajor",
6165
+ baseValueKey: "topupBaseValue",
6166
+ baseUnitKey: "topupBaseUnit",
6167
+ mode: ctx.form.topupUnit === "currency" ? "currency" : "number",
6168
+ onValue: (value) => ctx.updateForm({
6169
+ topupAmountMajor: value,
6170
+ topupBaseValue: value,
6171
+ topupBaseUnit: ctx.form.topupUnit
6172
+ })
6173
+ }
6174
+ }[field];
6175
+ const inputId = (0, import_react32.useId)();
6176
+ const prefix = fieldConfig.mode === "currency" ? getCurrencySymbol2(ctx.currency) : void 0;
6177
+ const handleChange = (event) => {
6178
+ const raw = event.target.value;
6179
+ const next = fieldConfig.mode === "currency" ? raw.replace(/[^0-9.]/g, "") : raw.replace(/[^0-9]/g, "");
6180
+ fieldConfig.onValue(next);
6181
+ };
6182
+ const inputProps = {
6183
+ id: inputId,
6184
+ "data-solvapay-auto-recharge-amount": "",
6185
+ "data-field": field,
6186
+ type: "text",
6187
+ inputMode: fieldConfig.mode === "currency" ? "decimal" : "numeric",
6188
+ placeholder: fieldConfig.mode === "currency" ? "0.00" : "0",
6189
+ value: fieldConfig.value,
6190
+ "aria-label": fieldConfig.ariaLabel,
6191
+ onChange: composeEventHandlers(onChange, handleChange),
6192
+ className,
6193
+ ...rest
6194
+ };
6195
+ const slotRef = forwardedRef;
6196
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { "data-solvapay-auto-recharge-field": "", "data-field": field, children: [
6197
+ showLabel ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: inputId, children: fieldConfig.label }) : null,
6198
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { "data-solvapay-auto-recharge-amount-row": "", children: [
6199
+ prefix ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "data-solvapay-auto-recharge-currency-prefix": "", "aria-hidden": "true", children: prefix }) : null,
6200
+ asChild ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Slot, { ref: slotRef, ...inputProps }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("input", { ref: forwardedRef, ...inputProps }),
6201
+ ctx.canToggleUnits ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6202
+ UnitToggle,
6203
+ {
6204
+ unit: fieldConfig.unit,
6205
+ fieldLabel: fieldConfig.unitToggleLabel,
6206
+ onToggle: () => ctx.flipUnit(
6207
+ fieldConfig.valueKey,
6208
+ fieldConfig.unitKey,
6209
+ fieldConfig.baseValueKey,
6210
+ fieldConfig.baseUnitKey,
6211
+ fieldConfig.unit
6212
+ )
6213
+ }
6214
+ ) : null
6215
+ ] })
6216
+ ] });
6217
+ });
6218
+ var ThresholdField = (0, import_react32.forwardRef)(
6219
+ function AutoRechargeThresholdField({ className, ...rest }, ref) {
6220
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("section", { ref, className, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AmountField, { field: "threshold" }) });
6221
+ }
6222
+ );
6223
+ var TopupField = (0, import_react32.forwardRef)(
6224
+ function AutoRechargeTopupField({ className, ...rest }, ref) {
6225
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6226
+ "section",
6227
+ {
6228
+ ref,
6229
+ className,
6230
+ "data-solvapay-auto-recharge-topup-field": "",
6231
+ ...rest,
6232
+ children: [
6233
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AmountField, { field: "fixed" }),
6234
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Hint, {})
6235
+ ]
6236
+ }
6237
+ );
6238
+ }
6239
+ );
6240
+ var UnitToggle = (0, import_react32.forwardRef)(function AutoRechargeUnitToggle({ unit, fieldLabel, onToggle, className, ...rest }, forwardedRef) {
6241
+ const ctx = useAutoRechargeCtx("UnitToggle");
6242
+ const targetUnitLabel = unit === "currency" ? "credits" : "currency";
6243
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6244
+ "button",
6245
+ {
6246
+ ref: forwardedRef,
6247
+ type: "button",
6248
+ className,
6249
+ "data-solvapay-auto-recharge-unit-toggle": "",
6250
+ "aria-label": `Switch ${fieldLabel} to ${targetUnitLabel}`,
6251
+ onClick: onToggle,
6252
+ ...rest,
6253
+ children: unit === "currency" ? ctx.currency.toUpperCase() : "credits"
6254
+ }
6255
+ );
6256
+ });
6257
+ var Hint = (0, import_react32.forwardRef)(
6258
+ function AutoRechargeHint({ className, ...rest }, forwardedRef) {
6259
+ const ctx = useAutoRechargeCtx("Hint");
6260
+ const copy = useCopy();
6261
+ const hint = ctx.fixedTopupHint;
6262
+ if (!hint) return null;
6263
+ const isCreditsHint = ctx.form.topupUnit === "currency";
6264
+ const text = isCreditsHint ? interpolate(
6265
+ ctx.isApproximate ? copy.autoRecharge.creditsPerRechargeApprox : copy.autoRecharge.creditsPerRecharge,
6266
+ { credits: new Intl.NumberFormat().format(Number(hint)) }
6267
+ ) : interpolate(
6268
+ ctx.isApproximate ? copy.autoRecharge.currencyPerRechargeApprox : copy.autoRecharge.currencyPerRecharge,
6269
+ { amount: hint }
6270
+ );
6271
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-hint": "", ...rest, children: text });
6272
+ }
6273
+ );
6274
+ var ValidationError = (0, import_react32.forwardRef)(function AutoRechargeValidationError({ className, ...rest }, forwardedRef) {
6275
+ const ctx = useAutoRechargeCtx("ValidationError");
6276
+ if (!ctx.validationError) return null;
6277
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6278
+ "p",
6279
+ {
6280
+ ref: forwardedRef,
6281
+ role: "alert",
6282
+ "aria-live": "polite",
6283
+ className,
6284
+ "data-solvapay-auto-recharge-validation-error": "",
6285
+ ...rest,
6286
+ children: ctx.validationError
6287
+ }
6288
+ );
6289
+ });
6290
+ var Actions = (0, import_react32.forwardRef)(
6291
+ function AutoRechargeActions({ className, children, ...rest }, forwardedRef) {
6292
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6293
+ "menu",
6294
+ {
6295
+ ref: forwardedRef,
6296
+ className,
6297
+ "data-solvapay-auto-recharge-actions": "",
6298
+ ...rest,
6299
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6300
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CancelButton, {}) }),
6301
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SaveButton, {}) })
6302
+ ] })
6303
+ }
6304
+ );
6305
+ }
6306
+ );
6307
+ var SaveButton = (0, import_react32.forwardRef)(function AutoRechargeSaveButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
6308
+ const ctx = useAutoRechargeCtx("SaveButton");
6309
+ const copy = useCopy();
6310
+ const dataState = ctx.saving ? "processing" : ctx.validationError ? "disabled" : "idle";
6311
+ const commonProps = {
6312
+ "data-solvapay-auto-recharge-save": "",
6313
+ "data-state": dataState,
6314
+ type: "button",
6315
+ disabled: ctx.saving || ctx.disabling || !!ctx.validationError,
6316
+ "aria-busy": ctx.saving,
6317
+ onClick: composeEventHandlers(onClick, (event) => {
6318
+ event.preventDefault();
6319
+ void ctx.save();
6320
+ }),
6321
+ className,
6322
+ ...rest
6323
+ };
6324
+ const content = ctx.saving ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6325
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Spinner, { size: "sm" }),
6326
+ " ",
6327
+ copy.cta.processing
6328
+ ] }) : children ?? copy.autoRecharge.saveButton;
6329
+ if (asChild) {
6330
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6331
+ Slot,
6332
+ {
6333
+ ref: forwardedRef,
6334
+ ...commonProps,
6335
+ children: content
6336
+ }
6337
+ );
6338
+ }
6339
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { ref: forwardedRef, ...commonProps, children: content });
6340
+ });
6341
+ var DisableButton = (0, import_react32.forwardRef)(
6342
+ function AutoRechargeDisableButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
6343
+ const ctx = useAutoRechargeCtx("DisableButton");
6344
+ const copy = useCopy();
6345
+ if (!ctx.config) return null;
6346
+ const commonProps = {
6347
+ "data-solvapay-auto-recharge-disable": "",
6348
+ type: "button",
6349
+ disabled: ctx.saving || ctx.disabling,
6350
+ "aria-busy": ctx.disabling,
6351
+ onClick: composeEventHandlers(onClick, (event) => {
6352
+ event.preventDefault();
6353
+ void ctx.disable();
6354
+ }),
6355
+ className,
6356
+ ...rest
6357
+ };
6358
+ if (asChild) {
6359
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6360
+ Slot,
6361
+ {
6362
+ ref: forwardedRef,
6363
+ ...commonProps,
6364
+ children: children ?? copy.autoRecharge.disableButton
6365
+ }
6366
+ );
6367
+ }
6368
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.disableButton });
6369
+ }
6370
+ );
6371
+ var ErrorSlot7 = (0, import_react32.forwardRef)(
6372
+ function AutoRechargeError({ className, children, ...rest }, forwardedRef) {
6373
+ const ctx = useAutoRechargeCtx("Error");
6374
+ if (!ctx.error) return null;
6375
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6376
+ "p",
6377
+ {
6378
+ ref: forwardedRef,
6379
+ role: "alert",
6380
+ "aria-live": "polite",
6381
+ className,
6382
+ "data-solvapay-auto-recharge-error": "",
6383
+ ...rest,
6384
+ children: children ?? ctx.error.message
6385
+ }
6386
+ );
6387
+ }
6388
+ );
6389
+ var StatusMessage = (0, import_react32.forwardRef)(
6390
+ function AutoRechargeStatusMessage({ className, children, ...rest }, forwardedRef) {
6391
+ const ctx = useAutoRechargeCtx("StatusMessage");
6392
+ if (!ctx.statusMessage) return null;
6393
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6394
+ "p",
6395
+ {
6396
+ ref: forwardedRef,
6397
+ "aria-live": "polite",
6398
+ className,
6399
+ "data-solvapay-auto-recharge-status-message": "",
6400
+ ...rest,
6401
+ children: children ?? ctx.statusMessage
6402
+ }
6403
+ );
6404
+ }
6405
+ );
6406
+ var Status = (0, import_react32.forwardRef)(
6407
+ function AutoRechargeStatus({ className, ...rest }, forwardedRef) {
6408
+ const ctx = useAutoRechargeCtx("Status");
6409
+ const copy = useCopy();
6410
+ const status = ctx.config?.status;
6411
+ if (!status || status === "active" || status === "disabled" || status === "pending_setup") {
6412
+ return null;
6413
+ }
6414
+ const label = status === "failed" ? copy.autoRecharge.statusFailed : null;
6415
+ if (!label) return null;
6416
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6417
+ "span",
6418
+ {
6419
+ ref: forwardedRef,
6420
+ className,
6421
+ "data-solvapay-auto-recharge-status": "",
6422
+ "data-status": status,
6423
+ ...rest,
6424
+ children: label
6425
+ }
6426
+ );
6427
+ }
6428
+ );
6429
+ function CardSetupInner({ onComplete }) {
6430
+ const copy = useCopy();
6431
+ const stripe = (0, import_react_stripe_js3.useStripe)();
6432
+ const elements = (0, import_react_stripe_js3.useElements)();
6433
+ const [processing, setProcessing] = (0, import_react32.useState)(false);
6434
+ const [error, setError] = (0, import_react32.useState)(null);
6435
+ (0, import_react32.useEffect)(() => {
6436
+ if (!stripe) return;
6437
+ const clientSecret = readSetupIntentClientSecret(window.location.search);
6438
+ if (!clientSecret) return;
6439
+ let cancelled = false;
6440
+ void (async () => {
6441
+ setProcessing(true);
6442
+ const { setupIntent, error: retrieveError } = await stripe.retrieveSetupIntent(clientSecret);
6443
+ if (cancelled) return;
6444
+ stripSetupIntentParams();
6445
+ if (retrieveError || !setupIntent) {
6446
+ setError(copy.autoRecharge.setupAuthFailed);
6447
+ setProcessing(false);
6448
+ return;
6449
+ }
6450
+ if (setupIntent.status === "succeeded" || setupIntent.status === "processing") {
6451
+ await onComplete();
6452
+ } else {
6453
+ setError(copy.autoRecharge.setupAuthFailed);
6454
+ }
6455
+ if (!cancelled) setProcessing(false);
6456
+ })();
6457
+ return () => {
6458
+ cancelled = true;
6459
+ };
6460
+ }, [stripe, onComplete, copy.autoRecharge]);
6461
+ const handleSubmit = async (event) => {
6462
+ event.preventDefault();
6463
+ if (!stripe || !elements) {
6464
+ setError("Stripe is still loading. Please wait.");
6465
+ return;
6466
+ }
6467
+ setProcessing(true);
6468
+ setError(null);
6469
+ const { error: submitError } = await elements.submit();
6470
+ if (submitError) {
6471
+ setError(submitError.message ?? "Card authorization failed");
6472
+ setProcessing(false);
6473
+ return;
6474
+ }
6475
+ const { error: confirmError } = await stripe.confirmSetup({
6476
+ elements,
6477
+ confirmParams: {
6478
+ return_url: typeof window !== "undefined" ? window.location.href : "/"
6479
+ },
6480
+ redirect: "if_required"
6481
+ });
6482
+ if (confirmError) {
6483
+ setError(confirmError.message ?? "Card authorization failed");
6484
+ setProcessing(false);
6485
+ return;
6486
+ }
6487
+ await onComplete();
6488
+ setProcessing(false);
6489
+ };
6490
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { onSubmit: handleSubmit, "data-solvapay-auto-recharge-setup": "", children: [
6491
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { children: copy.autoRecharge.setupHeading }),
6492
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { children: copy.autoRecharge.setupDescription }),
6493
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_stripe_js3.PaymentElement, { options: withPaymentElementDefaults() }),
6494
+ error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { role: "alert", "aria-live": "polite", "data-solvapay-auto-recharge-setup-error": "", children: error }) : null,
6495
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6496
+ "button",
6497
+ {
6498
+ type: "submit",
6499
+ disabled: processing || !stripe,
6500
+ "data-solvapay-auto-recharge-setup-submit": "",
6501
+ children: processing ? copy.autoRecharge.setupProcessing : copy.autoRecharge.setupSubmit
6502
+ }
6503
+ )
6504
+ ] });
6505
+ }
6506
+ function CardSetup({ setup, onComplete }) {
6507
+ const stripePromise = (0, import_react32.useMemo)(() => {
6508
+ if (!setup.publishableKey || !setup.setupClientSecret) return null;
6509
+ const options = {
6510
+ ...setup.stripeAccountId ? { stripeAccount: setup.stripeAccountId } : {},
6511
+ developerTools: { assistant: { enabled: false } }
6512
+ };
6513
+ const cacheKey = getStripeCacheKey3(setup.publishableKey, setup.stripeAccountId);
6514
+ const cached = stripePromiseCache3.get(cacheKey);
6515
+ if (cached) return cached;
6516
+ const promise = (0, import_stripe_js3.loadStripe)(setup.publishableKey, options);
6517
+ stripePromiseCache3.set(cacheKey, promise);
6518
+ return promise;
6519
+ }, [setup.publishableKey, setup.setupClientSecret, setup.stripeAccountId]);
6520
+ if (!stripePromise || !setup.setupClientSecret) {
6521
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { "data-solvapay-auto-recharge-setup-loading": "", children: [
6522
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Spinner, { size: "sm" }),
6523
+ " Loading card form\u2026"
6524
+ ] });
6525
+ }
6526
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6527
+ import_react_stripe_js3.Elements,
6528
+ {
6529
+ stripe: stripePromise,
6530
+ options: { clientSecret: setup.setupClientSecret },
6531
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardSetupInner, { onComplete })
6532
+ },
6533
+ setup.setupClientSecret
6534
+ );
6535
+ }
6536
+ var AutoRechargeRoot2 = Root10;
6537
+ var AutoRechargeLoading2 = Loading7;
6538
+ var AutoRechargeCard2 = Card2;
6539
+ var AutoRechargeCardHeading2 = CardHeading;
6540
+ var AutoRechargeCardSummary2 = CardSummary;
6541
+ var AutoRechargeTrigger2 = Trigger;
6542
+ var AutoRechargeOverlay2 = Overlay;
6543
+ var AutoRechargeContent2 = Content;
6544
+ var AutoRechargeTitle2 = Title;
6545
+ var AutoRechargeEnableQuestion2 = EnableQuestion;
6546
+ var AutoRechargeEnableSentence2 = EnableSentence;
6547
+ var AutoRechargeEnableRow2 = EnableRow;
6548
+ var AutoRechargeCancelButton2 = CancelButton;
6549
+ var AutoRechargeHeader2 = Header;
6550
+ var AutoRechargeDescription2 = Description;
6551
+ var AutoRechargeEnableSwitch2 = EnableSwitch;
6552
+ var AutoRechargeFields2 = Fields;
6553
+ var AutoRechargeSetup2 = Setup;
6554
+ var AutoRechargeBody2 = Body;
6555
+ var AutoRechargeSummary2 = Summary3;
6556
+ var AutoRechargeThresholdField2 = ThresholdField;
6557
+ var AutoRechargeTopupField2 = TopupField;
6558
+ var AutoRechargeAmountField2 = AmountField;
6559
+ var AutoRechargeUnitToggle2 = UnitToggle;
6560
+ var AutoRechargeHint2 = Hint;
6561
+ var AutoRechargeValidationError2 = ValidationError;
6562
+ var AutoRechargeActions2 = Actions;
6563
+ var AutoRechargeSaveButton2 = SaveButton;
6564
+ var AutoRechargeDisableButton2 = DisableButton;
6565
+ var AutoRechargeError2 = ErrorSlot7;
6566
+ var AutoRechargeStatusMessage2 = StatusMessage;
6567
+ var AutoRechargeStatus2 = Status;
6568
+ var AutoRechargeCardSetup = CardSetup;
6569
+ var AutoRecharge = {
6570
+ Root: Root10,
6571
+ Loading: Loading7,
6572
+ Card: Card2,
6573
+ CardHeading,
6574
+ CardSummary,
6575
+ Trigger,
6576
+ Overlay,
6577
+ Content,
6578
+ Title,
6579
+ EnableQuestion,
6580
+ EnableSentence,
6581
+ EnableRow,
6582
+ CancelButton,
6583
+ Header,
6584
+ Description,
6585
+ EnableSwitch,
6586
+ Fields,
6587
+ Setup,
6588
+ Body,
6589
+ Summary: Summary3,
6590
+ ThresholdField,
6591
+ TopupField,
6592
+ AmountField,
6593
+ UnitToggle,
6594
+ Hint,
6595
+ ValidationError,
6596
+ Actions,
6597
+ SaveButton,
6598
+ DisableButton,
6599
+ Error: ErrorSlot7,
6600
+ StatusMessage,
6601
+ Status,
6602
+ CardSetup
6603
+ };
6604
+ function useAutoRechargeForm() {
6605
+ return useAutoRechargeCtx("useAutoRechargeForm");
6606
+ }
6607
+
6608
+ // src/primitives/ProductBadge.tsx
6609
+ var import_react33 = require("react");
6610
+ var import_jsx_runtime23 = require("react/jsx-runtime");
6611
+ var ProductBadgeImpl = (0, import_react33.forwardRef)(function ProductBadge({ asChild, children, ...rest }, forwardedRef) {
6612
+ const solva = (0, import_react33.useContext)(SolvaPayContext);
6613
+ if (!solva) throw new MissingProviderError("ProductBadge");
6614
+ const { purchases, loading, hasPaidPurchase, activePurchase } = usePurchase();
6615
+ const copy = useCopy();
6616
+ const [hasLoadedOnce, setHasLoadedOnce] = (0, import_react33.useState)(false);
6617
+ (0, import_react33.useEffect)(() => {
6618
+ if (!loading) setHasLoadedOnce(true);
6619
+ }, [loading]);
6620
+ const planToDisplay = activePurchase?.productName ?? null;
6621
+ const shouldShow = planToDisplay !== null && (!loading || hasLoadedOnce);
6622
+ if (!shouldShow) return null;
6623
+ const commonProps = {
6624
+ "data-solvapay-product-badge": "",
6625
+ "data-loading": loading ? "" : void 0,
6626
+ "data-has-purchase": activePurchase ? "" : void 0,
6627
+ "data-has-paid-purchase": hasPaidPurchase ? "" : void 0,
6628
+ role: "status",
6629
+ "aria-live": "polite",
6630
+ "aria-busy": loading,
6631
+ "aria-label": interpolate(copy.product.currentProductLabel, { name: planToDisplay }),
6632
+ ...rest
6633
+ };
6634
+ if (asChild) {
6635
+ return (
6636
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6637
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Slot, { ref: forwardedRef, ...commonProps, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children: planToDisplay }) })
6638
+ );
6639
+ }
6640
+ void purchases;
6641
+ return (
6642
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6643
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: forwardedRef, ...commonProps, children: children ?? planToDisplay })
6644
+ );
6645
+ });
6646
+ var ProductBadge2 = ProductBadgeImpl;
6647
+ var PlanBadge = ProductBadgeImpl;
6648
+
6649
+ // src/primitives/PaywallNotice.tsx
6650
+ var import_react38 = require("react");
6651
+
6652
+ // src/primitives/checkout/index.tsx
6653
+ var import_react36 = require("react");
6654
+
6655
+ // src/hooks/useCheckoutFlow.ts
6656
+ var import_react35 = require("react");
6657
+
6658
+ // src/hooks/useTransport.ts
6659
+ var import_react34 = require("react");
6660
+ function useTransport() {
6661
+ const { _config } = useSolvaPay();
6662
+ return (0, import_react34.useMemo)(() => _config?.transport ?? createHttpTransport(_config), [_config]);
6663
+ }
6664
+
6665
+ // src/primitives/checkout/shared.ts
6666
+ function isPayg(plan) {
6667
+ return isPaygPlan(plan ?? null);
6668
+ }
6669
+ function planSortByPaygFirstThenAsc(a, b) {
6670
+ const aPayg = isPayg(a);
6671
+ const bPayg = isPayg(b);
6672
+ if (aPayg && !bPayg) return -1;
6673
+ if (!aPayg && bPayg) return 1;
6674
+ return (a.price ?? 0) - (b.price ?? 0);
6675
+ }
6676
+ function buildDefaultCheckoutPlanFilter(allPlans) {
6677
+ const hasNonPaygPaid = allPlans.some(
6678
+ (p) => p.requiresPayment !== false && !isPayg(p)
6679
+ );
6680
+ return (plan) => {
6681
+ if (plan.requiresPayment === false) return false;
6682
+ if (hasNonPaygPaid && isPayg(plan)) return false;
6683
+ return true;
6684
+ };
6685
+ }
6686
+ function formatContinueLabel(plan, locale, pricingOption) {
6687
+ if (!plan) return "Continue";
6688
+ if (isPayg(plan)) {
6689
+ return `Continue with ${plan.name ?? "Pay as you go"}`;
6690
+ }
6691
+ const option = pricingOption ?? resolvePlanPricingOption(plan, null);
6692
+ const currency = option.currency.toUpperCase();
6693
+ const priceLabel = formatPrice(option.price ?? 0, currency, { locale });
6694
+ const cycle = plan.billingCycle ? `/${shortCycle(plan.billingCycle)}` : "";
6695
+ return `Continue with ${plan.name ?? "Plan"} \u2014 ${priceLabel}${cycle}`;
6696
+ }
6697
+ function formatPaygRate(plan, locale) {
6698
+ const creditsPerUnit = plan.creditsPerUnit ?? 1;
6699
+ const creditLabel = creditsPerUnit === 1 ? "credit" : "credits";
6700
+ return `${creditsPerUnit.toLocaleString(locale)} ${creditLabel} / call`;
6701
+ }
6702
+ function inferIncludedCredits(plan) {
6703
+ const price = plan.price ?? 0;
6704
+ const creditsPerUnit = plan.creditsPerUnit ?? 0;
6705
+ if (price > 0 && creditsPerUnit > 0) {
6706
+ return Math.round(price * creditsPerUnit);
6707
+ }
6708
+ return 0;
6709
+ }
6710
+ function shortCycle(cycle) {
6711
+ if (!cycle) return "mo";
6712
+ const lc = cycle.toLowerCase();
6713
+ if (lc.startsWith("year") || lc === "annually" || lc === "annual") return "yr";
6714
+ if (lc.startsWith("week")) return "wk";
6715
+ if (lc.startsWith("day")) return "d";
6716
+ return "mo";
6717
+ }
6718
+
6719
+ // src/hooks/useCheckoutFlow.ts
6720
+ function useCheckoutFlow(opts) {
6721
+ const {
6722
+ productRef,
6723
+ initialStep = "plan",
6724
+ initialAmountMinor = null
6725
+ } = opts;
6726
+ const onPlanSelectRef = (0, import_react35.useRef)(opts.onPlanSelect);
6727
+ const onAmountSelectRef = (0, import_react35.useRef)(opts.onAmountSelect);
6728
+ const onPurchaseSuccessRef = (0, import_react35.useRef)(opts.onPurchaseSuccess);
6729
+ const onErrorRef = (0, import_react35.useRef)(opts.onError);
6730
+ onPlanSelectRef.current = opts.onPlanSelect;
6731
+ onAmountSelectRef.current = opts.onAmountSelect;
6732
+ onPurchaseSuccessRef.current = opts.onPurchaseSuccess;
6733
+ onErrorRef.current = opts.onError;
6734
+ const planCtx = usePlanSelector();
6735
+ const planSelection = usePlanSelection();
6736
+ const transport = useTransport();
6737
+ const locale = useLocale();
6738
+ const balance = useBalance();
6739
+ const { creditsPerMinorUnit, displayExchangeRate, adjustBalance } = balance;
6740
+ const { refetchPurchase } = useSolvaPay();
6741
+ const { merchant } = useMerchant();
6742
+ const [topupCurrencyOverride, setTopupCurrencyOverride] = (0, import_react35.useState)(null);
6743
+ const topupCurrencies = (0, import_react35.useMemo)(() => {
6744
+ const fromMerchant = (merchant?.supportedTopupCurrencies ?? []).map((code) => code.toUpperCase()).filter(Boolean);
6745
+ const fallback = opts.topupCurrency?.toUpperCase() ?? merchant?.defaultCurrency?.toUpperCase() ?? null;
6746
+ const list = fromMerchant.length > 0 ? fromMerchant : fallback ? [fallback] : [];
6747
+ return Array.from(new Set(list));
6748
+ }, [merchant?.supportedTopupCurrencies, merchant?.defaultCurrency, opts.topupCurrency]);
6749
+ const resolvedDefaultTopupCurrency = opts.topupCurrency?.toUpperCase() ?? merchant?.defaultCurrency?.toUpperCase() ?? null;
6750
+ const planPickerCurrency = planCtx.preferredCurrency?.toUpperCase() ?? null;
6751
+ const topupCurrency = (topupCurrencyOverride && topupCurrencies.includes(topupCurrencyOverride) ? topupCurrencyOverride : null) ?? (planPickerCurrency && topupCurrencies.includes(planPickerCurrency) ? planPickerCurrency : null) ?? resolvedDefaultTopupCurrency;
6752
+ const topupCurrencyReady = topupCurrency != null;
6753
+ const setTopupCurrency = (0, import_react35.useCallback)(
6754
+ (code) => {
6755
+ const normalized = code.toUpperCase();
6756
+ setTopupCurrencyOverride(normalized);
6757
+ },
6758
+ []
6759
+ );
6760
+ const [step, setStep] = (0, import_react35.useState)(initialStep);
6761
+ const [status, setStatus] = (0, import_react35.useState)("idle");
6762
+ const [selectedAmountMinor, setSelectedAmountMinor] = (0, import_react35.useState)(initialAmountMinor);
6763
+ const [successMeta, setSuccessMeta] = (0, import_react35.useState)(null);
6764
+ const [error, setError] = (0, import_react35.useState)(null);
6765
+ const selectedAmountMinorRef = (0, import_react35.useRef)(initialAmountMinor);
6766
+ const selectedPlan = planCtx.selectedPlan;
6767
+ const selectedPlanRef = planCtx.selectedPlanRef;
6768
+ const selectedPlanShape = selectedPlan;
6769
+ const branch = selectedPlanShape ? isPayg(selectedPlanShape) ? "payg" : "recurring" : null;
6770
+ const canGoBack = step === "amount" || step === "payment";
6771
+ const selectPlan = (0, import_react35.useCallback)(
5068
6772
  (ref) => {
5069
6773
  planCtx.select(ref);
5070
6774
  const plan = planCtx.plans.find((p) => p.reference === ref) ?? null;
@@ -5074,7 +6778,7 @@ function useCheckoutFlow(opts) {
5074
6778
  },
5075
6779
  [planCtx]
5076
6780
  );
5077
- const selectAmount = (0, import_react33.useCallback)(
6781
+ const selectAmount = (0, import_react35.useCallback)(
5078
6782
  (amountMinor) => {
5079
6783
  selectedAmountMinorRef.current = amountMinor;
5080
6784
  setSelectedAmountMinor(amountMinor);
@@ -5083,7 +6787,7 @@ function useCheckoutFlow(opts) {
5083
6787
  },
5084
6788
  [topupCurrency]
5085
6789
  );
5086
- const runActivate = (0, import_react33.useCallback)(async () => {
6790
+ const runActivate = (0, import_react35.useCallback)(async () => {
5087
6791
  if (!selectedPlanShape || !selectedPlanRef) return false;
5088
6792
  setError(null);
5089
6793
  setStatus("activating");
@@ -5100,7 +6804,7 @@ function useCheckoutFlow(opts) {
5100
6804
  return false;
5101
6805
  }
5102
6806
  }, [productRef, selectedPlanRef, selectedPlanShape, transport]);
5103
- const advanceFromPlan = (0, import_react33.useCallback)(async () => {
6807
+ const advanceFromPlan = (0, import_react35.useCallback)(async () => {
5104
6808
  if (!selectedPlanShape || !selectedPlanRef) return;
5105
6809
  if (branch === "payg") {
5106
6810
  if (planCtx.currentPlanRef === selectedPlanRef) {
@@ -5114,7 +6818,7 @@ function useCheckoutFlow(opts) {
5114
6818
  setError(null);
5115
6819
  setStep("payment");
5116
6820
  }, [branch, planCtx.currentPlanRef, runActivate, selectedPlanRef, selectedPlanShape]);
5117
- const recordPaygSuccess = (0, import_react33.useCallback)(
6821
+ const recordPaygSuccess = (0, import_react35.useCallback)(
5118
6822
  (creditsAddedFromBackend) => {
5119
6823
  if (!selectedPlanShape || selectedAmountMinor == null) return;
5120
6824
  const currency = topupCurrency ?? "USD";
@@ -5148,7 +6852,7 @@ function useCheckoutFlow(opts) {
5148
6852
  topupCurrency
5149
6853
  ]
5150
6854
  );
5151
- const recordRecurringSuccess = (0, import_react33.useCallback)(() => {
6855
+ const recordRecurringSuccess = (0, import_react35.useCallback)(() => {
5152
6856
  if (!selectedPlanShape) return;
5153
6857
  const pricingOption = selectedPlan ? resolvePlanPricingOption(selectedPlan, planSelection?.selectedCurrency) : {
5154
6858
  currency: selectedPlanShape.currency ?? "USD",
@@ -5167,7 +6871,7 @@ function useCheckoutFlow(opts) {
5167
6871
  setStep("success");
5168
6872
  onPurchaseSuccessRef.current?.(meta);
5169
6873
  }, [selectedPlanShape, selectedPlan, planSelection?.selectedCurrency]);
5170
- const advance = (0, import_react33.useCallback)(async () => {
6874
+ const advance = (0, import_react35.useCallback)(async () => {
5171
6875
  if (step === "plan") {
5172
6876
  await advanceFromPlan();
5173
6877
  return;
@@ -5194,7 +6898,7 @@ function useCheckoutFlow(opts) {
5194
6898
  selectedAmountMinor,
5195
6899
  step
5196
6900
  ]);
5197
- const back = (0, import_react33.useCallback)(() => {
6901
+ const back = (0, import_react35.useCallback)(() => {
5198
6902
  setError(null);
5199
6903
  if (step === "amount") {
5200
6904
  setStep("plan");
@@ -5205,7 +6909,7 @@ function useCheckoutFlow(opts) {
5205
6909
  return;
5206
6910
  }
5207
6911
  }, [branch, step]);
5208
- const reset = (0, import_react33.useCallback)(() => {
6912
+ const reset = (0, import_react35.useCallback)(() => {
5209
6913
  setStep("plan");
5210
6914
  selectedAmountMinorRef.current = null;
5211
6915
  setSelectedAmountMinor(null);
@@ -5214,13 +6918,13 @@ function useCheckoutFlow(opts) {
5214
6918
  setStatus("idle");
5215
6919
  setTopupCurrencyOverride(null);
5216
6920
  }, []);
5217
- const retry = (0, import_react33.useCallback)(async () => {
6921
+ const retry = (0, import_react35.useCallback)(async () => {
5218
6922
  if (status !== "error") return;
5219
6923
  if (step === "plan" && branch === "payg") {
5220
6924
  await runActivate();
5221
6925
  }
5222
6926
  }, [branch, runActivate, status, step]);
5223
- const notifyPaymentSuccess = (0, import_react33.useCallback)(
6927
+ const notifyPaymentSuccess = (0, import_react35.useCallback)(
5224
6928
  (_intent, extras) => {
5225
6929
  if (branch === "payg") {
5226
6930
  recordPaygSuccess(extras?.creditsAdded);
@@ -5230,7 +6934,7 @@ function useCheckoutFlow(opts) {
5230
6934
  },
5231
6935
  [branch, recordPaygSuccess, recordRecurringSuccess]
5232
6936
  );
5233
- return (0, import_react33.useMemo)(
6937
+ return (0, import_react35.useMemo)(
5234
6938
  () => ({
5235
6939
  step,
5236
6940
  status,
@@ -5279,10 +6983,10 @@ function useCheckoutFlow(opts) {
5279
6983
  }
5280
6984
 
5281
6985
  // src/primitives/checkout/index.tsx
5282
- var import_jsx_runtime23 = require("react/jsx-runtime");
5283
- var CheckoutContext = (0, import_react34.createContext)(null);
6986
+ var import_jsx_runtime24 = require("react/jsx-runtime");
6987
+ var CheckoutContext = (0, import_react36.createContext)(null);
5284
6988
  function useCheckoutContext(part) {
5285
- const ctx = (0, import_react34.useContext)(CheckoutContext);
6989
+ const ctx = (0, import_react36.useContext)(CheckoutContext);
5286
6990
  if (!ctx) {
5287
6991
  throw new Error(`CheckoutSteps.${part} must be rendered inside <CheckoutSteps.Root>.`);
5288
6992
  }
@@ -5291,7 +6995,7 @@ function useCheckoutContext(part) {
5291
6995
  function useCheckoutSteps() {
5292
6996
  return useCheckoutContext("useCheckoutSteps");
5293
6997
  }
5294
- var Root10 = (0, import_react34.forwardRef)(function CheckoutStepsRoot(props, forwardedRef) {
6998
+ var Root11 = (0, import_react36.forwardRef)(function CheckoutStepsRoot(props, forwardedRef) {
5295
6999
  const {
5296
7000
  productRef,
5297
7001
  returnUrl: _returnUrl,
@@ -5313,9 +7017,9 @@ var Root10 = (0, import_react34.forwardRef)(function CheckoutStepsRoot(props, fo
5313
7017
  children
5314
7018
  } = props;
5315
7019
  if (externalFlow) {
5316
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", className, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CheckoutContext.Provider, { value: externalFlow, children }) });
7020
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", className, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutContext.Provider, { value: externalFlow, children }) });
5317
7021
  }
5318
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7022
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5319
7023
  RootWithPlanSelector,
5320
7024
  {
5321
7025
  productRef,
@@ -5358,11 +7062,11 @@ function RootWithPlanSelector({
5358
7062
  children
5359
7063
  }) {
5360
7064
  const { plans } = usePlans({ productRef });
5361
- const resolvedFilter = (0, import_react34.useMemo)(
7065
+ const resolvedFilter = (0, import_react36.useMemo)(
5362
7066
  () => filter ?? buildDefaultCheckoutPlanFilter(plans),
5363
7067
  [filter, plans]
5364
7068
  );
5365
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7069
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5366
7070
  PlanSelector.Root,
5367
7071
  {
5368
7072
  productRef,
@@ -5372,7 +7076,7 @@ function RootWithPlanSelector({
5372
7076
  currentPlanRef,
5373
7077
  autoSelectFirstPaid,
5374
7078
  initialPlanRef,
5375
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7079
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5376
7080
  FlowProvider,
5377
7081
  {
5378
7082
  productRef,
@@ -5414,22 +7118,22 @@ function FlowProvider({
5414
7118
  onPurchaseSuccess,
5415
7119
  onError
5416
7120
  });
5417
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", "data-step": flow.step, className, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CheckoutContext.Provider, { value: flow, children }) });
7121
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", "data-step": flow.step, className, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutContext.Provider, { value: flow, children }) });
5418
7122
  }
5419
7123
  function IfStep({ step, children }) {
5420
7124
  const flow = useCheckoutContext("IfStep");
5421
7125
  const matches = Array.isArray(step) ? step.includes(flow.step) : flow.step === step;
5422
7126
  if (!matches) return null;
5423
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_jsx_runtime23.Fragment, { children });
7127
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children });
5424
7128
  }
5425
- var StepHeading = (0, import_react34.forwardRef)(function CheckoutStepsStepHeading({ asChild, children, className, ...rest }, forwardedRef) {
7129
+ var StepHeading = (0, import_react36.forwardRef)(function CheckoutStepsStepHeading({ asChild, children, className, ...rest }, forwardedRef) {
5426
7130
  const flow = useCheckoutContext("StepHeading");
5427
7131
  const copy = useCopy();
5428
7132
  const paywallCtx = usePaywallNoticeOptional();
5429
7133
  if (flow.step === "success") return null;
5430
7134
  const defaultText = resolveStepHeading(flow.step, copy, paywallCtx?.content ?? null);
5431
7135
  const Comp = asChild ? Slot : "h3";
5432
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7136
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5433
7137
  Comp,
5434
7138
  {
5435
7139
  ref: forwardedRef,
@@ -5441,7 +7145,7 @@ var StepHeading = (0, import_react34.forwardRef)(function CheckoutStepsStepHeadi
5441
7145
  }
5442
7146
  );
5443
7147
  });
5444
- var StepMessage = (0, import_react34.forwardRef)(function CheckoutStepsStepMessage({ asChild, children, className, ...rest }, forwardedRef) {
7148
+ var StepMessage = (0, import_react36.forwardRef)(function CheckoutStepsStepMessage({ asChild, children, className, ...rest }, forwardedRef) {
5445
7149
  const flow = useCheckoutContext("StepMessage");
5446
7150
  const copy = useCopy();
5447
7151
  const paywallCtx = usePaywallNoticeOptional();
@@ -5449,7 +7153,7 @@ var StepMessage = (0, import_react34.forwardRef)(function CheckoutStepsStepMessa
5449
7153
  const defaultText = resolveStepMessage(flow, copy, paywallCtx?.content ?? null);
5450
7154
  if (!defaultText && children == null) return null;
5451
7155
  const Comp = asChild ? Slot : "p";
5452
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7156
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5453
7157
  Comp,
5454
7158
  {
5455
7159
  ref: forwardedRef,
@@ -5496,21 +7200,21 @@ function resolveStepMessage(flow, copy, content) {
5496
7200
  return "";
5497
7201
  }
5498
7202
  function PlanGrid({ className, children }) {
5499
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PlanSelector.Grid, { className: className ?? "solvapay-checkout-plan-grid", children: children ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(PlanSelector.Card, { className: "solvapay-checkout-plan-card", children: [
5500
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PlanSelector.CardBadge, { className: "solvapay-checkout-plan-card-badge" }),
5501
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PlanSelector.CardName, { className: "solvapay-checkout-plan-card-name" }),
5502
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PlanSelector.CardPrice, { className: "solvapay-checkout-plan-card-price" }),
5503
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PlanSelector.CardInterval, { className: "solvapay-checkout-plan-card-interval" })
7203
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Grid, { className: className ?? "solvapay-checkout-plan-grid", children: children ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(PlanSelector.Card, { className: "solvapay-checkout-plan-card", children: [
7204
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardBadge, { className: "solvapay-checkout-plan-card-badge" }),
7205
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardName, { className: "solvapay-checkout-plan-card-name" }),
7206
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardPrice, { className: "solvapay-checkout-plan-card-price" }),
7207
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardInterval, { className: "solvapay-checkout-plan-card-interval" })
5504
7208
  ] }) });
5505
7209
  }
5506
- var PlanContinueButton = (0, import_react34.forwardRef)(
7210
+ var PlanContinueButton = (0, import_react36.forwardRef)(
5507
7211
  function PlanContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
5508
7212
  const flow = useCheckoutContext("PlanContinueButton");
5509
7213
  const locale = useLocale();
5510
7214
  const selectedPlanShape = flow.selectedPlan;
5511
7215
  const isDisabled = disabled || !flow.selectedPlanRef || flow.status === "activating";
5512
7216
  const label = children ?? formatContinueLabel(selectedPlanShape, locale);
5513
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7217
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5514
7218
  "button",
5515
7219
  {
5516
7220
  ref,
@@ -5533,13 +7237,13 @@ var PlanContinueButton = (0, import_react34.forwardRef)(
5533
7237
  function AmountPicker2({ className, children }) {
5534
7238
  const flow = useCheckoutContext("AmountPicker");
5535
7239
  if (!flow.topupCurrencyReady || flow.topupCurrency == null) {
5536
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7240
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5537
7241
  "div",
5538
7242
  {
5539
7243
  className: className ?? "solvapay-amount-picker",
5540
7244
  "data-state": "loading",
5541
7245
  "aria-busy": "true",
5542
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-amount-picker-pills", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7246
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-amount-picker-pills", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5543
7247
  "span",
5544
7248
  {
5545
7249
  className: "solvapay-amount-picker-pill",
@@ -5551,7 +7255,7 @@ function AmountPicker2({ className, children }) {
5551
7255
  }
5552
7256
  );
5553
7257
  }
5554
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7258
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5555
7259
  AmountPicker.Root,
5556
7260
  {
5557
7261
  currency: flow.topupCurrency,
@@ -5562,16 +7266,16 @@ function AmountPicker2({ className, children }) {
5562
7266
  flow.selectAmount(value);
5563
7267
  }
5564
7268
  },
5565
- children: children ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DefaultAmountTree, {})
7269
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DefaultAmountTree, {})
5566
7270
  }
5567
7271
  );
5568
7272
  }
5569
7273
  function DefaultAmountTree() {
5570
7274
  const ctx = useAmountPicker();
5571
7275
  const { selectAmountLabel, customAmountLabel, creditEstimate } = useAmountPickerCopy();
5572
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5573
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "solvapay-amount-picker-label", children: selectAmountLabel }),
5574
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-amount-picker-pills", children: ctx.quickAmounts.map((amount) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7276
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
7277
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "solvapay-amount-picker-label", children: selectAmountLabel }),
7278
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-amount-picker-pills", children: ctx.quickAmounts.map((amount) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5575
7279
  AmountPicker.Option,
5576
7280
  {
5577
7281
  amount,
@@ -5579,11 +7283,11 @@ function DefaultAmountTree() {
5579
7283
  },
5580
7284
  amount
5581
7285
  )) }),
5582
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-amount-picker-custom-wrapper", children: [
5583
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "solvapay-amount-picker-custom-label", children: customAmountLabel }),
5584
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-amount-picker-custom-row", children: [
5585
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "solvapay-amount-picker-currency-symbol", children: ctx.currencySymbol }),
5586
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7286
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-amount-picker-custom-wrapper", children: [
7287
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "solvapay-amount-picker-custom-label", children: customAmountLabel }),
7288
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-amount-picker-custom-row", children: [
7289
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "solvapay-amount-picker-currency-symbol", children: ctx.currencySymbol }),
7290
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5587
7291
  AmountPicker.Custom,
5588
7292
  {
5589
7293
  className: "solvapay-amount-picker-custom-input",
@@ -5592,7 +7296,7 @@ function DefaultAmountTree() {
5592
7296
  )
5593
7297
  ] })
5594
7298
  ] }),
5595
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7299
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5596
7300
  "p",
5597
7301
  {
5598
7302
  className: "solvapay-amount-picker-credit-estimate",
@@ -5602,7 +7306,7 @@ function DefaultAmountTree() {
5602
7306
  )
5603
7307
  ] });
5604
7308
  }
5605
- var AmountContinueButton = (0, import_react34.forwardRef)(
7309
+ var AmountContinueButton = (0, import_react36.forwardRef)(
5606
7310
  function AmountContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
5607
7311
  const flow = useCheckoutContext("AmountContinueButton");
5608
7312
  const locale = useLocale();
@@ -5611,7 +7315,7 @@ var AmountContinueButton = (0, import_react34.forwardRef)(
5611
7315
  const ready = flow.topupCurrencyReady && currency != null;
5612
7316
  const isDisabled = disabled || !ready || amountMinor == null;
5613
7317
  const label = children ?? (ready && currency != null && amountMinor != null ? `Continue \u2014 ${formatPrice(amountMinor, currency, { locale })}` : "Continue");
5614
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
7318
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5615
7319
  "button",
5616
7320
  {
5617
7321
  ref,
@@ -5634,10 +7338,10 @@ var AmountContinueButton = (0, import_react34.forwardRef)(
5634
7338
  function Payment({ className }) {
5635
7339
  const flow = useCheckoutContext("Payment");
5636
7340
  if (flow.branch === "payg") {
5637
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaygPayment, { className });
7341
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaygPayment, { className });
5638
7342
  }
5639
7343
  if (flow.branch === "recurring") {
5640
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(RecurringPayment, { className });
7344
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(RecurringPayment, { className });
5641
7345
  }
5642
7346
  return null;
5643
7347
  }
@@ -5651,12 +7355,12 @@ function PaygPayment({ className }) {
5651
7355
  const currency = flow.topupCurrency;
5652
7356
  if (!selectedPlanShape || amountMinor == null || currency == null) return null;
5653
7357
  const creditsAdded = creditsPerMinorUnit != null && creditsPerMinorUnit > 0 ? Math.floor(amountMinor / (displayExchangeRate ?? 1) * creditsPerMinorUnit) : null;
5654
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "payg", children: [
5655
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "payg", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
5656
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: creditsAdded != null ? `${creditsAdded.toLocaleString(locale)} credits` : formatPrice(amountMinor, currency, { locale }) }),
5657
- creditsAdded != null ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: formatPrice(amountMinor, currency, { locale }) }) : null
7358
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "payg", children: [
7359
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "payg", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
7360
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: creditsAdded != null ? `${creditsAdded.toLocaleString(locale)} credits` : formatPrice(amountMinor, currency, { locale }) }),
7361
+ creditsAdded != null ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: formatPrice(amountMinor, currency, { locale }) }) : null
5658
7362
  ] }) }),
5659
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
7363
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5660
7364
  TopupForm.Root,
5661
7365
  {
5662
7366
  amount: amountMinor,
@@ -5665,11 +7369,11 @@ function PaygPayment({ className }) {
5665
7369
  className: "solvapay-checkout-topup-form",
5666
7370
  onSuccess: (intent, extras) => flow.notifyPaymentSuccess(intent, extras),
5667
7371
  children: [
5668
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TopupForm.Loading, {}),
5669
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TopupForm.PaymentElement, {}),
5670
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TopupForm.Error, { className: "solvapay-checkout-error" }),
5671
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(MandateText, { mode: "topup", amountMinor, currency }),
5672
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(TopupForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: [
7372
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TopupForm.Loading, {}),
7373
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TopupForm.PaymentElement, {}),
7374
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TopupForm.Error, { className: "solvapay-checkout-error" }),
7375
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(MandateText, { mode: "topup", amountMinor, currency }),
7376
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(TopupForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: [
5673
7377
  "Pay ",
5674
7378
  formatPrice(amountMinor, currency, { locale })
5675
7379
  ] })
@@ -5692,12 +7396,12 @@ function RecurringPayment({ className }) {
5692
7396
  const isRecurring = !!cycle;
5693
7397
  const formattedAmount = formatPrice(amountMinor, currency, { locale });
5694
7398
  const priceLine = isRecurring ? `${formattedAmount}/${shortCycle(cycle)}` : formattedAmount;
5695
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "recurring", children: [
5696
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "recurring", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
5697
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: planName }),
5698
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: priceLine })
7399
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "recurring", children: [
7400
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "recurring", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
7401
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: planName }),
7402
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: priceLine })
5699
7403
  ] }) }),
5700
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
7404
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5701
7405
  PaymentForm.Root,
5702
7406
  {
5703
7407
  planRef: flow.selectedPlanRef,
@@ -5706,28 +7410,28 @@ function RecurringPayment({ className }) {
5706
7410
  requireTermsAcceptance: false,
5707
7411
  onSuccess: (intent) => flow.notifyPaymentSuccess(intent),
5708
7412
  children: [
5709
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaymentForm.Loading, {}),
5710
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaymentForm.PaymentElement, {}),
5711
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaymentForm.Error, { className: "solvapay-checkout-error" }),
5712
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaymentForm.MandateText, {}),
5713
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PaymentForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: isRecurring ? `Subscribe \u2014 ${priceLine}` : `Pay ${formattedAmount}` })
7413
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentForm.Loading, {}),
7414
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentForm.PaymentElement, {}),
7415
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentForm.Error, { className: "solvapay-checkout-error" }),
7416
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentForm.MandateText, {}),
7417
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaymentForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: isRecurring ? `Subscribe \u2014 ${priceLine}` : `Pay ${formattedAmount}` })
5714
7418
  ]
5715
7419
  }
5716
7420
  )
5717
7421
  ] });
5718
7422
  }
5719
- var CheckoutEnvContext = (0, import_react34.createContext)(null);
7423
+ var CheckoutEnvContext = (0, import_react36.createContext)(null);
5720
7424
  function useReturnUrl() {
5721
- return (0, import_react34.useContext)(CheckoutEnvContext)?.returnUrl ?? "";
7425
+ return (0, import_react36.useContext)(CheckoutEnvContext)?.returnUrl ?? "";
5722
7426
  }
5723
7427
  function useProductRef() {
5724
- return (0, import_react34.useContext)(CheckoutEnvContext)?.productRef ?? "";
7428
+ return (0, import_react36.useContext)(CheckoutEnvContext)?.productRef ?? "";
5725
7429
  }
5726
- var BackLink = (0, import_react34.forwardRef)(function CheckoutStepsBackLink({ label, glyph = "\u2190", className, onClick, ...rest }, ref) {
7430
+ var BackLink = (0, import_react36.forwardRef)(function CheckoutStepsBackLink({ label, glyph = "\u2190", className, onClick, ...rest }, ref) {
5727
7431
  const flow = useCheckoutContext("BackLink");
5728
7432
  if (!flow.canGoBack) return null;
5729
7433
  const resolvedLabel = label ?? (flow.step === "payment" && flow.branch === "payg" ? "Change amount" : flow.step === "payment" && flow.branch === "recurring" ? "Change plan" : "Back");
5730
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
7434
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5731
7435
  "button",
5732
7436
  {
5733
7437
  ref,
@@ -5741,8 +7445,8 @@ var BackLink = (0, import_react34.forwardRef)(function CheckoutStepsBackLink({ l
5741
7445
  },
5742
7446
  ...rest,
5743
7447
  children: [
5744
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "solvapay-checkout-back-link-glyph", "aria-hidden": "true", children: glyph }),
5745
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "solvapay-checkout-back-link-label", children: resolvedLabel })
7448
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "solvapay-checkout-back-link-glyph", "aria-hidden": "true", children: glyph }),
7449
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "solvapay-checkout-back-link-label", children: resolvedLabel })
5746
7450
  ]
5747
7451
  }
5748
7452
  );
@@ -5752,74 +7456,74 @@ function Success({ className, children }) {
5752
7456
  const locale = useLocale();
5753
7457
  if (flow.step !== "success" || !flow.successMeta) return null;
5754
7458
  if (children) {
5755
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: className ?? "solvapay-checkout-success", children });
7459
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: className ?? "solvapay-checkout-success", children });
5756
7460
  }
5757
7461
  const meta = flow.successMeta;
5758
7462
  if (meta.branch === "payg") {
5759
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "payg", children: [
5760
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
5761
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "solvapay-checkout-success-heading", children: "Credits added" }),
5762
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Pay as you go plan is active." }),
5763
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "payg", children: [
5764
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5765
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Amount" }),
5766
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: formatPrice(meta.amountMinor, meta.currency, { locale }) })
7463
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "payg", children: [
7464
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
7465
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "solvapay-checkout-success-heading", children: "Credits added" }),
7466
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Pay as you go plan is active." }),
7467
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "payg", children: [
7468
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7469
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Amount" }),
7470
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: formatPrice(meta.amountMinor, meta.currency, { locale }) })
5767
7471
  ] }),
5768
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5769
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Credits" }),
5770
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dd", { children: [
7472
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7473
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Credits" }),
7474
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("dd", { children: [
5771
7475
  "+",
5772
7476
  meta.creditsAdded.toLocaleString(locale)
5773
7477
  ] })
5774
7478
  ] }),
5775
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5776
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Plan" }),
5777
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: meta.plan.name ?? "Pay as you go" })
7479
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7480
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Plan" }),
7481
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: meta.plan.name ?? "Pay as you go" })
5778
7482
  ] }),
5779
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5780
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Rate" }),
5781
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: meta.rateLabel })
7483
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7484
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Rate" }),
7485
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: meta.rateLabel })
5782
7486
  ] })
5783
7487
  ] })
5784
7488
  ] });
5785
7489
  }
5786
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "recurring", children: [
5787
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
5788
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("h2", { className: "solvapay-checkout-success-heading", children: [
7490
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "recurring", children: [
7491
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
7492
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h2", { className: "solvapay-checkout-success-heading", children: [
5789
7493
  meta.plan.name ?? "Plan",
5790
7494
  " active"
5791
7495
  ] }),
5792
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Subscription is live and credits are ready." }),
5793
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "recurring", children: [
5794
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5795
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Plan" }),
5796
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: meta.plan.name ?? "Plan" })
7496
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Subscription is live and credits are ready." }),
7497
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "recurring", children: [
7498
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7499
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Plan" }),
7500
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: meta.plan.name ?? "Plan" })
5797
7501
  ] }),
5798
- meta.creditsIncluded > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5799
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Credits" }),
5800
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dd", { children: [
7502
+ meta.creditsIncluded > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7503
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Credits" }),
7504
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("dd", { children: [
5801
7505
  "+",
5802
7506
  meta.creditsIncluded.toLocaleString(locale)
5803
7507
  ] })
5804
7508
  ] }) : null,
5805
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5806
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Charged today" }),
5807
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: formatPrice(meta.chargedTodayMinor, meta.currency, { locale }) })
7509
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7510
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Charged today" }),
7511
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: formatPrice(meta.chargedTodayMinor, meta.currency, { locale }) })
5808
7512
  ] }),
5809
- meta.nextRenewalLabel ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
5810
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { children: "Next renewal" }),
5811
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { children: meta.nextRenewalLabel })
7513
+ meta.nextRenewalLabel ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
7514
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dt", { children: "Next renewal" }),
7515
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("dd", { children: meta.nextRenewalLabel })
5812
7516
  ] }) : null
5813
7517
  ] })
5814
7518
  ] });
5815
7519
  }
5816
- var RootWithEnv = (0, import_react34.forwardRef)(
7520
+ var RootWithEnv = (0, import_react36.forwardRef)(
5817
7521
  function CheckoutStepsRootWithEnv(props, forwardedRef) {
5818
- const env = (0, import_react34.useMemo)(
7522
+ const env = (0, import_react36.useMemo)(
5819
7523
  () => ({ returnUrl: props.returnUrl, productRef: props.productRef }),
5820
7524
  [props.returnUrl, props.productRef]
5821
7525
  );
5822
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CheckoutEnvContext.Provider, { value: env, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Root10, { ...props, ref: forwardedRef }) });
7526
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutEnvContext.Provider, { value: env, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Root11, { ...props, ref: forwardedRef }) });
5823
7527
  }
5824
7528
  );
5825
7529
  var CheckoutSteps = {
@@ -5848,7 +7552,7 @@ var CheckoutStepsBackLink2 = BackLink;
5848
7552
  var CheckoutStepsSuccess = Success;
5849
7553
 
5850
7554
  // src/hooks/usePaywallResolver.ts
5851
- var import_react35 = require("react");
7555
+ var import_react37 = require("react");
5852
7556
  function balanceCoversNextUnit(balance, credits) {
5853
7557
  if (!balance) return false;
5854
7558
  if (typeof balance.remainingUnits === "number" && balance.remainingUnits > 0) {
@@ -5862,7 +7566,7 @@ function balanceCoversNextUnit(balance, credits) {
5862
7566
  function usePaywallResolver(content) {
5863
7567
  const { activePurchase, hasPaidPurchase, refetch: refetchPurchase } = usePurchase();
5864
7568
  const { credits, refetch: refetchBalance } = useBalance();
5865
- const resolved = (0, import_react35.useMemo)(() => {
7569
+ const resolved = (0, import_react37.useMemo)(() => {
5866
7570
  if (!content) return false;
5867
7571
  const productMatches = !content.product || activePurchase?.productRef === content.product || activePurchase?.productName === content.product;
5868
7572
  if (content.kind === "payment_required") {
@@ -5872,7 +7576,7 @@ function usePaywallResolver(content) {
5872
7576
  if (balanceCoversNextUnit(content.balance, credits)) return true;
5873
7577
  return Boolean(productMatches && activePurchase?.status === "active");
5874
7578
  }, [content, hasPaidPurchase, activePurchase, credits]);
5875
- const refetch = (0, import_react35.useCallback)(async () => {
7579
+ const refetch = (0, import_react37.useCallback)(async () => {
5876
7580
  await Promise.all([
5877
7581
  refetchPurchase().catch(() => void 0),
5878
7582
  refetchBalance().catch(() => void 0)
@@ -5882,32 +7586,32 @@ function usePaywallResolver(content) {
5882
7586
  }
5883
7587
 
5884
7588
  // src/primitives/PaywallNotice.tsx
5885
- var import_jsx_runtime24 = require("react/jsx-runtime");
5886
- var PaywallNoticeContext = (0, import_react36.createContext)(null);
7589
+ var import_jsx_runtime25 = require("react/jsx-runtime");
7590
+ var PaywallNoticeContext = (0, import_react38.createContext)(null);
5887
7591
  function usePaywallNoticeCtx(part) {
5888
- const ctx = (0, import_react36.useContext)(PaywallNoticeContext);
7592
+ const ctx = (0, import_react38.useContext)(PaywallNoticeContext);
5889
7593
  if (!ctx) {
5890
7594
  throw new Error(`PaywallNotice.${part} must be rendered inside <PaywallNotice.Root>.`);
5891
7595
  }
5892
7596
  return ctx;
5893
7597
  }
5894
- var Root11 = (0, import_react36.forwardRef)(function PaywallNoticeRoot({ content, onResolved, classNames, asChild, children, ...rest }, forwardedRef) {
7598
+ var Root12 = (0, import_react38.forwardRef)(function PaywallNoticeRoot({ content, onResolved, classNames, asChild, children, ...rest }, forwardedRef) {
5895
7599
  const { resolved, refetch } = usePaywallResolver(content);
5896
- const classNamesResolved = (0, import_react36.useMemo)(() => classNames ?? {}, [classNames]);
5897
- const onResolvedRef = (0, import_react36.useRef)(onResolved);
5898
- (0, import_react36.useEffect)(() => {
7600
+ const classNamesResolved = (0, import_react38.useMemo)(() => classNames ?? {}, [classNames]);
7601
+ const onResolvedRef = (0, import_react38.useRef)(onResolved);
7602
+ (0, import_react38.useEffect)(() => {
5899
7603
  onResolvedRef.current = onResolved;
5900
7604
  }, [onResolved]);
5901
- const hasResolvedRef = (0, import_react36.useRef)(false);
5902
- const signalResolved = (0, import_react36.useCallback)(() => {
7605
+ const hasResolvedRef = (0, import_react38.useRef)(false);
7606
+ const signalResolved = (0, import_react38.useCallback)(() => {
5903
7607
  if (hasResolvedRef.current) return;
5904
7608
  hasResolvedRef.current = true;
5905
7609
  onResolvedRef.current?.();
5906
7610
  }, []);
5907
- (0, import_react36.useEffect)(() => {
7611
+ (0, import_react38.useEffect)(() => {
5908
7612
  if (resolved) signalResolved();
5909
7613
  }, [resolved, signalResolved]);
5910
- const ctx = (0, import_react36.useMemo)(
7614
+ const ctx = (0, import_react38.useMemo)(
5911
7615
  () => ({
5912
7616
  content,
5913
7617
  resolved,
@@ -5918,7 +7622,7 @@ var Root11 = (0, import_react36.forwardRef)(function PaywallNoticeRoot({ content
5918
7622
  [content, resolved, refetch, signalResolved, classNamesResolved]
5919
7623
  );
5920
7624
  const Comp = asChild ? Slot : "div";
5921
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PaywallNoticeContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7625
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PaywallNoticeContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5922
7626
  Comp,
5923
7627
  {
5924
7628
  ref: forwardedRef,
@@ -5931,12 +7635,12 @@ var Root11 = (0, import_react36.forwardRef)(function PaywallNoticeRoot({ content
5931
7635
  }
5932
7636
  ) });
5933
7637
  });
5934
- var Heading4 = (0, import_react36.forwardRef)(function PaywallNoticeHeading({ asChild, children, className, ...rest }, forwardedRef) {
7638
+ var Heading4 = (0, import_react38.forwardRef)(function PaywallNoticeHeading({ asChild, children, className, ...rest }, forwardedRef) {
5935
7639
  const ctx = usePaywallNoticeCtx("Heading");
5936
7640
  const copy = useCopy();
5937
7641
  const defaultText = ctx.resolved ? copy.paywall.resolvedHeading : ctx.content.kind === "payment_required" ? copy.paywall.paymentRequiredHeading : isTopupGate(ctx.content) ? copy.paywall.topupRequiredHeading : copy.paywall.activationRequiredHeading;
5938
7642
  const Comp = asChild ? Slot : "h2";
5939
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7643
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5940
7644
  Comp,
5941
7645
  {
5942
7646
  ref: forwardedRef,
@@ -5947,12 +7651,12 @@ var Heading4 = (0, import_react36.forwardRef)(function PaywallNoticeHeading({ as
5947
7651
  }
5948
7652
  );
5949
7653
  });
5950
- var Message = (0, import_react36.forwardRef)(function PaywallNoticeMessage({ asChild, children, className, ...rest }, forwardedRef) {
7654
+ var Message = (0, import_react38.forwardRef)(function PaywallNoticeMessage({ asChild, children, className, ...rest }, forwardedRef) {
5951
7655
  const ctx = usePaywallNoticeCtx("Message");
5952
7656
  const copy = useCopy();
5953
7657
  const Comp = asChild ? Slot : "p";
5954
7658
  const defaultText = resolvePaywallMessage(ctx.content, copy.paywall);
5955
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7659
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5956
7660
  Comp,
5957
7661
  {
5958
7662
  ref: forwardedRef,
@@ -5995,14 +7699,14 @@ function resolvePaywallMessage(content, paywallCopy) {
5995
7699
  }
5996
7700
  return content.message ?? "";
5997
7701
  }
5998
- var ProductContext = (0, import_react36.forwardRef)(function PaywallNoticeProductContext({ asChild, children, className, ...rest }, forwardedRef) {
7702
+ var ProductContext = (0, import_react38.forwardRef)(function PaywallNoticeProductContext({ asChild, children, className, ...rest }, forwardedRef) {
5999
7703
  const ctx = usePaywallNoticeCtx("ProductContext");
6000
7704
  const copy = useCopy();
6001
7705
  const product = ctx.content.kind === "activation_required" ? ctx.content.productDetails : void 0;
6002
7706
  if (!product?.name) return null;
6003
7707
  const label = interpolate(copy.paywall.productContext, { product: product.name });
6004
7708
  const Comp = asChild ? Slot : "div";
6005
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7709
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6006
7710
  Comp,
6007
7711
  {
6008
7712
  ref: forwardedRef,
@@ -6013,7 +7717,7 @@ var ProductContext = (0, import_react36.forwardRef)(function PaywallNoticeProduc
6013
7717
  }
6014
7718
  );
6015
7719
  });
6016
- var Balance = (0, import_react36.forwardRef)(function PaywallNoticeBalance({ asChild, children, className, ...rest }, forwardedRef) {
7720
+ var Balance = (0, import_react38.forwardRef)(function PaywallNoticeBalance({ asChild, children, className, ...rest }, forwardedRef) {
6017
7721
  const ctx = usePaywallNoticeCtx("Balance");
6018
7722
  const copy = useCopy();
6019
7723
  const balance = ctx.content.balance;
@@ -6023,7 +7727,7 @@ var Balance = (0, import_react36.forwardRef)(function PaywallNoticeBalance({ asC
6023
7727
  required: String(balance.creditsPerUnit ?? 1)
6024
7728
  });
6025
7729
  const Comp = asChild ? Slot : "div";
6026
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7730
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6027
7731
  Comp,
6028
7732
  {
6029
7733
  ref: forwardedRef,
@@ -6039,27 +7743,27 @@ function Plans({ className, children }) {
6039
7743
  if (ctx.content.kind !== "activation_required") return null;
6040
7744
  if (!ctx.content.product) return null;
6041
7745
  const defaultClass = className ?? ctx.classNames.plans ?? "solvapay-paywall-plans";
6042
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { "data-solvapay-paywall-plans": "", className: defaultClass, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Root, { productRef: ctx.content.product, filter: hidesFreePlan, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
6043
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Grid, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(PlanSelector.Card, { children: [
6044
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardBadge, {}),
6045
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardName, {}),
6046
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardPrice, {}),
6047
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.CardInterval, {})
7746
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "data-solvapay-paywall-plans": "", className: defaultClass, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Root, { productRef: ctx.content.product, filter: hidesFreePlan, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
7747
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Grid, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PlanSelector.Card, { children: [
7748
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.CardBadge, {}),
7749
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.CardName, {}),
7750
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.CardPrice, {}),
7751
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.CardInterval, {})
6048
7752
  ] }) }),
6049
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Loading, {}),
6050
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Error, {})
7753
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Loading, {}),
7754
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Error, {})
6051
7755
  ] }) }) });
6052
7756
  }
6053
7757
  function hidesFreePlan(plan) {
6054
7758
  return plan.requiresPayment !== false;
6055
7759
  }
6056
- var HostedCheckoutLink = (0, import_react36.forwardRef)(function PaywallNoticeHostedCheckoutLink({ asChild, children, className, ...rest }, forwardedRef) {
7760
+ var HostedCheckoutLink = (0, import_react38.forwardRef)(function PaywallNoticeHostedCheckoutLink({ asChild, children, className, ...rest }, forwardedRef) {
6057
7761
  const ctx = usePaywallNoticeCtx("HostedCheckoutLink");
6058
7762
  const copy = useCopy();
6059
7763
  const href = ctx.content.checkoutUrl;
6060
7764
  if (!href) return null;
6061
7765
  const Comp = asChild ? Slot : "a";
6062
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7766
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6063
7767
  Comp,
6064
7768
  {
6065
7769
  ref: forwardedRef,
@@ -6077,12 +7781,12 @@ function EmbeddedCheckout({ returnUrl, topupCurrency, className }) {
6077
7781
  const ctx = usePaywallNoticeCtx("EmbeddedCheckout");
6078
7782
  const productRef = ctx.content.product;
6079
7783
  const { plans } = usePlans({ productRef: productRef ?? void 0 });
6080
- const filter = (0, import_react36.useMemo)(() => buildDefaultCheckoutPlanFilter(plans), [plans]);
7784
+ const filter = (0, import_react38.useMemo)(() => buildDefaultCheckoutPlanFilter(plans), [plans]);
6081
7785
  if (!productRef) return null;
6082
7786
  const resolvedClassName = className ?? ctx.classNames.embeddedCheckout ?? "solvapay-paywall-embedded-checkout";
6083
7787
  const headingClassName = ctx.classNames.heading ?? "solvapay-paywall-step-heading";
6084
7788
  const messageClassName = ctx.classNames.message ?? "solvapay-paywall-step-message";
6085
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
7789
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
6086
7790
  CheckoutSteps.Root,
6087
7791
  {
6088
7792
  productRef,
@@ -6095,33 +7799,33 @@ function EmbeddedCheckout({ returnUrl, topupCurrency, className }) {
6095
7799
  },
6096
7800
  className: resolvedClassName,
6097
7801
  children: [
6098
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.StepHeading, { className: headingClassName }),
6099
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.StepMessage, { className: messageClassName }),
6100
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CheckoutSteps.IfStep, { step: "plan", children: [
6101
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.PlanGrid, {}),
6102
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Loading, {}),
6103
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PlanSelector.Error, {}),
6104
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.PlanContinueButton, {})
7802
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.StepHeading, { className: headingClassName }),
7803
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.StepMessage, { className: messageClassName }),
7804
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CheckoutSteps.IfStep, { step: "plan", children: [
7805
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.PlanGrid, {}),
7806
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Loading, {}),
7807
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PlanSelector.Error, {}),
7808
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.PlanContinueButton, {})
6105
7809
  ] }),
6106
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CheckoutSteps.IfStep, { step: "amount", children: [
6107
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.BackLink, {}),
6108
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.AmountPicker, {}),
6109
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.AmountContinueButton, {})
7810
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CheckoutSteps.IfStep, { step: "amount", children: [
7811
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.BackLink, {}),
7812
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.AmountPicker, {}),
7813
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.AmountContinueButton, {})
6110
7814
  ] }),
6111
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CheckoutSteps.IfStep, { step: "payment", children: [
6112
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.BackLink, {}),
6113
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.Payment, {})
7815
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CheckoutSteps.IfStep, { step: "payment", children: [
7816
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.BackLink, {}),
7817
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.Payment, {})
6114
7818
  ] }),
6115
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.IfStep, { step: "success", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CheckoutSteps.Success, {}) })
7819
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.IfStep, { step: "success", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CheckoutSteps.Success, {}) })
6116
7820
  ]
6117
7821
  }
6118
7822
  );
6119
7823
  }
6120
- var Retry = (0, import_react36.forwardRef)(function PaywallNoticeRetry({ asChild, children, className, onClick, ...rest }, forwardedRef) {
7824
+ var Retry = (0, import_react38.forwardRef)(function PaywallNoticeRetry({ asChild, children, className, onClick, ...rest }, forwardedRef) {
6121
7825
  const ctx = usePaywallNoticeCtx("Retry");
6122
7826
  const copy = useCopy();
6123
7827
  const Comp = asChild ? Slot : "button";
6124
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
7828
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
6125
7829
  Comp,
6126
7830
  {
6127
7831
  ref: forwardedRef,
@@ -6139,8 +7843,8 @@ var Retry = (0, import_react36.forwardRef)(function PaywallNoticeRetry({ asChild
6139
7843
  }
6140
7844
  );
6141
7845
  });
6142
- var PaywallNotice = Object.assign(Root11, {
6143
- Root: Root11,
7846
+ var PaywallNotice = Object.assign(Root12, {
7847
+ Root: Root12,
6144
7848
  Heading: Heading4,
6145
7849
  Message,
6146
7850
  ProductContext,
@@ -6154,14 +7858,14 @@ function usePaywallNotice() {
6154
7858
  return usePaywallNoticeCtx("usePaywallNotice");
6155
7859
  }
6156
7860
  function usePaywallNoticeOptional() {
6157
- return (0, import_react36.useContext)(PaywallNoticeContext);
7861
+ return (0, import_react38.useContext)(PaywallNoticeContext);
6158
7862
  }
6159
7863
 
6160
7864
  // src/primitives/UsageMeter.tsx
6161
- var import_react38 = require("react");
7865
+ var import_react40 = require("react");
6162
7866
 
6163
7867
  // src/hooks/useUsage.ts
6164
- var import_react37 = require("react");
7868
+ var import_react39 = require("react");
6165
7869
  function deriveUsage(purchase) {
6166
7870
  if (!purchase) return null;
6167
7871
  const snap = purchase.planSnapshot;
@@ -6186,16 +7890,16 @@ function deriveUsage(purchase) {
6186
7890
  function useUsage() {
6187
7891
  const { activePurchase, refetch: refetchPurchase, loading: purchaseLoading } = usePurchase();
6188
7892
  const transport = useTransport();
6189
- const [override, setOverride] = (0, import_react37.useState)(null);
6190
- const [error, setError] = (0, import_react37.useState)(null);
6191
- const [transportLoading, setTransportLoading] = (0, import_react37.useState)(false);
6192
- const derived = (0, import_react37.useMemo)(() => deriveUsage(activePurchase ?? null), [activePurchase]);
7893
+ const [override, setOverride] = (0, import_react39.useState)(null);
7894
+ const [error, setError] = (0, import_react39.useState)(null);
7895
+ const [transportLoading, setTransportLoading] = (0, import_react39.useState)(false);
7896
+ const derived = (0, import_react39.useMemo)(() => deriveUsage(activePurchase ?? null), [activePurchase]);
6193
7897
  const activePurchaseRef = activePurchase?.reference ?? null;
6194
- (0, import_react37.useEffect)(() => {
7898
+ (0, import_react39.useEffect)(() => {
6195
7899
  setOverride(null);
6196
7900
  }, [activePurchaseRef]);
6197
7901
  const usage = override ?? derived;
6198
- const refetch = (0, import_react37.useCallback)(async () => {
7902
+ const refetch = (0, import_react39.useCallback)(async () => {
6199
7903
  setError(null);
6200
7904
  if (typeof transport.getUsage === "function") {
6201
7905
  setTransportLoading(true);
@@ -6233,16 +7937,16 @@ function useUsage() {
6233
7937
  }
6234
7938
 
6235
7939
  // src/primitives/UsageMeter.tsx
6236
- var import_jsx_runtime25 = require("react/jsx-runtime");
6237
- var UsageMeterContext = (0, import_react38.createContext)(null);
7940
+ var import_jsx_runtime26 = require("react/jsx-runtime");
7941
+ var UsageMeterContext = (0, import_react40.createContext)(null);
6238
7942
  function useUsageMeterCtx(part) {
6239
- const ctx = (0, import_react38.useContext)(UsageMeterContext);
7943
+ const ctx = (0, import_react40.useContext)(UsageMeterContext);
6240
7944
  if (!ctx) {
6241
7945
  throw new Error(`UsageMeter.${part} must be rendered inside <UsageMeter.Root>.`);
6242
7946
  }
6243
7947
  return ctx;
6244
7948
  }
6245
- var Root12 = (0, import_react38.forwardRef)(function UsageMeterRoot({
7949
+ var Root13 = (0, import_react40.forwardRef)(function UsageMeterRoot({
6246
7950
  warningAt = 75,
6247
7951
  criticalAt = 90,
6248
7952
  classNames,
@@ -6257,7 +7961,7 @@ var Root12 = (0, import_react38.forwardRef)(function UsageMeterRoot({
6257
7961
  const loading = hookResult.loading && !usage;
6258
7962
  const percentUsed = usage?.percentUsed ?? null;
6259
7963
  const state = loading ? "loading" : percentUsed === null ? "safe" : percentUsed >= criticalAt ? "critical" : percentUsed >= warningAt ? "warning" : "safe";
6260
- const ctx = (0, import_react38.useMemo)(
7964
+ const ctx = (0, import_react40.useMemo)(
6261
7965
  () => ({
6262
7966
  usage,
6263
7967
  loading,
@@ -6285,7 +7989,7 @@ var Root12 = (0, import_react38.forwardRef)(function UsageMeterRoot({
6285
7989
  );
6286
7990
  const rootClass = [classNames?.root ?? "solvapay-usage-meter", className].filter(Boolean).join(" ");
6287
7991
  const Comp = asChild ? Slot : "div";
6288
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(UsageMeterContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
7992
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(UsageMeterContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6289
7993
  Comp,
6290
7994
  {
6291
7995
  ref: forwardedRef,
@@ -6297,10 +8001,10 @@ var Root12 = (0, import_react38.forwardRef)(function UsageMeterRoot({
6297
8001
  }
6298
8002
  ) });
6299
8003
  });
6300
- var Bar = (0, import_react38.forwardRef)(function UsageMeterBar({ className, style, ...rest }, forwardedRef) {
8004
+ var Bar = (0, import_react40.forwardRef)(function UsageMeterBar({ className, style, ...rest }, forwardedRef) {
6301
8005
  const ctx = useUsageMeterCtx("Bar");
6302
8006
  const width = ctx.percentUsed === null ? 0 : Math.max(0, Math.min(100, ctx.percentUsed));
6303
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8007
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6304
8008
  "div",
6305
8009
  {
6306
8010
  ref: forwardedRef,
@@ -6321,12 +8025,12 @@ var Bar = (0, import_react38.forwardRef)(function UsageMeterBar({ className, sty
6321
8025
  }
6322
8026
  );
6323
8027
  });
6324
- var Label = (0, import_react38.forwardRef)(function UsageMeterLabel({ className, children, ...rest }, forwardedRef) {
8028
+ var Label = (0, import_react40.forwardRef)(function UsageMeterLabel({ className, children, ...rest }, forwardedRef) {
6325
8029
  const ctx = useUsageMeterCtx("Label");
6326
8030
  const copy = useCopy();
6327
8031
  if (!ctx.usage) return null;
6328
8032
  if (ctx.isUnlimited) {
6329
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8033
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6330
8034
  "span",
6331
8035
  {
6332
8036
  ref: forwardedRef,
@@ -6346,7 +8050,7 @@ var Label = (0, import_react38.forwardRef)(function UsageMeterLabel({ className,
6346
8050
  remaining: String(ctx.usage.remaining ?? 0),
6347
8051
  unit
6348
8052
  });
6349
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8053
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6350
8054
  "span",
6351
8055
  {
6352
8056
  ref: forwardedRef,
@@ -6357,11 +8061,11 @@ var Label = (0, import_react38.forwardRef)(function UsageMeterLabel({ className,
6357
8061
  }
6358
8062
  );
6359
8063
  });
6360
- var Percentage = (0, import_react38.forwardRef)(function UsageMeterPercentage({ className, children, ...rest }, forwardedRef) {
8064
+ var Percentage = (0, import_react40.forwardRef)(function UsageMeterPercentage({ className, children, ...rest }, forwardedRef) {
6361
8065
  const ctx = useUsageMeterCtx("Percentage");
6362
8066
  const copy = useCopy();
6363
8067
  if (ctx.percentUsed === null) return null;
6364
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8068
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6365
8069
  "span",
6366
8070
  {
6367
8071
  ref: forwardedRef,
@@ -6378,14 +8082,14 @@ function formatResetsIn(copy, periodEnd, nowMs = typeof performance !== "undefin
6378
8082
  const daysLeft = Math.max(0, Math.ceil((end - nowMs) / (24 * 60 * 60 * 1e3)));
6379
8083
  return daysLeft > 0 ? interpolate(copy.usage.resetsInLabel, { days: String(daysLeft) }) : interpolate(copy.usage.resetsOnLabel, { date: new Date(periodEnd).toLocaleDateString() });
6380
8084
  }
6381
- var ResetsIn = (0, import_react38.forwardRef)(function UsageMeterResetsIn({ className, children, ...rest }, forwardedRef) {
8085
+ var ResetsIn = (0, import_react40.forwardRef)(function UsageMeterResetsIn({ className, children, ...rest }, forwardedRef) {
6382
8086
  const ctx = useUsageMeterCtx("ResetsIn");
6383
8087
  const copy = useCopy();
6384
8088
  const periodEnd = ctx.usage?.periodEnd;
6385
8089
  if (!periodEnd) return null;
6386
8090
  const label = formatResetsIn(copy, periodEnd);
6387
8091
  if (!label) return null;
6388
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8092
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6389
8093
  "span",
6390
8094
  {
6391
8095
  ref: forwardedRef,
@@ -6396,11 +8100,11 @@ var ResetsIn = (0, import_react38.forwardRef)(function UsageMeterResetsIn({ clas
6396
8100
  }
6397
8101
  );
6398
8102
  });
6399
- var Loading7 = (0, import_react38.forwardRef)(function UsageMeterLoading({ className, children, ...rest }, forwardedRef) {
8103
+ var Loading8 = (0, import_react40.forwardRef)(function UsageMeterLoading({ className, children, ...rest }, forwardedRef) {
6400
8104
  const ctx = useUsageMeterCtx("Loading");
6401
8105
  const copy = useCopy();
6402
8106
  if (ctx.state !== "loading") return null;
6403
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8107
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6404
8108
  "div",
6405
8109
  {
6406
8110
  ref: forwardedRef,
@@ -6411,11 +8115,11 @@ var Loading7 = (0, import_react38.forwardRef)(function UsageMeterLoading({ class
6411
8115
  }
6412
8116
  );
6413
8117
  });
6414
- var Empty = (0, import_react38.forwardRef)(function UsageMeterEmpty({ className, children, ...rest }, forwardedRef) {
8118
+ var Empty = (0, import_react40.forwardRef)(function UsageMeterEmpty({ className, children, ...rest }, forwardedRef) {
6415
8119
  const ctx = useUsageMeterCtx("Empty");
6416
8120
  const copy = useCopy();
6417
8121
  if (ctx.loading || ctx.usage !== null) return null;
6418
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8122
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
6419
8123
  "div",
6420
8124
  {
6421
8125
  ref: forwardedRef,
@@ -6426,13 +8130,13 @@ var Empty = (0, import_react38.forwardRef)(function UsageMeterEmpty({ className,
6426
8130
  }
6427
8131
  );
6428
8132
  });
6429
- var UsageMeter = Object.assign(Root12, {
6430
- Root: Root12,
8133
+ var UsageMeter = Object.assign(Root13, {
8134
+ Root: Root13,
6431
8135
  Bar,
6432
8136
  Label,
6433
8137
  Percentage,
6434
8138
  ResetsIn,
6435
- Loading: Loading7,
8139
+ Loading: Loading8,
6436
8140
  Empty
6437
8141
  });
6438
8142
  function useUsageMeter() {
@@ -6455,6 +8159,40 @@ function useUsageMeter() {
6455
8159
  AmountPickerCustom,
6456
8160
  AmountPickerOption,
6457
8161
  AmountPickerRoot,
8162
+ AutoRecharge,
8163
+ AutoRechargeActions,
8164
+ AutoRechargeAmountField,
8165
+ AutoRechargeBody,
8166
+ AutoRechargeCancelButton,
8167
+ AutoRechargeCard,
8168
+ AutoRechargeCardHeading,
8169
+ AutoRechargeCardSetup,
8170
+ AutoRechargeCardSummary,
8171
+ AutoRechargeContent,
8172
+ AutoRechargeDescription,
8173
+ AutoRechargeDisableButton,
8174
+ AutoRechargeEnableQuestion,
8175
+ AutoRechargeEnableRow,
8176
+ AutoRechargeEnableSentence,
8177
+ AutoRechargeEnableSwitch,
8178
+ AutoRechargeError,
8179
+ AutoRechargeFields,
8180
+ AutoRechargeHeader,
8181
+ AutoRechargeHint,
8182
+ AutoRechargeLoading,
8183
+ AutoRechargeOverlay,
8184
+ AutoRechargeRoot,
8185
+ AutoRechargeSaveButton,
8186
+ AutoRechargeSetup,
8187
+ AutoRechargeStatus,
8188
+ AutoRechargeStatusMessage,
8189
+ AutoRechargeSummary,
8190
+ AutoRechargeThresholdField,
8191
+ AutoRechargeTitle,
8192
+ AutoRechargeTopupField,
8193
+ AutoRechargeTrigger,
8194
+ AutoRechargeUnitToggle,
8195
+ AutoRechargeValidationError,
6458
8196
  BalanceBadge,
6459
8197
  CancelPlanButton,
6460
8198
  CancelledPlanNotice,
@@ -6560,6 +8298,7 @@ function useUsageMeter() {
6560
8298
  useActivationFlow,
6561
8299
  useAmountPicker,
6562
8300
  useAmountPickerCopy,
8301
+ useAutoRechargeForm,
6563
8302
  useCancelledPlanNotice,
6564
8303
  useCheckoutStepsContext,
6565
8304
  useCheckoutSummary,