@solvapay/react 2.2.1 → 2.2.2-preview-09731417a0a7b4fd3afb4783fdf20b5ad293f63d
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/CHANGELOG.md +12 -0
- package/dist/{UsageMeter-CkJ_nowq.d.ts → UsageMeter-BZWfC5KX.d.ts} +1 -1
- package/dist/{UsageMeter-ClENA677.d.cts → UsageMeter-BiujMmVR.d.cts} +1 -1
- package/dist/{chunk-QZLY6SIU.js → chunk-4UFQDYG5.js} +1 -1
- package/dist/{chunk-LCBCOFXZ.js → chunk-GPP4MY3I.js} +54 -86
- package/dist/{chunk-AW5PCAYK.js → chunk-KUH3SNWZ.js} +1 -1
- package/dist/{index-DFtP872_.d.cts → index-B5QUesJE.d.cts} +5 -1
- package/dist/{index-D4EhOmYp.d.ts → index-BAYpUp5R.d.ts} +5 -1
- package/dist/index.cjs +32 -55
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +3 -3
- package/dist/mcp/index.cjs +29 -57
- package/dist/mcp/index.d.cts +2 -2
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +6 -10
- package/dist/primitives/index.cjs +32 -55
- package/dist/primitives/index.d.cts +5 -5
- package/dist/primitives/index.d.ts +5 -5
- package/dist/primitives/index.js +2 -2
- package/dist/{useUsage-x6DQG7xe.d.cts → useUsage-CRd_E6J3.d.cts} +9 -0
- package/dist/{useUsage-CfM9dQwB.d.ts → useUsage-DSPWQ37m.d.ts} +9 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @solvapay/react changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.2-preview-09731417a0a7b4fd3afb4783fdf20b5ad293f63d
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 567db3e: The customer's active plan is no longer selectable in the plan picker. The active PAYG plan is no longer auto-selected — topping up happens from the account surface, not by re-activating the current plan from the list.
|
|
8
|
+
- Updated dependencies [c67e78e]
|
|
9
|
+
- Updated dependencies [dbd0108]
|
|
10
|
+
- Updated dependencies [c67e78e]
|
|
11
|
+
- Updated dependencies [c67e78e]
|
|
12
|
+
- Updated dependencies [c67e78e]
|
|
13
|
+
- @solvapay/mcp-core@0.4.2-preview-09731417a0a7b4fd3afb4783fdf20b5ad293f63d
|
|
14
|
+
|
|
3
15
|
## 2.2.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1880,15 +1880,14 @@ function processPlans(raw, filter, sortBy) {
|
|
|
1880
1880
|
if (filter) result = result.filter(filter);
|
|
1881
1881
|
return result;
|
|
1882
1882
|
}
|
|
1883
|
-
function computeInitialIndex(plans, initialPlanRef, autoSelectFirstPaid) {
|
|
1883
|
+
function computeInitialIndex(plans, initialPlanRef, autoSelectFirstPaid, excludePlanRef) {
|
|
1884
1884
|
if (plans.length === 0) return 0;
|
|
1885
1885
|
if (initialPlanRef) {
|
|
1886
1886
|
const idx = plans.findIndex((p) => p.reference === initialPlanRef);
|
|
1887
1887
|
if (idx >= 0) return idx;
|
|
1888
1888
|
}
|
|
1889
1889
|
if (autoSelectFirstPaid) {
|
|
1890
|
-
|
|
1891
|
-
return idx >= 0 ? idx : 0;
|
|
1890
|
+
return plans.findIndex((p) => p.requiresPayment !== false && p.reference !== excludePlanRef);
|
|
1892
1891
|
}
|
|
1893
1892
|
return -1;
|
|
1894
1893
|
}
|
|
@@ -1900,6 +1899,7 @@ function usePlans(options) {
|
|
|
1900
1899
|
sortBy,
|
|
1901
1900
|
autoSelectFirstPaid = false,
|
|
1902
1901
|
initialPlanRef,
|
|
1902
|
+
excludePlanRef,
|
|
1903
1903
|
selectionReady = true
|
|
1904
1904
|
} = options;
|
|
1905
1905
|
const solvaContext = useContext5(SolvaPayContext);
|
|
@@ -1913,6 +1913,7 @@ function usePlans(options) {
|
|
|
1913
1913
|
const sortByRef = useRef3(sortBy);
|
|
1914
1914
|
const autoSelectFirstPaidRef = useRef3(autoSelectFirstPaid);
|
|
1915
1915
|
const initialPlanRefRef = useRef3(initialPlanRef);
|
|
1916
|
+
const excludePlanRefRef = useRef3(excludePlanRef);
|
|
1916
1917
|
const selectionReadyRef = useRef3(selectionReady);
|
|
1917
1918
|
const hasAppliedInitialRef = useRef3(false);
|
|
1918
1919
|
const userHasSelectedRef = useRef3(false);
|
|
@@ -1924,7 +1925,7 @@ function usePlans(options) {
|
|
|
1924
1925
|
}
|
|
1925
1926
|
const processed = processPlans(cached.plans, filter, sortBy);
|
|
1926
1927
|
if (processed.length === 0) return 0;
|
|
1927
|
-
const idx = computeInitialIndex(processed, initialPlanRef, autoSelectFirstPaid);
|
|
1928
|
+
const idx = computeInitialIndex(processed, initialPlanRef, autoSelectFirstPaid, excludePlanRef);
|
|
1928
1929
|
hasAppliedInitialRef.current = true;
|
|
1929
1930
|
return idx;
|
|
1930
1931
|
});
|
|
@@ -1953,6 +1954,9 @@ function usePlans(options) {
|
|
|
1953
1954
|
useEffect2(() => {
|
|
1954
1955
|
initialPlanRefRef.current = initialPlanRef;
|
|
1955
1956
|
}, [initialPlanRef]);
|
|
1957
|
+
useEffect2(() => {
|
|
1958
|
+
excludePlanRefRef.current = excludePlanRef;
|
|
1959
|
+
}, [excludePlanRef]);
|
|
1956
1960
|
useEffect2(() => {
|
|
1957
1961
|
selectionReadyRef.current = selectionReady;
|
|
1958
1962
|
}, [selectionReady]);
|
|
@@ -1967,7 +1971,8 @@ function usePlans(options) {
|
|
|
1967
1971
|
const idx = computeInitialIndex(
|
|
1968
1972
|
processedPlans,
|
|
1969
1973
|
initialPlanRefRef.current,
|
|
1970
|
-
autoSelectFirstPaidRef.current
|
|
1974
|
+
autoSelectFirstPaidRef.current,
|
|
1975
|
+
excludePlanRefRef.current
|
|
1971
1976
|
);
|
|
1972
1977
|
setSelectedPlanIndexState(idx);
|
|
1973
1978
|
}, []);
|
|
@@ -1984,11 +1989,7 @@ function usePlans(options) {
|
|
|
1984
1989
|
try {
|
|
1985
1990
|
setLoading(true);
|
|
1986
1991
|
const fetchedPlans = await cached.promise;
|
|
1987
|
-
const processedPlans = processPlans(
|
|
1988
|
-
fetchedPlans,
|
|
1989
|
-
filterRef.current,
|
|
1990
|
-
sortByRef.current
|
|
1991
|
-
);
|
|
1992
|
+
const processedPlans = processPlans(fetchedPlans, filterRef.current, sortByRef.current);
|
|
1992
1993
|
setPlans(processedPlans);
|
|
1993
1994
|
setError(null);
|
|
1994
1995
|
applyInitialSelection(processedPlans);
|
|
@@ -2000,11 +2001,7 @@ function usePlans(options) {
|
|
|
2000
2001
|
return;
|
|
2001
2002
|
}
|
|
2002
2003
|
if (!force && cached && cached.plans.length > 0 && now - cached.timestamp < CACHE_DURATION3) {
|
|
2003
|
-
const processedPlans = processPlans(
|
|
2004
|
-
cached.plans,
|
|
2005
|
-
filterRef.current,
|
|
2006
|
-
sortByRef.current
|
|
2007
|
-
);
|
|
2004
|
+
const processedPlans = processPlans(cached.plans, filterRef.current, sortByRef.current);
|
|
2008
2005
|
setPlans(processedPlans);
|
|
2009
2006
|
setLoading(false);
|
|
2010
2007
|
setError(null);
|
|
@@ -2018,11 +2015,7 @@ function usePlans(options) {
|
|
|
2018
2015
|
plansCache.set(productRef, { plans: [], timestamp: now, promise: fetchPromise });
|
|
2019
2016
|
const fetchedPlans = await fetchPromise;
|
|
2020
2017
|
plansCache.set(productRef, { plans: fetchedPlans, timestamp: now, promise: null });
|
|
2021
|
-
const processedPlans = processPlans(
|
|
2022
|
-
fetchedPlans,
|
|
2023
|
-
filterRef.current,
|
|
2024
|
-
sortByRef.current
|
|
2025
|
-
);
|
|
2018
|
+
const processedPlans = processPlans(fetchedPlans, filterRef.current, sortByRef.current);
|
|
2026
2019
|
setPlans(processedPlans);
|
|
2027
2020
|
applyInitialSelection(processedPlans);
|
|
2028
2021
|
} catch (err) {
|
|
@@ -5851,21 +5844,7 @@ var BalanceBadge = forwardRef8(function BalanceBadge2({ asChild, numberOnly, low
|
|
|
5851
5844
|
});
|
|
5852
5845
|
|
|
5853
5846
|
// src/primitives/PlanSelector.tsx
|
|
5854
|
-
import {
|
|
5855
|
-
createContext as createContext9,
|
|
5856
|
-
forwardRef as forwardRef9,
|
|
5857
|
-
useCallback as useCallback15,
|
|
5858
|
-
useContext as useContext13,
|
|
5859
|
-
useEffect as useEffect12,
|
|
5860
|
-
useMemo as useMemo11,
|
|
5861
|
-
useRef as useRef8,
|
|
5862
|
-
useState as useState14
|
|
5863
|
-
} from "react";
|
|
5864
|
-
|
|
5865
|
-
// src/utils/isPayg.ts
|
|
5866
|
-
function isPaygPlan(plan) {
|
|
5867
|
-
return plan?.type === "usage-based" || plan?.type === "hybrid";
|
|
5868
|
-
}
|
|
5847
|
+
import { createContext as createContext9, forwardRef as forwardRef9, useCallback as useCallback15, useContext as useContext13, useMemo as useMemo11, useState as useState14 } from "react";
|
|
5869
5848
|
|
|
5870
5849
|
// src/utils/planPricing.ts
|
|
5871
5850
|
import { headlineCharges } from "@solvapay/core";
|
|
@@ -5940,19 +5919,20 @@ var Root5 = forwardRef9(function PlanSelectorRoot(props, forwardedRef) {
|
|
|
5940
5919
|
() => fetcher ?? ((ref) => defaultListPlans(ref, _config)),
|
|
5941
5920
|
[fetcher, _config]
|
|
5942
5921
|
);
|
|
5922
|
+
const autoCurrentPlanRef = useMemo11(() => {
|
|
5923
|
+
const active = purchases.filter((p) => p.status === "active").sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime())[0];
|
|
5924
|
+
return active?.planSnapshot?.reference ?? null;
|
|
5925
|
+
}, [purchases]);
|
|
5926
|
+
const resolvedCurrentPlanRef = currentPlanRef === null ? null : currentPlanRef ?? autoCurrentPlanRef;
|
|
5943
5927
|
const { plans, selectedPlan, selectPlan, setSelectedPlanIndex, loading, error } = usePlans({
|
|
5944
5928
|
productRef,
|
|
5945
5929
|
fetcher: effectiveFetcher,
|
|
5946
5930
|
filter,
|
|
5947
5931
|
sortBy,
|
|
5948
5932
|
autoSelectFirstPaid,
|
|
5949
|
-
initialPlanRef
|
|
5933
|
+
initialPlanRef,
|
|
5934
|
+
excludePlanRef: resolvedCurrentPlanRef
|
|
5950
5935
|
});
|
|
5951
|
-
const autoCurrentPlanRef = useMemo11(() => {
|
|
5952
|
-
const active = purchases.filter((p) => p.status === "active").sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime())[0];
|
|
5953
|
-
return active?.planSnapshot?.reference ?? null;
|
|
5954
|
-
}, [purchases]);
|
|
5955
|
-
const resolvedCurrentPlanRef = currentPlanRef === null ? null : currentPlanRef ?? autoCurrentPlanRef;
|
|
5956
5936
|
const isCurrent = useCallback15(
|
|
5957
5937
|
(ref) => resolvedCurrentPlanRef === ref,
|
|
5958
5938
|
[resolvedCurrentPlanRef]
|
|
@@ -5961,19 +5941,17 @@ var Root5 = forwardRef9(function PlanSelectorRoot(props, forwardedRef) {
|
|
|
5961
5941
|
(ref) => plans.find((p) => p.reference === ref)?.requiresPayment === false,
|
|
5962
5942
|
[plans]
|
|
5963
5943
|
);
|
|
5964
|
-
const isPopular = useCallback15(
|
|
5965
|
-
(ref) => popularPlanRef === ref,
|
|
5966
|
-
[popularPlanRef]
|
|
5967
|
-
);
|
|
5944
|
+
const isPopular = useCallback15((ref) => popularPlanRef === ref, [popularPlanRef]);
|
|
5968
5945
|
const select = useCallback15(
|
|
5969
5946
|
(ref) => {
|
|
5970
5947
|
const plan = plans.find((p) => p.reference === ref);
|
|
5971
5948
|
if (!plan) return;
|
|
5972
5949
|
if (plan.requiresPayment === false) return;
|
|
5950
|
+
if (isCurrent(ref)) return;
|
|
5973
5951
|
selectPlan(ref);
|
|
5974
5952
|
onSelect?.(ref, plan);
|
|
5975
5953
|
},
|
|
5976
|
-
[plans, selectPlan, onSelect]
|
|
5954
|
+
[plans, selectPlan, onSelect, isCurrent]
|
|
5977
5955
|
);
|
|
5978
5956
|
const clearSelection = useCallback15(() => {
|
|
5979
5957
|
setSelectedPlanIndex(-1);
|
|
@@ -5996,22 +5974,6 @@ var Root5 = forwardRef9(function PlanSelectorRoot(props, forwardedRef) {
|
|
|
5996
5974
|
setSelectedCurrencies((current) => ({ ...current, [planRef]: currency }));
|
|
5997
5975
|
}, []);
|
|
5998
5976
|
const selectedCurrency = selectedPlan ? getSelectedOption(selectedPlan).currency : null;
|
|
5999
|
-
const autoCurrentAppliedKeyRef = useRef8(null);
|
|
6000
|
-
useEffect12(() => {
|
|
6001
|
-
if (autoCurrentAppliedKeyRef.current === productRef) return;
|
|
6002
|
-
if (selectedPlanRef) {
|
|
6003
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6004
|
-
return;
|
|
6005
|
-
}
|
|
6006
|
-
if (!resolvedCurrentPlanRef || plans.length === 0) return;
|
|
6007
|
-
const currentPlan = plans.find((p) => p.reference === resolvedCurrentPlanRef);
|
|
6008
|
-
if (!currentPlan || !isPaygPlan(currentPlan)) {
|
|
6009
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6010
|
-
return;
|
|
6011
|
-
}
|
|
6012
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6013
|
-
select(resolvedCurrentPlanRef);
|
|
6014
|
-
}, [productRef, plans, resolvedCurrentPlanRef, selectedPlanRef, select]);
|
|
6015
5977
|
const ctx = useMemo11(
|
|
6016
5978
|
() => ({
|
|
6017
5979
|
plans,
|
|
@@ -6088,9 +6050,8 @@ var Grid = forwardRef9(function PlanSelectorGrid({ children, ...rest }, forwarde
|
|
|
6088
6050
|
const isFree = ctx.isFree(plan.reference);
|
|
6089
6051
|
const isPopular = ctx.isPopular(plan.reference);
|
|
6090
6052
|
const selected = ctx.selectedPlanRef === plan.reference;
|
|
6091
|
-
const
|
|
6092
|
-
const
|
|
6093
|
-
const state = isCurrent && !isPaygCurrent ? "current" : selected ? "selected" : isCurrent ? "current" : isFree ? "disabled" : "idle";
|
|
6053
|
+
const disabled = isFree || isCurrent;
|
|
6054
|
+
const state = isCurrent ? "current" : selected ? "selected" : isFree ? "disabled" : "idle";
|
|
6094
6055
|
const pricingOptions = getPlanPricingOptions(plan);
|
|
6095
6056
|
const selectedOption = ctx.getSelectedOption(plan);
|
|
6096
6057
|
const cardCtx = {
|
|
@@ -6588,7 +6549,7 @@ function useTransport() {
|
|
|
6588
6549
|
}
|
|
6589
6550
|
|
|
6590
6551
|
// src/hooks/useLimits.ts
|
|
6591
|
-
import { useCallback as useCallback19, useEffect as
|
|
6552
|
+
import { useCallback as useCallback19, useEffect as useEffect12, useRef as useRef8, useState as useState16 } from "react";
|
|
6592
6553
|
var CACHE_TTL_MS = 1e4;
|
|
6593
6554
|
var OPTIMISTIC_GRACE_MS = 8e3;
|
|
6594
6555
|
var limitsCache = /* @__PURE__ */ new Map();
|
|
@@ -6626,12 +6587,12 @@ function useLimits(options) {
|
|
|
6626
6587
|
setData(null);
|
|
6627
6588
|
}
|
|
6628
6589
|
const unlimited = data === null ? null : isUnlimited(data.remaining);
|
|
6629
|
-
const optimisticTimerRef =
|
|
6630
|
-
const unlimitedRef =
|
|
6631
|
-
|
|
6590
|
+
const optimisticTimerRef = useRef8(null);
|
|
6591
|
+
const unlimitedRef = useRef8(false);
|
|
6592
|
+
useEffect12(() => {
|
|
6632
6593
|
unlimitedRef.current = unlimited === true;
|
|
6633
6594
|
}, [unlimited]);
|
|
6634
|
-
|
|
6595
|
+
useEffect12(() => {
|
|
6635
6596
|
return () => {
|
|
6636
6597
|
if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
|
|
6637
6598
|
};
|
|
@@ -6694,11 +6655,11 @@ function useLimits(options) {
|
|
|
6694
6655
|
},
|
|
6695
6656
|
[transport, customerRef, productRef, meterName2, enabled, attachToFetch]
|
|
6696
6657
|
);
|
|
6697
|
-
|
|
6658
|
+
useEffect12(() => {
|
|
6698
6659
|
fetchLimits(false);
|
|
6699
6660
|
}, [fetchLimits]);
|
|
6700
|
-
const prevPurchasesRef =
|
|
6701
|
-
|
|
6661
|
+
const prevPurchasesRef = useRef8(null);
|
|
6662
|
+
useEffect12(() => {
|
|
6702
6663
|
if (prevPurchasesRef.current !== null && prevPurchasesRef.current !== purchase.purchases) {
|
|
6703
6664
|
fetchLimits(true).catch(() => {
|
|
6704
6665
|
});
|
|
@@ -6764,7 +6725,7 @@ function useLimits(options) {
|
|
|
6764
6725
|
|
|
6765
6726
|
// src/hooks/useUsage.ts
|
|
6766
6727
|
import { countsUsage } from "@solvapay/core";
|
|
6767
|
-
import { useCallback as useCallback20, useEffect as
|
|
6728
|
+
import { useCallback as useCallback20, useEffect as useEffect13, useMemo as useMemo15, useState as useState17 } from "react";
|
|
6768
6729
|
var seededUsage = null;
|
|
6769
6730
|
var usageSeedGeneration = 0;
|
|
6770
6731
|
function seedUsageSnapshot(usage) {
|
|
@@ -6826,7 +6787,7 @@ function useUsage() {
|
|
|
6826
6787
|
[activePurchase, limitRemaining, unlimited, meterName2, limitUsed, limit]
|
|
6827
6788
|
);
|
|
6828
6789
|
const activePurchaseRef = activePurchase?.reference ?? null;
|
|
6829
|
-
|
|
6790
|
+
useEffect13(() => {
|
|
6830
6791
|
setOverride(seededUsage);
|
|
6831
6792
|
}, [activePurchaseRef]);
|
|
6832
6793
|
const usage = override ?? derived;
|
|
@@ -7077,7 +7038,7 @@ function useUsageMeter() {
|
|
|
7077
7038
|
}
|
|
7078
7039
|
|
|
7079
7040
|
// src/hooks/useAutoRecharge.ts
|
|
7080
|
-
import { useCallback as useCallback21, useEffect as
|
|
7041
|
+
import { useCallback as useCallback21, useEffect as useEffect14, useRef as useRef9, useState as useState18 } from "react";
|
|
7081
7042
|
function mergeAutoRechargeConfig(config, display) {
|
|
7082
7043
|
return display ? { ...config, display } : config;
|
|
7083
7044
|
}
|
|
@@ -7101,7 +7062,7 @@ function useAutoRecharge() {
|
|
|
7101
7062
|
const [saving, setSaving] = useState18(false);
|
|
7102
7063
|
const [disabling, setDisabling] = useState18(false);
|
|
7103
7064
|
const [error, setError] = useState18(null);
|
|
7104
|
-
const requestSeq =
|
|
7065
|
+
const requestSeq = useRef9(0);
|
|
7105
7066
|
const load = useCallback21(
|
|
7106
7067
|
async (force = false) => {
|
|
7107
7068
|
const seq = requestSeq.current;
|
|
@@ -7161,10 +7122,10 @@ function useAutoRecharge() {
|
|
|
7161
7122
|
},
|
|
7162
7123
|
[_config, key]
|
|
7163
7124
|
);
|
|
7164
|
-
|
|
7125
|
+
useEffect14(() => {
|
|
7165
7126
|
void load();
|
|
7166
7127
|
}, [load]);
|
|
7167
|
-
|
|
7128
|
+
useEffect14(() => {
|
|
7168
7129
|
return subscribeAutoRecharge(key, () => {
|
|
7169
7130
|
const cached = autoRechargeCache.get(key);
|
|
7170
7131
|
if (cached) {
|
|
@@ -7557,7 +7518,7 @@ function flipUnitValue(anchor, targetUnit, currency, creditsPerMinorUnit, displa
|
|
|
7557
7518
|
}
|
|
7558
7519
|
|
|
7559
7520
|
// src/hooks/useCheckoutFlow.ts
|
|
7560
|
-
import { useCallback as useCallback22, useMemo as useMemo17, useRef as
|
|
7521
|
+
import { useCallback as useCallback22, useMemo as useMemo17, useRef as useRef10, useState as useState19 } from "react";
|
|
7561
7522
|
|
|
7562
7523
|
// src/primitives/checkout/shared.ts
|
|
7563
7524
|
import {
|
|
@@ -7568,6 +7529,13 @@ import {
|
|
|
7568
7529
|
planPricingShape,
|
|
7569
7530
|
usageRate
|
|
7570
7531
|
} from "@solvapay/core";
|
|
7532
|
+
|
|
7533
|
+
// src/utils/isPayg.ts
|
|
7534
|
+
function isPaygPlan(plan) {
|
|
7535
|
+
return plan?.type === "usage-based" || plan?.type === "hybrid";
|
|
7536
|
+
}
|
|
7537
|
+
|
|
7538
|
+
// src/primitives/checkout/shared.ts
|
|
7571
7539
|
function isPayg(plan) {
|
|
7572
7540
|
return isPaygPlan(plan ?? null);
|
|
7573
7541
|
}
|
|
@@ -7676,10 +7644,10 @@ function resolveInitialCheckoutStep(initialStep) {
|
|
|
7676
7644
|
}
|
|
7677
7645
|
function useCheckoutFlow(opts) {
|
|
7678
7646
|
const { productRef, initialStep = "plan", initialAmountMinor = null } = opts;
|
|
7679
|
-
const onPlanSelectRef =
|
|
7680
|
-
const onAmountSelectRef =
|
|
7681
|
-
const onPurchaseSuccessRef =
|
|
7682
|
-
const onErrorRef =
|
|
7647
|
+
const onPlanSelectRef = useRef10(opts.onPlanSelect);
|
|
7648
|
+
const onAmountSelectRef = useRef10(opts.onAmountSelect);
|
|
7649
|
+
const onPurchaseSuccessRef = useRef10(opts.onPurchaseSuccess);
|
|
7650
|
+
const onErrorRef = useRef10(opts.onError);
|
|
7683
7651
|
onPlanSelectRef.current = opts.onPlanSelect;
|
|
7684
7652
|
onAmountSelectRef.current = opts.onAmountSelect;
|
|
7685
7653
|
onPurchaseSuccessRef.current = opts.onPurchaseSuccess;
|
|
@@ -7712,7 +7680,7 @@ function useCheckoutFlow(opts) {
|
|
|
7712
7680
|
const [selectedAmountMinor, setSelectedAmountMinor] = useState19(initialAmountMinor);
|
|
7713
7681
|
const [successMeta, setSuccessMeta] = useState19(null);
|
|
7714
7682
|
const [error, setError] = useState19(null);
|
|
7715
|
-
const selectedAmountMinorRef =
|
|
7683
|
+
const selectedAmountMinorRef = useRef10(initialAmountMinor);
|
|
7716
7684
|
const selectedPlan = planCtx.selectedPlan;
|
|
7717
7685
|
const selectedPlanRef = planCtx.selectedPlanRef;
|
|
7718
7686
|
const selectedPlanShape = toBootstrapPlanLike(selectedPlan);
|
|
@@ -8090,7 +8058,6 @@ export {
|
|
|
8090
8058
|
TopupForm,
|
|
8091
8059
|
useTopupForm,
|
|
8092
8060
|
BalanceBadge,
|
|
8093
|
-
isPaygPlan,
|
|
8094
8061
|
resolvePlanPricingOption,
|
|
8095
8062
|
PlanSelectorRoot2 as PlanSelectorRoot,
|
|
8096
8063
|
PlanSelectorHeading2 as PlanSelectorHeading,
|
|
@@ -8133,6 +8100,7 @@ export {
|
|
|
8133
8100
|
Empty,
|
|
8134
8101
|
UsageMeter,
|
|
8135
8102
|
useUsageMeter,
|
|
8103
|
+
isPaygPlan,
|
|
8136
8104
|
isPayg,
|
|
8137
8105
|
planSortByPaygFirstThenAsc,
|
|
8138
8106
|
buildDefaultCheckoutPlanFilter,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a4 as components, b as Plan, P as PaymentFormProps, a as PrefillCustomer, A as ActivationResult, s as UseTopupAmountSelectorReturn, a5 as AutoRechargeInput, u as AutoRechargeConfig, a6 as AutoRechargeDisplayBlock, E as CheckoutStep, O as SuccessMeta } from './useUsage-
|
|
1
|
+
import { a4 as components, b as Plan, P as PaymentFormProps, a as PrefillCustomer, A as ActivationResult, s as UseTopupAmountSelectorReturn, a5 as AutoRechargeInput, u as AutoRechargeConfig, a6 as AutoRechargeDisplayBlock, E as CheckoutStep, O as SuccessMeta } from './useUsage-CRd_E6J3.cjs';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { PaymentElement, CardElement } from '@stripe/react-stripe-js';
|
|
4
4
|
import { TaxBreakdown } from '@solvapay/core';
|
|
@@ -76,6 +76,10 @@ type PaywallGateRecoveryFields = {
|
|
|
76
76
|
shortfallCredits?: number;
|
|
77
77
|
/** How many calls the current allowance or wallet still covers. */
|
|
78
78
|
remainingCalls?: number;
|
|
79
|
+
/** Credits per minor currency unit, from the limits balance peg. */
|
|
80
|
+
creditsPerMinorUnit?: number;
|
|
81
|
+
/** USD → display-currency rate used with `creditsPerMinorUnit`. */
|
|
82
|
+
displayExchangeRate?: number;
|
|
79
83
|
/** Active purchase reference when the customer already holds a purchase. */
|
|
80
84
|
purchaseRef?: string;
|
|
81
85
|
/** Purchase/plan status when the backend sent one. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a4 as components, b as Plan, P as PaymentFormProps, a as PrefillCustomer, A as ActivationResult, s as UseTopupAmountSelectorReturn, a5 as AutoRechargeInput, u as AutoRechargeConfig, a6 as AutoRechargeDisplayBlock, E as CheckoutStep, O as SuccessMeta } from './useUsage-
|
|
1
|
+
import { a4 as components, b as Plan, P as PaymentFormProps, a as PrefillCustomer, A as ActivationResult, s as UseTopupAmountSelectorReturn, a5 as AutoRechargeInput, u as AutoRechargeConfig, a6 as AutoRechargeDisplayBlock, E as CheckoutStep, O as SuccessMeta } from './useUsage-DSPWQ37m.js';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { PaymentElement, CardElement } from '@stripe/react-stripe-js';
|
|
4
4
|
import { TaxBreakdown } from '@solvapay/core';
|
|
@@ -76,6 +76,10 @@ type PaywallGateRecoveryFields = {
|
|
|
76
76
|
shortfallCredits?: number;
|
|
77
77
|
/** How many calls the current allowance or wallet still covers. */
|
|
78
78
|
remainingCalls?: number;
|
|
79
|
+
/** Credits per minor currency unit, from the limits balance peg. */
|
|
80
|
+
creditsPerMinorUnit?: number;
|
|
81
|
+
/** USD → display-currency rate used with `creditsPerMinorUnit`. */
|
|
82
|
+
displayExchangeRate?: number;
|
|
79
83
|
/** Active purchase reference when the customer already holds a purchase. */
|
|
80
84
|
purchaseRef?: string;
|
|
81
85
|
/** Purchase/plan status when the backend sent one. */
|
package/dist/index.cjs
CHANGED
|
@@ -2330,15 +2330,14 @@ function processPlans(raw, filter, sortBy) {
|
|
|
2330
2330
|
if (filter) result = result.filter(filter);
|
|
2331
2331
|
return result;
|
|
2332
2332
|
}
|
|
2333
|
-
function computeInitialIndex(plans, initialPlanRef, autoSelectFirstPaid) {
|
|
2333
|
+
function computeInitialIndex(plans, initialPlanRef, autoSelectFirstPaid, excludePlanRef) {
|
|
2334
2334
|
if (plans.length === 0) return 0;
|
|
2335
2335
|
if (initialPlanRef) {
|
|
2336
2336
|
const idx = plans.findIndex((p) => p.reference === initialPlanRef);
|
|
2337
2337
|
if (idx >= 0) return idx;
|
|
2338
2338
|
}
|
|
2339
2339
|
if (autoSelectFirstPaid) {
|
|
2340
|
-
|
|
2341
|
-
return idx >= 0 ? idx : 0;
|
|
2340
|
+
return plans.findIndex((p) => p.requiresPayment !== false && p.reference !== excludePlanRef);
|
|
2342
2341
|
}
|
|
2343
2342
|
return -1;
|
|
2344
2343
|
}
|
|
@@ -2350,6 +2349,7 @@ function usePlans(options) {
|
|
|
2350
2349
|
sortBy,
|
|
2351
2350
|
autoSelectFirstPaid = false,
|
|
2352
2351
|
initialPlanRef,
|
|
2352
|
+
excludePlanRef,
|
|
2353
2353
|
selectionReady = true
|
|
2354
2354
|
} = options;
|
|
2355
2355
|
const solvaContext = (0, import_react10.useContext)(SolvaPayContext);
|
|
@@ -2363,6 +2363,7 @@ function usePlans(options) {
|
|
|
2363
2363
|
const sortByRef = (0, import_react10.useRef)(sortBy);
|
|
2364
2364
|
const autoSelectFirstPaidRef = (0, import_react10.useRef)(autoSelectFirstPaid);
|
|
2365
2365
|
const initialPlanRefRef = (0, import_react10.useRef)(initialPlanRef);
|
|
2366
|
+
const excludePlanRefRef = (0, import_react10.useRef)(excludePlanRef);
|
|
2366
2367
|
const selectionReadyRef = (0, import_react10.useRef)(selectionReady);
|
|
2367
2368
|
const hasAppliedInitialRef = (0, import_react10.useRef)(false);
|
|
2368
2369
|
const userHasSelectedRef = (0, import_react10.useRef)(false);
|
|
@@ -2374,7 +2375,7 @@ function usePlans(options) {
|
|
|
2374
2375
|
}
|
|
2375
2376
|
const processed = processPlans(cached.plans, filter, sortBy);
|
|
2376
2377
|
if (processed.length === 0) return 0;
|
|
2377
|
-
const idx = computeInitialIndex(processed, initialPlanRef, autoSelectFirstPaid);
|
|
2378
|
+
const idx = computeInitialIndex(processed, initialPlanRef, autoSelectFirstPaid, excludePlanRef);
|
|
2378
2379
|
hasAppliedInitialRef.current = true;
|
|
2379
2380
|
return idx;
|
|
2380
2381
|
});
|
|
@@ -2403,6 +2404,9 @@ function usePlans(options) {
|
|
|
2403
2404
|
(0, import_react10.useEffect)(() => {
|
|
2404
2405
|
initialPlanRefRef.current = initialPlanRef;
|
|
2405
2406
|
}, [initialPlanRef]);
|
|
2407
|
+
(0, import_react10.useEffect)(() => {
|
|
2408
|
+
excludePlanRefRef.current = excludePlanRef;
|
|
2409
|
+
}, [excludePlanRef]);
|
|
2406
2410
|
(0, import_react10.useEffect)(() => {
|
|
2407
2411
|
selectionReadyRef.current = selectionReady;
|
|
2408
2412
|
}, [selectionReady]);
|
|
@@ -2417,7 +2421,8 @@ function usePlans(options) {
|
|
|
2417
2421
|
const idx = computeInitialIndex(
|
|
2418
2422
|
processedPlans,
|
|
2419
2423
|
initialPlanRefRef.current,
|
|
2420
|
-
autoSelectFirstPaidRef.current
|
|
2424
|
+
autoSelectFirstPaidRef.current,
|
|
2425
|
+
excludePlanRefRef.current
|
|
2421
2426
|
);
|
|
2422
2427
|
setSelectedPlanIndexState(idx);
|
|
2423
2428
|
}, []);
|
|
@@ -2434,11 +2439,7 @@ function usePlans(options) {
|
|
|
2434
2439
|
try {
|
|
2435
2440
|
setLoading(true);
|
|
2436
2441
|
const fetchedPlans = await cached.promise;
|
|
2437
|
-
const processedPlans = processPlans(
|
|
2438
|
-
fetchedPlans,
|
|
2439
|
-
filterRef.current,
|
|
2440
|
-
sortByRef.current
|
|
2441
|
-
);
|
|
2442
|
+
const processedPlans = processPlans(fetchedPlans, filterRef.current, sortByRef.current);
|
|
2442
2443
|
setPlans(processedPlans);
|
|
2443
2444
|
setError(null);
|
|
2444
2445
|
applyInitialSelection(processedPlans);
|
|
@@ -2450,11 +2451,7 @@ function usePlans(options) {
|
|
|
2450
2451
|
return;
|
|
2451
2452
|
}
|
|
2452
2453
|
if (!force && cached && cached.plans.length > 0 && now - cached.timestamp < CACHE_DURATION3) {
|
|
2453
|
-
const processedPlans = processPlans(
|
|
2454
|
-
cached.plans,
|
|
2455
|
-
filterRef.current,
|
|
2456
|
-
sortByRef.current
|
|
2457
|
-
);
|
|
2454
|
+
const processedPlans = processPlans(cached.plans, filterRef.current, sortByRef.current);
|
|
2458
2455
|
setPlans(processedPlans);
|
|
2459
2456
|
setLoading(false);
|
|
2460
2457
|
setError(null);
|
|
@@ -2468,11 +2465,7 @@ function usePlans(options) {
|
|
|
2468
2465
|
plansCache.set(productRef, { plans: [], timestamp: now, promise: fetchPromise });
|
|
2469
2466
|
const fetchedPlans = await fetchPromise;
|
|
2470
2467
|
plansCache.set(productRef, { plans: fetchedPlans, timestamp: now, promise: null });
|
|
2471
|
-
const processedPlans = processPlans(
|
|
2472
|
-
fetchedPlans,
|
|
2473
|
-
filterRef.current,
|
|
2474
|
-
sortByRef.current
|
|
2475
|
-
);
|
|
2468
|
+
const processedPlans = processPlans(fetchedPlans, filterRef.current, sortByRef.current);
|
|
2476
2469
|
setPlans(processedPlans);
|
|
2477
2470
|
applyInitialSelection(processedPlans);
|
|
2478
2471
|
} catch (err) {
|
|
@@ -6271,11 +6264,6 @@ var import_react32 = require("react");
|
|
|
6271
6264
|
// src/primitives/PlanSelector.tsx
|
|
6272
6265
|
var import_react30 = require("react");
|
|
6273
6266
|
|
|
6274
|
-
// src/utils/isPayg.ts
|
|
6275
|
-
function isPaygPlan(plan) {
|
|
6276
|
-
return plan?.type === "usage-based" || plan?.type === "hybrid";
|
|
6277
|
-
}
|
|
6278
|
-
|
|
6279
6267
|
// src/utils/planPricing.ts
|
|
6280
6268
|
var import_core7 = require("@solvapay/core");
|
|
6281
6269
|
function getPlanPricingOptions(plan) {
|
|
@@ -6349,19 +6337,20 @@ var Root6 = (0, import_react30.forwardRef)(function PlanSelectorRoot(props, forw
|
|
|
6349
6337
|
() => fetcher ?? ((ref) => defaultListPlans(ref, _config)),
|
|
6350
6338
|
[fetcher, _config]
|
|
6351
6339
|
);
|
|
6340
|
+
const autoCurrentPlanRef = (0, import_react30.useMemo)(() => {
|
|
6341
|
+
const active = purchases.filter((p) => p.status === "active").sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime())[0];
|
|
6342
|
+
return active?.planSnapshot?.reference ?? null;
|
|
6343
|
+
}, [purchases]);
|
|
6344
|
+
const resolvedCurrentPlanRef = currentPlanRef === null ? null : currentPlanRef ?? autoCurrentPlanRef;
|
|
6352
6345
|
const { plans, selectedPlan, selectPlan, setSelectedPlanIndex, loading, error } = usePlans({
|
|
6353
6346
|
productRef,
|
|
6354
6347
|
fetcher: effectiveFetcher,
|
|
6355
6348
|
filter,
|
|
6356
6349
|
sortBy,
|
|
6357
6350
|
autoSelectFirstPaid,
|
|
6358
|
-
initialPlanRef
|
|
6351
|
+
initialPlanRef,
|
|
6352
|
+
excludePlanRef: resolvedCurrentPlanRef
|
|
6359
6353
|
});
|
|
6360
|
-
const autoCurrentPlanRef = (0, import_react30.useMemo)(() => {
|
|
6361
|
-
const active = purchases.filter((p) => p.status === "active").sort((a, b) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime())[0];
|
|
6362
|
-
return active?.planSnapshot?.reference ?? null;
|
|
6363
|
-
}, [purchases]);
|
|
6364
|
-
const resolvedCurrentPlanRef = currentPlanRef === null ? null : currentPlanRef ?? autoCurrentPlanRef;
|
|
6365
6354
|
const isCurrent = (0, import_react30.useCallback)(
|
|
6366
6355
|
(ref) => resolvedCurrentPlanRef === ref,
|
|
6367
6356
|
[resolvedCurrentPlanRef]
|
|
@@ -6370,19 +6359,17 @@ var Root6 = (0, import_react30.forwardRef)(function PlanSelectorRoot(props, forw
|
|
|
6370
6359
|
(ref) => plans.find((p) => p.reference === ref)?.requiresPayment === false,
|
|
6371
6360
|
[plans]
|
|
6372
6361
|
);
|
|
6373
|
-
const isPopular = (0, import_react30.useCallback)(
|
|
6374
|
-
(ref) => popularPlanRef === ref,
|
|
6375
|
-
[popularPlanRef]
|
|
6376
|
-
);
|
|
6362
|
+
const isPopular = (0, import_react30.useCallback)((ref) => popularPlanRef === ref, [popularPlanRef]);
|
|
6377
6363
|
const select = (0, import_react30.useCallback)(
|
|
6378
6364
|
(ref) => {
|
|
6379
6365
|
const plan = plans.find((p) => p.reference === ref);
|
|
6380
6366
|
if (!plan) return;
|
|
6381
6367
|
if (plan.requiresPayment === false) return;
|
|
6368
|
+
if (isCurrent(ref)) return;
|
|
6382
6369
|
selectPlan(ref);
|
|
6383
6370
|
onSelect?.(ref, plan);
|
|
6384
6371
|
},
|
|
6385
|
-
[plans, selectPlan, onSelect]
|
|
6372
|
+
[plans, selectPlan, onSelect, isCurrent]
|
|
6386
6373
|
);
|
|
6387
6374
|
const clearSelection = (0, import_react30.useCallback)(() => {
|
|
6388
6375
|
setSelectedPlanIndex(-1);
|
|
@@ -6405,22 +6392,6 @@ var Root6 = (0, import_react30.forwardRef)(function PlanSelectorRoot(props, forw
|
|
|
6405
6392
|
setSelectedCurrencies((current) => ({ ...current, [planRef]: currency }));
|
|
6406
6393
|
}, []);
|
|
6407
6394
|
const selectedCurrency = selectedPlan ? getSelectedOption(selectedPlan).currency : null;
|
|
6408
|
-
const autoCurrentAppliedKeyRef = (0, import_react30.useRef)(null);
|
|
6409
|
-
(0, import_react30.useEffect)(() => {
|
|
6410
|
-
if (autoCurrentAppliedKeyRef.current === productRef) return;
|
|
6411
|
-
if (selectedPlanRef) {
|
|
6412
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6413
|
-
return;
|
|
6414
|
-
}
|
|
6415
|
-
if (!resolvedCurrentPlanRef || plans.length === 0) return;
|
|
6416
|
-
const currentPlan = plans.find((p) => p.reference === resolvedCurrentPlanRef);
|
|
6417
|
-
if (!currentPlan || !isPaygPlan(currentPlan)) {
|
|
6418
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6419
|
-
return;
|
|
6420
|
-
}
|
|
6421
|
-
autoCurrentAppliedKeyRef.current = productRef;
|
|
6422
|
-
select(resolvedCurrentPlanRef);
|
|
6423
|
-
}, [productRef, plans, resolvedCurrentPlanRef, selectedPlanRef, select]);
|
|
6424
6395
|
const ctx = (0, import_react30.useMemo)(
|
|
6425
6396
|
() => ({
|
|
6426
6397
|
plans,
|
|
@@ -6497,9 +6468,8 @@ var Grid = (0, import_react30.forwardRef)(function PlanSelectorGrid({ children,
|
|
|
6497
6468
|
const isFree = ctx.isFree(plan.reference);
|
|
6498
6469
|
const isPopular = ctx.isPopular(plan.reference);
|
|
6499
6470
|
const selected = ctx.selectedPlanRef === plan.reference;
|
|
6500
|
-
const
|
|
6501
|
-
const
|
|
6502
|
-
const state = isCurrent && !isPaygCurrent ? "current" : selected ? "selected" : isCurrent ? "current" : isFree ? "disabled" : "idle";
|
|
6471
|
+
const disabled = isFree || isCurrent;
|
|
6472
|
+
const state = isCurrent ? "current" : selected ? "selected" : isFree ? "disabled" : "idle";
|
|
6503
6473
|
const pricingOptions = getPlanPricingOptions(plan);
|
|
6504
6474
|
const selectedOption = ctx.getSelectedOption(plan);
|
|
6505
6475
|
const cardCtx = {
|
|
@@ -8703,6 +8673,13 @@ var UsageMeter = Object.assign(Root10, {
|
|
|
8703
8673
|
|
|
8704
8674
|
// src/primitives/checkout/shared.ts
|
|
8705
8675
|
var import_core10 = require("@solvapay/core");
|
|
8676
|
+
|
|
8677
|
+
// src/utils/isPayg.ts
|
|
8678
|
+
function isPaygPlan(plan) {
|
|
8679
|
+
return plan?.type === "usage-based" || plan?.type === "hybrid";
|
|
8680
|
+
}
|
|
8681
|
+
|
|
8682
|
+
// src/primitives/checkout/shared.ts
|
|
8706
8683
|
function isPayg(plan) {
|
|
8707
8684
|
return isPaygPlan(plan ?? null);
|
|
8708
8685
|
}
|