@solvapay/react 2.2.2-preview-cf2672297243fbf98ba33872a7348aca170e7b01 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  ExternalLinkGlyph,
3
3
  LaunchCustomerPortalButton,
4
- paymentMethodCache
5
- } from "../chunk-3OR5EEP4.js";
4
+ paymentMethodCache,
5
+ usePaymentMethod
6
+ } from "../chunk-4UFQDYG5.js";
6
7
  import {
7
8
  AmountPicker,
8
9
  BalanceBadge,
@@ -16,9 +17,12 @@ import {
16
17
  SolvaPayProvider,
17
18
  TopupForm,
18
19
  UsageMeter,
20
+ buildSummaryLine,
21
+ configToForm,
19
22
  createDefaultAutoRechargeForm,
20
23
  createTransportCacheKey,
21
24
  estimateCredits,
25
+ formatAmountWithUnit,
22
26
  formatContinueLabel,
23
27
  formatCycleSuffix,
24
28
  formatPaygRate,
@@ -39,6 +43,7 @@ import {
39
43
  seedUsageSnapshot,
40
44
  useActivation,
41
45
  useAmountPicker,
46
+ useAutoRecharge,
42
47
  useBalance,
43
48
  useCheckoutFlow,
44
49
  useCopy,
@@ -57,7 +62,7 @@ import {
57
62
  useTransport,
58
63
  useUsage,
59
64
  validateAutoRechargeForm
60
- } from "../chunk-JVBZHE7B.js";
65
+ } from "../chunk-GPP4MY3I.js";
61
66
  import "../chunk-UMXOAUW7.js";
62
67
  import "../chunk-MLKGABMK.js";
63
68
 
@@ -128,54 +133,19 @@ import { MCP_TOOL_NAMES as MCP_TOOL_NAMES3 } from "@solvapay/mcp-core";
128
133
  // src/mcp/useStripeProbe.ts
129
134
  import { useEffect, useState } from "react";
130
135
  import { loadStripe } from "@stripe/stripe-js";
131
- var STRIPE_LOAD_TIMEOUT_MS = 1e4;
132
- var ELEMENT_MOUNT_TIMEOUT_MS = 6e3;
133
- var CACHEABLE_BLOCKED_REASONS = /* @__PURE__ */ new Set([
134
- "csp-frame-src",
135
- "loaderror",
136
- "load-rejected",
137
- "load-null-instance",
138
- "elements-create-threw"
139
- ]);
140
- var stripeProbeCache = /* @__PURE__ */ new Map();
141
- function resetStripeProbeCacheForTests() {
142
- stripeProbeCache.clear();
143
- }
144
- function readCachedProbe(publishableKey) {
145
- if (!publishableKey) return "blocked";
146
- return stripeProbeCache.get(publishableKey) ?? "loading";
147
- }
148
- function cacheProbeVerdict(publishableKey, next, reason) {
149
- if (next === "ready") {
150
- stripeProbeCache.set(publishableKey, "ready");
151
- return;
152
- }
153
- if (next === "blocked" && reason && CACHEABLE_BLOCKED_REASONS.has(reason)) {
154
- stripeProbeCache.set(publishableKey, "blocked");
155
- }
156
- }
136
+ var STRIPE_LOAD_TIMEOUT_MS = 3e3;
137
+ var ELEMENT_MOUNT_TIMEOUT_MS = 2e3;
157
138
  function useStripeProbe(publishableKey) {
158
- const [state, setState] = useState(() => readCachedProbe(publishableKey));
139
+ const [state, setState] = useState(
140
+ publishableKey ? "loading" : "blocked"
141
+ );
159
142
  useEffect(() => {
160
143
  if (typeof document === "undefined") return;
161
144
  if (!publishableKey) {
162
- console.warn("[solvapay-mcp] stripe probe blocked", {
163
- reason: "no-publishable-key",
164
- elapsedMs: 0,
165
- loadMs: null
166
- });
167
145
  setState("blocked");
168
146
  return;
169
147
  }
170
- const cached = stripeProbeCache.get(publishableKey);
171
- if (cached) {
172
- setState(cached);
173
- return;
174
- }
175
148
  setState("loading");
176
- const startedAt = Date.now();
177
- let loadResolvedAt = null;
178
- let mountStartedAt = null;
179
149
  let cancelled = false;
180
150
  let resolved = false;
181
151
  let cspBlockedStripeFrame = false;
@@ -213,7 +183,7 @@ function useStripeProbe(publishableKey) {
213
183
  sourceFile: event.sourceFile
214
184
  }
215
185
  );
216
- resolve("blocked", "csp-frame-src");
186
+ resolve("blocked");
217
187
  };
218
188
  document.addEventListener("securitypolicyviolation", onCspViolation);
219
189
  const teardown = () => {
@@ -231,46 +201,24 @@ function useStripeProbe(publishableKey) {
231
201
  host = null;
232
202
  }
233
203
  };
234
- const logBlocked = (reason) => {
235
- console.warn("[solvapay-mcp] stripe probe blocked", {
236
- reason,
237
- elapsedMs: Date.now() - startedAt,
238
- loadMs: loadResolvedAt !== null ? loadResolvedAt - startedAt : null
239
- });
240
- };
241
- const logReady = () => {
242
- const now = Date.now();
243
- console.warn("[solvapay-mcp] stripe probe ready", {
244
- elapsedMs: now - startedAt,
245
- loadMs: loadResolvedAt !== null ? loadResolvedAt - startedAt : null,
246
- mountMs: mountStartedAt !== null ? now - mountStartedAt : null
247
- });
248
- };
249
- const resolve = (next, reason) => {
204
+ const resolve = (next) => {
250
205
  if (cancelled || resolved) return;
251
206
  resolved = true;
252
- if (next === "ready") {
253
- logReady();
254
- } else if (reason) {
255
- logBlocked(reason);
256
- }
257
- cacheProbeVerdict(publishableKey, next, reason);
258
207
  teardown();
259
208
  setState(next);
260
209
  };
261
210
  loadTimeoutId = setTimeout(() => {
262
211
  loadTimeoutId = null;
263
- resolve("blocked", "load-timeout");
212
+ resolve("blocked");
264
213
  }, STRIPE_LOAD_TIMEOUT_MS);
265
214
  loadStripe(publishableKey, { developerTools: { assistant: { enabled: false } } }).then((stripe) => {
266
- loadResolvedAt = Date.now();
267
215
  if (cancelled || resolved) return;
268
216
  if (loadTimeoutId !== null) {
269
217
  clearTimeout(loadTimeoutId);
270
218
  loadTimeoutId = null;
271
219
  }
272
220
  if (!stripe) {
273
- resolve("blocked", "load-null-instance");
221
+ resolve("blocked");
274
222
  return;
275
223
  }
276
224
  try {
@@ -285,24 +233,22 @@ function useStripeProbe(publishableKey) {
285
233
  if (cspBlockedStripeFrame) return;
286
234
  resolve("ready");
287
235
  });
288
- element.on("loaderror", () => resolve("blocked", "loaderror"));
236
+ element.on("loaderror", () => resolve("blocked"));
289
237
  elementTimeoutId = setTimeout(() => {
290
238
  elementTimeoutId = null;
291
- resolve("blocked", "mount-timeout");
239
+ resolve("blocked");
292
240
  }, ELEMENT_MOUNT_TIMEOUT_MS);
293
- mountStartedAt = Date.now();
294
241
  element.mount(host);
295
242
  } catch {
296
- resolve("blocked", "elements-create-threw");
243
+ resolve("blocked");
297
244
  }
298
245
  }).catch(() => {
299
- loadResolvedAt = Date.now();
300
246
  if (cancelled || resolved) return;
301
247
  if (loadTimeoutId !== null) {
302
248
  clearTimeout(loadTimeoutId);
303
249
  loadTimeoutId = null;
304
250
  }
305
- resolve("blocked", "load-rejected");
251
+ resolve("blocked");
306
252
  });
307
253
  return () => {
308
254
  cancelled = true;
@@ -570,8 +516,7 @@ function parseBootstrapFromToolResult(result, toolName, fallbackView) {
570
516
  merchant: structured?.merchant ?? {},
571
517
  product: structured?.product ?? { reference: ref },
572
518
  plans: Array.isArray(structured?.plans) ? structured.plans : [],
573
- customer: structured?.customer ?? null,
574
- ...typeof structured?.autoRechargeUrl === "string" ? { autoRechargeUrl: structured.autoRechargeUrl } : {}
519
+ customer: structured?.customer ?? null
575
520
  };
576
521
  }
577
522
  function waitForInitialToolResult(app, options = {}) {
@@ -703,11 +648,11 @@ function seedMcpCaches(initial, config) {
703
648
  }
704
649
 
705
650
  // src/mcp/McpApp.tsx
706
- import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef8, useState as useState12 } from "react";
651
+ import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef6, useState as useState11 } from "react";
707
652
  import { VIEW_FOR_TOOL as VIEW_FOR_TOOL2 } from "@solvapay/mcp-core";
708
653
 
709
654
  // src/mcp/McpAppShell.tsx
710
- import { useCallback as useCallback5, useState as useState10 } from "react";
655
+ import { useCallback as useCallback5, useState as useState9 } from "react";
711
656
 
712
657
  // src/mcp/account-state.ts
713
658
  import {
@@ -2024,8 +1969,7 @@ function CreditAccountPanel({
2024
1969
  locale,
2025
1970
  classNames,
2026
1971
  onTopup,
2027
- autoRecharge,
2028
- autoRechargeUrl,
1972
+ onAutoRecharge,
2029
1973
  onChangePlan,
2030
1974
  showPortalCta
2031
1975
  }) {
@@ -2033,7 +1977,8 @@ function CreditAccountPanel({
2033
1977
  const copy = useCopy();
2034
1978
  const balance = useBalance();
2035
1979
  const { merchant } = useMerchant();
2036
- const handleExternalClick = useExternalLinkClick();
1980
+ const { config: autoRecharge } = useAutoRecharge();
1981
+ const { paymentMethod } = usePaymentMethod();
2037
1982
  const { displayMode } = useDisplayMode();
2038
1983
  const isFullscreen = displayMode === "fullscreen";
2039
1984
  const history = useHistory({
@@ -2051,13 +1996,10 @@ function CreditAccountPanel({
2051
1996
  paidPlanCount
2052
1997
  });
2053
1998
  const showChangePlan = Boolean(onChangePlan && (actions.changePlan || actions.upgrade));
2054
- const status = autoRecharge?.status;
2055
- const enabled = autoRecharge?.enabled === true;
2056
- const failed = status === "failed";
2057
- const pendingSetup = enabled && status === "pending_setup";
2058
- const title = failed ? copy.autoRecharge.statusFailed : pendingSetup ? copy.account.autoRechargePending : enabled ? copy.account.autoRechargeOn : copy.account.autoRechargeOff;
2059
- const caption = !enabled && !failed ? accountState === "D" ? copy.account.autoRechargeOffFixCaption : copy.account.autoRechargeOffCaption : null;
2060
- const actionLabel = failed ? copy.account.fixCard : enabled ? copy.account.manage : copy.account.turnOn;
1999
+ const autoRechargeOn = Boolean(autoRecharge?.enabled);
2000
+ const hasReusableCard = paymentMethod?.kind === "card" && paymentMethod.reusable;
2001
+ const autoRechargeAction = onAutoRecharge && (autoRechargeOn || hasReusableCard) ? onAutoRecharge : void 0;
2002
+ const autoRechargeActionLabel = autoRechargeOn ? copy.account.manage : copy.account.turnOn;
2061
2003
  return /* @__PURE__ */ jsxs5("div", { className: "solvapay-mcp-account", children: [
2062
2004
  /* @__PURE__ */ jsxs5("div", { className: cx2.card, children: [
2063
2005
  /* @__PURE__ */ jsx8(
@@ -2086,24 +2028,10 @@ function CreditAccountPanel({
2086
2028
  onTopup ? /* @__PURE__ */ jsx8("button", { type: "button", className: cx2.button, onClick: onTopup, children: copy.account.addFunds }) : null,
2087
2029
  /* @__PURE__ */ jsxs5(SplitRow, { children: [
2088
2030
  /* @__PURE__ */ jsxs5("div", { className: "solvapay-mcp-auto-recharge-copy", children: [
2089
- /* @__PURE__ */ jsx8("p", { children: title }),
2090
- caption ? /* @__PURE__ */ jsx8("p", { className: cx2.muted, children: caption }) : null
2031
+ /* @__PURE__ */ jsx8("p", { children: autoRechargeOn ? copy.account.autoRechargeOn : copy.account.autoRechargeOff }),
2032
+ !autoRechargeOn ? /* @__PURE__ */ jsx8("p", { className: cx2.muted, children: accountState === "D" ? copy.account.autoRechargeOffFixCaption : copy.account.autoRechargeOffCaption }) : null
2091
2033
  ] }),
2092
- autoRechargeUrl ? /* @__PURE__ */ jsxs5(
2093
- "a",
2094
- {
2095
- href: autoRechargeUrl,
2096
- target: "_blank",
2097
- rel: "noopener noreferrer",
2098
- className: cx2.linkButton,
2099
- "aria-label": `${actionLabel} (opens in a new tab)`,
2100
- onClick: handleExternalClick,
2101
- children: [
2102
- actionLabel,
2103
- /* @__PURE__ */ jsx8(ExternalLinkGlyph, {})
2104
- ]
2105
- }
2106
- ) : null
2034
+ autoRechargeAction ? /* @__PURE__ */ jsx8("button", { type: "button", className: cx2.linkButton, onClick: autoRechargeAction, children: autoRechargeActionLabel }) : null
2107
2035
  ] }),
2108
2036
  showPortalCta && !isFullscreen ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
2109
2037
  /* @__PURE__ */ jsx8("p", { className: cx2.muted, "data-solvapay-mcp-portal-hint": "", children: copy.currentPlan.portalHint }),
@@ -2693,8 +2621,7 @@ function McpAccountView({
2693
2621
  productRef,
2694
2622
  classNames,
2695
2623
  onTopup,
2696
- autoRecharge,
2697
- autoRechargeUrl,
2624
+ onAutoRecharge,
2698
2625
  onChangePlan,
2699
2626
  plans
2700
2627
  }) {
@@ -2738,8 +2665,7 @@ function McpAccountView({
2738
2665
  locale,
2739
2666
  classNames,
2740
2667
  onTopup,
2741
- autoRecharge,
2742
- autoRechargeUrl,
2668
+ onAutoRecharge,
2743
2669
  onChangePlan,
2744
2670
  showPortalCta
2745
2671
  }
@@ -2798,11 +2724,8 @@ function McpAccountView({
2798
2724
  );
2799
2725
  }
2800
2726
 
2801
- // src/mcp/views/checkout/EmbeddedCheckout.tsx
2802
- import { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef5, useState as useState8 } from "react";
2803
-
2804
- // src/mcp/views/checkout/steps/PlanStep.tsx
2805
- import { memo } from "react";
2727
+ // src/mcp/views/McpAutoRechargeView.tsx
2728
+ import { useState as useState5 } from "react";
2806
2729
 
2807
2730
  // src/mcp/views/BackLink.tsx
2808
2731
  import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -2822,8 +2745,256 @@ function BackLink({ label, glyph = "\u2190", className, onClick, ...rest }) {
2822
2745
  );
2823
2746
  }
2824
2747
 
2748
+ // src/mcp/views/autoRecharge/McpAutoRechargeFields.tsx
2749
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2750
+ function currencySymbol(currency) {
2751
+ try {
2752
+ const parts = new Intl.NumberFormat("en", {
2753
+ style: "currency",
2754
+ currency,
2755
+ currencyDisplay: "narrowSymbol"
2756
+ }).formatToParts(0);
2757
+ return parts.find((part) => part.type === "currency")?.value ?? currency.toUpperCase();
2758
+ } catch {
2759
+ return currency.toUpperCase();
2760
+ }
2761
+ }
2762
+ function McpAutoRechargeFields({
2763
+ form,
2764
+ onChange,
2765
+ currency,
2766
+ validationError,
2767
+ creditsPerMinorUnit,
2768
+ displayExchangeRate
2769
+ }) {
2770
+ const copy = useCopy();
2771
+ const prefix = currencySymbol(currency);
2772
+ const suffix = currency.toUpperCase();
2773
+ const credits = estimateCredits(
2774
+ Number(form.topupAmountMajor),
2775
+ currency,
2776
+ creditsPerMinorUnit,
2777
+ displayExchangeRate
2778
+ );
2779
+ const explainer = credits != null ? interpolate(copy.autoRechargeView.explainer, {
2780
+ credits: new Intl.NumberFormat().format(credits)
2781
+ }) : copy.autoRechargeView.explainerNoEstimate;
2782
+ return /* @__PURE__ */ jsxs9("div", { className: "solvapay-mcp-auto-recharge-fields", children: [
2783
+ /* @__PURE__ */ jsx14(
2784
+ Field,
2785
+ {
2786
+ id: "mcp-auto-recharge-threshold",
2787
+ label: copy.autoRechargeView.thresholdLabel,
2788
+ value: form.thresholdAmountMajor,
2789
+ prefix,
2790
+ suffix,
2791
+ onChange: (thresholdAmountMajor) => onChange({ ...form, thresholdAmountMajor })
2792
+ }
2793
+ ),
2794
+ /* @__PURE__ */ jsx14(
2795
+ Field,
2796
+ {
2797
+ id: "mcp-auto-recharge-topup",
2798
+ label: copy.autoRechargeView.topupLabel,
2799
+ value: form.topupAmountMajor,
2800
+ prefix,
2801
+ suffix,
2802
+ onChange: (topupAmountMajor) => onChange({ ...form, topupAmountMajor })
2803
+ }
2804
+ ),
2805
+ /* @__PURE__ */ jsx14(
2806
+ Field,
2807
+ {
2808
+ id: "mcp-auto-recharge-cap",
2809
+ label: copy.autoRechargeView.maxMonthlySpendLabel,
2810
+ value: form.maxMonthlySpendMajor,
2811
+ prefix,
2812
+ suffix,
2813
+ placeholder: copy.autoRechargeView.maxMonthlySpendPlaceholder,
2814
+ onChange: (maxMonthlySpendMajor) => onChange({ ...form, maxMonthlySpendMajor })
2815
+ }
2816
+ ),
2817
+ /* @__PURE__ */ jsx14("p", { className: "solvapay-mcp-auto-recharge-fields-explainer", children: explainer }),
2818
+ validationError ? /* @__PURE__ */ jsx14("p", { className: "solvapay-mcp-auto-recharge-fields-error", role: "alert", children: validationError }) : null
2819
+ ] });
2820
+ }
2821
+
2822
+ // src/mcp/views/McpAutoRechargeView.tsx
2823
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
2824
+ var FALLBACK_CURRENCY = "USD";
2825
+ function resolveCurrency(displayCurrency, merchantCurrency) {
2826
+ if (displayCurrency) return displayCurrency.toUpperCase();
2827
+ if (merchantCurrency) return merchantCurrency.toUpperCase();
2828
+ return FALLBACK_CURRENCY;
2829
+ }
2830
+ function McpAutoRechargeView({ classNames, onBack }) {
2831
+ const cx2 = resolveMcpClassNames(classNames);
2832
+ const copy = useCopy();
2833
+ const { merchant, loading: merchantLoading } = useMerchant();
2834
+ const { displayCurrency, creditsPerMinorUnit, displayExchangeRate } = useBalance();
2835
+ const { config, loading, saving, disabling, error, save, disable } = useAutoRecharge();
2836
+ const currency = resolveCurrency(displayCurrency, merchant?.defaultCurrency);
2837
+ const conversion = { creditsPerMinorUnit, displayExchangeRate };
2838
+ const [form, setForm] = useState5(() => ({
2839
+ ...createDefaultAutoRechargeForm(currency),
2840
+ enabled: true
2841
+ }));
2842
+ const [hydrated, setHydrated] = useState5(false);
2843
+ const [validationError, setValidationError] = useState5(null);
2844
+ const [setupError, setSetupError] = useState5(null);
2845
+ if (!loading && !hydrated) {
2846
+ setHydrated(true);
2847
+ if (config?.enabled) {
2848
+ setForm({ ...configToForm(config, currency), enabled: true });
2849
+ }
2850
+ }
2851
+ const editing = Boolean(config?.enabled);
2852
+ const summary = buildSummaryLine(form, currency);
2853
+ const thresholdDisplay = formatAmountWithUnit(
2854
+ form.thresholdAmountMajor,
2855
+ form.thresholdUnit,
2856
+ currency
2857
+ );
2858
+ if (loading || merchantLoading) {
2859
+ return /* @__PURE__ */ jsx15("section", { className: cx2.card, "aria-label": "Loading auto-recharge", children: /* @__PURE__ */ jsx15("p", { children: "Loading auto-recharge\u2026" }) });
2860
+ }
2861
+ const handleSave = async () => {
2862
+ const result = validateAutoRechargeForm(
2863
+ { ...form, enabled: true },
2864
+ currency,
2865
+ conversion,
2866
+ copy.autoRecharge
2867
+ );
2868
+ if (!result.ok) {
2869
+ setValidationError(result.error);
2870
+ return;
2871
+ }
2872
+ setValidationError(null);
2873
+ setSetupError(null);
2874
+ try {
2875
+ const response = await save(result.payload);
2876
+ if (response.setupClientSecret) {
2877
+ setSetupError(copy.autoRechargeView.setupUnexpected);
2878
+ return;
2879
+ }
2880
+ onBack?.();
2881
+ } catch {
2882
+ }
2883
+ };
2884
+ const handleDisable = async () => {
2885
+ setSetupError(null);
2886
+ try {
2887
+ await disable();
2888
+ onBack?.();
2889
+ } catch {
2890
+ }
2891
+ };
2892
+ const loudError = setupError ?? (error ? error.message : null);
2893
+ return /* @__PURE__ */ jsx15("section", { className: cx2.card, "aria-label": copy.autoRechargeView.heading, children: /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-view", children: [
2894
+ onBack ? /* @__PURE__ */ jsx15(BackLink, { label: copy.autoRechargeView.back, onClick: onBack }) : null,
2895
+ /* @__PURE__ */ jsxs10("div", { className: cx2.stack, children: [
2896
+ /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-heading", children: [
2897
+ /* @__PURE__ */ jsx15("h2", { className: cx2.heading, children: copy.autoRechargeView.heading }),
2898
+ editing ? /* @__PURE__ */ jsx15(StatusDot, { label: copy.autoRechargeView.statusOn }) : null
2899
+ ] }),
2900
+ editing ? null : /* @__PURE__ */ jsx15("p", { className: cx2.muted, children: copy.autoRechargeView.description }),
2901
+ summary ? /* @__PURE__ */ jsx15("p", { className: "solvapay-mcp-auto-recharge-summary", children: summary }) : null
2902
+ ] }),
2903
+ /* @__PURE__ */ jsx15(Section, { children: /* @__PURE__ */ jsx15(
2904
+ McpAutoRechargeFields,
2905
+ {
2906
+ form,
2907
+ onChange: (next) => {
2908
+ setValidationError(null);
2909
+ setForm(next);
2910
+ },
2911
+ currency,
2912
+ validationError,
2913
+ creditsPerMinorUnit,
2914
+ displayExchangeRate
2915
+ }
2916
+ ) }),
2917
+ loudError ? /* @__PURE__ */ jsx15("p", { className: cx2.error, role: "alert", children: loudError }) : null,
2918
+ editing ? /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-actions-stack", children: [
2919
+ /* @__PURE__ */ jsx15(
2920
+ "button",
2921
+ {
2922
+ type: "button",
2923
+ className: cx2.button,
2924
+ disabled: saving || disabling,
2925
+ onClick: () => {
2926
+ void handleSave();
2927
+ },
2928
+ children: copy.autoRechargeView.save
2929
+ }
2930
+ ),
2931
+ /* @__PURE__ */ jsx15(
2932
+ "button",
2933
+ {
2934
+ type: "button",
2935
+ className: cx2.button,
2936
+ "data-variant": "secondary",
2937
+ disabled: saving || disabling,
2938
+ onClick: onBack,
2939
+ children: copy.autoRechargeView.cancel
2940
+ }
2941
+ ),
2942
+ /* @__PURE__ */ jsx15(
2943
+ "button",
2944
+ {
2945
+ type: "button",
2946
+ className: `${cx2.linkButton} solvapay-mcp-auto-recharge-turn-off`.trim(),
2947
+ disabled: saving || disabling,
2948
+ onClick: () => {
2949
+ void handleDisable();
2950
+ },
2951
+ children: copy.autoRechargeView.turnOff
2952
+ }
2953
+ )
2954
+ ] }) : /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-footer", children: [
2955
+ /* @__PURE__ */ jsx15("p", { className: cx2.muted, children: interpolate(copy.autoRechargeView.footerCaption, {
2956
+ threshold: thresholdDisplay
2957
+ }) }),
2958
+ /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-actions", children: [
2959
+ /* @__PURE__ */ jsx15(
2960
+ "button",
2961
+ {
2962
+ type: "button",
2963
+ className: cx2.button,
2964
+ "data-variant": "secondary",
2965
+ disabled: saving,
2966
+ onClick: onBack,
2967
+ children: copy.autoRechargeView.cancel
2968
+ }
2969
+ ),
2970
+ /* @__PURE__ */ jsx15(
2971
+ "button",
2972
+ {
2973
+ type: "button",
2974
+ className: cx2.button,
2975
+ disabled: saving,
2976
+ onClick: () => {
2977
+ void handleSave();
2978
+ },
2979
+ children: copy.autoRechargeView.turnOn
2980
+ }
2981
+ )
2982
+ ] })
2983
+ ] })
2984
+ ] }) });
2985
+ }
2986
+
2987
+ // src/mcp/views/McpCheckoutView.tsx
2988
+ import React11, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo4, useRef as useRef4, useState as useState7 } from "react";
2989
+
2990
+ // src/mcp/views/checkout/EmbeddedCheckout.tsx
2991
+ import { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef3 } from "react";
2992
+
2993
+ // src/mcp/views/checkout/steps/PlanStep.tsx
2994
+ import { memo } from "react";
2995
+
2825
2996
  // src/mcp/views/checkout/CheckoutPlanRow.tsx
2826
- import { jsx as jsx14 } from "react/jsx-runtime";
2997
+ import { jsx as jsx16 } from "react/jsx-runtime";
2827
2998
  function CheckoutPlanRow({
2828
2999
  plan,
2829
3000
  locale,
@@ -2840,7 +3011,7 @@ function CheckoutPlanRow({
2840
3011
  const state = resolvePlanRowState({ current, selected, free });
2841
3012
  const priceLabel = formatPlanPriceLabel(plan, locale, selectedOption);
2842
3013
  const description = descriptionOverride ?? planWhatItGives(plan, locale, balance);
2843
- return /* @__PURE__ */ jsx14(
3014
+ return /* @__PURE__ */ jsx16(
2844
3015
  PlanRow,
2845
3016
  {
2846
3017
  name: plan.name ?? plan.reference,
@@ -2880,7 +3051,7 @@ function planWhatItGives(plan, locale, balance) {
2880
3051
  }
2881
3052
 
2882
3053
  // src/mcp/views/checkout/steps/PlanStep.tsx
2883
- import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
3054
+ import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
2884
3055
  var PlanStep = memo(function PlanStep2({
2885
3056
  fromPaywall,
2886
3057
  paywallKind,
@@ -2900,14 +3071,14 @@ var PlanStep = memo(function PlanStep2({
2900
3071
  const pricingOption = selectedPlan ? getSelectedOption(selectedPlan) : void 0;
2901
3072
  const ctaLabel = formatContinueLabel(selectedPlanShape, locale, pricingOption);
2902
3073
  const showPreface = fromPaywall && !hideUpgradeBanner && paywallKind !== "payment_required";
2903
- return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2904
- onBack ? /* @__PURE__ */ jsx15(BackLink, { label: copy.checkout.backToAccount, onClick: onBack }) : null,
2905
- showPreface ? /* @__PURE__ */ jsx15("p", { className: cx2.muted, role: "status", children: "This tool needs a paid plan. Pick one to get started." }) : null,
2906
- /* @__PURE__ */ jsxs9("div", { className: "solvapay-mcp-plan-step-header", children: [
2907
- /* @__PURE__ */ jsx15("h2", { className: cx2.heading, children: "Choose a plan" }),
2908
- /* @__PURE__ */ jsx15(PlanSelector.CurrencySwitcher, { className: "solvapay-plan-selector-currency-switcher" })
3074
+ return /* @__PURE__ */ jsxs11(Fragment5, { children: [
3075
+ onBack ? /* @__PURE__ */ jsx17(BackLink, { label: copy.checkout.backToAccount, onClick: onBack }) : null,
3076
+ showPreface ? /* @__PURE__ */ jsx17("p", { className: cx2.muted, role: "status", children: "This tool needs a paid plan. Pick one to get started." }) : null,
3077
+ /* @__PURE__ */ jsxs11("div", { className: "solvapay-mcp-plan-step-header", children: [
3078
+ /* @__PURE__ */ jsx17("h2", { className: cx2.heading, children: "Choose a plan" }),
3079
+ /* @__PURE__ */ jsx17(PlanSelector.CurrencySwitcher, { className: "solvapay-plan-selector-currency-switcher" })
2909
3080
  ] }),
2910
- /* @__PURE__ */ jsx15("div", { className: "solvapay-mcp-plan-list", children: plans.map((plan) => /* @__PURE__ */ jsx15(
3081
+ /* @__PURE__ */ jsx17("div", { className: "solvapay-mcp-plan-list", children: plans.map((plan) => /* @__PURE__ */ jsx17(
2911
3082
  CheckoutPlanRow,
2912
3083
  {
2913
3084
  plan,
@@ -2921,10 +3092,10 @@ var PlanStep = memo(function PlanStep2({
2921
3092
  },
2922
3093
  plan.reference
2923
3094
  )) }),
2924
- /* @__PURE__ */ jsx15(PlanSelector.Loading, { className: "solvapay-plan-selector-loading" }),
2925
- /* @__PURE__ */ jsx15(PlanSelector.Error, { className: "solvapay-plan-selector-error" }),
2926
- activationError ? /* @__PURE__ */ jsx15("p", { className: cx2.error, role: "alert", children: activationError }) : null,
2927
- /* @__PURE__ */ jsx15(
3095
+ /* @__PURE__ */ jsx17(PlanSelector.Loading, { className: "solvapay-plan-selector-loading" }),
3096
+ /* @__PURE__ */ jsx17(PlanSelector.Error, { className: "solvapay-plan-selector-error" }),
3097
+ activationError ? /* @__PURE__ */ jsx17("p", { className: cx2.error, role: "alert", children: activationError }) : null,
3098
+ /* @__PURE__ */ jsx17(
2928
3099
  "button",
2929
3100
  {
2930
3101
  type: "button",
@@ -2935,7 +3106,7 @@ var PlanStep = memo(function PlanStep2({
2935
3106
  children: ctaLabel
2936
3107
  }
2937
3108
  ),
2938
- onStayOnFree ? /* @__PURE__ */ jsx15(
3109
+ onStayOnFree ? /* @__PURE__ */ jsx17(
2939
3110
  "button",
2940
3111
  {
2941
3112
  type: "button",
@@ -2949,143 +3120,7 @@ var PlanStep = memo(function PlanStep2({
2949
3120
  });
2950
3121
 
2951
3122
  // src/mcp/views/checkout/steps/AmountStep.tsx
2952
- import { memo as memo2, useRef as useRef3, useState as useState6 } from "react";
2953
-
2954
- // src/mcp/views/autoRecharge/McpInlineAutoRecharge.tsx
2955
- import { forwardRef, useImperativeHandle, useState as useState5 } from "react";
2956
-
2957
- // src/mcp/views/autoRecharge/McpAutoRechargeFields.tsx
2958
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
2959
- function currencySymbol(currency) {
2960
- try {
2961
- const parts = new Intl.NumberFormat("en", {
2962
- style: "currency",
2963
- currency,
2964
- currencyDisplay: "narrowSymbol"
2965
- }).formatToParts(0);
2966
- return parts.find((part) => part.type === "currency")?.value ?? currency.toUpperCase();
2967
- } catch {
2968
- return currency.toUpperCase();
2969
- }
2970
- }
2971
- function McpAutoRechargeFields({
2972
- form,
2973
- onChange,
2974
- currency,
2975
- validationError,
2976
- creditsPerMinorUnit,
2977
- displayExchangeRate
2978
- }) {
2979
- const copy = useCopy();
2980
- const prefix = currencySymbol(currency);
2981
- const suffix = currency.toUpperCase();
2982
- const credits = estimateCredits(
2983
- Number(form.topupAmountMajor),
2984
- currency,
2985
- creditsPerMinorUnit,
2986
- displayExchangeRate
2987
- );
2988
- const explainer = credits != null ? interpolate(copy.autoRechargeView.explainer, {
2989
- credits: new Intl.NumberFormat().format(credits)
2990
- }) : copy.autoRechargeView.explainerNoEstimate;
2991
- return /* @__PURE__ */ jsxs10("div", { className: "solvapay-mcp-auto-recharge-fields", children: [
2992
- /* @__PURE__ */ jsx16(
2993
- Field,
2994
- {
2995
- id: "mcp-auto-recharge-threshold",
2996
- label: copy.autoRechargeView.thresholdLabel,
2997
- value: form.thresholdAmountMajor,
2998
- prefix,
2999
- suffix,
3000
- onChange: (thresholdAmountMajor) => onChange({ ...form, thresholdAmountMajor })
3001
- }
3002
- ),
3003
- /* @__PURE__ */ jsx16(
3004
- Field,
3005
- {
3006
- id: "mcp-auto-recharge-topup",
3007
- label: copy.autoRechargeView.topupLabel,
3008
- value: form.topupAmountMajor,
3009
- prefix,
3010
- suffix,
3011
- onChange: (topupAmountMajor) => onChange({ ...form, topupAmountMajor })
3012
- }
3013
- ),
3014
- /* @__PURE__ */ jsx16(
3015
- Field,
3016
- {
3017
- id: "mcp-auto-recharge-cap",
3018
- label: copy.autoRechargeView.maxMonthlySpendLabel,
3019
- value: form.maxMonthlySpendMajor,
3020
- prefix,
3021
- suffix,
3022
- placeholder: copy.autoRechargeView.maxMonthlySpendPlaceholder,
3023
- onChange: (maxMonthlySpendMajor) => onChange({ ...form, maxMonthlySpendMajor })
3024
- }
3025
- ),
3026
- /* @__PURE__ */ jsx16("p", { className: "solvapay-mcp-auto-recharge-fields-explainer", children: explainer }),
3027
- validationError ? /* @__PURE__ */ jsx16("p", { className: "solvapay-mcp-auto-recharge-fields-error", role: "alert", children: validationError }) : null
3028
- ] });
3029
- }
3030
-
3031
- // src/mcp/views/autoRecharge/McpInlineAutoRecharge.tsx
3032
- import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
3033
- var McpInlineAutoRecharge = forwardRef(function McpInlineAutoRecharge2({ currency, creditsPerMinorUnit, displayExchangeRate }, ref) {
3034
- const copy = useCopy();
3035
- const [form, setForm] = useState5(() => createDefaultAutoRechargeForm(currency));
3036
- const [error, setError] = useState5(null);
3037
- useImperativeHandle(ref, () => ({
3038
- validate: () => {
3039
- const result = validateAutoRechargeForm(
3040
- form,
3041
- currency,
3042
- { creditsPerMinorUnit, displayExchangeRate },
3043
- copy.autoRecharge
3044
- );
3045
- if (!result.ok) {
3046
- setError(result.error);
3047
- return { ok: false };
3048
- }
3049
- setError(null);
3050
- return {
3051
- ok: true,
3052
- payload: result.payload.enabled ? result.payload : void 0
3053
- };
3054
- }
3055
- }));
3056
- return /* @__PURE__ */ jsxs11("div", { className: "solvapay-mcp-auto-recharge-inline", children: [
3057
- /* @__PURE__ */ jsxs11(SplitRow, { children: [
3058
- /* @__PURE__ */ jsx17("p", { children: copy.autoRechargeView.heading }),
3059
- /* @__PURE__ */ jsx17(
3060
- Toggle,
3061
- {
3062
- checked: form.enabled,
3063
- label: copy.autoRechargeView.heading,
3064
- onChange: (enabled) => {
3065
- setError(null);
3066
- setForm((current) => ({ ...current, enabled }));
3067
- }
3068
- }
3069
- )
3070
- ] }),
3071
- form.enabled ? /* @__PURE__ */ jsx17(
3072
- McpAutoRechargeFields,
3073
- {
3074
- form,
3075
- onChange: (next) => {
3076
- setError(null);
3077
- setForm(next);
3078
- },
3079
- currency,
3080
- validationError: error,
3081
- creditsPerMinorUnit,
3082
- displayExchangeRate
3083
- }
3084
- ) : null
3085
- ] });
3086
- });
3087
-
3088
- // src/mcp/views/checkout/steps/AmountStep.tsx
3123
+ import { memo as memo2, useState as useState6 } from "react";
3089
3124
  import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
3090
3125
  var AmountStep = memo2(function AmountStep2({
3091
3126
  topupCurrency,
@@ -3097,8 +3132,6 @@ var AmountStep = memo2(function AmountStep2({
3097
3132
  }) {
3098
3133
  const currency = (topupCurrency ?? "USD").toUpperCase();
3099
3134
  const locale = useHostLocale();
3100
- const { creditsPerMinorUnit, displayExchangeRate } = useBalance();
3101
- const autoRechargeRef = useRef3(null);
3102
3135
  const [stagedAmountMinor, setStagedAmountMinor] = useState6(null);
3103
3136
  const currencies = topupCurrencies ?? [];
3104
3137
  const showCurrencySwitch = currencies.length > 1 && !!onCurrencyChange;
@@ -3129,27 +3162,11 @@ var AmountStep = memo2(function AmountStep2({
3129
3162
  children: [
3130
3163
  /* @__PURE__ */ jsx18(PresetAmountRow, { cx: cx2, currencyDisplay }),
3131
3164
  /* @__PURE__ */ jsx18(CustomAmountRow, { rowClassName: cx2.amountCustom, currencyDisplay }),
3132
- /* @__PURE__ */ jsx18(
3133
- McpInlineAutoRecharge,
3134
- {
3135
- ref: autoRechargeRef,
3136
- currency,
3137
- creditsPerMinorUnit,
3138
- displayExchangeRate
3139
- }
3140
- ),
3141
3165
  /* @__PURE__ */ jsx18(
3142
3166
  AmountPicker.Confirm,
3143
3167
  {
3144
3168
  className: cx2.button,
3145
- onConfirm: (amountMinor) => {
3146
- const result = autoRechargeRef.current?.validate();
3147
- if (result == null) {
3148
- throw new Error("AmountStep: auto-recharge form is not mounted");
3149
- }
3150
- if (!result.ok) return;
3151
- onContinue(amountMinor, result.payload);
3152
- },
3169
+ onConfirm: (amountMinor) => onContinue(amountMinor),
3153
3170
  children: stagedAmountMinor ? `Continue \u2014 ${formatPrice(stagedAmountMinor, currency, { locale, currencyDisplay })}` : "Continue"
3154
3171
  }
3155
3172
  )
@@ -3281,7 +3298,6 @@ var PaygPaymentStep = memo3(function PaygPaymentStep2({
3281
3298
  plan: _plan,
3282
3299
  amountMinor,
3283
3300
  topupCurrency,
3284
- autoRecharge,
3285
3301
  returnUrl,
3286
3302
  onBack,
3287
3303
  onSuccess,
@@ -3298,7 +3314,6 @@ var PaygPaymentStep = memo3(function PaygPaymentStep2({
3298
3314
  {
3299
3315
  amount: amountMinor,
3300
3316
  currency,
3301
- autoRecharge,
3302
3317
  returnUrl,
3303
3318
  onSuccess: (_intent, extras) => onSuccess(extras),
3304
3319
  children: /* @__PURE__ */ jsxs15(McpHostedLayout, { children: [
@@ -3504,14 +3519,271 @@ var SuccessStep = memo5(function SuccessStep2({ meta, cx: cx2 }) {
3504
3519
  ] });
3505
3520
  });
3506
3521
 
3507
- // src/mcp/views/checkout/HostedCheckout.tsx
3508
- import React10, { useCallback as useCallback3, useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState7 } from "react";
3509
- import { Fragment as Fragment11, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
3522
+ // src/mcp/views/checkout/EmbeddedCheckout.tsx
3523
+ import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
3524
+ function EmbeddedCheckout({
3525
+ productRef,
3526
+ returnUrl,
3527
+ onPurchaseSuccess,
3528
+ fromPaywall,
3529
+ paywallKind,
3530
+ hideUpgradeBanner,
3531
+ plans,
3532
+ onClose,
3533
+ onBack,
3534
+ initialPlanRef,
3535
+ autoAdvance,
3536
+ cx: cx2,
3537
+ children
3538
+ }) {
3539
+ const { loading, isRefetching, activePurchase } = usePurchase();
3540
+ const currentPlanRef = activePurchase?.planSnapshot?.reference ?? null;
3541
+ const paidPlans = useMemo3(() => {
3542
+ const list = plans ?? [];
3543
+ return list.filter((p) => p.requiresPayment !== false);
3544
+ }, [plans]);
3545
+ const paygPlanRef = useMemo3(() => {
3546
+ const payg = paidPlans.find((p) => isPayg(p));
3547
+ return payg?.reference ?? void 0;
3548
+ }, [paidPlans]);
3549
+ const planFilter = useMemo3(
3550
+ () => (plan) => plan.requiresPayment !== false || plan.reference === currentPlanRef,
3551
+ [currentPlanRef]
3552
+ );
3553
+ if (loading) {
3554
+ return /* @__PURE__ */ jsx25("div", { className: cx2.card, children: /* @__PURE__ */ jsx25("p", { children: "Loading checkout\u2026" }) });
3555
+ }
3556
+ return /* @__PURE__ */ jsxs18("div", { className: cx2.card, "data-refreshing": isRefetching ? "true" : void 0, children: [
3557
+ /* @__PURE__ */ jsx25(
3558
+ PlanSelector.Root,
3559
+ {
3560
+ productRef,
3561
+ filter: planFilter,
3562
+ sortBy: planSortByPaygFirstThenAsc,
3563
+ popularPlanRef: paygPlanRef,
3564
+ currentPlanRef,
3565
+ autoSelectFirstPaid: Boolean(paygPlanRef),
3566
+ initialPlanRef,
3567
+ className: "solvapay-plan-selector",
3568
+ children: /* @__PURE__ */ jsx25(
3569
+ McpCheckoutBody,
3570
+ {
3571
+ productRef,
3572
+ returnUrl,
3573
+ onPurchaseSuccess,
3574
+ fromPaywall,
3575
+ paywallKind,
3576
+ hideUpgradeBanner,
3577
+ onClose,
3578
+ onBack,
3579
+ initialPlanRef,
3580
+ autoAdvance,
3581
+ cx: cx2
3582
+ }
3583
+ )
3584
+ }
3585
+ ),
3586
+ children
3587
+ ] });
3588
+ }
3589
+ function McpCheckoutBody({
3590
+ productRef,
3591
+ returnUrl,
3592
+ onPurchaseSuccess,
3593
+ fromPaywall,
3594
+ paywallKind,
3595
+ hideUpgradeBanner,
3596
+ onClose,
3597
+ onBack,
3598
+ initialPlanRef,
3599
+ autoAdvance,
3600
+ cx: cx2
3601
+ }) {
3602
+ const bridge = useMcpBridge();
3603
+ const locale = useHostLocale();
3604
+ const flow = useCheckoutFlow({
3605
+ productRef,
3606
+ // `notifyModelContext` for plan commit fires from the explicit
3607
+ // Continue handler below — not on `selectPlan` — so a stray
3608
+ // selection doesn't burn a host emit before the user opts in.
3609
+ onPurchaseSuccess: (meta) => {
3610
+ if (meta.branch === "payg" && meta.amountMinor != null && meta.currency != null) {
3611
+ void bridge.notifyModelContext({
3612
+ text: `Activated ${meta.plan.name ?? "plan"} with ${formatPrice(
3613
+ meta.amountMinor,
3614
+ meta.currency,
3615
+ { locale }
3616
+ )} in credits.`
3617
+ });
3618
+ void bridge.notifySuccess({
3619
+ kind: "topup",
3620
+ amountMinor: meta.amountMinor,
3621
+ currency: meta.currency
3622
+ });
3623
+ } else {
3624
+ void bridge.notifyModelContext({
3625
+ text: `Activated ${meta.plan.name ?? "plan"}.`
3626
+ });
3627
+ void bridge.notifySuccess({
3628
+ kind: "plan-activated",
3629
+ planName: meta.plan.name ?? null
3630
+ });
3631
+ }
3632
+ onPurchaseSuccess?.();
3633
+ }
3634
+ });
3635
+ const onStayOnFree = useCallback3(() => {
3636
+ void bridge.sendMessage({ text: "Sticking with the free tier for now." });
3637
+ onClose?.();
3638
+ }, [bridge, onClose]);
3639
+ const selectedPlanShape = flow.selectedPlan;
3640
+ const onPlanContinue = useCallback3(() => {
3641
+ if (selectedPlanShape) {
3642
+ void bridge.notifyModelContext({
3643
+ text: `User selected ${selectedPlanShape.name ?? "a plan"}.`
3644
+ });
3645
+ }
3646
+ void flow.advance();
3647
+ }, [bridge, flow, selectedPlanShape]);
3648
+ const autoAdvancedRef = useRef3(false);
3649
+ useEffect5(() => {
3650
+ if (!autoAdvance || autoAdvancedRef.current) return;
3651
+ if (flow.step !== "plan") return;
3652
+ if (flow.selectedPlanRef !== initialPlanRef) return;
3653
+ autoAdvancedRef.current = true;
3654
+ onPlanContinue();
3655
+ }, [autoAdvance, flow.selectedPlanRef, flow.step, initialPlanRef, onPlanContinue]);
3656
+ if (flow.step === "plan") {
3657
+ const waitingForSelection = Boolean(autoAdvance) && !flow.selectedPlanRef;
3658
+ const matchingPending = Boolean(autoAdvance) && flow.selectedPlanRef === initialPlanRef && flow.status === "activating";
3659
+ if (waitingForSelection || matchingPending) {
3660
+ return /* @__PURE__ */ jsx25("p", { children: "Loading checkout\u2026" });
3661
+ }
3662
+ return /* @__PURE__ */ jsx25(
3663
+ PlanStep,
3664
+ {
3665
+ fromPaywall,
3666
+ paywallKind,
3667
+ hideUpgradeBanner,
3668
+ onContinue: onPlanContinue,
3669
+ onStayOnFree: fromPaywall && onClose ? onStayOnFree : void 0,
3670
+ onBack,
3671
+ isActivating: flow.status === "activating",
3672
+ activationError: flow.error,
3673
+ cx: cx2
3674
+ }
3675
+ );
3676
+ }
3677
+ if (flow.step === "amount") {
3678
+ if (!selectedPlanShape) {
3679
+ return null;
3680
+ }
3681
+ return /* @__PURE__ */ jsx25(
3682
+ AmountStep,
3683
+ {
3684
+ plan: selectedPlanShape,
3685
+ topupCurrency: flow.topupCurrency,
3686
+ topupCurrencies: flow.topupCurrencies,
3687
+ onCurrencyChange: flow.setTopupCurrency,
3688
+ onBack: () => flow.back(),
3689
+ onContinue: (amountMinor) => {
3690
+ flow.selectAmount(amountMinor);
3691
+ void flow.advance();
3692
+ },
3693
+ cx: cx2
3694
+ }
3695
+ );
3696
+ }
3697
+ if (flow.step === "payment") {
3698
+ if (flow.branch === "payg" && selectedPlanShape && flow.selectedAmountMinor != null) {
3699
+ return /* @__PURE__ */ jsx25(
3700
+ PaygPaymentStep,
3701
+ {
3702
+ plan: selectedPlanShape,
3703
+ amountMinor: flow.selectedAmountMinor,
3704
+ topupCurrency: flow.topupCurrency,
3705
+ returnUrl,
3706
+ onBack: () => flow.back(),
3707
+ onSuccess: (extras) => flow.notifyPaymentSuccess(void 0, extras),
3708
+ cx: cx2
3709
+ }
3710
+ );
3711
+ }
3712
+ if (flow.branch === "recurring" && selectedPlanShape && flow.selectedPlanRef) {
3713
+ return /* @__PURE__ */ jsx25(
3714
+ RecurringPaymentStep,
3715
+ {
3716
+ plan: selectedPlanShape,
3717
+ planRef: flow.selectedPlanRef,
3718
+ productRef,
3719
+ returnUrl,
3720
+ onBack: () => flow.back(),
3721
+ onSuccess: (intent) => flow.notifyPaymentSuccess(intent),
3722
+ cx: cx2
3723
+ }
3724
+ );
3725
+ }
3726
+ return null;
3727
+ }
3728
+ if (flow.step === "success" && flow.successMeta) {
3729
+ return /* @__PURE__ */ jsx25(SuccessStep, { meta: flow.successMeta, cx: cx2 });
3730
+ }
3731
+ return null;
3732
+ }
3733
+
3734
+ // src/mcp/views/McpCheckoutView.tsx
3735
+ import { Fragment as Fragment11, jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
3510
3736
  var POLL_INTERVAL_MS = 3e3;
3511
3737
  var AWAITING_TIMEOUT_MS = 10 * 60 * 1e3;
3738
+ function McpCheckoutView({
3739
+ productRef,
3740
+ publishableKey = null,
3741
+ returnUrl,
3742
+ onPurchaseSuccess,
3743
+ onRequestTopup: _onRequestTopup,
3744
+ fromPaywall = false,
3745
+ paywallKind,
3746
+ plans,
3747
+ onClose,
3748
+ onBack,
3749
+ initialPlanRef,
3750
+ autoAdvance,
3751
+ classNames,
3752
+ children
3753
+ }) {
3754
+ const cx2 = resolveMcpClassNames(classNames);
3755
+ const probe = useStripeProbe(publishableKey);
3756
+ if (probe === "loading") {
3757
+ return /* @__PURE__ */ jsxs19("div", { className: cx2.card, children: [
3758
+ /* @__PURE__ */ jsx26("p", { children: "Loading checkout\u2026" }),
3759
+ children
3760
+ ] });
3761
+ }
3762
+ if (probe === "ready") {
3763
+ return /* @__PURE__ */ jsx26(
3764
+ EmbeddedCheckout,
3765
+ {
3766
+ productRef,
3767
+ returnUrl,
3768
+ onPurchaseSuccess,
3769
+ fromPaywall,
3770
+ paywallKind,
3771
+ plans,
3772
+ onClose,
3773
+ onBack,
3774
+ initialPlanRef,
3775
+ autoAdvance,
3776
+ cx: cx2,
3777
+ classNames,
3778
+ children
3779
+ }
3780
+ );
3781
+ }
3782
+ return /* @__PURE__ */ jsx26(HostedCheckout, { productRef, onPurchaseSuccess, cx: cx2, children });
3783
+ }
3512
3784
  function useHostedUrl(enabled, fetcher, label) {
3513
3785
  const [state, setState] = useState7({ status: "idle" });
3514
- useEffect5(() => {
3786
+ useEffect6(() => {
3515
3787
  if (!enabled) {
3516
3788
  setState({ status: "idle" });
3517
3789
  return;
@@ -3532,7 +3804,7 @@ function useHostedUrl(enabled, fetcher, label) {
3532
3804
  }, [enabled, fetcher, label]);
3533
3805
  return state;
3534
3806
  }
3535
- var HostedLinkButton = React10.memo(function HostedLinkButton2({
3807
+ var HostedLinkButton = React11.memo(function HostedLinkButton2({
3536
3808
  state,
3537
3809
  loadingLabel,
3538
3810
  readyLabel,
@@ -3541,7 +3813,7 @@ var HostedLinkButton = React10.memo(function HostedLinkButton2({
3541
3813
  }) {
3542
3814
  const handleExternalClick = useExternalLinkClick();
3543
3815
  if (state.status === "ready") {
3544
- return /* @__PURE__ */ jsx25(
3816
+ return /* @__PURE__ */ jsx26(
3545
3817
  "a",
3546
3818
  {
3547
3819
  className: "solvapay-mcp-hosted-link",
@@ -3553,19 +3825,19 @@ var HostedLinkButton = React10.memo(function HostedLinkButton2({
3553
3825
  onLaunch?.(state.href);
3554
3826
  handleExternalClick(event);
3555
3827
  },
3556
- children: /* @__PURE__ */ jsxs18("button", { type: "button", className: cx2.button, children: [
3828
+ children: /* @__PURE__ */ jsxs19("button", { type: "button", className: cx2.button, children: [
3557
3829
  readyLabel,
3558
- /* @__PURE__ */ jsx25(ExternalLinkGlyph, {})
3830
+ /* @__PURE__ */ jsx26(ExternalLinkGlyph, {})
3559
3831
  ] })
3560
3832
  }
3561
3833
  );
3562
3834
  }
3563
- return /* @__PURE__ */ jsx25("button", { type: "button", className: cx2.button, disabled: true, children: state.status === "error" ? "Unavailable" : loadingLabel });
3835
+ return /* @__PURE__ */ jsx26("button", { type: "button", className: cx2.button, disabled: true, children: state.status === "error" ? "Unavailable" : loadingLabel });
3564
3836
  });
3565
3837
  function Spinner() {
3566
- return /* @__PURE__ */ jsx25("span", { className: "solvapay-mcp-spinner", "aria-hidden": "true" });
3838
+ return /* @__PURE__ */ jsx26("span", { className: "solvapay-mcp-spinner", "aria-hidden": "true" });
3567
3839
  }
3568
- var AwaitingBody = React10.memo(function AwaitingBody2({
3840
+ var AwaitingBody = React11.memo(function AwaitingBody2({
3569
3841
  href,
3570
3842
  timedOut,
3571
3843
  onReopen,
@@ -3573,13 +3845,13 @@ var AwaitingBody = React10.memo(function AwaitingBody2({
3573
3845
  cx: cx2
3574
3846
  }) {
3575
3847
  const handleExternalClick = useExternalLinkClick();
3576
- return /* @__PURE__ */ jsxs18(Fragment11, { children: [
3577
- /* @__PURE__ */ jsxs18("div", { className: cx2.awaitingHeader, children: [
3578
- /* @__PURE__ */ jsx25(Spinner, {}),
3579
- /* @__PURE__ */ jsx25("h2", { className: cx2.heading, children: timedOut ? "Still waiting for payment" : "Waiting for payment\u2026" })
3848
+ return /* @__PURE__ */ jsxs19(Fragment11, { children: [
3849
+ /* @__PURE__ */ jsxs19("div", { className: cx2.awaitingHeader, children: [
3850
+ /* @__PURE__ */ jsx26(Spinner, {}),
3851
+ /* @__PURE__ */ jsx26("h2", { className: cx2.heading, children: timedOut ? "Still waiting for payment" : "Waiting for payment\u2026" })
3580
3852
  ] }),
3581
- /* @__PURE__ */ jsx25("p", { className: cx2.muted, children: timedOut ? "We haven't seen your purchase yet. If you completed payment, give it another moment \u2014 otherwise reopen checkout or cancel." : "Complete payment in the other tab. Your purchase will show up here automatically." }),
3582
- /* @__PURE__ */ jsx25(
3853
+ /* @__PURE__ */ jsx26("p", { className: cx2.muted, children: timedOut ? "We haven't seen your purchase yet. If you completed payment, give it another moment \u2014 otherwise reopen checkout or cancel." : "Complete payment in the other tab. Your purchase will show up here automatically." }),
3854
+ /* @__PURE__ */ jsx26(
3583
3855
  "a",
3584
3856
  {
3585
3857
  className: "solvapay-mcp-hosted-link",
@@ -3591,16 +3863,16 @@ var AwaitingBody = React10.memo(function AwaitingBody2({
3591
3863
  onReopen();
3592
3864
  handleExternalClick(event);
3593
3865
  },
3594
- children: /* @__PURE__ */ jsxs18("button", { type: "button", className: cx2.button, children: [
3866
+ children: /* @__PURE__ */ jsxs19("button", { type: "button", className: cx2.button, children: [
3595
3867
  "Reopen checkout",
3596
- /* @__PURE__ */ jsx25(ExternalLinkGlyph, {})
3868
+ /* @__PURE__ */ jsx26(ExternalLinkGlyph, {})
3597
3869
  ] })
3598
3870
  }
3599
3871
  ),
3600
- /* @__PURE__ */ jsx25("button", { type: "button", className: cx2.linkButton, onClick: onCancel, children: "Didn't complete? Cancel" })
3872
+ /* @__PURE__ */ jsx26("button", { type: "button", className: cx2.linkButton, onClick: onCancel, children: "Didn't complete? Cancel" })
3601
3873
  ] });
3602
3874
  });
3603
- var CancelledBody = React10.memo(function CancelledBody2({
3875
+ var CancelledBody = React11.memo(function CancelledBody2({
3604
3876
  productName,
3605
3877
  endDate,
3606
3878
  daysLeft,
@@ -3609,25 +3881,25 @@ var CancelledBody = React10.memo(function CancelledBody2({
3609
3881
  onLaunch,
3610
3882
  cx: cx2
3611
3883
  }) {
3612
- return /* @__PURE__ */ jsxs18(Fragment11, { children: [
3613
- /* @__PURE__ */ jsxs18("h2", { className: cx2.heading, children: [
3884
+ return /* @__PURE__ */ jsxs19(Fragment11, { children: [
3885
+ /* @__PURE__ */ jsxs19("h2", { className: cx2.heading, children: [
3614
3886
  "Your ",
3615
3887
  productName,
3616
3888
  " purchase is cancelled"
3617
3889
  ] }),
3618
- endDate && formattedEndDate ? /* @__PURE__ */ jsxs18("div", { className: cx2.notice, children: [
3619
- /* @__PURE__ */ jsx25("p", { children: /* @__PURE__ */ jsxs18("strong", { children: [
3890
+ endDate && formattedEndDate ? /* @__PURE__ */ jsxs19("div", { className: cx2.notice, children: [
3891
+ /* @__PURE__ */ jsx26("p", { children: /* @__PURE__ */ jsxs19("strong", { children: [
3620
3892
  "Access expires ",
3621
3893
  formattedEndDate
3622
3894
  ] }) }),
3623
- daysLeft !== null && daysLeft > 0 && /* @__PURE__ */ jsxs18("p", { className: cx2.muted, children: [
3895
+ daysLeft !== null && daysLeft > 0 && /* @__PURE__ */ jsxs19("p", { className: cx2.muted, children: [
3624
3896
  daysLeft,
3625
3897
  " ",
3626
3898
  daysLeft === 1 ? "day" : "days",
3627
3899
  " remaining"
3628
3900
  ] })
3629
- ] }) : /* @__PURE__ */ jsx25("p", { className: cx2.muted, children: "Your purchase access has ended." }),
3630
- /* @__PURE__ */ jsx25(
3901
+ ] }) : /* @__PURE__ */ jsx26("p", { className: cx2.muted, children: "Your purchase access has ended." }),
3902
+ /* @__PURE__ */ jsx26(
3631
3903
  HostedLinkButton,
3632
3904
  {
3633
3905
  state: checkout,
@@ -3637,19 +3909,14 @@ var CancelledBody = React10.memo(function CancelledBody2({
3637
3909
  cx: cx2
3638
3910
  }
3639
3911
  ),
3640
- checkout.status === "error" && /* @__PURE__ */ jsx25("p", { className: cx2.error, role: "alert", children: checkout.message })
3912
+ checkout.status === "error" && /* @__PURE__ */ jsx26("p", { className: cx2.error, role: "alert", children: checkout.message })
3641
3913
  ] });
3642
3914
  });
3643
- var UpgradeBody = React10.memo(function UpgradeBody2({
3644
- planName,
3645
- checkout,
3646
- onLaunch,
3647
- cx: cx2
3648
- }) {
3649
- return /* @__PURE__ */ jsxs18(Fragment11, { children: [
3650
- /* @__PURE__ */ jsx25("h2", { className: cx2.heading, children: planName ? `Complete your ${planName} purchase` : "Upgrade your plan" }),
3651
- /* @__PURE__ */ jsx25("p", { className: cx2.muted, children: "The SolvaPay checkout opens in a new tab. Return here after payment and your purchase will show up automatically." }),
3652
- /* @__PURE__ */ jsx25(
3915
+ var UpgradeBody = React11.memo(function UpgradeBody2({ checkout, onLaunch, cx: cx2 }) {
3916
+ return /* @__PURE__ */ jsxs19(Fragment11, { children: [
3917
+ /* @__PURE__ */ jsx26("h2", { className: cx2.heading, children: "Upgrade your plan" }),
3918
+ /* @__PURE__ */ jsx26("p", { className: cx2.muted, children: "The SolvaPay checkout opens in a new tab. Return here after payment and your purchase will show up automatically." }),
3919
+ /* @__PURE__ */ jsx26(
3653
3920
  HostedLinkButton,
3654
3921
  {
3655
3922
  state: checkout,
@@ -3659,13 +3926,11 @@ var UpgradeBody = React10.memo(function UpgradeBody2({
3659
3926
  cx: cx2
3660
3927
  }
3661
3928
  ),
3662
- checkout.status === "error" && /* @__PURE__ */ jsx25("p", { className: cx2.error, role: "alert", children: checkout.message })
3929
+ checkout.status === "error" && /* @__PURE__ */ jsx26("p", { className: cx2.error, role: "alert", children: checkout.message })
3663
3930
  ] });
3664
3931
  });
3665
3932
  function HostedCheckout({
3666
3933
  productRef,
3667
- planRef,
3668
- planName,
3669
3934
  onPurchaseSuccess,
3670
3935
  cx: cx2,
3671
3936
  children
@@ -3677,26 +3942,23 @@ function HostedCheckout({
3677
3942
  const [awaitingTimedOut, setAwaitingTimedOut] = useState7(false);
3678
3943
  const [hasLoadedOnce, setHasLoadedOnce] = useState7(false);
3679
3944
  const onPurchaseSuccessRef = useRef4(onPurchaseSuccess);
3680
- useEffect5(() => {
3945
+ useEffect6(() => {
3681
3946
  onPurchaseSuccessRef.current = onPurchaseSuccess;
3682
3947
  }, [onPurchaseSuccess]);
3683
- useEffect5(() => {
3948
+ useEffect6(() => {
3684
3949
  if (!loading && !hasLoadedOnce) setHasLoadedOnce(true);
3685
3950
  }, [loading, hasLoadedOnce]);
3686
- const fetchCheckoutUrl = useCallback3(async () => {
3687
- const { checkoutUrl } = await transport.createCheckoutSession({
3688
- productRef,
3689
- ...planRef ? { planRef } : {}
3690
- });
3951
+ const fetchCheckoutUrl = useCallback4(async () => {
3952
+ const { checkoutUrl } = await transport.createCheckoutSession({ productRef });
3691
3953
  return { href: checkoutUrl };
3692
- }, [planRef, productRef, transport]);
3954
+ }, [productRef, transport]);
3693
3955
  const checkout = useHostedUrl(hasLoadedOnce, fetchCheckoutUrl, "checkout session");
3694
- const safeRefetch = useCallback3(() => {
3956
+ const safeRefetch = useCallback4(() => {
3695
3957
  refetch().catch((err) => {
3696
3958
  console.warn("[solvapay-mcp] refetch failed", err);
3697
3959
  });
3698
3960
  }, [refetch]);
3699
- useEffect5(() => {
3961
+ useEffect6(() => {
3700
3962
  const onFocus = () => safeRefetch();
3701
3963
  const onVisibility = () => {
3702
3964
  if (document.visibilityState === "visible") safeRefetch();
@@ -3708,7 +3970,7 @@ function HostedCheckout({
3708
3970
  document.removeEventListener("visibilitychange", onVisibility);
3709
3971
  };
3710
3972
  }, [safeRefetch]);
3711
- useEffect5(() => {
3973
+ useEffect6(() => {
3712
3974
  if (!awaiting) return;
3713
3975
  const interval = window.setInterval(() => {
3714
3976
  if (document.visibilityState === "hidden") return;
@@ -3722,7 +3984,7 @@ function HostedCheckout({
3722
3984
  window.clearTimeout(timeout);
3723
3985
  };
3724
3986
  }, [awaiting, safeRefetch]);
3725
- useEffect5(() => {
3987
+ useEffect6(() => {
3726
3988
  if (!awaiting) return;
3727
3989
  if (!hasPaidPurchase) return;
3728
3990
  const newRef = activePurchase?.reference ?? null;
@@ -3733,7 +3995,7 @@ function HostedCheckout({
3733
3995
  onPurchaseSuccessRef.current?.();
3734
3996
  }
3735
3997
  }, [awaiting, hasPaidPurchase, activePurchase?.reference]);
3736
- const beginAwaiting = useCallback3(
3998
+ const beginAwaiting = useCallback4(
3737
3999
  (href) => {
3738
4000
  setAwaiting({
3739
4001
  baselineActiveRef: activePurchase?.reference ?? null,
@@ -3745,27 +4007,27 @@ function HostedCheckout({
3745
4007
  },
3746
4008
  [activePurchase?.reference, hasPaidPurchase]
3747
4009
  );
3748
- const cancelAwaiting = useCallback3(() => {
4010
+ const cancelAwaiting = useCallback4(() => {
3749
4011
  setAwaiting(null);
3750
4012
  setAwaitingTimedOut(false);
3751
4013
  }, []);
3752
- const dismissTimeout = useCallback3(() => {
4014
+ const dismissTimeout = useCallback4(() => {
3753
4015
  setAwaitingTimedOut(false);
3754
4016
  }, []);
3755
4017
  const cancelledProductName = cancelledPurchase?.productName ?? null;
3756
4018
  const cancelledEndDate = cancelledPurchase?.endDate;
3757
- const cancelledDaysLeft = useMemo3(
4019
+ const cancelledDaysLeft = useMemo4(
3758
4020
  () => cancelledEndDate ? getDaysUntilExpiration(cancelledEndDate) : null,
3759
4021
  [cancelledEndDate, getDaysUntilExpiration]
3760
4022
  );
3761
- const cancelledFormattedEndDate = useMemo3(
4023
+ const cancelledFormattedEndDate = useMemo4(
3762
4024
  () => cancelledEndDate ? formatDate(cancelledEndDate) : null,
3763
4025
  [cancelledEndDate, formatDate]
3764
4026
  );
3765
4027
  const awaitingHref = awaiting?.href ?? null;
3766
- const inner = useMemo3(() => {
4028
+ const inner = useMemo4(() => {
3767
4029
  if (awaiting && awaitingHref) {
3768
- return /* @__PURE__ */ jsx25(
4030
+ return /* @__PURE__ */ jsx26(
3769
4031
  AwaitingBody,
3770
4032
  {
3771
4033
  href: awaitingHref,
@@ -3777,7 +4039,7 @@ function HostedCheckout({
3777
4039
  );
3778
4040
  }
3779
4041
  if (shouldShowCancelledNotice && cancelledProductName) {
3780
- return /* @__PURE__ */ jsx25(
4042
+ return /* @__PURE__ */ jsx26(
3781
4043
  CancelledBody,
3782
4044
  {
3783
4045
  productName: cancelledProductName,
@@ -3790,7 +4052,7 @@ function HostedCheckout({
3790
4052
  }
3791
4053
  );
3792
4054
  }
3793
- return /* @__PURE__ */ jsx25(UpgradeBody, { planName, checkout, onLaunch: beginAwaiting, cx: cx2 });
4055
+ return /* @__PURE__ */ jsx26(UpgradeBody, { checkout, onLaunch: beginAwaiting, cx: cx2 });
3794
4056
  }, [
3795
4057
  awaiting,
3796
4058
  awaitingHref,
@@ -3804,297 +4066,19 @@ function HostedCheckout({
3804
4066
  cancelledFormattedEndDate,
3805
4067
  checkout,
3806
4068
  beginAwaiting,
3807
- planName,
3808
4069
  cx2
3809
4070
  ]);
3810
4071
  if (loading) {
3811
- return /* @__PURE__ */ jsx25("div", { className: cx2.card, children: /* @__PURE__ */ jsx25("p", { children: "Loading purchase\u2026" }) });
3812
- }
3813
- return /* @__PURE__ */ jsxs18("div", { className: cx2.card, "data-refreshing": isRefetching ? "true" : void 0, children: [
3814
- inner,
3815
- children
3816
- ] });
3817
- }
3818
-
3819
- // src/mcp/views/checkout/EmbeddedCheckout.tsx
3820
- import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
3821
- function EmbeddedCheckout({
3822
- productRef,
3823
- returnUrl,
3824
- onPurchaseSuccess,
3825
- fromPaywall,
3826
- paywallKind,
3827
- hideUpgradeBanner,
3828
- plans,
3829
- onClose,
3830
- onBack,
3831
- initialPlanRef,
3832
- autoAdvance,
3833
- stripeProbe,
3834
- cx: cx2,
3835
- children
3836
- }) {
3837
- const { loading, isRefetching, activePurchase } = usePurchase();
3838
- const currentPlanRef = activePurchase?.planSnapshot?.reference ?? null;
3839
- const paidPlans = useMemo4(() => {
3840
- const list = plans ?? [];
3841
- return list.filter((p) => p.requiresPayment !== false);
3842
- }, [plans]);
3843
- const paygPlanRef = useMemo4(() => {
3844
- const payg = paidPlans.find((p) => isPayg(p));
3845
- return payg?.reference ?? void 0;
3846
- }, [paidPlans]);
3847
- const planFilter = useMemo4(
3848
- () => (plan) => plan.requiresPayment !== false || plan.reference === currentPlanRef,
3849
- [currentPlanRef]
3850
- );
3851
- if (loading) {
3852
- return /* @__PURE__ */ jsx26("div", { className: cx2.card, children: /* @__PURE__ */ jsx26("p", { children: "Loading checkout\u2026" }) });
4072
+ return /* @__PURE__ */ jsx26("div", { className: cx2.card, children: /* @__PURE__ */ jsx26("p", { children: "Loading purchase\u2026" }) });
3853
4073
  }
3854
4074
  return /* @__PURE__ */ jsxs19("div", { className: cx2.card, "data-refreshing": isRefetching ? "true" : void 0, children: [
3855
- /* @__PURE__ */ jsx26(
3856
- PlanSelector.Root,
3857
- {
3858
- productRef,
3859
- filter: planFilter,
3860
- sortBy: planSortByPaygFirstThenAsc,
3861
- popularPlanRef: paygPlanRef,
3862
- currentPlanRef,
3863
- autoSelectFirstPaid: Boolean(paygPlanRef),
3864
- initialPlanRef,
3865
- className: "solvapay-plan-selector",
3866
- children: /* @__PURE__ */ jsx26(
3867
- McpCheckoutBody,
3868
- {
3869
- productRef,
3870
- returnUrl,
3871
- onPurchaseSuccess,
3872
- fromPaywall,
3873
- paywallKind,
3874
- hideUpgradeBanner,
3875
- onClose,
3876
- onBack,
3877
- initialPlanRef,
3878
- autoAdvance,
3879
- stripeProbe,
3880
- cx: cx2
3881
- }
3882
- )
3883
- }
3884
- ),
4075
+ inner,
3885
4076
  children
3886
4077
  ] });
3887
4078
  }
3888
- function McpCheckoutBody({
3889
- productRef,
3890
- returnUrl,
3891
- onPurchaseSuccess,
3892
- fromPaywall,
3893
- paywallKind,
3894
- hideUpgradeBanner,
3895
- onClose,
3896
- onBack,
3897
- initialPlanRef,
3898
- autoAdvance,
3899
- stripeProbe,
3900
- cx: cx2
3901
- }) {
3902
- const bridge = useMcpBridge();
3903
- const locale = useHostLocale();
3904
- const flow = useCheckoutFlow({
3905
- productRef,
3906
- // `notifyModelContext` for plan commit fires from the explicit
3907
- // Continue handler below — not on `selectPlan` — so a stray
3908
- // selection doesn't burn a host emit before the user opts in.
3909
- onPurchaseSuccess: (meta) => {
3910
- if (meta.branch === "payg" && meta.amountMinor != null && meta.currency != null) {
3911
- void bridge.notifyModelContext({
3912
- text: `Activated ${meta.plan.name ?? "plan"} with ${formatPrice(
3913
- meta.amountMinor,
3914
- meta.currency,
3915
- { locale }
3916
- )} in credits.`
3917
- });
3918
- void bridge.notifySuccess({
3919
- kind: "topup",
3920
- amountMinor: meta.amountMinor,
3921
- currency: meta.currency
3922
- });
3923
- } else {
3924
- void bridge.notifyModelContext({
3925
- text: `Activated ${meta.plan.name ?? "plan"}.`
3926
- });
3927
- void bridge.notifySuccess({
3928
- kind: "plan-activated",
3929
- planName: meta.plan.name ?? null
3930
- });
3931
- }
3932
- onPurchaseSuccess?.();
3933
- }
3934
- });
3935
- const onStayOnFree = useCallback4(() => {
3936
- void bridge.sendMessage({ text: "Sticking with the free tier for now." });
3937
- onClose?.();
3938
- }, [bridge, onClose]);
3939
- const selectedPlanShape = flow.selectedPlan;
3940
- const [autoRecharge, setAutoRecharge] = useState8();
3941
- const onPlanContinue = useCallback4(() => {
3942
- if (selectedPlanShape) {
3943
- void bridge.notifyModelContext({
3944
- text: `User selected ${selectedPlanShape.name ?? "a plan"}.`
3945
- });
3946
- }
3947
- void flow.advance();
3948
- }, [bridge, flow, selectedPlanShape]);
3949
- const autoAdvancedRef = useRef5(false);
3950
- useEffect6(() => {
3951
- if (!autoAdvance || autoAdvancedRef.current) return;
3952
- if (flow.step !== "plan") return;
3953
- if (flow.selectedPlanRef !== initialPlanRef) return;
3954
- autoAdvancedRef.current = true;
3955
- onPlanContinue();
3956
- }, [autoAdvance, flow.selectedPlanRef, flow.step, initialPlanRef, onPlanContinue]);
3957
- if (flow.step === "plan") {
3958
- const waitingForSelection = Boolean(autoAdvance) && !flow.selectedPlanRef;
3959
- const matchingPending = Boolean(autoAdvance) && flow.selectedPlanRef === initialPlanRef && flow.status === "activating";
3960
- if (waitingForSelection || matchingPending) {
3961
- return /* @__PURE__ */ jsx26("p", { children: "Loading checkout\u2026" });
3962
- }
3963
- return /* @__PURE__ */ jsx26(
3964
- PlanStep,
3965
- {
3966
- fromPaywall,
3967
- paywallKind,
3968
- hideUpgradeBanner,
3969
- onContinue: onPlanContinue,
3970
- onStayOnFree: fromPaywall && onClose ? onStayOnFree : void 0,
3971
- onBack,
3972
- isActivating: flow.status === "activating",
3973
- activationError: flow.error,
3974
- cx: cx2
3975
- }
3976
- );
3977
- }
3978
- if (flow.step === "amount") {
3979
- if (!selectedPlanShape) {
3980
- return null;
3981
- }
3982
- return /* @__PURE__ */ jsx26(
3983
- AmountStep,
3984
- {
3985
- plan: selectedPlanShape,
3986
- topupCurrency: flow.topupCurrency,
3987
- topupCurrencies: flow.topupCurrencies,
3988
- onCurrencyChange: (code) => {
3989
- setAutoRecharge(void 0);
3990
- flow.setTopupCurrency(code);
3991
- },
3992
- onBack: () => flow.back(),
3993
- onContinue: (amountMinor, nextAutoRecharge) => {
3994
- setAutoRecharge(nextAutoRecharge);
3995
- flow.selectAmount(amountMinor);
3996
- void flow.advance();
3997
- },
3998
- cx: cx2
3999
- }
4000
- );
4001
- }
4002
- if (flow.step === "payment") {
4003
- if (stripeProbe === "loading") {
4004
- return /* @__PURE__ */ jsx26("p", { children: "Loading checkout\u2026" });
4005
- }
4006
- if (stripeProbe === "blocked") {
4007
- return /* @__PURE__ */ jsx26(
4008
- HostedCheckout,
4009
- {
4010
- productRef,
4011
- planRef: flow.selectedPlanRef ?? void 0,
4012
- planName: selectedPlanShape?.name ?? void 0,
4013
- onPurchaseSuccess,
4014
- cx: cx2
4015
- }
4016
- );
4017
- }
4018
- if (flow.branch === "payg" && selectedPlanShape && flow.selectedAmountMinor != null) {
4019
- return /* @__PURE__ */ jsx26(
4020
- PaygPaymentStep,
4021
- {
4022
- plan: selectedPlanShape,
4023
- amountMinor: flow.selectedAmountMinor,
4024
- topupCurrency: flow.topupCurrency,
4025
- autoRecharge,
4026
- returnUrl,
4027
- onBack: () => flow.back(),
4028
- onSuccess: (extras) => flow.notifyPaymentSuccess(void 0, extras),
4029
- cx: cx2
4030
- }
4031
- );
4032
- }
4033
- if (flow.branch === "recurring" && selectedPlanShape && flow.selectedPlanRef) {
4034
- return /* @__PURE__ */ jsx26(
4035
- RecurringPaymentStep,
4036
- {
4037
- plan: selectedPlanShape,
4038
- planRef: flow.selectedPlanRef,
4039
- productRef,
4040
- returnUrl,
4041
- onBack: () => flow.back(),
4042
- onSuccess: (intent) => flow.notifyPaymentSuccess(intent),
4043
- cx: cx2
4044
- }
4045
- );
4046
- }
4047
- return null;
4048
- }
4049
- if (flow.step === "success" && flow.successMeta) {
4050
- return /* @__PURE__ */ jsx26(SuccessStep, { meta: flow.successMeta, cx: cx2 });
4051
- }
4052
- return null;
4053
- }
4054
-
4055
- // src/mcp/views/McpCheckoutView.tsx
4056
- import { jsx as jsx27 } from "react/jsx-runtime";
4057
- function McpCheckoutView({
4058
- productRef,
4059
- publishableKey = null,
4060
- returnUrl,
4061
- onPurchaseSuccess,
4062
- onRequestTopup: _onRequestTopup,
4063
- fromPaywall = false,
4064
- paywallKind,
4065
- plans,
4066
- onClose,
4067
- onBack,
4068
- initialPlanRef,
4069
- autoAdvance,
4070
- classNames,
4071
- children
4072
- }) {
4073
- const cx2 = resolveMcpClassNames(classNames);
4074
- const probe = useStripeProbe(publishableKey);
4075
- return /* @__PURE__ */ jsx27(
4076
- EmbeddedCheckout,
4077
- {
4078
- productRef,
4079
- returnUrl,
4080
- onPurchaseSuccess,
4081
- fromPaywall,
4082
- paywallKind,
4083
- plans,
4084
- onClose,
4085
- onBack,
4086
- initialPlanRef,
4087
- autoAdvance,
4088
- stripeProbe: probe,
4089
- cx: cx2,
4090
- classNames,
4091
- children
4092
- }
4093
- );
4094
- }
4095
4079
 
4096
4080
  // src/mcp/views/McpTopupView.tsx
4097
- import { useRef as useRef6, useState as useState9 } from "react";
4081
+ import { useState as useState8 } from "react";
4098
4082
 
4099
4083
  // src/mcp/format-compact-credits.ts
4100
4084
  function formatCompactCredits(credits, locale = "en-US") {
@@ -4111,7 +4095,7 @@ function formatCompactCredits(credits, locale = "en-US") {
4111
4095
  }
4112
4096
 
4113
4097
  // src/mcp/views/McpTopupView.tsx
4114
- import { Fragment as Fragment12, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
4098
+ import { Fragment as Fragment12, jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
4115
4099
  var FALLBACK_TOPUP_CURRENCY = "USD";
4116
4100
  function resolveDefaultCurrency(merchant) {
4117
4101
  if (merchant?.defaultCurrency) {
@@ -4137,15 +4121,18 @@ function McpTopupView({
4137
4121
  const cx2 = resolveMcpClassNames(classNames);
4138
4122
  const probe = useStripeProbe(publishableKey);
4139
4123
  const { merchant, loading: merchantLoading } = useMerchant();
4140
- if (merchantLoading) {
4141
- return /* @__PURE__ */ jsx28("section", { className: cx2.card, "aria-label": "Loading top-up", children: /* @__PURE__ */ jsx28("p", { children: "Loading top-up\u2026" }) });
4124
+ if (probe === "loading" || merchantLoading) {
4125
+ return /* @__PURE__ */ jsx27("section", { className: cx2.card, "aria-label": "Loading top-up", children: /* @__PURE__ */ jsx27("p", { children: "Loading top-up\u2026" }) });
4126
+ }
4127
+ if (probe === "blocked") {
4128
+ return /* @__PURE__ */ jsx27(HostedTopupFallback, { cx: cx2, onBack });
4142
4129
  }
4143
4130
  const defaultCurrency = resolveDefaultCurrency(merchant ?? void 0);
4144
4131
  const fromMerchant = (merchant?.supportedTopupCurrencies ?? []).map((code) => code.toUpperCase()).filter(Boolean);
4145
4132
  const topupCurrencies = Array.from(
4146
4133
  new Set(fromMerchant.length > 0 ? fromMerchant : [defaultCurrency])
4147
4134
  );
4148
- return /* @__PURE__ */ jsx28(
4135
+ return /* @__PURE__ */ jsx27(
4149
4136
  EmbeddedTopup,
4150
4137
  {
4151
4138
  returnUrl,
@@ -4153,7 +4140,6 @@ function McpTopupView({
4153
4140
  topupCurrencies,
4154
4141
  onTopupSuccess,
4155
4142
  onBack,
4156
- stripeProbe: probe,
4157
4143
  cx: cx2
4158
4144
  }
4159
4145
  );
@@ -4164,15 +4150,18 @@ function EmbeddedTopup({
4164
4150
  topupCurrencies,
4165
4151
  onTopupSuccess,
4166
4152
  onBack,
4167
- stripeProbe,
4168
4153
  cx: cx2
4169
4154
  }) {
4170
- const [screen, setScreen] = useState9({ step: "amount" });
4171
- const [selectedCurrency, setSelectedCurrency] = useState9(defaultCurrency);
4155
+ const [screen, setScreen] = useState8({ step: "amount" });
4156
+ const [selectedCurrency, setSelectedCurrency] = useState8(defaultCurrency);
4172
4157
  const currency = selectedCurrency;
4173
4158
  const showCurrencySwitch = topupCurrencies.length > 1;
4174
4159
  const { adjustBalance, credits, creditsPerMinorUnit, displayCurrency, displayExchangeRate } = useBalance();
4175
- const autoRechargeRef = useRef6(null);
4160
+ const copy = useCopy();
4161
+ const [autoRechargeForm, setAutoRechargeForm] = useState8(
4162
+ () => createDefaultAutoRechargeForm(currency)
4163
+ );
4164
+ const [autoRechargeError, setAutoRechargeError] = useState8(null);
4176
4165
  const locale = useHostLocale();
4177
4166
  const { notifyModelContext, notifySuccess } = useMcpBridge();
4178
4167
  const topupSelector = useTopupAmountSelector({ currency });
@@ -4184,38 +4173,29 @@ function EmbeddedTopup({
4184
4173
  topupSelector.reset();
4185
4174
  };
4186
4175
  if (screen.step === "success") {
4187
- const estimate = estimateTopupCredits(
4188
- screen.amountMinor,
4189
- currency,
4190
- displayCurrency,
4191
- creditsPerMinorUnit,
4192
- displayExchangeRate
4193
- );
4176
+ const displayAmount = formatPrice(screen.amountMinor, currency, { locale, free: "" });
4194
4177
  return /* @__PURE__ */ jsxs20("section", { className: cx2.card, "aria-label": "Top-up success", children: [
4195
- /* @__PURE__ */ jsx28("div", { className: "solvapay-mcp-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
4196
- /* @__PURE__ */ jsx28("h2", { className: cx2.heading, children: "Credits added" }),
4197
- /* @__PURE__ */ jsxs20("dl", { className: "solvapay-mcp-checkout-receipt", "data-variant": "payg", children: [
4198
- /* @__PURE__ */ jsxs20("div", { className: "solvapay-mcp-checkout-receipt-row", children: [
4199
- /* @__PURE__ */ jsx28("dt", { children: "Amount" }),
4200
- /* @__PURE__ */ jsx28("dd", { children: formatPrice(screen.amountMinor, currency, { locale, free: "" }) })
4201
- ] }),
4202
- estimate.kind === "available" ? /* @__PURE__ */ jsxs20("div", { className: "solvapay-mcp-checkout-receipt-row", children: [
4203
- /* @__PURE__ */ jsx28("dt", { children: "Credits" }),
4204
- /* @__PURE__ */ jsxs20("dd", { children: [
4205
- "+",
4206
- estimate.credits.toLocaleString(locale)
4207
- ] })
4208
- ] }) : null
4209
- ] })
4178
+ onBack ? /* @__PURE__ */ jsx27(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4179
+ /* @__PURE__ */ jsxs20("header", { className: cx2.balanceRow, children: [
4180
+ /* @__PURE__ */ jsx27("h2", { className: cx2.heading, children: "Credits added" }),
4181
+ /* @__PURE__ */ jsx27(BalanceBadge, {})
4182
+ ] }),
4183
+ /* @__PURE__ */ jsxs20("p", { className: cx2.muted, children: [
4184
+ displayAmount,
4185
+ " landed in your balance."
4186
+ ] }),
4187
+ /* @__PURE__ */ jsx27("button", { type: "button", className: cx2.button, onClick: () => setScreen({ step: "amount" }), children: "Add more credits" }),
4188
+ /* @__PURE__ */ jsx27(
4189
+ LaunchCustomerPortalButton,
4190
+ {
4191
+ className: cx2.button,
4192
+ loadingClassName: cx2.button,
4193
+ errorClassName: cx2.button
4194
+ }
4195
+ )
4210
4196
  ] });
4211
4197
  }
4212
4198
  if (screen.step === "payment") {
4213
- if (stripeProbe === "loading") {
4214
- return /* @__PURE__ */ jsx28("section", { className: cx2.card, "aria-label": "Loading top-up", children: /* @__PURE__ */ jsx28("p", { children: "Loading top-up\u2026" }) });
4215
- }
4216
- if (stripeProbe === "blocked") {
4217
- return /* @__PURE__ */ jsx28(HostedTopupFallback, { cx: cx2, onChangeAmount: () => setScreen({ step: "amount" }) });
4218
- }
4219
4199
  const committedAmountMinor = screen.amountMinor;
4220
4200
  const creditEstimate = estimateTopupCredits(
4221
4201
  committedAmountMinor,
@@ -4229,7 +4209,7 @@ function EmbeddedTopup({
4229
4209
  creditEstimate.kind === "available" ? `Adds ${creditEstimate.credits.toLocaleString(locale)} credits` : void 0,
4230
4210
  formattedBalance ? `Balance ${formattedBalance} credits` : void 0
4231
4211
  ].filter((part) => part != null);
4232
- return /* @__PURE__ */ jsx28("section", { className: cx2.card, "aria-label": "Top-up payment", children: /* @__PURE__ */ jsx28(
4212
+ return /* @__PURE__ */ jsx27("section", { className: cx2.card, "aria-label": "Top-up payment", children: /* @__PURE__ */ jsx27(
4233
4213
  TopupForm.Root,
4234
4214
  {
4235
4215
  amount: committedAmountMinor,
@@ -4255,14 +4235,14 @@ function EmbeddedTopup({
4255
4235
  onTopupSuccess?.(committedAmountMinor);
4256
4236
  },
4257
4237
  children: /* @__PURE__ */ jsxs20(McpHostedLayout, { children: [
4258
- /* @__PURE__ */ jsx28(McpSummaryRail, { children: /* @__PURE__ */ jsxs20("section", { className: cx2.stack, children: [
4259
- /* @__PURE__ */ jsx28("p", { className: cx2.muted, children: "Total due today" }),
4260
- /* @__PURE__ */ jsx28("p", { className: cx2.topupAmountHero, children: /* @__PURE__ */ jsx28(TopupChargeAmount, { amountMinor: committedAmountMinor, currency }) }),
4261
- contextParts.length > 0 ? /* @__PURE__ */ jsx28("p", { className: cx2.topupBalanceContext, children: contextParts.join(" \xB7 ") }) : null,
4262
- isFullscreen ? /* @__PURE__ */ jsx28(TopupForm.Summary.Rows, { className: cx2.taxSummary }) : /* @__PURE__ */ jsx28(TopupForm.Summary.TaxNote, { className: cx2.muted })
4238
+ /* @__PURE__ */ jsx27(McpSummaryRail, { children: /* @__PURE__ */ jsxs20("section", { className: cx2.stack, children: [
4239
+ /* @__PURE__ */ jsx27("p", { className: cx2.muted, children: "Total due today" }),
4240
+ /* @__PURE__ */ jsx27("p", { className: cx2.topupAmountHero, children: /* @__PURE__ */ jsx27(TopupChargeAmount, { amountMinor: committedAmountMinor, currency }) }),
4241
+ contextParts.length > 0 ? /* @__PURE__ */ jsx27("p", { className: cx2.topupBalanceContext, children: contextParts.join(" \xB7 ") }) : null,
4242
+ isFullscreen ? /* @__PURE__ */ jsx27(TopupForm.Summary.Rows, { className: cx2.taxSummary }) : /* @__PURE__ */ jsx27(TopupForm.Summary.TaxNote, { className: cx2.muted })
4263
4243
  ] }) }),
4264
4244
  /* @__PURE__ */ jsxs20(McpHostedBody, { children: [
4265
- /* @__PURE__ */ jsx28(
4245
+ /* @__PURE__ */ jsx27(
4266
4246
  McpPaymentHeader,
4267
4247
  {
4268
4248
  backLabel: "Change amount",
@@ -4270,16 +4250,16 @@ function EmbeddedTopup({
4270
4250
  }
4271
4251
  ),
4272
4252
  /* @__PURE__ */ jsxs20("div", { className: cx2.topupForm, children: [
4273
- /* @__PURE__ */ jsx28(TopupForm.Loading, {}),
4274
- /* @__PURE__ */ jsx28(TopupForm.PaymentElement, {}),
4275
- /* @__PURE__ */ jsx28(TopupForm.BusinessDetails.Root, { className: cx2.businessDetails, children: /* @__PURE__ */ jsx28(TopupForm.BusinessDetails.Fields, {}) }),
4276
- /* @__PURE__ */ jsx28(TopupForm.Error, { className: cx2.error }),
4253
+ /* @__PURE__ */ jsx27(TopupForm.Loading, {}),
4254
+ /* @__PURE__ */ jsx27(TopupForm.PaymentElement, {}),
4255
+ /* @__PURE__ */ jsx27(TopupForm.BusinessDetails.Root, { className: cx2.businessDetails, children: /* @__PURE__ */ jsx27(TopupForm.BusinessDetails.Fields, {}) }),
4256
+ /* @__PURE__ */ jsx27(TopupForm.Error, { className: cx2.error }),
4277
4257
  /* @__PURE__ */ jsxs20(TopupForm.SubmitButton, { className: cx2.button, children: [
4278
4258
  "Top up",
4279
4259
  " ",
4280
- /* @__PURE__ */ jsx28(TopupChargeAmount, { amountMinor: committedAmountMinor, currency })
4260
+ /* @__PURE__ */ jsx27(TopupChargeAmount, { amountMinor: committedAmountMinor, currency })
4281
4261
  ] }),
4282
- /* @__PURE__ */ jsx28(MandateText, { mode: "topup", amountMinor: committedAmountMinor, currency })
4262
+ /* @__PURE__ */ jsx27(MandateText, { mode: "topup", amountMinor: committedAmountMinor, currency })
4283
4263
  ] })
4284
4264
  ] })
4285
4265
  ] })
@@ -4295,7 +4275,7 @@ function EmbeddedTopup({
4295
4275
  selector: topupSelector,
4296
4276
  className: cx2.amountPicker,
4297
4277
  children: [
4298
- isFullscreen ? null : /* @__PURE__ */ jsx28(
4278
+ isFullscreen ? null : /* @__PURE__ */ jsx27(
4299
4279
  AmountStepHeader,
4300
4280
  {
4301
4281
  cx: cx2,
@@ -4305,38 +4285,65 @@ function EmbeddedTopup({
4305
4285
  onCurrencyChange: handleCurrencyChange
4306
4286
  }
4307
4287
  ),
4308
- /* @__PURE__ */ jsx28(PresetAmountGrid, { currencyDisplay, locale }),
4309
- /* @__PURE__ */ jsx28(
4288
+ /* @__PURE__ */ jsx27(PresetAmountGrid, { currencyDisplay, locale }),
4289
+ /* @__PURE__ */ jsx27(
4310
4290
  CustomAmountRow2,
4311
4291
  {
4312
4292
  rowClassName: cx2.amountCustom,
4313
4293
  currencyDisplay
4314
4294
  }
4315
4295
  ),
4316
- /* @__PURE__ */ jsx28(
4317
- McpInlineAutoRecharge,
4318
- {
4319
- ref: autoRechargeRef,
4320
- currency,
4321
- creditsPerMinorUnit,
4322
- displayExchangeRate
4323
- }
4324
- ),
4325
- /* @__PURE__ */ jsx28(AmountDueSummary, { locale, currency }),
4326
- /* @__PURE__ */ jsx28(
4296
+ /* @__PURE__ */ jsxs20("div", { className: "solvapay-mcp-auto-recharge-inline", children: [
4297
+ /* @__PURE__ */ jsxs20(SplitRow, { children: [
4298
+ /* @__PURE__ */ jsx27("p", { children: copy.autoRechargeView.heading }),
4299
+ /* @__PURE__ */ jsx27(
4300
+ Toggle,
4301
+ {
4302
+ checked: autoRechargeForm.enabled,
4303
+ label: copy.autoRechargeView.heading,
4304
+ onChange: (enabled) => {
4305
+ setAutoRechargeError(null);
4306
+ setAutoRechargeForm((current) => ({ ...current, enabled }));
4307
+ }
4308
+ }
4309
+ )
4310
+ ] }),
4311
+ autoRechargeForm.enabled ? /* @__PURE__ */ jsx27(
4312
+ McpAutoRechargeFields,
4313
+ {
4314
+ form: autoRechargeForm,
4315
+ onChange: (next) => {
4316
+ setAutoRechargeError(null);
4317
+ setAutoRechargeForm(next);
4318
+ },
4319
+ currency,
4320
+ validationError: autoRechargeError,
4321
+ creditsPerMinorUnit,
4322
+ displayExchangeRate
4323
+ }
4324
+ ) : null
4325
+ ] }),
4326
+ /* @__PURE__ */ jsx27(AmountDueSummary, { locale, currency }),
4327
+ /* @__PURE__ */ jsx27(
4327
4328
  AmountPicker.Confirm,
4328
4329
  {
4329
4330
  className: cx2.button,
4330
4331
  onConfirm: (amountMinor) => {
4331
- const result = autoRechargeRef.current?.validate();
4332
- if (result == null) {
4333
- throw new Error("McpTopupView: auto-recharge form is not mounted");
4332
+ const result = validateAutoRechargeForm(
4333
+ autoRechargeForm,
4334
+ currency,
4335
+ { creditsPerMinorUnit, displayExchangeRate },
4336
+ copy.autoRecharge
4337
+ );
4338
+ if (!result.ok) {
4339
+ setAutoRechargeError(result.error);
4340
+ return;
4334
4341
  }
4335
- if (!result.ok) return;
4342
+ setAutoRechargeError(null);
4336
4343
  setScreen({
4337
4344
  step: "payment",
4338
4345
  amountMinor,
4339
- autoRecharge: result.payload
4346
+ autoRecharge: result.payload.enabled ? result.payload : void 0
4340
4347
  });
4341
4348
  void notifyModelContext({
4342
4349
  text: `User confirmed topup of ${formatPrice(amountMinor, currency, {
@@ -4352,8 +4359,8 @@ function EmbeddedTopup({
4352
4359
  }
4353
4360
  );
4354
4361
  if (isFullscreen) {
4355
- return /* @__PURE__ */ jsx28("section", { className: cx2.card, "aria-label": "Add credits", children: /* @__PURE__ */ jsxs20(McpHostedLayout, { children: [
4356
- /* @__PURE__ */ jsx28(McpSummaryRail, { children: /* @__PURE__ */ jsx28(
4362
+ return /* @__PURE__ */ jsx27("section", { className: cx2.card, "aria-label": "Add credits", children: /* @__PURE__ */ jsxs20(McpHostedLayout, { children: [
4363
+ /* @__PURE__ */ jsx27(McpSummaryRail, { children: /* @__PURE__ */ jsx27(
4357
4364
  AmountStepHeader,
4358
4365
  {
4359
4366
  cx: cx2,
@@ -4365,13 +4372,13 @@ function EmbeddedTopup({
4365
4372
  }
4366
4373
  ) }),
4367
4374
  /* @__PURE__ */ jsxs20(McpHostedBody, { children: [
4368
- onBack ? /* @__PURE__ */ jsx28(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4375
+ onBack ? /* @__PURE__ */ jsx27(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4369
4376
  amountForm
4370
4377
  ] })
4371
4378
  ] }) });
4372
4379
  }
4373
4380
  return /* @__PURE__ */ jsxs20("section", { className: cx2.card, "aria-label": "Add credits", children: [
4374
- onBack ? /* @__PURE__ */ jsx28(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4381
+ onBack ? /* @__PURE__ */ jsx27(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4375
4382
  amountForm
4376
4383
  ] });
4377
4384
  }
@@ -4382,7 +4389,7 @@ function TopupChargeAmount({
4382
4389
  const locale = useHostLocale();
4383
4390
  const { taxBreakdown } = useTopupForm();
4384
4391
  const minor = chargeAmountMinor(taxBreakdown, amountMinor);
4385
- return /* @__PURE__ */ jsx28(Fragment12, { children: formatPrice(minor, taxBreakdown?.currency ?? currency, { locale, free: "" }) });
4392
+ return /* @__PURE__ */ jsx27(Fragment12, { children: formatPrice(minor, taxBreakdown?.currency ?? currency, { locale, free: "" }) });
4386
4393
  }
4387
4394
  function AmountStepHeader({
4388
4395
  cx: cx2,
@@ -4397,26 +4404,26 @@ function AmountStepHeader({
4397
4404
  const formattedBalance = credits != null ? new Intl.NumberFormat(locale).format(credits) : void 0;
4398
4405
  return /* @__PURE__ */ jsxs20("header", { className: rail ? cx2.stack : void 0, children: [
4399
4406
  rail ? /* @__PURE__ */ jsxs20(Fragment12, { children: [
4400
- /* @__PURE__ */ jsx28(Eyebrow, { variant: "rail", children: "Add credits" }),
4407
+ /* @__PURE__ */ jsx27(Eyebrow, { variant: "rail", children: "Add credits" }),
4401
4408
  formattedBalance ? /* @__PURE__ */ jsxs20("p", { className: cx2.muted, children: [
4402
4409
  "Balance ",
4403
4410
  formattedBalance,
4404
4411
  " credits"
4405
4412
  ] }) : null
4406
4413
  ] }) : /* @__PURE__ */ jsxs20("div", { className: cx2.balanceRow, children: [
4407
- /* @__PURE__ */ jsx28("h2", { className: cx2.heading, children: "Add credits" }),
4408
- /* @__PURE__ */ jsx28(BalanceBadge, {})
4414
+ /* @__PURE__ */ jsx27("h2", { className: cx2.heading, children: "Add credits" }),
4415
+ /* @__PURE__ */ jsx27(BalanceBadge, {})
4409
4416
  ] }),
4410
4417
  showCurrencySwitch ? /* @__PURE__ */ jsxs20("label", { className: "solvapay-mcp-step-header", children: [
4411
- /* @__PURE__ */ jsx28("span", { className: cx2.muted, children: "Pay in" }),
4412
- /* @__PURE__ */ jsx28(
4418
+ /* @__PURE__ */ jsx27("span", { className: cx2.muted, children: "Pay in" }),
4419
+ /* @__PURE__ */ jsx27(
4413
4420
  "select",
4414
4421
  {
4415
4422
  className: "solvapay-mcp-currency-switch",
4416
4423
  value: currency,
4417
4424
  onChange: (event) => onCurrencyChange(event.target.value),
4418
4425
  "aria-label": "Topup currency",
4419
- children: topupCurrencies.map((code) => /* @__PURE__ */ jsx28("option", { value: code, children: code }, code))
4426
+ children: topupCurrencies.map((code) => /* @__PURE__ */ jsx27("option", { value: code, children: code }, code))
4420
4427
  }
4421
4428
  )
4422
4429
  ] }) : null
@@ -4428,7 +4435,7 @@ function PresetAmountGrid({
4428
4435
  }) {
4429
4436
  const { quickAmounts, currency, creditsPerMinorUnit, displayExchangeRate } = useAmountPicker();
4430
4437
  const { displayCurrency } = useBalance();
4431
- return /* @__PURE__ */ jsx28("div", { className: "solvapay-mcp-preset-grid", "aria-label": "Quick amounts", children: quickAmounts.map((amount) => {
4438
+ return /* @__PURE__ */ jsx27("div", { className: "solvapay-mcp-preset-grid", "aria-label": "Quick amounts", children: quickAmounts.map((amount) => {
4432
4439
  const minor = amount * getMinorUnitsPerMajor(currency);
4433
4440
  const label = formatPrice(minor, currency, {
4434
4441
  locale,
@@ -4443,21 +4450,21 @@ function PresetAmountGrid({
4443
4450
  displayExchangeRate
4444
4451
  );
4445
4452
  return /* @__PURE__ */ jsxs20(AmountPicker.Option, { amount, className: "solvapay-mcp-preset-tile", children: [
4446
- /* @__PURE__ */ jsx28("span", { className: "solvapay-mcp-preset-tile-amount", children: label }),
4447
- /* @__PURE__ */ jsx28("span", { className: "solvapay-mcp-preset-tile-credits", children: estimate.kind === "available" ? formatCompactCredits(estimate.credits, locale) : "" })
4453
+ /* @__PURE__ */ jsx27("span", { className: "solvapay-mcp-preset-tile-amount", children: label }),
4454
+ /* @__PURE__ */ jsx27("span", { className: "solvapay-mcp-preset-tile-credits", children: estimate.kind === "available" ? formatCompactCredits(estimate.credits, locale) : "" })
4448
4455
  ] }, amount);
4449
4456
  }) });
4450
4457
  }
4451
4458
  function AmountDueSummary({ locale, currency }) {
4452
4459
  const { resolvedAmountMinor } = useAmountPicker();
4453
4460
  const displayAmount = resolvedAmountMinor != null ? formatPrice(resolvedAmountMinor, currency, { locale, free: "" }) : formatPrice(0, currency, { locale, free: "" });
4454
- return /* @__PURE__ */ jsx28(
4461
+ return /* @__PURE__ */ jsx27(
4455
4462
  AmountLadder,
4456
4463
  {
4457
4464
  rows: [
4458
4465
  {
4459
4466
  label: "Total due today",
4460
- value: /* @__PURE__ */ jsx28("span", { className: "solvapay-mcp-topup-total", children: displayAmount })
4467
+ value: /* @__PURE__ */ jsx27("span", { className: "solvapay-mcp-topup-total", children: displayAmount })
4461
4468
  }
4462
4469
  ]
4463
4470
  }
@@ -4470,19 +4477,16 @@ function CustomAmountRow2({
4470
4477
  const { currencySymbol: currencySymbol2, currency } = useAmountPicker();
4471
4478
  const prefix = currencyDisplay === "code" ? currency.toUpperCase() : currencySymbol2;
4472
4479
  return /* @__PURE__ */ jsxs20("label", { className: rowClassName, children: [
4473
- /* @__PURE__ */ jsx28("span", { className: "solvapay-mcp-amount-currency-symbol", children: prefix }),
4474
- /* @__PURE__ */ jsx28(AmountPicker.Custom, { className: "solvapay-mcp-amount-custom-input", placeholder: "0.00" })
4480
+ /* @__PURE__ */ jsx27("span", { className: "solvapay-mcp-amount-currency-symbol", children: prefix }),
4481
+ /* @__PURE__ */ jsx27(AmountPicker.Custom, { className: "solvapay-mcp-amount-custom-input", placeholder: "0.00" })
4475
4482
  ] });
4476
4483
  }
4477
- function HostedTopupFallback({
4478
- cx: cx2,
4479
- onChangeAmount
4480
- }) {
4484
+ function HostedTopupFallback({ cx: cx2, onBack }) {
4481
4485
  return /* @__PURE__ */ jsxs20("section", { className: cx2.card, "aria-label": "Add credits", children: [
4482
- /* @__PURE__ */ jsx28(BackLink, { label: "Change amount", onClick: onChangeAmount }),
4483
- /* @__PURE__ */ jsx28("h2", { className: cx2.heading, children: "Add credits" }),
4484
- /* @__PURE__ */ jsx28("p", { className: cx2.muted, children: "This host doesn't allow embedded payments. Open the SolvaPay portal in a new tab to complete your top-up there." }),
4485
- /* @__PURE__ */ jsx28(
4486
+ onBack ? /* @__PURE__ */ jsx27(BackLink, { label: "Back to my account", onClick: onBack }) : null,
4487
+ /* @__PURE__ */ jsx27("h2", { className: cx2.heading, children: "Add credits" }),
4488
+ /* @__PURE__ */ jsx27("p", { className: cx2.muted, children: "This host doesn't allow embedded payments. Open the SolvaPay portal in a new tab to complete your top-up there." }),
4489
+ /* @__PURE__ */ jsx27(
4486
4490
  LaunchCustomerPortalButton,
4487
4491
  {
4488
4492
  className: cx2.button,
@@ -4495,7 +4499,7 @@ function HostedTopupFallback({
4495
4499
  }
4496
4500
 
4497
4501
  // src/mcp/McpAppShell.tsx
4498
- import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
4502
+ import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
4499
4503
  function resolveSurface(bootstrapView) {
4500
4504
  switch (bootstrapView) {
4501
4505
  case "checkout":
@@ -4522,8 +4526,8 @@ function McpAppShell({
4522
4526
  onRefreshBootstrap,
4523
4527
  onClose
4524
4528
  }) {
4525
- const [overrideView, setOverrideView] = useState10(null);
4526
- const [overridePlanRef, setOverridePlanRef] = useState10();
4529
+ const [overrideView, setOverrideView] = useState9(null);
4530
+ const [overridePlanRef, setOverridePlanRef] = useState9();
4527
4531
  const handleSurfaceChange = useCallback5((next, intent) => {
4528
4532
  setOverrideView(next);
4529
4533
  setOverridePlanRef(intent?.planRef);
@@ -4533,7 +4537,7 @@ function McpAppShell({
4533
4537
  const showFooter = footer ?? true;
4534
4538
  const surface = effectiveView === "account" || effectiveView === "auto-recharge" ? "management" : "payment";
4535
4539
  return /* @__PURE__ */ jsxs21("div", { className: "solvapay-mcp-shell", children: [
4536
- /* @__PURE__ */ jsx29(McpHostedColumn, { surface, children: /* @__PURE__ */ jsx29(McpHostedLayout, { children: /* @__PURE__ */ jsx29("div", { className: "solvapay-mcp-shell-body", children: /* @__PURE__ */ jsx29(
4540
+ /* @__PURE__ */ jsx28(McpHostedColumn, { surface, children: /* @__PURE__ */ jsx28(McpHostedLayout, { children: /* @__PURE__ */ jsx28("div", { className: "solvapay-mcp-shell-body", children: /* @__PURE__ */ jsx28(
4537
4541
  McpViewRouter,
4538
4542
  {
4539
4543
  view: effectiveView,
@@ -4546,12 +4550,12 @@ function McpAppShell({
4546
4550
  onClose
4547
4551
  }
4548
4552
  ) }) }) }),
4549
- showFooter ? /* @__PURE__ */ jsx29(ShellFooter, { classNames }) : null
4553
+ showFooter ? /* @__PURE__ */ jsx28(ShellFooter, { classNames }) : null
4550
4554
  ] });
4551
4555
  }
4552
4556
  function ShellFooter({ classNames }) {
4553
4557
  const cx2 = resolveMcpClassNames(classNames);
4554
- return /* @__PURE__ */ jsx29("footer", { className: `solvapay-mcp-shell-footer ${cx2.muted}`.trim(), children: /* @__PURE__ */ jsx29(LegalFooter, { attribution: "provided" }) });
4558
+ return /* @__PURE__ */ jsx28("footer", { className: `solvapay-mcp-shell-footer ${cx2.muted}`.trim(), children: /* @__PURE__ */ jsx28(LegalFooter, { attribution: "provided" }) });
4555
4559
  }
4556
4560
  function McpViewRouter({
4557
4561
  view,
@@ -4567,12 +4571,14 @@ function McpViewRouter({
4567
4571
  const CheckoutView = views?.checkout ?? McpCheckoutView;
4568
4572
  const AccountView = views?.account ?? McpAccountView;
4569
4573
  const TopupView = views?.topup ?? McpTopupView;
4574
+ const AutoRechargeView = views?.autoRecharge ?? McpAutoRechargeView;
4570
4575
  const goCheckout = onSurfaceChange ? (planRef) => onSurfaceChange("checkout", typeof planRef === "string" ? { planRef } : void 0) : void 0;
4571
4576
  const goTopup = onSurfaceChange ? () => onSurfaceChange("topup") : void 0;
4572
4577
  const goAccount = onSurfaceChange ? () => onSurfaceChange("account") : void 0;
4578
+ const goAutoRecharge = onSurfaceChange ? () => onSurfaceChange("auto-recharge") : void 0;
4573
4579
  switch (view) {
4574
4580
  case "checkout":
4575
- return /* @__PURE__ */ jsx29(
4581
+ return /* @__PURE__ */ jsx28(
4576
4582
  CheckoutView,
4577
4583
  {
4578
4584
  productRef,
@@ -4588,23 +4594,23 @@ function McpViewRouter({
4588
4594
  autoAdvance: Boolean(overridePlanRef)
4589
4595
  }
4590
4596
  );
4591
- case "auto-recharge":
4592
4597
  case "account":
4593
- return /* @__PURE__ */ jsx29(
4598
+ return /* @__PURE__ */ jsx28(
4594
4599
  AccountView,
4595
4600
  {
4596
4601
  classNames,
4597
4602
  product: bootstrap.product,
4598
4603
  productRef,
4599
4604
  onTopup: goTopup,
4600
- autoRecharge: bootstrap.customer?.autoRecharge ?? null,
4601
- autoRechargeUrl: bootstrap.autoRechargeUrl ?? null,
4605
+ onAutoRecharge: goAutoRecharge,
4602
4606
  onChangePlan: goCheckout,
4603
4607
  plans: bootstrap.plans
4604
4608
  }
4605
4609
  );
4610
+ case "auto-recharge":
4611
+ return /* @__PURE__ */ jsx28(AutoRechargeView, { classNames, onBack: goAccount });
4606
4612
  case "topup":
4607
- return /* @__PURE__ */ jsx29(
4613
+ return /* @__PURE__ */ jsx28(
4608
4614
  TopupView,
4609
4615
  {
4610
4616
  publishableKey: stripePublishableKey,
@@ -4619,21 +4625,21 @@ function McpViewRouter({
4619
4625
  }
4620
4626
 
4621
4627
  // src/mcp/views/AppHeader.tsx
4622
- import { useContext as useContext4, useLayoutEffect, useRef as useRef7, useState as useState11 } from "react";
4628
+ import { useContext as useContext4, useLayoutEffect, useRef as useRef5, useState as useState10 } from "react";
4623
4629
 
4624
4630
  // src/mcp/hooks/useHostInfo.tsx
4625
4631
  import { createContext as createContext3, useContext as useContext3 } from "react";
4626
- import { jsx as jsx30 } from "react/jsx-runtime";
4632
+ import { jsx as jsx29 } from "react/jsx-runtime";
4627
4633
  var McpHostInfoContext = createContext3(null);
4628
4634
  function McpHostInfoProvider({ hostName, children }) {
4629
- return /* @__PURE__ */ jsx30(McpHostInfoContext.Provider, { value: hostName, children });
4635
+ return /* @__PURE__ */ jsx29(McpHostInfoContext.Provider, { value: hostName, children });
4630
4636
  }
4631
4637
  function useHostName() {
4632
4638
  return useContext3(McpHostInfoContext);
4633
4639
  }
4634
4640
 
4635
4641
  // src/mcp/views/AppHeader.tsx
4636
- import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
4642
+ import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
4637
4643
  var HOSTS_WITH_MERCHANT_CHROME = /chatgpt|openai|claude/i;
4638
4644
  function useMerchantSafe() {
4639
4645
  const ctx = useContext4(SolvaPayContext);
@@ -4670,9 +4676,9 @@ function AppHeader({
4670
4676
  const hostName = useHostName();
4671
4677
  const name = merchant?.displayName ?? "SolvaPay";
4672
4678
  const iconUrl = merchant?.iconUrl ?? merchant?.logoUrl ?? null;
4673
- const [imgFailed, setImgFailed] = useState11(false);
4674
- const [imgLoaded, setImgLoaded] = useState11(false);
4675
- const imgRef = useRef7(null);
4679
+ const [imgFailed, setImgFailed] = useState10(false);
4680
+ const [imgLoaded, setImgLoaded] = useState10(false);
4681
+ const imgRef = useRef5(null);
4676
4682
  useLayoutEffect(() => {
4677
4683
  const el = imgRef.current;
4678
4684
  const cached = el ? el.complete && el.naturalHeight > 0 : false;
@@ -4687,7 +4693,7 @@ function AppHeader({
4687
4693
  const hasIconUrl = iconUrl !== null && !imgFailed;
4688
4694
  const showInitials = !hasIconUrl || !imgLoaded;
4689
4695
  return /* @__PURE__ */ jsxs22("header", { className: rootClass, children: [
4690
- hasIconUrl ? /* @__PURE__ */ jsx31(
4696
+ hasIconUrl ? /* @__PURE__ */ jsx30(
4691
4697
  "img",
4692
4698
  {
4693
4699
  ref: imgRef,
@@ -4699,14 +4705,14 @@ function AppHeader({
4699
4705
  onError: () => setImgFailed(true)
4700
4706
  }
4701
4707
  ) : null,
4702
- showInitials ? /* @__PURE__ */ jsx31("span", { className: cx2.appHeaderInitials, "aria-hidden": "true", children: getInitials(name) }) : null,
4703
- /* @__PURE__ */ jsx31("span", { className: cx2.appHeaderName, children: name }),
4704
- children ? /* @__PURE__ */ jsx31("span", { className: "solvapay-mcp-app-header-slot", children }) : null
4708
+ showInitials ? /* @__PURE__ */ jsx30("span", { className: cx2.appHeaderInitials, "aria-hidden": "true", children: getInitials(name) }) : null,
4709
+ /* @__PURE__ */ jsx30("span", { className: cx2.appHeaderName, children: name }),
4710
+ children ? /* @__PURE__ */ jsx30("span", { className: "solvapay-mcp-app-header-slot", children }) : null
4705
4711
  ] });
4706
4712
  }
4707
4713
 
4708
4714
  // src/mcp/McpApp.tsx
4709
- import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
4715
+ import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
4710
4716
  function bootstrapToInitial(bs) {
4711
4717
  return {
4712
4718
  customerRef: bs.customer?.ref ?? null,
@@ -4732,15 +4738,15 @@ function McpApp({
4732
4738
  messageOnSuccess
4733
4739
  }) {
4734
4740
  const cx2 = resolveMcpClassNames(classNames);
4735
- const [bootstrap, setBootstrap] = useState12(null);
4736
- const [initError, setInitError] = useState12(null);
4737
- const [hostName, setHostName] = useState12(null);
4738
- const [displayModeState, setDisplayModeState] = useState12(
4741
+ const [bootstrap, setBootstrap] = useState11(null);
4742
+ const [initError, setInitError] = useState11(null);
4743
+ const [hostName, setHostName] = useState11(null);
4744
+ const [displayModeState, setDisplayModeState] = useState11(
4739
4745
  DEFAULT_DISPLAY_MODE_STATE
4740
4746
  );
4741
- const pendingBootstrapFetchRef = useRef8(0);
4742
- const applyContextRef = useRef8(applyContext);
4743
- const onInitErrorRef = useRef8(onInitError);
4747
+ const pendingBootstrapFetchRef = useRef6(0);
4748
+ const applyContextRef = useRef6(applyContext);
4749
+ const onInitErrorRef = useRef6(onInitError);
4744
4750
  useEffect7(() => {
4745
4751
  applyContextRef.current = applyContext;
4746
4752
  }, [applyContext]);
@@ -4900,7 +4906,7 @@ function McpApp({
4900
4906
  };
4901
4907
  return resolved;
4902
4908
  }, [transport, initial, app]);
4903
- const seededInitialRef = useRef8(null);
4909
+ const seededInitialRef = useRef6(null);
4904
4910
  if (initial && seededInitialRef.current !== initial) {
4905
4911
  seedMcpCaches(initial, providerConfig);
4906
4912
  seededInitialRef.current = initial;
@@ -4928,14 +4934,14 @@ function McpApp({
4928
4934
  );
4929
4935
  const effectiveOnClose = onClose ?? defaultOnClose;
4930
4936
  const effectiveBootstrap = bootstrap && productRefOverride ? { ...bootstrap, productRef: productRefOverride } : bootstrap;
4931
- return /* @__PURE__ */ jsx32(McpHostInfoProvider, { hostName, children: /* @__PURE__ */ jsx32(McpDisplayModeProvider, { value: displayModeState, children: /* @__PURE__ */ jsxs23(
4937
+ return /* @__PURE__ */ jsx31(McpHostInfoProvider, { hostName, children: /* @__PURE__ */ jsx31(McpDisplayModeProvider, { value: displayModeState, children: /* @__PURE__ */ jsxs23(
4932
4938
  "main",
4933
4939
  {
4934
4940
  className: "solvapay-mcp-main",
4935
4941
  "data-display-mode": displayModeState.displayMode,
4936
4942
  style: hostSafeAreaPadding(displayModeState.safeAreaInsets),
4937
4943
  children: [
4938
- /* @__PURE__ */ jsx32("div", { className: "solvapay-mcp-chrome-row", children: displayModeState.displayMode !== "fullscreen" ? /* @__PURE__ */ jsx32(
4944
+ /* @__PURE__ */ jsx31("div", { className: "solvapay-mcp-chrome-row", children: displayModeState.displayMode !== "fullscreen" ? /* @__PURE__ */ jsx31(
4939
4945
  AppHeader,
4940
4946
  {
4941
4947
  classNames,
@@ -4943,16 +4949,16 @@ function McpApp({
4943
4949
  }
4944
4950
  ) : null }),
4945
4951
  initError ? /* @__PURE__ */ jsxs23("div", { className: `${cx2.card} ${cx2.error}`.trim(), children: [
4946
- /* @__PURE__ */ jsx32("h2", { className: cx2.heading, children: "Unable to load SolvaPay" }),
4947
- /* @__PURE__ */ jsx32("p", { children: initError })
4952
+ /* @__PURE__ */ jsx31("h2", { className: cx2.heading, children: "Unable to load SolvaPay" }),
4953
+ /* @__PURE__ */ jsx31("p", { children: initError })
4948
4954
  ] }) : !effectiveBootstrap ? (
4949
4955
  // Intent-tool / fallback entries show a loading card while the
4950
4956
  // in-flight `fetchMcpBootstrap` call resolves. Data-tool iframe
4951
4957
  // entries no longer exist (payable merchant tools don't advertise
4952
4958
  // `_meta.ui.resourceUri`) so this is always legitimate user
4953
4959
  // feedback for an in-flight tool call.
4954
- /* @__PURE__ */ jsx32("div", { className: cx2.card, children: /* @__PURE__ */ jsx32("p", { children: "Loading\u2026" }) })
4955
- ) : /* @__PURE__ */ jsx32(SolvaPayProvider, { config: providerConfig, children: /* @__PURE__ */ jsx32(McpBridgeProvider, { app, messageOnSuccess, children: /* @__PURE__ */ jsx32(
4960
+ /* @__PURE__ */ jsx31("div", { className: cx2.card, children: /* @__PURE__ */ jsx31("p", { children: "Loading\u2026" }) })
4961
+ ) : /* @__PURE__ */ jsx31(SolvaPayProvider, { config: providerConfig, children: /* @__PURE__ */ jsx31(McpBridgeProvider, { app, messageOnSuccess, children: /* @__PURE__ */ jsx31(
4956
4962
  McpAppShell,
4957
4963
  {
4958
4964
  bootstrap: effectiveBootstrap,
@@ -4989,6 +4995,7 @@ export {
4989
4995
  McpAccountView,
4990
4996
  McpApp,
4991
4997
  McpAppShell,
4998
+ McpAutoRechargeView,
4992
4999
  McpBridgeProvider,
4993
5000
  McpCheckoutView,
4994
5001
  McpDisplayModeProvider,
@@ -5031,7 +5038,6 @@ export {
5031
5038
  planConsequence,
5032
5039
  readDisplayModeState,
5033
5040
  remainingCap,
5034
- resetStripeProbeCacheForTests,
5035
5041
  resolveAccountState,
5036
5042
  resolveActivationStrategy,
5037
5043
  resolveActivityStrip,