@solvapay/react 1.3.0 → 1.4.0-preview-ecd61384a4e849717e13d47ab2daa086cdcd91c5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/adapters/auth.js +1 -0
- package/dist/adapters/auth0.js +1 -0
- package/dist/adapters/session-auth.js +1 -0
- package/dist/{chunk-DW5FJUUG.js → chunk-6RR4J74H.js} +214 -24
- package/dist/chunk-GFWMLRR3.js +3224 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/{chunk-4ISNB3JU.js → chunk-SUHDOG7Q.js} +1 -1
- package/dist/{index-BwwdMBdt.d.ts → index-CDvQcobx.d.cts} +21 -2
- package/dist/{index-kXLvp7EU.d.cts → index-w_VMlKm5.d.ts} +21 -2
- package/dist/index.cjs +2216 -363
- package/dist/index.d.cts +34 -5
- package/dist/index.d.ts +34 -5
- package/dist/index.js +66 -3
- package/dist/mcp/index.cjs +216 -29
- package/dist/mcp/index.d.cts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +3 -2
- package/dist/primitives/index.cjs +2101 -362
- package/dist/primitives/index.d.cts +180 -5
- package/dist/primitives/index.d.ts +180 -5
- package/dist/primitives/index.js +73 -2
- package/dist/{shared-lIhc8DS3.d.ts → shared-D8raw1Nv.d.ts} +143 -12
- package/dist/{shared-BNZAIWkU.d.cts → shared-LcjvX4fD.d.cts} +143 -12
- package/dist/styles.css +513 -0
- package/dist/webapi-K5XBCEO6.js +3775 -0
- package/package.json +5 -5
- package/dist/chunk-K7ZUJI26.js +0 -1527
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ActivationFlow: () => ActivationFlow2,
|
|
34
34
|
AmountPicker: () => AmountPicker2,
|
|
35
|
+
AutoRecharge: () => AutoRecharge2,
|
|
35
36
|
BalanceBadge: () => BalanceBadge,
|
|
36
37
|
CancelPlanButton: () => CancelPlanButton,
|
|
37
38
|
CancelledPlanNotice: () => CancelledPlanNotice2,
|
|
@@ -58,6 +59,7 @@ __export(index_exports, {
|
|
|
58
59
|
TopupForm: () => TopupForm2,
|
|
59
60
|
UnsupportedTransportMethodError: () => UnsupportedTransportMethodError,
|
|
60
61
|
UpdatePaymentMethodButton: () => UpdatePaymentMethodButton,
|
|
62
|
+
configToAutoRechargeInput: () => configToAutoRechargeInput,
|
|
61
63
|
confirmPayment: () => confirmPayment,
|
|
62
64
|
createAnonymousAuthAdapter: () => createAnonymousAuthAdapter,
|
|
63
65
|
createHttpTransport: () => createHttpTransport,
|
|
@@ -83,6 +85,7 @@ __export(index_exports, {
|
|
|
83
85
|
toMajorUnits: () => toMajorUnits,
|
|
84
86
|
useActivation: () => useActivation,
|
|
85
87
|
useAutoActivateFreePlan: () => useAutoActivateFreePlan,
|
|
88
|
+
useAutoRecharge: () => useAutoRecharge,
|
|
86
89
|
useBalance: () => useBalance,
|
|
87
90
|
useCheckout: () => useCheckout,
|
|
88
91
|
useCheckoutFlow: () => useCheckoutFlow,
|
|
@@ -112,6 +115,29 @@ module.exports = __toCommonJS(index_exports);
|
|
|
112
115
|
// src/SolvaPayProvider.tsx
|
|
113
116
|
var import_react2 = require("react");
|
|
114
117
|
|
|
118
|
+
// ../server/src/index.ts
|
|
119
|
+
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
120
|
+
var import_core = require("@solvapay/core");
|
|
121
|
+
|
|
122
|
+
// ../server/src/helpers/balance-poll.ts
|
|
123
|
+
var BALANCE_RECONCILE_DELAYS_MS = [500, 1e3, 2e3, 4e3, 8e3, 16e3];
|
|
124
|
+
async function pollBalanceUntilIncreased(getBalance, baseline, delays = BALANCE_RECONCILE_DELAYS_MS) {
|
|
125
|
+
for (const delay of delays) {
|
|
126
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
127
|
+
try {
|
|
128
|
+
const post = await getBalance();
|
|
129
|
+
if (post.credits > baseline) {
|
|
130
|
+
return { creditsAdded: post.credits - baseline };
|
|
131
|
+
}
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/helpers/auto-recharge-cache.ts
|
|
139
|
+
var BALANCE_RECONCILE_GRACE_MS = BALANCE_RECONCILE_DELAYS_MS.reduce((sum, delay) => sum + delay, 0) + 1e3;
|
|
140
|
+
|
|
115
141
|
// src/utils/purchases.ts
|
|
116
142
|
function filterPurchases(purchases) {
|
|
117
143
|
return purchases.filter((purchase) => purchase.status === "active");
|
|
@@ -308,6 +334,7 @@ var DEFAULT_ROUTES = {
|
|
|
308
334
|
getProduct: "/api/get-product",
|
|
309
335
|
listPlans: "/api/list-plans",
|
|
310
336
|
getPaymentMethod: "/api/payment-method",
|
|
337
|
+
autoRecharge: "/api/auto-recharge",
|
|
311
338
|
getUsage: "/api/usage",
|
|
312
339
|
getLimits: "/api/limits"
|
|
313
340
|
};
|
|
@@ -345,7 +372,11 @@ function createHttpTransport(config) {
|
|
|
345
372
|
}),
|
|
346
373
|
createTopupPayment: (params) => request(config, routeFor(config, "createTopupPayment"), {
|
|
347
374
|
method: "POST",
|
|
348
|
-
body: {
|
|
375
|
+
body: {
|
|
376
|
+
amount: params.amount,
|
|
377
|
+
currency: params.currency,
|
|
378
|
+
...params.autoRecharge ? { autoRecharge: params.autoRecharge } : {}
|
|
379
|
+
},
|
|
349
380
|
onErrorContext: "createTopupPayment",
|
|
350
381
|
errorPrefix: "Failed to create topup payment"
|
|
351
382
|
}),
|
|
@@ -394,16 +425,12 @@ function createHttpTransport(config) {
|
|
|
394
425
|
}
|
|
395
426
|
);
|
|
396
427
|
},
|
|
397
|
-
createCustomerSession: () => request(
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
onErrorContext: "createCustomerSession",
|
|
404
|
-
errorPrefix: "Failed to create customer session"
|
|
405
|
-
}
|
|
406
|
-
),
|
|
428
|
+
createCustomerSession: () => request(config, routeFor(config, "createCustomerSession"), {
|
|
429
|
+
method: "POST",
|
|
430
|
+
body: {},
|
|
431
|
+
onErrorContext: "createCustomerSession",
|
|
432
|
+
errorPrefix: "Failed to create customer session"
|
|
433
|
+
}),
|
|
407
434
|
getMerchant: () => request(config, routeFor(config, "getMerchant"), {
|
|
408
435
|
method: "GET",
|
|
409
436
|
onErrorContext: "getMerchant",
|
|
@@ -433,6 +460,22 @@ function createHttpTransport(config) {
|
|
|
433
460
|
onErrorContext: "getPaymentMethod",
|
|
434
461
|
errorPrefix: "Failed to load payment method"
|
|
435
462
|
}),
|
|
463
|
+
getAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
|
|
464
|
+
method: "GET",
|
|
465
|
+
onErrorContext: "getAutoRecharge",
|
|
466
|
+
errorPrefix: "Failed to load auto-recharge"
|
|
467
|
+
}),
|
|
468
|
+
saveAutoRecharge: (input) => request(config, routeFor(config, "autoRecharge"), {
|
|
469
|
+
method: "PUT",
|
|
470
|
+
body: input,
|
|
471
|
+
onErrorContext: "saveAutoRecharge",
|
|
472
|
+
errorPrefix: "Failed to save auto-recharge"
|
|
473
|
+
}),
|
|
474
|
+
disableAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
|
|
475
|
+
method: "DELETE",
|
|
476
|
+
onErrorContext: "disableAutoRecharge",
|
|
477
|
+
errorPrefix: "Failed to disable auto-recharge"
|
|
478
|
+
}),
|
|
436
479
|
getUsage: () => request(config, routeFor(config, "getUsage"), {
|
|
437
480
|
method: "GET",
|
|
438
481
|
onErrorContext: "getUsage",
|
|
@@ -571,6 +614,42 @@ var enCopy = {
|
|
|
571
614
|
creditEstimateExact: "= {credits} credits",
|
|
572
615
|
creditEstimateApprox: "~ {credits} credits"
|
|
573
616
|
},
|
|
617
|
+
autoRecharge: {
|
|
618
|
+
heading: "Auto recharge",
|
|
619
|
+
description: "Automatically top up so you never run out \u2014 recommended for production. You can turn this off anytime.",
|
|
620
|
+
settingsHeading: "Auto recharge settings",
|
|
621
|
+
setupTriggerLabel: "Set up auto-recharge",
|
|
622
|
+
modifyTriggerLabel: "Modify",
|
|
623
|
+
notConfiguredHint: "Automatic top-ups are off. Set up auto-recharge if you want credits added when your balance runs low.",
|
|
624
|
+
enableLabel: "Enable auto-recharge",
|
|
625
|
+
enableQuestion: "Would you like to set up automatic recharge?",
|
|
626
|
+
enableSentence: "Yes, automatically recharge my card when my credit balance falls below a threshold",
|
|
627
|
+
thresholdLabel: "When balance falls below",
|
|
628
|
+
thresholdAriaLabel: "Balance threshold",
|
|
629
|
+
fixedAmountLabel: "Add this amount",
|
|
630
|
+
fixedAmountAriaLabel: "Fixed top-up amount",
|
|
631
|
+
saveButton: "Save settings",
|
|
632
|
+
cancelButton: "Cancel",
|
|
633
|
+
disableButton: "Disable automatic top-up",
|
|
634
|
+
savedMessage: "Automatic top-up settings saved.",
|
|
635
|
+
disabledMessage: "Automatic top-ups disabled.",
|
|
636
|
+
setupRequiredMessage: "Confirm your card to activate automatic top-ups.",
|
|
637
|
+
setupHeading: "Authorize card",
|
|
638
|
+
setupDescription: "Authorize a card for automatic top-ups. You will not be charged now.",
|
|
639
|
+
setupSubmit: "Save card for auto-recharge",
|
|
640
|
+
setupProcessing: "Authorizing...",
|
|
641
|
+
setupAwaitingConfirmation: "Card authorized. Finishing activation \u2014 this can take a moment.",
|
|
642
|
+
setupAuthFailed: "Card authentication failed. Please try a different card.",
|
|
643
|
+
invalidThreshold: "Enter a valid balance threshold.",
|
|
644
|
+
thresholdTooLow: "Balance threshold must be greater than zero.",
|
|
645
|
+
minTopupAmount: "Top-up amount must be at least {amount}.",
|
|
646
|
+
topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount}).",
|
|
647
|
+
creditsPerRecharge: "\u2248 {credits} credits per recharge",
|
|
648
|
+
creditsPerRechargeApprox: "~ {credits} credits per recharge",
|
|
649
|
+
currencyPerRecharge: "\u2248 {amount} per recharge",
|
|
650
|
+
currencyPerRechargeApprox: "~ {amount} per recharge",
|
|
651
|
+
statusFailed: "Payment failed \u2014 update your card to resume"
|
|
652
|
+
},
|
|
574
653
|
activationFlow: {
|
|
575
654
|
heading: "Confirm your plan",
|
|
576
655
|
activateButton: "Activate",
|
|
@@ -798,12 +877,18 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
798
877
|
const [displayExchangeRateValue, setDisplayExchangeRateValue] = (0, import_react2.useState)(
|
|
799
878
|
initial?.balance?.displayExchangeRate ?? null
|
|
800
879
|
);
|
|
880
|
+
const [displayBlockValue, setDisplayBlockValue] = (0, import_react2.useState)(
|
|
881
|
+
initial?.balance?.display ?? null
|
|
882
|
+
);
|
|
801
883
|
const [balanceLoading, setBalanceLoading] = (0, import_react2.useState)(false);
|
|
802
884
|
const balanceInFlightRef = (0, import_react2.useRef)(false);
|
|
803
885
|
const balanceLoadedRef = (0, import_react2.useRef)(!!initial?.balance);
|
|
886
|
+
const creditsValueRef = (0, import_react2.useRef)(initial?.balance?.credits ?? null);
|
|
804
887
|
const optimisticUntilRef = (0, import_react2.useRef)(0);
|
|
805
888
|
const optimisticTimerRef = (0, import_react2.useRef)(null);
|
|
806
889
|
const fetchBalanceRef = (0, import_react2.useRef)(null);
|
|
890
|
+
const reconcileRunningRef = (0, import_react2.useRef)(false);
|
|
891
|
+
const reconcilePollRef = (0, import_react2.useRef)(null);
|
|
807
892
|
const inFlightRef = (0, import_react2.useRef)(null);
|
|
808
893
|
const loadedCacheKeysRef = (0, import_react2.useRef)(
|
|
809
894
|
new Set(initial?.customerRef ? [initial.customerRef] : [])
|
|
@@ -821,10 +906,12 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
821
906
|
const fetchBalanceImpl = (0, import_react2.useCallback)(async () => {
|
|
822
907
|
if (optimisticUntilRef.current > Date.now()) return;
|
|
823
908
|
if (!isAuthenticated && !internalCustomerRef) {
|
|
909
|
+
creditsValueRef.current = null;
|
|
824
910
|
setCreditsValue(null);
|
|
825
911
|
setDisplayCurrencyValue(null);
|
|
826
912
|
setCreditsPerMinorUnitValue(null);
|
|
827
913
|
setDisplayExchangeRateValue(null);
|
|
914
|
+
setDisplayBlockValue(null);
|
|
828
915
|
setBalanceLoading(false);
|
|
829
916
|
balanceLoadedRef.current = false;
|
|
830
917
|
return;
|
|
@@ -841,10 +928,12 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
841
928
|
return;
|
|
842
929
|
}
|
|
843
930
|
const data = await transportRef.current.getBalance();
|
|
931
|
+
creditsValueRef.current = data.credits ?? null;
|
|
844
932
|
setCreditsValue(data.credits ?? null);
|
|
845
933
|
setDisplayCurrencyValue(data.displayCurrency ?? null);
|
|
846
934
|
setCreditsPerMinorUnitValue(data.creditsPerMinorUnit ?? null);
|
|
847
935
|
setDisplayExchangeRateValue(data.displayExchangeRate ?? null);
|
|
936
|
+
setDisplayBlockValue(data.display ?? null);
|
|
848
937
|
balanceLoadedRef.current = true;
|
|
849
938
|
} catch (error) {
|
|
850
939
|
console.error("[SolvaPayProvider] Failed to fetch balance:", error);
|
|
@@ -859,18 +948,112 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
859
948
|
(0, import_react2.useEffect)(() => {
|
|
860
949
|
return () => {
|
|
861
950
|
if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
|
|
951
|
+
reconcilePollRef.current = null;
|
|
952
|
+
reconcileRunningRef.current = false;
|
|
862
953
|
};
|
|
863
954
|
}, []);
|
|
864
955
|
const OPTIMISTIC_GRACE_MS2 = 8e3;
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
optimisticUntilRef.current =
|
|
956
|
+
const DEBIT_GRACE_MS = 2e3;
|
|
957
|
+
const clearOptimisticGrace = (0, import_react2.useCallback)(() => {
|
|
958
|
+
optimisticUntilRef.current = 0;
|
|
959
|
+
if (optimisticTimerRef.current) {
|
|
960
|
+
clearTimeout(optimisticTimerRef.current);
|
|
961
|
+
optimisticTimerRef.current = null;
|
|
962
|
+
}
|
|
963
|
+
}, []);
|
|
964
|
+
const applyBalanceSnapshot = (0, import_react2.useCallback)(
|
|
965
|
+
(data) => {
|
|
966
|
+
creditsValueRef.current = data.credits ?? null;
|
|
967
|
+
setCreditsValue(data.credits ?? null);
|
|
968
|
+
setDisplayCurrencyValue(data.displayCurrency ?? null);
|
|
969
|
+
setCreditsPerMinorUnitValue(data.creditsPerMinorUnit ?? null);
|
|
970
|
+
setDisplayExchangeRateValue(data.displayExchangeRate ?? null);
|
|
971
|
+
setDisplayBlockValue(data.display ?? null);
|
|
972
|
+
balanceLoadedRef.current = true;
|
|
973
|
+
},
|
|
974
|
+
[]
|
|
975
|
+
);
|
|
976
|
+
const reconcileBalanceIncreaseImpl = (0, import_react2.useCallback)(async () => {
|
|
977
|
+
if (!transportRef.current.getBalance) return;
|
|
978
|
+
const finishReconcilePoll = () => {
|
|
979
|
+
reconcilePollRef.current = null;
|
|
980
|
+
clearOptimisticGrace();
|
|
981
|
+
};
|
|
982
|
+
reconcileRunningRef.current = true;
|
|
983
|
+
try {
|
|
984
|
+
while (reconcilePollRef.current) {
|
|
985
|
+
const { baseline: activeBaseline, generation: activeGeneration } = reconcilePollRef.current;
|
|
986
|
+
const pollResult = await pollBalanceUntilIncreased(
|
|
987
|
+
async () => {
|
|
988
|
+
const data = await transportRef.current.getBalance();
|
|
989
|
+
return { credits: data.credits ?? 0 };
|
|
990
|
+
},
|
|
991
|
+
activeBaseline,
|
|
992
|
+
BALANCE_RECONCILE_DELAYS_MS
|
|
993
|
+
);
|
|
994
|
+
const pollState = reconcilePollRef.current;
|
|
995
|
+
if (!pollState || pollState.generation !== activeGeneration) {
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
if (!pollResult) {
|
|
999
|
+
finishReconcilePoll();
|
|
1000
|
+
break;
|
|
1001
|
+
}
|
|
1002
|
+
try {
|
|
1003
|
+
const data = await transportRef.current.getBalance();
|
|
1004
|
+
applyBalanceSnapshot(data);
|
|
1005
|
+
pollState.pending -= 1;
|
|
1006
|
+
if (pollState.pending > 0) {
|
|
1007
|
+
pollState.baseline = data.credits ?? 0;
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
} catch (error) {
|
|
1011
|
+
console.error("[SolvaPayProvider] Failed to reconcile balance after auto-recharge:", error);
|
|
1012
|
+
}
|
|
1013
|
+
finishReconcilePoll();
|
|
1014
|
+
break;
|
|
1015
|
+
}
|
|
1016
|
+
} finally {
|
|
1017
|
+
reconcileRunningRef.current = false;
|
|
1018
|
+
}
|
|
1019
|
+
}, [applyBalanceSnapshot, clearOptimisticGrace]);
|
|
1020
|
+
const scheduleGraceRefetch = (0, import_react2.useCallback)((graceMs) => {
|
|
1021
|
+
optimisticUntilRef.current = Date.now() + graceMs;
|
|
868
1022
|
if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
|
|
869
1023
|
optimisticTimerRef.current = setTimeout(() => {
|
|
870
1024
|
optimisticUntilRef.current = 0;
|
|
871
1025
|
fetchBalanceRef.current?.();
|
|
872
|
-
},
|
|
1026
|
+
}, graceMs);
|
|
873
1027
|
}, []);
|
|
1028
|
+
const adjustBalanceImpl = (0, import_react2.useCallback)(
|
|
1029
|
+
(credits) => {
|
|
1030
|
+
const nextCredits = (creditsValueRef.current ?? 0) + credits;
|
|
1031
|
+
creditsValueRef.current = nextCredits;
|
|
1032
|
+
setCreditsValue(nextCredits);
|
|
1033
|
+
if (credits >= 0) {
|
|
1034
|
+
scheduleGraceRefetch(OPTIMISTIC_GRACE_MS2);
|
|
1035
|
+
} else {
|
|
1036
|
+
scheduleGraceRefetch(DEBIT_GRACE_MS);
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
[scheduleGraceRefetch]
|
|
1040
|
+
);
|
|
1041
|
+
const reconcileAfterUsageDebitImpl = (0, import_react2.useCallback)(
|
|
1042
|
+
(opts) => {
|
|
1043
|
+
if (opts?.expectIncrease !== true) {
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
const nextCredits = creditsValueRef.current ?? 0;
|
|
1047
|
+
const generation = (reconcilePollRef.current?.generation ?? 0) + 1;
|
|
1048
|
+
const pending = (reconcilePollRef.current?.pending ?? 0) + 1;
|
|
1049
|
+
reconcilePollRef.current = { baseline: nextCredits, generation, pending };
|
|
1050
|
+
scheduleGraceRefetch(BALANCE_RECONCILE_GRACE_MS);
|
|
1051
|
+
if (!reconcileRunningRef.current) {
|
|
1052
|
+
void reconcileBalanceIncreaseImpl();
|
|
1053
|
+
}
|
|
1054
|
+
},
|
|
1055
|
+
[reconcileBalanceIncreaseImpl, scheduleGraceRefetch]
|
|
1056
|
+
);
|
|
874
1057
|
const createPayment = (0, import_react2.useCallback)(
|
|
875
1058
|
(params) => transportRef.current.createPayment(params),
|
|
876
1059
|
[]
|
|
@@ -1042,6 +1225,7 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
1042
1225
|
setDisplayCurrencyValue(next.balance?.displayCurrency ?? null);
|
|
1043
1226
|
setCreditsPerMinorUnitValue(next.balance?.creditsPerMinorUnit ?? null);
|
|
1044
1227
|
setDisplayExchangeRateValue(next.balance?.displayExchangeRate ?? null);
|
|
1228
|
+
setDisplayBlockValue(next.balance?.display ?? null);
|
|
1045
1229
|
balanceLoadedRef.current = !!next.balance;
|
|
1046
1230
|
}, []);
|
|
1047
1231
|
(0, import_react2.useEffect)(() => {
|
|
@@ -1146,8 +1330,10 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
1146
1330
|
displayCurrency: displayCurrencyValue,
|
|
1147
1331
|
creditsPerMinorUnit: creditsPerMinorUnitValue,
|
|
1148
1332
|
displayExchangeRate: displayExchangeRateValue,
|
|
1333
|
+
display: displayBlockValue,
|
|
1149
1334
|
refetch: fetchBalanceImpl,
|
|
1150
|
-
adjustBalance: adjustBalanceImpl
|
|
1335
|
+
adjustBalance: adjustBalanceImpl,
|
|
1336
|
+
reconcileAfterUsageDebit: reconcileAfterUsageDebitImpl
|
|
1151
1337
|
}),
|
|
1152
1338
|
[
|
|
1153
1339
|
balanceLoading,
|
|
@@ -1155,8 +1341,10 @@ var SolvaPayProvider = ({ config, children }) => {
|
|
|
1155
1341
|
displayCurrencyValue,
|
|
1156
1342
|
creditsPerMinorUnitValue,
|
|
1157
1343
|
displayExchangeRateValue,
|
|
1344
|
+
displayBlockValue,
|
|
1158
1345
|
fetchBalanceImpl,
|
|
1159
|
-
adjustBalanceImpl
|
|
1346
|
+
adjustBalanceImpl,
|
|
1347
|
+
reconcileAfterUsageDebitImpl
|
|
1160
1348
|
]
|
|
1161
1349
|
);
|
|
1162
1350
|
const contextValue = (0, import_react2.useMemo)(
|
|
@@ -1401,7 +1589,7 @@ function withPaymentElementDefaults(options) {
|
|
|
1401
1589
|
|
|
1402
1590
|
// src/utils/errors.ts
|
|
1403
1591
|
var DOCS_BASE_URL = "https://solvapay.com/docs";
|
|
1404
|
-
var
|
|
1592
|
+
var SolvaPayError2 = class extends Error {
|
|
1405
1593
|
code;
|
|
1406
1594
|
docsUrl;
|
|
1407
1595
|
constructor(code, message, docsUrl) {
|
|
@@ -1411,7 +1599,7 @@ var SolvaPayError = class extends Error {
|
|
|
1411
1599
|
this.docsUrl = docsUrl;
|
|
1412
1600
|
}
|
|
1413
1601
|
};
|
|
1414
|
-
var MissingProviderError = class extends
|
|
1602
|
+
var MissingProviderError = class extends SolvaPayError2 {
|
|
1415
1603
|
constructor(primitiveName) {
|
|
1416
1604
|
const docsUrl = `${DOCS_BASE_URL}/troubleshooting/missing-provider`;
|
|
1417
1605
|
super(
|
|
@@ -1422,7 +1610,7 @@ var MissingProviderError = class extends SolvaPayError {
|
|
|
1422
1610
|
this.name = "MissingProviderError";
|
|
1423
1611
|
}
|
|
1424
1612
|
};
|
|
1425
|
-
var MissingProductRefError = class extends
|
|
1613
|
+
var MissingProductRefError = class extends SolvaPayError2 {
|
|
1426
1614
|
constructor(primitiveName) {
|
|
1427
1615
|
const docsUrl = `${DOCS_BASE_URL}/primitives/product-ref`;
|
|
1428
1616
|
super(
|
|
@@ -3674,7 +3862,7 @@ function getStripeCacheKey2(publishableKey, accountId) {
|
|
|
3674
3862
|
return accountId ? `${publishableKey}:${accountId}` : publishableKey;
|
|
3675
3863
|
}
|
|
3676
3864
|
function useTopup(options) {
|
|
3677
|
-
const { amount, currency } = options;
|
|
3865
|
+
const { amount, currency, autoRecharge } = options;
|
|
3678
3866
|
const { createTopupPayment, customerRef, updateCustomerRef } = useSolvaPay();
|
|
3679
3867
|
const [loading, setLoading] = (0, import_react20.useState)(false);
|
|
3680
3868
|
const [error, setError] = (0, import_react20.useState)(null);
|
|
@@ -3693,7 +3881,7 @@ function useTopup(options) {
|
|
|
3693
3881
|
setLoading(true);
|
|
3694
3882
|
setError(null);
|
|
3695
3883
|
try {
|
|
3696
|
-
const result = await createTopupPayment({ amount, currency });
|
|
3884
|
+
const result = await createTopupPayment({ amount, currency, autoRecharge });
|
|
3697
3885
|
if (!result || typeof result !== "object") {
|
|
3698
3886
|
throw new Error("Invalid topup payment intent response from server");
|
|
3699
3887
|
}
|
|
@@ -3725,7 +3913,7 @@ function useTopup(options) {
|
|
|
3725
3913
|
setLoading(false);
|
|
3726
3914
|
isStartingRef.current = false;
|
|
3727
3915
|
}
|
|
3728
|
-
}, [amount, currency, createTopupPayment, customerRef, updateCustomerRef, loading]);
|
|
3916
|
+
}, [amount, currency, autoRecharge, createTopupPayment, customerRef, updateCustomerRef, loading]);
|
|
3729
3917
|
const reset = (0, import_react20.useCallback)(() => {
|
|
3730
3918
|
isStartingRef.current = false;
|
|
3731
3919
|
setLoading(false);
|
|
@@ -3757,6 +3945,7 @@ var Root4 = (0, import_react21.forwardRef)(function TopupFormRoot(props, forward
|
|
|
3757
3945
|
const {
|
|
3758
3946
|
amount,
|
|
3759
3947
|
currency,
|
|
3948
|
+
autoRecharge,
|
|
3760
3949
|
onSuccess,
|
|
3761
3950
|
onError,
|
|
3762
3951
|
returnUrl,
|
|
@@ -3780,7 +3969,8 @@ var Root4 = (0, import_react21.forwardRef)(function TopupFormRoot(props, forward
|
|
|
3780
3969
|
stripePromise
|
|
3781
3970
|
} = useTopup({
|
|
3782
3971
|
amount,
|
|
3783
|
-
currency
|
|
3972
|
+
currency,
|
|
3973
|
+
autoRecharge
|
|
3784
3974
|
});
|
|
3785
3975
|
const hasInitializedRef = (0, import_react21.useRef)(false);
|
|
3786
3976
|
const hasAmount = amount > 0;
|
|
@@ -4343,7 +4533,7 @@ var StripePaymentFormWrapper = ({
|
|
|
4343
4533
|
|
|
4344
4534
|
// src/primitives/BalanceBadge.tsx
|
|
4345
4535
|
var import_react25 = require("react");
|
|
4346
|
-
var
|
|
4536
|
+
var import_core2 = require("@solvapay/core");
|
|
4347
4537
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4348
4538
|
var BalanceBadge = (0, import_react25.forwardRef)(function BalanceBadge2({ asChild, numberOnly, lowThreshold = 10, children, ...rest }, forwardedRef) {
|
|
4349
4539
|
const solva = (0, import_react25.useContext)(SolvaPayContext);
|
|
@@ -4372,14 +4562,14 @@ var BalanceBadge = (0, import_react25.forwardRef)(function BalanceBadge2({ asChi
|
|
|
4372
4562
|
const formattedCredits = new Intl.NumberFormat(locale).format(credits);
|
|
4373
4563
|
let currencyEquivalent = "";
|
|
4374
4564
|
if (!numberOnly && displayCurrency && creditsPerMinorUnit) {
|
|
4375
|
-
const displayMinor = (0,
|
|
4565
|
+
const displayMinor = (0, import_core2.creditsToDisplayMinorUnits)({
|
|
4376
4566
|
credits,
|
|
4377
4567
|
creditsPerMinorUnit,
|
|
4378
4568
|
displayExchangeRate: displayExchangeRate ?? 1,
|
|
4379
4569
|
displayCurrency
|
|
4380
4570
|
});
|
|
4381
4571
|
if (displayMinor !== null) {
|
|
4382
|
-
const minorPerMajor = (0,
|
|
4572
|
+
const minorPerMajor = (0, import_core2.minorUnitsPerMajor)(displayCurrency);
|
|
4383
4573
|
const formatted = new Intl.NumberFormat(locale, {
|
|
4384
4574
|
style: "currency",
|
|
4385
4575
|
currency: displayCurrency,
|
|
@@ -6816,177 +7006,1837 @@ var CurrentPlanCard = ({
|
|
|
6816
7006
|
);
|
|
6817
7007
|
};
|
|
6818
7008
|
|
|
6819
|
-
// src/
|
|
7009
|
+
// src/primitives/AutoRecharge.tsx
|
|
7010
|
+
var import_react42 = require("react");
|
|
7011
|
+
var import_react_dom = require("react-dom");
|
|
7012
|
+
var import_react_stripe_js4 = require("@stripe/react-stripe-js");
|
|
7013
|
+
var import_stripe_js3 = require("@stripe/stripe-js");
|
|
7014
|
+
|
|
7015
|
+
// src/hooks/useAutoRecharge.ts
|
|
6820
7016
|
var import_react41 = require("react");
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
var
|
|
6824
|
-
|
|
6825
|
-
|
|
7017
|
+
|
|
7018
|
+
// src/hooks/autoRechargeCache.ts
|
|
7019
|
+
var autoRechargeCache = /* @__PURE__ */ new Map();
|
|
7020
|
+
var CACHE_DURATION6 = 5 * 60 * 1e3;
|
|
7021
|
+
function autoRechargeCacheKeyFor(config) {
|
|
7022
|
+
return createTransportCacheKey(config, config?.api?.autoRecharge || "/api/auto-recharge");
|
|
6826
7023
|
}
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
const
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
7024
|
+
|
|
7025
|
+
// src/hooks/useAutoRecharge.ts
|
|
7026
|
+
function mergeAutoRechargeConfig(config, display) {
|
|
7027
|
+
return display ? { ...config, display } : config;
|
|
7028
|
+
}
|
|
7029
|
+
async function fetchAutoRecharge(config) {
|
|
7030
|
+
const transport = config?.transport ?? createHttpTransport(config);
|
|
7031
|
+
if (!transport.getAutoRecharge) return null;
|
|
7032
|
+
const response = await transport.getAutoRecharge();
|
|
7033
|
+
if (!response.config) return null;
|
|
7034
|
+
return mergeAutoRechargeConfig(response.config, response.display);
|
|
7035
|
+
}
|
|
7036
|
+
function useAutoRecharge() {
|
|
7037
|
+
const { _config } = useSolvaPay();
|
|
7038
|
+
const key = autoRechargeCacheKeyFor(_config);
|
|
7039
|
+
const [config, setConfig] = (0, import_react41.useState)(
|
|
7040
|
+
() => autoRechargeCache.get(key)?.config ?? null
|
|
7041
|
+
);
|
|
6840
7042
|
const [loading, setLoading] = (0, import_react41.useState)(() => {
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
if (!cached) return true;
|
|
6844
|
-
if (cached.promise) return true;
|
|
6845
|
-
if (Date.now() - cached.timestamp >= CACHE_TTL_MS) return true;
|
|
6846
|
-
return false;
|
|
7043
|
+
const cached = autoRechargeCache.get(key);
|
|
7044
|
+
return !cached || !cached.config && !cached.promise;
|
|
6847
7045
|
});
|
|
7046
|
+
const [saving, setSaving] = (0, import_react41.useState)(false);
|
|
7047
|
+
const [disabling, setDisabling] = (0, import_react41.useState)(false);
|
|
6848
7048
|
const [error, setError] = (0, import_react41.useState)(null);
|
|
6849
|
-
const
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
7049
|
+
const requestSeq = (0, import_react41.useRef)(0);
|
|
7050
|
+
const load = (0, import_react41.useCallback)(
|
|
7051
|
+
async (force = false) => {
|
|
7052
|
+
const seq = requestSeq.current;
|
|
7053
|
+
const cached = autoRechargeCache.get(key);
|
|
7054
|
+
const now = Date.now();
|
|
7055
|
+
if (!force && cached?.config && now - cached.timestamp < CACHE_DURATION6) {
|
|
7056
|
+
if (seq !== requestSeq.current) return;
|
|
7057
|
+
setConfig(cached.config);
|
|
7058
|
+
setLoading(false);
|
|
7059
|
+
setError(null);
|
|
7060
|
+
return;
|
|
7061
|
+
}
|
|
7062
|
+
if (!force && cached?.promise) {
|
|
7063
|
+
setLoading(true);
|
|
7064
|
+
try {
|
|
7065
|
+
const value = await cached.promise;
|
|
7066
|
+
if (seq !== requestSeq.current) return;
|
|
7067
|
+
setConfig(value);
|
|
7068
|
+
setError(null);
|
|
7069
|
+
} catch (caught) {
|
|
7070
|
+
if (seq !== requestSeq.current) return;
|
|
7071
|
+
setError(caught instanceof Error ? caught : new Error(String(caught)));
|
|
7072
|
+
} finally {
|
|
7073
|
+
if (seq === requestSeq.current) {
|
|
7074
|
+
setLoading(false);
|
|
7075
|
+
}
|
|
7076
|
+
}
|
|
7077
|
+
return;
|
|
7078
|
+
}
|
|
6862
7079
|
setLoading(true);
|
|
7080
|
+
setError(null);
|
|
7081
|
+
const promise = fetchAutoRecharge(_config);
|
|
7082
|
+
autoRechargeCache.set(key, {
|
|
7083
|
+
config: cached?.config ?? null,
|
|
7084
|
+
promise,
|
|
7085
|
+
timestamp: now
|
|
7086
|
+
});
|
|
6863
7087
|
try {
|
|
6864
|
-
const
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
} catch (
|
|
6869
|
-
|
|
6870
|
-
|
|
7088
|
+
const value = await promise;
|
|
7089
|
+
if (seq !== requestSeq.current) return;
|
|
7090
|
+
autoRechargeCache.set(key, { config: value, promise: null, timestamp: Date.now() });
|
|
7091
|
+
setConfig(value);
|
|
7092
|
+
} catch (caught) {
|
|
7093
|
+
if (seq !== requestSeq.current) return;
|
|
7094
|
+
const err = caught instanceof Error ? caught : new Error(String(caught));
|
|
7095
|
+
autoRechargeCache.set(key, { config: null, promise: null, timestamp: Date.now() });
|
|
7096
|
+
setError(err);
|
|
6871
7097
|
} finally {
|
|
6872
|
-
|
|
7098
|
+
if (seq === requestSeq.current) {
|
|
7099
|
+
setLoading(false);
|
|
7100
|
+
}
|
|
6873
7101
|
}
|
|
6874
7102
|
},
|
|
6875
|
-
[]
|
|
7103
|
+
[_config, key]
|
|
6876
7104
|
);
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
setData(cached.data);
|
|
6892
|
-
setLoading(false);
|
|
6893
|
-
setError(null);
|
|
6894
|
-
return;
|
|
7105
|
+
(0, import_react41.useEffect)(() => {
|
|
7106
|
+
void load();
|
|
7107
|
+
}, [load]);
|
|
7108
|
+
const refresh = (0, import_react41.useCallback)(
|
|
7109
|
+
async (force = true) => {
|
|
7110
|
+
await load(force);
|
|
7111
|
+
},
|
|
7112
|
+
[load]
|
|
7113
|
+
);
|
|
7114
|
+
const save = (0, import_react41.useCallback)(
|
|
7115
|
+
async (input) => {
|
|
7116
|
+
const transport = _config?.transport ?? createHttpTransport(_config);
|
|
7117
|
+
if (!transport.saveAutoRecharge) {
|
|
7118
|
+
throw new Error("saveAutoRecharge is not available on this transport");
|
|
6895
7119
|
}
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
const
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
7120
|
+
setSaving(true);
|
|
7121
|
+
setError(null);
|
|
7122
|
+
const seq = ++requestSeq.current;
|
|
7123
|
+
try {
|
|
7124
|
+
const result = await transport.saveAutoRecharge(input);
|
|
7125
|
+
if (seq !== requestSeq.current) return result;
|
|
7126
|
+
const nextConfig = mergeAutoRechargeConfig(result.config, result.display);
|
|
7127
|
+
autoRechargeCache.set(key, {
|
|
7128
|
+
config: nextConfig,
|
|
7129
|
+
promise: null,
|
|
7130
|
+
timestamp: Date.now()
|
|
7131
|
+
});
|
|
7132
|
+
setConfig(nextConfig);
|
|
7133
|
+
return result;
|
|
7134
|
+
} catch (caught) {
|
|
7135
|
+
const err = caught instanceof Error ? caught : new Error(String(caught));
|
|
7136
|
+
setError(err);
|
|
7137
|
+
throw err;
|
|
7138
|
+
} finally {
|
|
7139
|
+
setSaving(false);
|
|
6903
7140
|
}
|
|
6904
7141
|
},
|
|
6905
|
-
[
|
|
7142
|
+
[_config, key]
|
|
6906
7143
|
);
|
|
6907
|
-
(0, import_react41.
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
(0, import_react41.useEffect)(() => {
|
|
6912
|
-
if (prevPurchasesRef.current !== null && prevPurchasesRef.current !== purchase.purchases) {
|
|
6913
|
-
fetchLimits(true).catch(() => {
|
|
6914
|
-
});
|
|
7144
|
+
const disable = (0, import_react41.useCallback)(async () => {
|
|
7145
|
+
const transport = _config?.transport ?? createHttpTransport(_config);
|
|
7146
|
+
if (!transport.disableAutoRecharge) {
|
|
7147
|
+
throw new Error("disableAutoRecharge is not available on this transport");
|
|
6915
7148
|
}
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6921
|
-
if (
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
// Don't optimistically flip `withinLimits` — paywall gating
|
|
6931
|
-
// can hinge on factors beyond `remaining > 0`
|
|
6932
|
-
// (activationRequired, etc.). Let the trailing refetch
|
|
6933
|
-
// confirm.
|
|
6934
|
-
};
|
|
6935
|
-
limitsCache.set(key, {
|
|
6936
|
-
data: next,
|
|
6937
|
-
timestamp: Date.now(),
|
|
6938
|
-
promise: cached?.promise ?? null
|
|
7149
|
+
setDisabling(true);
|
|
7150
|
+
setError(null);
|
|
7151
|
+
const seq = ++requestSeq.current;
|
|
7152
|
+
try {
|
|
7153
|
+
const result = await transport.disableAutoRecharge();
|
|
7154
|
+
if (seq === requestSeq.current) {
|
|
7155
|
+
setConfig((current) => {
|
|
7156
|
+
const disabledConfig = current ? { ...current, enabled: false } : null;
|
|
7157
|
+
autoRechargeCache.set(key, {
|
|
7158
|
+
config: disabledConfig,
|
|
7159
|
+
promise: null,
|
|
7160
|
+
timestamp: Date.now()
|
|
7161
|
+
});
|
|
7162
|
+
return disabledConfig;
|
|
6939
7163
|
});
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
7164
|
+
await refresh(true);
|
|
7165
|
+
setConfig((current) => {
|
|
7166
|
+
const disabledConfig = current ? { ...current, enabled: false } : null;
|
|
7167
|
+
autoRechargeCache.set(key, {
|
|
7168
|
+
config: disabledConfig,
|
|
7169
|
+
promise: null,
|
|
7170
|
+
timestamp: Date.now()
|
|
7171
|
+
});
|
|
7172
|
+
return disabledConfig;
|
|
6946
7173
|
});
|
|
6947
|
-
}
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
refetch,
|
|
6959
|
-
adjustRemaining
|
|
6960
|
-
};
|
|
7174
|
+
}
|
|
7175
|
+
return result;
|
|
7176
|
+
} catch (caught) {
|
|
7177
|
+
const err = caught instanceof Error ? caught : new Error(String(caught));
|
|
7178
|
+
setError(err);
|
|
7179
|
+
throw err;
|
|
7180
|
+
} finally {
|
|
7181
|
+
setDisabling(false);
|
|
7182
|
+
}
|
|
7183
|
+
}, [_config, key, refresh]);
|
|
7184
|
+
return { config, loading, saving, disabling, error, refresh, save, disable };
|
|
6961
7185
|
}
|
|
6962
7186
|
|
|
6963
|
-
// src/
|
|
6964
|
-
var
|
|
6965
|
-
function
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
7187
|
+
// src/primitives/autoRechargeActivation.ts
|
|
7188
|
+
var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7189
|
+
async function waitForAutoRechargeActivation({
|
|
7190
|
+
refresh,
|
|
7191
|
+
getStatus,
|
|
7192
|
+
attempts = 5,
|
|
7193
|
+
delayMs = 800,
|
|
7194
|
+
sleep = defaultSleep
|
|
7195
|
+
}) {
|
|
7196
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
7197
|
+
await refresh(true);
|
|
7198
|
+
if (getStatus() === "active") return true;
|
|
7199
|
+
if (attempt < attempts - 1) await sleep(delayMs);
|
|
7200
|
+
}
|
|
7201
|
+
return getStatus() === "active";
|
|
7202
|
+
}
|
|
7203
|
+
|
|
7204
|
+
// src/primitives/setupIntentReturn.ts
|
|
7205
|
+
var SETUP_INTENT_PARAMS = ["setup_intent", "setup_intent_client_secret", "redirect_status"];
|
|
7206
|
+
function readSetupIntentClientSecret(search) {
|
|
7207
|
+
return new URLSearchParams(search).get("setup_intent_client_secret");
|
|
7208
|
+
}
|
|
7209
|
+
function stripSetupIntentParams() {
|
|
7210
|
+
if (typeof window === "undefined") return;
|
|
7211
|
+
const url = new URL(window.location.href);
|
|
7212
|
+
let changed = false;
|
|
7213
|
+
for (const param of SETUP_INTENT_PARAMS) {
|
|
7214
|
+
if (url.searchParams.has(param)) {
|
|
7215
|
+
url.searchParams.delete(param);
|
|
7216
|
+
changed = true;
|
|
7217
|
+
}
|
|
7218
|
+
}
|
|
7219
|
+
if (!changed) return;
|
|
7220
|
+
const query = url.searchParams.toString();
|
|
7221
|
+
window.history.replaceState({}, "", `${url.pathname}${query ? `?${query}` : ""}${url.hash}`);
|
|
7222
|
+
}
|
|
7223
|
+
|
|
7224
|
+
// src/utils/credit-estimation.ts
|
|
7225
|
+
var import_core3 = require("@solvapay/core");
|
|
7226
|
+
function estimateCredits(resolvedAmountMajor, currency, creditsPerMinorUnit, displayExchangeRate) {
|
|
7227
|
+
if (resolvedAmountMajor == null || resolvedAmountMajor <= 0) return null;
|
|
7228
|
+
if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
|
|
7229
|
+
const rate = displayExchangeRate ?? 1;
|
|
7230
|
+
const resolvedAmountMinor = Math.round(resolvedAmountMajor * getMinorUnitsPerMajor(currency));
|
|
7231
|
+
return Math.round(resolvedAmountMinor / rate * creditsPerMinorUnit);
|
|
7232
|
+
}
|
|
7233
|
+
function estimateCurrencyMajorFromCredits(credits, currency, creditsPerMinorUnit, displayExchangeRate) {
|
|
7234
|
+
if (credits == null || credits <= 0) return null;
|
|
7235
|
+
if (creditsPerMinorUnit == null || creditsPerMinorUnit <= 0) return null;
|
|
7236
|
+
const rate = displayExchangeRate ?? 1;
|
|
7237
|
+
const displayMinor = (0, import_core3.creditsToDisplayMinorUnits)({
|
|
7238
|
+
credits,
|
|
7239
|
+
creditsPerMinorUnit,
|
|
7240
|
+
displayExchangeRate: rate,
|
|
7241
|
+
displayCurrency: currency
|
|
6971
7242
|
});
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
7243
|
+
if (displayMinor === null) return null;
|
|
7244
|
+
return displayMinor / getMinorUnitsPerMajor(currency);
|
|
7245
|
+
}
|
|
7246
|
+
|
|
7247
|
+
// src/helpers/stripe-minimums.ts
|
|
7248
|
+
var STRIPE_MINIMUM_MINOR = {
|
|
7249
|
+
USD: 50,
|
|
7250
|
+
EUR: 50,
|
|
7251
|
+
GBP: 30,
|
|
7252
|
+
SEK: 300,
|
|
7253
|
+
NOK: 300,
|
|
7254
|
+
DKK: 250,
|
|
7255
|
+
CHF: 50,
|
|
7256
|
+
CAD: 50,
|
|
7257
|
+
AUD: 50,
|
|
7258
|
+
JPY: 50,
|
|
7259
|
+
KRW: 500
|
|
7260
|
+
};
|
|
7261
|
+
var DEFAULT_MINIMUM_MINOR = 50;
|
|
7262
|
+
function getStripeMinimumMinor(currency) {
|
|
7263
|
+
return STRIPE_MINIMUM_MINOR[currency.toUpperCase()] ?? DEFAULT_MINIMUM_MINOR;
|
|
7264
|
+
}
|
|
7265
|
+
|
|
7266
|
+
// src/helpers/auto-recharge-form.ts
|
|
7267
|
+
var DEFAULT_VALIDATION_MESSAGES = {
|
|
7268
|
+
invalidThreshold: "Enter a valid balance threshold.",
|
|
7269
|
+
thresholdTooLow: "Balance threshold must be greater than zero.",
|
|
7270
|
+
minTopupAmount: "Top-up amount must be at least {amount}.",
|
|
7271
|
+
topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount})."
|
|
7272
|
+
};
|
|
7273
|
+
function amountAnchors(thresholdValue, topupValue, unit = "currency") {
|
|
7274
|
+
return {
|
|
7275
|
+
thresholdBaseValue: thresholdValue,
|
|
7276
|
+
thresholdBaseUnit: unit,
|
|
7277
|
+
topupBaseValue: topupValue,
|
|
7278
|
+
topupBaseUnit: unit
|
|
7279
|
+
};
|
|
7280
|
+
}
|
|
7281
|
+
function createDefaultAutoRechargeForm(currency, defaultTopupMajor, defaultThresholdMajor) {
|
|
7282
|
+
const topup = defaultTopupMajor != null && defaultTopupMajor > 0 ? String(defaultTopupMajor) : "10";
|
|
7283
|
+
const threshold = defaultThresholdMajor != null && defaultThresholdMajor >= 0 ? String(defaultThresholdMajor) : "5";
|
|
7284
|
+
return {
|
|
7285
|
+
enabled: false,
|
|
7286
|
+
thresholdAmountMajor: threshold,
|
|
7287
|
+
thresholdUnit: "currency",
|
|
7288
|
+
topupAmountMajor: topup,
|
|
7289
|
+
topupUnit: "currency",
|
|
7290
|
+
...amountAnchors(threshold, topup, "currency")
|
|
7291
|
+
};
|
|
7292
|
+
}
|
|
7293
|
+
function parsePositiveNumber(value) {
|
|
7294
|
+
const trimmed = value.trim();
|
|
7295
|
+
if (trimmed.length === 0) return null;
|
|
7296
|
+
const parsed = Number(trimmed);
|
|
7297
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
7298
|
+
return parsed;
|
|
7299
|
+
}
|
|
7300
|
+
function parseNonNegativeNumber(value) {
|
|
7301
|
+
const trimmed = value.trim();
|
|
7302
|
+
if (trimmed.length === 0) return null;
|
|
7303
|
+
const parsed = Number(trimmed);
|
|
7304
|
+
if (!Number.isFinite(parsed) || parsed < 0) return null;
|
|
7305
|
+
return parsed;
|
|
7306
|
+
}
|
|
7307
|
+
function validateAutoRechargeForm(form, currency, conversion, messages = DEFAULT_VALIDATION_MESSAGES) {
|
|
7308
|
+
if (!form.enabled) {
|
|
7309
|
+
return {
|
|
7310
|
+
ok: true,
|
|
7311
|
+
payload: {
|
|
7312
|
+
enabled: false,
|
|
7313
|
+
triggerType: "balance",
|
|
7314
|
+
currency: currency.toUpperCase()
|
|
7315
|
+
}
|
|
7316
|
+
};
|
|
7317
|
+
}
|
|
7318
|
+
const payload = {
|
|
7319
|
+
enabled: true,
|
|
7320
|
+
triggerType: "balance",
|
|
7321
|
+
currency: currency.toUpperCase()
|
|
7322
|
+
};
|
|
7323
|
+
const minorPerMajor = getMinorUnitsPerMajor(currency);
|
|
7324
|
+
const minMinor = getStripeMinimumMinor(currency);
|
|
7325
|
+
const thresholdRaw = parseNonNegativeNumber(form.thresholdAmountMajor);
|
|
7326
|
+
if (thresholdRaw == null) {
|
|
7327
|
+
return { ok: false, error: messages.invalidThreshold };
|
|
7328
|
+
}
|
|
7329
|
+
if (form.thresholdUnit === "credits") {
|
|
7330
|
+
const major = estimateCurrencyMajorFromCredits(
|
|
7331
|
+
thresholdRaw,
|
|
7332
|
+
currency,
|
|
7333
|
+
conversion?.creditsPerMinorUnit,
|
|
7334
|
+
conversion?.displayExchangeRate
|
|
7335
|
+
);
|
|
7336
|
+
if (major == null) {
|
|
7337
|
+
return { ok: false, error: messages.invalidThreshold };
|
|
7338
|
+
}
|
|
7339
|
+
payload.thresholdAmountMajor = major;
|
|
7340
|
+
} else {
|
|
7341
|
+
payload.thresholdAmountMajor = thresholdRaw;
|
|
7342
|
+
}
|
|
7343
|
+
if (payload.thresholdAmountMajor == null || payload.thresholdAmountMajor <= 0) {
|
|
7344
|
+
return { ok: false, error: messages.thresholdTooLow };
|
|
7345
|
+
}
|
|
7346
|
+
const amountRaw = parsePositiveNumber(form.topupAmountMajor);
|
|
7347
|
+
if (amountRaw == null) {
|
|
7348
|
+
return {
|
|
7349
|
+
ok: false,
|
|
7350
|
+
error: interpolate(messages.minTopupAmount, {
|
|
7351
|
+
amount: formatPrice(minMinor, currency, { free: "" })
|
|
7352
|
+
})
|
|
7353
|
+
};
|
|
7354
|
+
}
|
|
7355
|
+
const amountMajor = form.topupUnit === "credits" ? estimateCurrencyMajorFromCredits(
|
|
7356
|
+
amountRaw,
|
|
7357
|
+
currency,
|
|
7358
|
+
conversion?.creditsPerMinorUnit,
|
|
7359
|
+
conversion?.displayExchangeRate
|
|
7360
|
+
) : amountRaw;
|
|
7361
|
+
if (amountMajor == null || Math.round(amountMajor * minorPerMajor) < minMinor) {
|
|
7362
|
+
return {
|
|
7363
|
+
ok: false,
|
|
7364
|
+
error: interpolate(messages.minTopupAmount, {
|
|
7365
|
+
amount: formatPrice(minMinor, currency, { free: "" })
|
|
7366
|
+
})
|
|
7367
|
+
};
|
|
7368
|
+
}
|
|
7369
|
+
payload.topupAmountMajor = amountMajor;
|
|
7370
|
+
if (amountMajor < payload.thresholdAmountMajor) {
|
|
7371
|
+
return {
|
|
7372
|
+
ok: false,
|
|
7373
|
+
error: interpolate(messages.topupBelowThreshold, {
|
|
7374
|
+
amount: formatPrice(
|
|
7375
|
+
Math.round(payload.thresholdAmountMajor * minorPerMajor),
|
|
7376
|
+
currency,
|
|
7377
|
+
{ free: "" }
|
|
7378
|
+
)
|
|
7379
|
+
})
|
|
7380
|
+
};
|
|
7381
|
+
}
|
|
7382
|
+
return { ok: true, payload };
|
|
7383
|
+
}
|
|
7384
|
+
function triggerAmountMajorFromConfig(config) {
|
|
7385
|
+
const topupCurrency = config.topup.currency.toUpperCase();
|
|
7386
|
+
const minorPerMajor = getMinorUnitsPerMajor(topupCurrency);
|
|
7387
|
+
const { thresholdAmountMinor } = config.trigger;
|
|
7388
|
+
if (!Number.isFinite(thresholdAmountMinor) || thresholdAmountMinor < 0) {
|
|
7389
|
+
return null;
|
|
7390
|
+
}
|
|
7391
|
+
return thresholdAmountMinor / minorPerMajor;
|
|
7392
|
+
}
|
|
7393
|
+
function configToAutoRechargeInput(config, options) {
|
|
7394
|
+
if (!config.enabled) return null;
|
|
7395
|
+
const display = options?.display ?? config.display;
|
|
7396
|
+
const currency = (display?.currency ?? config.topup.currency ?? options?.currency ?? "USD").toUpperCase();
|
|
7397
|
+
if (display?.thresholdAmountMajor != null && display.topupAmountMajor != null) {
|
|
7398
|
+
return {
|
|
7399
|
+
enabled: true,
|
|
7400
|
+
triggerType: "balance",
|
|
7401
|
+
thresholdAmountMajor: display.thresholdAmountMajor,
|
|
7402
|
+
topupAmountMajor: display.topupAmountMajor,
|
|
7403
|
+
currency
|
|
7404
|
+
};
|
|
7405
|
+
}
|
|
7406
|
+
const thresholdMajor = triggerAmountMajorFromConfig(config);
|
|
7407
|
+
const topupAmountMajor = config.topup.amountMinor / getMinorUnitsPerMajor(currency);
|
|
7408
|
+
if (thresholdMajor == null || !Number.isFinite(topupAmountMajor) || topupAmountMajor <= 0) {
|
|
7409
|
+
return null;
|
|
7410
|
+
}
|
|
7411
|
+
return {
|
|
7412
|
+
enabled: true,
|
|
7413
|
+
triggerType: "balance",
|
|
7414
|
+
thresholdAmountMajor: Math.max(0, thresholdMajor),
|
|
7415
|
+
topupAmountMajor,
|
|
7416
|
+
currency
|
|
7417
|
+
};
|
|
7418
|
+
}
|
|
7419
|
+
function configToForm(config, currency) {
|
|
7420
|
+
const base = createDefaultAutoRechargeForm(currency);
|
|
7421
|
+
const display = config.display;
|
|
7422
|
+
if (display?.thresholdAmountMajor != null && display.topupAmountMajor != null) {
|
|
7423
|
+
const thresholdStr2 = String(Math.max(0, display.thresholdAmountMajor));
|
|
7424
|
+
const topupStr2 = String(display.topupAmountMajor);
|
|
7425
|
+
return {
|
|
7426
|
+
...base,
|
|
7427
|
+
enabled: config.enabled,
|
|
7428
|
+
thresholdAmountMajor: thresholdStr2,
|
|
7429
|
+
topupAmountMajor: topupStr2,
|
|
7430
|
+
...amountAnchors(thresholdStr2, topupStr2, "currency")
|
|
7431
|
+
};
|
|
7432
|
+
}
|
|
7433
|
+
const thresholdMajor = triggerAmountMajorFromConfig(config);
|
|
7434
|
+
const thresholdStr = thresholdMajor != null ? String(Math.max(0, thresholdMajor)) : "0";
|
|
7435
|
+
const topupStr = String(config.topup.amountMinor / getMinorUnitsPerMajor(currency));
|
|
7436
|
+
return {
|
|
7437
|
+
...base,
|
|
7438
|
+
enabled: config.enabled,
|
|
7439
|
+
thresholdAmountMajor: thresholdStr,
|
|
7440
|
+
topupAmountMajor: topupStr,
|
|
7441
|
+
...amountAnchors(thresholdStr, topupStr, "currency")
|
|
7442
|
+
};
|
|
7443
|
+
}
|
|
7444
|
+
function formatAmountWithUnit(value, unit, currency) {
|
|
7445
|
+
const num = Number(value);
|
|
7446
|
+
if (!value || !Number.isFinite(num)) return "\u2014";
|
|
7447
|
+
if (unit === "credits") {
|
|
7448
|
+
return `${new Intl.NumberFormat().format(num)} credits`;
|
|
7449
|
+
}
|
|
7450
|
+
return formatPrice(Math.round(num * getMinorUnitsPerMajor(currency)), currency, { free: "" });
|
|
7451
|
+
}
|
|
7452
|
+
function buildSummaryLine(form, currency) {
|
|
7453
|
+
if (!form.enabled) return null;
|
|
7454
|
+
const thresholdDisplay = formatAmountWithUnit(
|
|
7455
|
+
form.thresholdAmountMajor,
|
|
7456
|
+
form.thresholdUnit,
|
|
7457
|
+
currency
|
|
7458
|
+
);
|
|
7459
|
+
const fixedDisplay = formatAmountWithUnit(form.topupAmountMajor, form.topupUnit, currency);
|
|
7460
|
+
return `When my balance falls below ${thresholdDisplay}, add ${fixedDisplay}.`;
|
|
7461
|
+
}
|
|
7462
|
+
function convertAmountForUnitFlip(value, fromUnit, toUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
|
|
7463
|
+
if (fromUnit === toUnit) return value;
|
|
7464
|
+
const parsed = Number(value);
|
|
7465
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return value;
|
|
7466
|
+
if (fromUnit === "currency" && toUnit === "credits") {
|
|
7467
|
+
const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
|
|
7468
|
+
return credits != null ? String(credits) : value;
|
|
7469
|
+
}
|
|
7470
|
+
const major = estimateCurrencyMajorFromCredits(
|
|
7471
|
+
parsed,
|
|
7472
|
+
currency,
|
|
7473
|
+
creditsPerMinorUnit,
|
|
7474
|
+
displayExchangeRate
|
|
7475
|
+
);
|
|
7476
|
+
return major != null ? String(major) : value;
|
|
7477
|
+
}
|
|
7478
|
+
function flipUnitValue(anchor, targetUnit, currency, creditsPerMinorUnit, displayExchangeRate) {
|
|
7479
|
+
if (targetUnit === anchor.unit) {
|
|
7480
|
+
return { value: anchor.value, unit: anchor.unit };
|
|
7481
|
+
}
|
|
7482
|
+
const converted = convertAmountForUnitFlip(
|
|
7483
|
+
anchor.value,
|
|
7484
|
+
anchor.unit,
|
|
7485
|
+
targetUnit,
|
|
7486
|
+
currency,
|
|
7487
|
+
creditsPerMinorUnit,
|
|
7488
|
+
displayExchangeRate
|
|
7489
|
+
);
|
|
7490
|
+
return { value: converted, unit: targetUnit };
|
|
7491
|
+
}
|
|
7492
|
+
|
|
7493
|
+
// src/primitives/AutoRecharge.tsx
|
|
7494
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
7495
|
+
var AutoRechargeContext = (0, import_react42.createContext)(null);
|
|
7496
|
+
function useAutoRechargeCtx(part) {
|
|
7497
|
+
const ctx = (0, import_react42.useContext)(AutoRechargeContext);
|
|
7498
|
+
if (!ctx) {
|
|
7499
|
+
throw new Error(`AutoRecharge.${part} must be rendered inside <AutoRecharge.Root>.`);
|
|
7500
|
+
}
|
|
7501
|
+
return ctx;
|
|
7502
|
+
}
|
|
7503
|
+
function getCurrencySymbol2(currency) {
|
|
7504
|
+
try {
|
|
7505
|
+
const parts = new Intl.NumberFormat("en", { style: "currency", currency }).formatToParts(0);
|
|
7506
|
+
const sym = parts.find((p) => p.type === "currency");
|
|
7507
|
+
return sym?.value ?? currency.toUpperCase();
|
|
7508
|
+
} catch {
|
|
7509
|
+
return currency.toUpperCase();
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
var stripePromiseCache3 = /* @__PURE__ */ new Map();
|
|
7513
|
+
function getStripeCacheKey3(publishableKey, accountId) {
|
|
7514
|
+
return accountId ? `${publishableKey}:${accountId}` : publishableKey;
|
|
7515
|
+
}
|
|
7516
|
+
var Root11 = (0, import_react42.forwardRef)(function AutoRechargeRoot({
|
|
7517
|
+
currency = "USD",
|
|
7518
|
+
defaultThresholdAmountMajor,
|
|
7519
|
+
defaultTopupAmountMajor,
|
|
7520
|
+
open: openProp,
|
|
7521
|
+
defaultOpen = false,
|
|
7522
|
+
onOpenChange,
|
|
7523
|
+
onSetupRequired,
|
|
7524
|
+
onSaved,
|
|
7525
|
+
onDisabled,
|
|
7526
|
+
deferCardSetup = false,
|
|
7527
|
+
onPendingConfig,
|
|
7528
|
+
asChild,
|
|
7529
|
+
children,
|
|
7530
|
+
className,
|
|
7531
|
+
...rest
|
|
7532
|
+
}, forwardedRef) {
|
|
7533
|
+
const solva = (0, import_react42.useContext)(SolvaPayContext);
|
|
7534
|
+
if (!solva) throw new MissingProviderError("AutoRecharge");
|
|
7535
|
+
const autoRecharge = useAutoRecharge();
|
|
7536
|
+
const { creditsPerMinorUnit, displayExchangeRate } = useBalance();
|
|
7537
|
+
const copy = useCopy();
|
|
7538
|
+
const titleId = (0, import_react42.useId)();
|
|
7539
|
+
const triggerRef = (0, import_react42.useRef)(null);
|
|
7540
|
+
const defaultTopup = defaultTopupAmountMajor ?? defaultThresholdAmountMajor ?? void 0;
|
|
7541
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react42.useState)(defaultOpen);
|
|
7542
|
+
const isControlled = openProp !== void 0;
|
|
7543
|
+
const open = isControlled ? openProp : uncontrolledOpen;
|
|
7544
|
+
const setOpen = (0, import_react42.useCallback)(
|
|
7545
|
+
(next) => {
|
|
7546
|
+
if (!isControlled) {
|
|
7547
|
+
setUncontrolledOpen(next);
|
|
7548
|
+
}
|
|
7549
|
+
onOpenChange?.(next);
|
|
7550
|
+
},
|
|
7551
|
+
[isControlled, onOpenChange]
|
|
7552
|
+
);
|
|
7553
|
+
const registerTriggerRef = (0, import_react42.useCallback)((node) => {
|
|
7554
|
+
triggerRef.current = node;
|
|
7555
|
+
}, []);
|
|
7556
|
+
const focusTrigger = (0, import_react42.useCallback)(() => {
|
|
7557
|
+
triggerRef.current?.focus();
|
|
7558
|
+
}, []);
|
|
7559
|
+
const [form, setForm] = (0, import_react42.useState)(
|
|
7560
|
+
() => autoRecharge.config ? configToForm(autoRecharge.config, currency) : createDefaultAutoRechargeForm(currency, defaultTopup)
|
|
7561
|
+
);
|
|
7562
|
+
const [validationError, setValidationError] = (0, import_react42.useState)(null);
|
|
7563
|
+
const [statusMessage, setStatusMessage] = (0, import_react42.useState)(null);
|
|
7564
|
+
const [setup, setSetup] = (0, import_react42.useState)(null);
|
|
7565
|
+
const latestConfigRef = (0, import_react42.useRef)(autoRecharge.config);
|
|
7566
|
+
(0, import_react42.useEffect)(() => {
|
|
7567
|
+
latestConfigRef.current = autoRecharge.config;
|
|
7568
|
+
}, [autoRecharge.config]);
|
|
7569
|
+
(0, import_react42.useEffect)(() => {
|
|
7570
|
+
if (autoRecharge.config) {
|
|
7571
|
+
setForm(configToForm(autoRecharge.config, currency));
|
|
7572
|
+
}
|
|
7573
|
+
}, [autoRecharge.config, currency]);
|
|
7574
|
+
const canToggleUnits = creditsPerMinorUnit != null && creditsPerMinorUnit > 0;
|
|
7575
|
+
const rate = displayExchangeRate ?? 1;
|
|
7576
|
+
const isApproximate = rate !== 1;
|
|
7577
|
+
const emitValidation = (0, import_react42.useCallback)(
|
|
7578
|
+
(next) => {
|
|
7579
|
+
const result = validateAutoRechargeForm(
|
|
7580
|
+
next,
|
|
7581
|
+
currency,
|
|
7582
|
+
{ creditsPerMinorUnit, displayExchangeRate },
|
|
7583
|
+
copy.autoRecharge
|
|
7584
|
+
);
|
|
7585
|
+
if (!result.ok) {
|
|
7586
|
+
setValidationError(result.error);
|
|
7587
|
+
return null;
|
|
7588
|
+
}
|
|
7589
|
+
setValidationError(null);
|
|
7590
|
+
return result.payload;
|
|
7591
|
+
},
|
|
7592
|
+
[currency, creditsPerMinorUnit, displayExchangeRate, copy.autoRecharge]
|
|
7593
|
+
);
|
|
7594
|
+
const updateForm = (0, import_react42.useCallback)(
|
|
7595
|
+
(patch) => {
|
|
7596
|
+
setForm((prev) => {
|
|
7597
|
+
const next = { ...prev, ...patch };
|
|
7598
|
+
emitValidation(next);
|
|
7599
|
+
return next;
|
|
7600
|
+
});
|
|
7601
|
+
},
|
|
7602
|
+
[emitValidation]
|
|
7603
|
+
);
|
|
7604
|
+
const resetForm = (0, import_react42.useCallback)(() => {
|
|
7605
|
+
if (autoRecharge.config) {
|
|
7606
|
+
setForm(configToForm(autoRecharge.config, currency));
|
|
7607
|
+
} else {
|
|
7608
|
+
setForm(createDefaultAutoRechargeForm(currency, defaultTopup));
|
|
7609
|
+
}
|
|
7610
|
+
setValidationError(null);
|
|
7611
|
+
}, [autoRecharge.config, currency, defaultTopup]);
|
|
7612
|
+
const flipUnit = (0, import_react42.useCallback)(
|
|
7613
|
+
(valueKey, unitKey, baseValueKey, baseUnitKey, currentUnit) => {
|
|
7614
|
+
const nextUnit = currentUnit === "currency" ? "credits" : "currency";
|
|
7615
|
+
setForm((prev) => {
|
|
7616
|
+
const anchor = { value: prev[baseValueKey], unit: prev[baseUnitKey] };
|
|
7617
|
+
const flipped = flipUnitValue(
|
|
7618
|
+
anchor,
|
|
7619
|
+
nextUnit,
|
|
7620
|
+
currency,
|
|
7621
|
+
creditsPerMinorUnit,
|
|
7622
|
+
displayExchangeRate
|
|
7623
|
+
);
|
|
7624
|
+
const next = {
|
|
7625
|
+
...prev,
|
|
7626
|
+
[unitKey]: flipped.unit,
|
|
7627
|
+
[valueKey]: flipped.value
|
|
7628
|
+
};
|
|
7629
|
+
emitValidation(next);
|
|
7630
|
+
return next;
|
|
7631
|
+
});
|
|
7632
|
+
},
|
|
7633
|
+
[currency, creditsPerMinorUnit, displayExchangeRate, emitValidation]
|
|
7634
|
+
);
|
|
7635
|
+
const fixedTopupHint = (0, import_react42.useMemo)(() => {
|
|
7636
|
+
const parsed = Number(form.topupAmountMajor);
|
|
7637
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
7638
|
+
if (form.topupUnit === "currency") {
|
|
7639
|
+
const credits = estimateCredits(parsed, currency, creditsPerMinorUnit, displayExchangeRate);
|
|
7640
|
+
if (credits == null) return null;
|
|
7641
|
+
return { credits, approximate: isApproximate };
|
|
7642
|
+
}
|
|
7643
|
+
const major = estimateCurrencyMajorFromCredits(
|
|
7644
|
+
parsed,
|
|
7645
|
+
currency,
|
|
7646
|
+
creditsPerMinorUnit,
|
|
7647
|
+
displayExchangeRate
|
|
7648
|
+
);
|
|
7649
|
+
if (major == null) return null;
|
|
7650
|
+
return { major, approximate: isApproximate };
|
|
7651
|
+
}, [
|
|
7652
|
+
form.topupAmountMajor,
|
|
7653
|
+
form.topupUnit,
|
|
7654
|
+
currency,
|
|
7655
|
+
creditsPerMinorUnit,
|
|
7656
|
+
displayExchangeRate,
|
|
7657
|
+
isApproximate
|
|
7658
|
+
]);
|
|
7659
|
+
const summaryLine = (0, import_react42.useMemo)(() => buildSummaryLine(form, currency), [form, currency]);
|
|
7660
|
+
const savedSummaryLine = (0, import_react42.useMemo)(() => {
|
|
7661
|
+
if (!autoRecharge.config?.enabled) return null;
|
|
7662
|
+
return buildSummaryLine(
|
|
7663
|
+
configToForm(autoRecharge.config, currency),
|
|
7664
|
+
currency
|
|
7665
|
+
);
|
|
7666
|
+
}, [autoRecharge.config, currency]);
|
|
7667
|
+
const save = (0, import_react42.useCallback)(async () => {
|
|
7668
|
+
const payload = emitValidation(form);
|
|
7669
|
+
if (!payload) return;
|
|
7670
|
+
const saveInput = deferCardSetup ? { ...payload, deferSetupIntent: true } : payload;
|
|
7671
|
+
const result = await autoRecharge.save(saveInput);
|
|
7672
|
+
if (result.setupClientSecret) {
|
|
7673
|
+
setSetup(result);
|
|
7674
|
+
setStatusMessage(copy.autoRecharge.setupRequiredMessage);
|
|
7675
|
+
await onSetupRequired?.(result);
|
|
7676
|
+
return;
|
|
7677
|
+
}
|
|
7678
|
+
setSetup(null);
|
|
7679
|
+
if (deferCardSetup) {
|
|
7680
|
+
await onPendingConfig?.(payload);
|
|
7681
|
+
}
|
|
7682
|
+
setStatusMessage(
|
|
7683
|
+
payload.enabled ? copy.autoRecharge.savedMessage : copy.autoRecharge.disabledMessage
|
|
7684
|
+
);
|
|
7685
|
+
setOpen(false);
|
|
7686
|
+
await onSaved?.(result);
|
|
7687
|
+
}, [
|
|
7688
|
+
autoRecharge,
|
|
7689
|
+
copy.autoRecharge,
|
|
7690
|
+
deferCardSetup,
|
|
7691
|
+
emitValidation,
|
|
7692
|
+
form,
|
|
7693
|
+
onPendingConfig,
|
|
7694
|
+
onSaved,
|
|
7695
|
+
onSetupRequired,
|
|
7696
|
+
setOpen
|
|
7697
|
+
]);
|
|
7698
|
+
const disable = (0, import_react42.useCallback)(async () => {
|
|
7699
|
+
await autoRecharge.disable();
|
|
7700
|
+
setStatusMessage(copy.autoRecharge.disabledMessage);
|
|
7701
|
+
setSetup(null);
|
|
7702
|
+
await onDisabled?.();
|
|
7703
|
+
}, [autoRecharge, copy.autoRecharge, onDisabled]);
|
|
7704
|
+
const completeSetup = (0, import_react42.useCallback)(async () => {
|
|
7705
|
+
const activated = await waitForAutoRechargeActivation({
|
|
7706
|
+
refresh: autoRecharge.refresh,
|
|
7707
|
+
getStatus: () => latestConfigRef.current?.status
|
|
7708
|
+
});
|
|
7709
|
+
setSetup(null);
|
|
7710
|
+
if (!form.enabled) return;
|
|
7711
|
+
if (activated) {
|
|
7712
|
+
setStatusMessage(copy.autoRecharge.savedMessage);
|
|
7713
|
+
setOpen(false);
|
|
7714
|
+
} else {
|
|
7715
|
+
setStatusMessage(copy.autoRecharge.setupAwaitingConfirmation);
|
|
7716
|
+
}
|
|
7717
|
+
}, [autoRecharge, copy.autoRecharge, form.enabled, setOpen]);
|
|
7718
|
+
const dataState = setup ? "setup" : autoRecharge.error ? "error" : autoRecharge.loading ? "loading" : autoRecharge.saving ? "saving" : autoRecharge.disabling ? "disabling" : "idle";
|
|
7719
|
+
const ctx = (0, import_react42.useMemo)(
|
|
7720
|
+
() => ({
|
|
7721
|
+
form,
|
|
7722
|
+
updateForm,
|
|
7723
|
+
resetForm,
|
|
7724
|
+
validationError,
|
|
7725
|
+
currency,
|
|
7726
|
+
config: autoRecharge.config,
|
|
7727
|
+
loading: autoRecharge.loading,
|
|
7728
|
+
saving: autoRecharge.saving,
|
|
7729
|
+
disabling: autoRecharge.disabling,
|
|
7730
|
+
error: autoRecharge.error,
|
|
7731
|
+
statusMessage,
|
|
7732
|
+
setup,
|
|
7733
|
+
dataState,
|
|
7734
|
+
creditsPerMinorUnit,
|
|
7735
|
+
displayExchangeRate,
|
|
7736
|
+
canToggleUnits,
|
|
7737
|
+
isApproximate,
|
|
7738
|
+
summaryLine,
|
|
7739
|
+
savedSummaryLine,
|
|
7740
|
+
deferCardSetup,
|
|
7741
|
+
fixedTopupHint: fixedTopupHint && "credits" in fixedTopupHint ? String(fixedTopupHint.credits) : fixedTopupHint && "major" in fixedTopupHint ? formatPrice(
|
|
7742
|
+
Math.round(fixedTopupHint.major * getMinorUnitsPerMajor(currency)),
|
|
7743
|
+
currency,
|
|
7744
|
+
{ free: "" }
|
|
7745
|
+
) : null,
|
|
7746
|
+
open,
|
|
7747
|
+
setOpen,
|
|
7748
|
+
titleId,
|
|
7749
|
+
registerTriggerRef,
|
|
7750
|
+
focusTrigger,
|
|
7751
|
+
save,
|
|
7752
|
+
disable,
|
|
7753
|
+
completeSetup,
|
|
7754
|
+
flipUnit
|
|
7755
|
+
}),
|
|
7756
|
+
[
|
|
7757
|
+
form,
|
|
7758
|
+
updateForm,
|
|
7759
|
+
resetForm,
|
|
7760
|
+
validationError,
|
|
7761
|
+
currency,
|
|
7762
|
+
autoRecharge.config,
|
|
7763
|
+
autoRecharge.loading,
|
|
7764
|
+
autoRecharge.saving,
|
|
7765
|
+
autoRecharge.disabling,
|
|
7766
|
+
autoRecharge.error,
|
|
7767
|
+
statusMessage,
|
|
7768
|
+
setup,
|
|
7769
|
+
dataState,
|
|
7770
|
+
creditsPerMinorUnit,
|
|
7771
|
+
displayExchangeRate,
|
|
7772
|
+
canToggleUnits,
|
|
7773
|
+
isApproximate,
|
|
7774
|
+
summaryLine,
|
|
7775
|
+
savedSummaryLine,
|
|
7776
|
+
deferCardSetup,
|
|
7777
|
+
fixedTopupHint,
|
|
7778
|
+
open,
|
|
7779
|
+
setOpen,
|
|
7780
|
+
titleId,
|
|
7781
|
+
registerTriggerRef,
|
|
7782
|
+
focusTrigger,
|
|
7783
|
+
save,
|
|
7784
|
+
disable,
|
|
7785
|
+
completeSetup,
|
|
7786
|
+
flipUnit
|
|
7787
|
+
]
|
|
7788
|
+
);
|
|
7789
|
+
const Comp = asChild ? Slot : "section";
|
|
7790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AutoRechargeContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7791
|
+
Comp,
|
|
7792
|
+
{
|
|
7793
|
+
ref: forwardedRef,
|
|
7794
|
+
className,
|
|
7795
|
+
"aria-label": "Automatic credit top-up",
|
|
7796
|
+
"data-solvapay-auto-recharge": "",
|
|
7797
|
+
"data-state": dataState,
|
|
7798
|
+
...rest,
|
|
7799
|
+
children
|
|
7800
|
+
}
|
|
7801
|
+
) });
|
|
7802
|
+
});
|
|
7803
|
+
var Loading8 = (0, import_react42.forwardRef)(
|
|
7804
|
+
function AutoRechargeLoading({ className, children, ...rest }, forwardedRef) {
|
|
7805
|
+
const ctx = useAutoRechargeCtx("Loading");
|
|
7806
|
+
if (!ctx.loading) return null;
|
|
7807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-loading": "", ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
7808
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Spinner, { size: "sm" }),
|
|
7809
|
+
" Loading auto-recharge settings\u2026"
|
|
7810
|
+
] }) });
|
|
7811
|
+
}
|
|
7812
|
+
);
|
|
7813
|
+
var Card2 = (0, import_react42.forwardRef)(function AutoRechargeCard({ className, children, ...rest }, forwardedRef) {
|
|
7814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7815
|
+
"section",
|
|
7816
|
+
{
|
|
7817
|
+
ref: forwardedRef,
|
|
7818
|
+
className,
|
|
7819
|
+
"data-solvapay-auto-recharge-card": "",
|
|
7820
|
+
...rest,
|
|
7821
|
+
children
|
|
7822
|
+
}
|
|
7823
|
+
);
|
|
7824
|
+
});
|
|
7825
|
+
var CardHeading = (0, import_react42.forwardRef)(
|
|
7826
|
+
function AutoRechargeCardHeading({ className, children, ...rest }, forwardedRef) {
|
|
7827
|
+
const copy = useCopy();
|
|
7828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7829
|
+
"h3",
|
|
7830
|
+
{
|
|
7831
|
+
ref: forwardedRef,
|
|
7832
|
+
className,
|
|
7833
|
+
"data-solvapay-auto-recharge-card-heading": "",
|
|
7834
|
+
...rest,
|
|
7835
|
+
children: children ?? copy.autoRecharge.heading
|
|
7836
|
+
}
|
|
7837
|
+
);
|
|
7838
|
+
}
|
|
7839
|
+
);
|
|
7840
|
+
var CardSummary = (0, import_react42.forwardRef)(
|
|
7841
|
+
function AutoRechargeCardSummary({ className, children, ...rest }, forwardedRef) {
|
|
7842
|
+
const ctx = useAutoRechargeCtx("CardSummary");
|
|
7843
|
+
const copy = useCopy();
|
|
7844
|
+
const text = ctx.savedSummaryLine ?? copy.autoRecharge.notConfiguredHint;
|
|
7845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7846
|
+
"p",
|
|
7847
|
+
{
|
|
7848
|
+
ref: forwardedRef,
|
|
7849
|
+
className,
|
|
7850
|
+
"data-solvapay-auto-recharge-card-summary": "",
|
|
7851
|
+
...rest,
|
|
7852
|
+
children: children ?? text
|
|
7853
|
+
}
|
|
7854
|
+
);
|
|
7855
|
+
}
|
|
7856
|
+
);
|
|
7857
|
+
var Trigger = (0, import_react42.forwardRef)(function AutoRechargeTrigger({ asChild, onClick, children, className, ...rest }, forwardedRef) {
|
|
7858
|
+
const ctx = useAutoRechargeCtx("Trigger");
|
|
7859
|
+
const copy = useCopy();
|
|
7860
|
+
const hasExistingConfig = Boolean(ctx.config?.enabled);
|
|
7861
|
+
const label = hasExistingConfig ? copy.autoRecharge.modifyTriggerLabel : copy.autoRecharge.setupTriggerLabel;
|
|
7862
|
+
const setRefs = (node) => {
|
|
7863
|
+
ctx.registerTriggerRef(node);
|
|
7864
|
+
if (typeof forwardedRef === "function") {
|
|
7865
|
+
forwardedRef(node);
|
|
7866
|
+
} else if (forwardedRef) {
|
|
7867
|
+
forwardedRef.current = node;
|
|
7868
|
+
}
|
|
7869
|
+
};
|
|
7870
|
+
const commonProps = {
|
|
7871
|
+
"data-solvapay-auto-recharge-trigger": "",
|
|
7872
|
+
type: "button",
|
|
7873
|
+
"aria-haspopup": "dialog",
|
|
7874
|
+
"aria-expanded": ctx.open,
|
|
7875
|
+
disabled: ctx.loading,
|
|
7876
|
+
onClick: composeEventHandlers(onClick, (event) => {
|
|
7877
|
+
event.preventDefault();
|
|
7878
|
+
ctx.resetForm();
|
|
7879
|
+
ctx.setOpen(true);
|
|
7880
|
+
}),
|
|
7881
|
+
className,
|
|
7882
|
+
...rest
|
|
7883
|
+
};
|
|
7884
|
+
if (asChild) {
|
|
7885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Slot, { ref: setRefs, ...commonProps, children: children ?? label });
|
|
7886
|
+
}
|
|
7887
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { ref: setRefs, ...commonProps, children: children ?? label });
|
|
7888
|
+
});
|
|
7889
|
+
var Overlay = (0, import_react42.forwardRef)(
|
|
7890
|
+
function AutoRechargeOverlay({ onClick, className, ...rest }, forwardedRef) {
|
|
7891
|
+
const ctx = useAutoRechargeCtx("Overlay");
|
|
7892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7893
|
+
"div",
|
|
7894
|
+
{
|
|
7895
|
+
ref: forwardedRef,
|
|
7896
|
+
className,
|
|
7897
|
+
"data-solvapay-auto-recharge-overlay": "",
|
|
7898
|
+
"aria-hidden": "true",
|
|
7899
|
+
onClick: composeEventHandlers(onClick, () => {
|
|
7900
|
+
ctx.resetForm();
|
|
7901
|
+
ctx.setOpen(false);
|
|
7902
|
+
ctx.focusTrigger();
|
|
7903
|
+
}),
|
|
7904
|
+
...rest
|
|
7905
|
+
}
|
|
7906
|
+
);
|
|
7907
|
+
}
|
|
7908
|
+
);
|
|
7909
|
+
var Content = (0, import_react42.forwardRef)(function AutoRechargeContent({ className, children, ...rest }, forwardedRef) {
|
|
7910
|
+
const ctx = useAutoRechargeCtx("Content");
|
|
7911
|
+
const panelRef = (0, import_react42.useRef)(null);
|
|
7912
|
+
(0, import_react42.useEffect)(() => {
|
|
7913
|
+
if (!ctx.open) return;
|
|
7914
|
+
const handleKeyDown = (event) => {
|
|
7915
|
+
if (event.key === "Escape") {
|
|
7916
|
+
ctx.resetForm();
|
|
7917
|
+
ctx.setOpen(false);
|
|
7918
|
+
ctx.focusTrigger();
|
|
7919
|
+
}
|
|
7920
|
+
};
|
|
7921
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
7922
|
+
const focusTarget = panelRef.current?.querySelector(
|
|
7923
|
+
'button:not([disabled]), input:not([disabled]), [href], [tabindex]:not([tabindex="-1"])'
|
|
7924
|
+
);
|
|
7925
|
+
focusTarget?.focus();
|
|
7926
|
+
return () => {
|
|
7927
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
7928
|
+
};
|
|
7929
|
+
}, [ctx.open, ctx.resetForm, ctx.setOpen, ctx.focusTrigger]);
|
|
7930
|
+
if (!ctx.open || typeof document === "undefined") return null;
|
|
7931
|
+
return (0, import_react_dom.createPortal)(
|
|
7932
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { "data-solvapay-auto-recharge-portal": "", children: [
|
|
7933
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Overlay, {}),
|
|
7934
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7935
|
+
"div",
|
|
7936
|
+
{
|
|
7937
|
+
ref: (node) => {
|
|
7938
|
+
panelRef.current = node;
|
|
7939
|
+
if (typeof forwardedRef === "function") {
|
|
7940
|
+
forwardedRef(node);
|
|
7941
|
+
} else if (forwardedRef) {
|
|
7942
|
+
forwardedRef.current = node;
|
|
7943
|
+
}
|
|
7944
|
+
},
|
|
7945
|
+
role: "dialog",
|
|
7946
|
+
"aria-modal": "true",
|
|
7947
|
+
"aria-labelledby": ctx.titleId,
|
|
7948
|
+
className,
|
|
7949
|
+
"data-solvapay-auto-recharge-content": "",
|
|
7950
|
+
...rest,
|
|
7951
|
+
children
|
|
7952
|
+
}
|
|
7953
|
+
)
|
|
7954
|
+
] }),
|
|
7955
|
+
document.body
|
|
7956
|
+
);
|
|
7957
|
+
});
|
|
7958
|
+
var Title = (0, import_react42.forwardRef)(
|
|
7959
|
+
function AutoRechargeTitle({ className, children, ...rest }, forwardedRef) {
|
|
7960
|
+
const ctx = useAutoRechargeCtx("Title");
|
|
7961
|
+
const copy = useCopy();
|
|
7962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7963
|
+
"h2",
|
|
7964
|
+
{
|
|
7965
|
+
ref: forwardedRef,
|
|
7966
|
+
id: ctx.titleId,
|
|
7967
|
+
className,
|
|
7968
|
+
"data-solvapay-auto-recharge-title": "",
|
|
7969
|
+
...rest,
|
|
7970
|
+
children: children ?? copy.autoRecharge.settingsHeading
|
|
7971
|
+
}
|
|
7972
|
+
);
|
|
7973
|
+
}
|
|
7974
|
+
);
|
|
7975
|
+
var EnableQuestion = (0, import_react42.forwardRef)(
|
|
7976
|
+
function AutoRechargeEnableQuestion({ className, children, ...rest }, forwardedRef) {
|
|
7977
|
+
const copy = useCopy();
|
|
7978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-question": "", ...rest, children: children ?? copy.autoRecharge.enableQuestion });
|
|
7979
|
+
}
|
|
7980
|
+
);
|
|
7981
|
+
var EnableSentence = (0, import_react42.forwardRef)(
|
|
7982
|
+
function AutoRechargeEnableSentence({ className, children, ...rest }, forwardedRef) {
|
|
7983
|
+
const copy = useCopy();
|
|
7984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7985
|
+
"label",
|
|
7986
|
+
{
|
|
7987
|
+
ref: forwardedRef,
|
|
7988
|
+
className,
|
|
7989
|
+
"data-solvapay-auto-recharge-enable-sentence": "",
|
|
7990
|
+
...rest,
|
|
7991
|
+
children: children ?? copy.autoRecharge.enableSentence
|
|
7992
|
+
}
|
|
7993
|
+
);
|
|
7994
|
+
}
|
|
7995
|
+
);
|
|
7996
|
+
var EnableRow = (0, import_react42.forwardRef)(
|
|
7997
|
+
function AutoRechargeEnableRow({ className, children, ...rest }, forwardedRef) {
|
|
7998
|
+
const enableId = (0, import_react42.useId)();
|
|
7999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8000
|
+
"div",
|
|
8001
|
+
{
|
|
8002
|
+
ref: forwardedRef,
|
|
8003
|
+
className,
|
|
8004
|
+
"data-solvapay-auto-recharge-enable-row": "",
|
|
8005
|
+
...rest,
|
|
8006
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
8007
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EnableSwitch, { appearance: "checkbox", id: enableId }),
|
|
8008
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EnableSentence, { htmlFor: enableId })
|
|
8009
|
+
] })
|
|
8010
|
+
}
|
|
8011
|
+
);
|
|
8012
|
+
}
|
|
8013
|
+
);
|
|
8014
|
+
var CancelButton = (0, import_react42.forwardRef)(
|
|
8015
|
+
function AutoRechargeCancelButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
|
|
8016
|
+
const ctx = useAutoRechargeCtx("CancelButton");
|
|
8017
|
+
const copy = useCopy();
|
|
8018
|
+
const commonProps = {
|
|
8019
|
+
"data-solvapay-auto-recharge-cancel": "",
|
|
8020
|
+
type: "button",
|
|
8021
|
+
onClick: composeEventHandlers(onClick, (event) => {
|
|
8022
|
+
event.preventDefault();
|
|
8023
|
+
ctx.resetForm();
|
|
8024
|
+
ctx.setOpen(false);
|
|
8025
|
+
ctx.focusTrigger();
|
|
8026
|
+
}),
|
|
8027
|
+
className,
|
|
8028
|
+
...rest
|
|
8029
|
+
};
|
|
8030
|
+
if (asChild) {
|
|
8031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8032
|
+
Slot,
|
|
8033
|
+
{
|
|
8034
|
+
ref: forwardedRef,
|
|
8035
|
+
...commonProps,
|
|
8036
|
+
children: children ?? copy.autoRecharge.cancelButton
|
|
8037
|
+
}
|
|
8038
|
+
);
|
|
8039
|
+
}
|
|
8040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.cancelButton });
|
|
8041
|
+
}
|
|
8042
|
+
);
|
|
8043
|
+
var Header = (0, import_react42.forwardRef)(
|
|
8044
|
+
function AutoRechargeHeader({ className, ...rest }, forwardedRef) {
|
|
8045
|
+
const copy = useCopy();
|
|
8046
|
+
const headingId = (0, import_react42.useId)();
|
|
8047
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
8048
|
+
"header",
|
|
8049
|
+
{
|
|
8050
|
+
ref: forwardedRef,
|
|
8051
|
+
className,
|
|
8052
|
+
"data-solvapay-auto-recharge-header": "",
|
|
8053
|
+
...rest,
|
|
8054
|
+
children: [
|
|
8055
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("section", { "data-solvapay-auto-recharge-heading-group": "", children: [
|
|
8056
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h3", { id: headingId, "data-solvapay-auto-recharge-heading": "", children: copy.autoRecharge.heading }),
|
|
8057
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Description, {})
|
|
8058
|
+
] }),
|
|
8059
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EnableSwitch, { "aria-labelledby": headingId })
|
|
8060
|
+
]
|
|
8061
|
+
}
|
|
8062
|
+
);
|
|
8063
|
+
}
|
|
8064
|
+
);
|
|
8065
|
+
var Description = (0, import_react42.forwardRef)(
|
|
8066
|
+
function AutoRechargeDescription({ className, children, ...rest }, forwardedRef) {
|
|
8067
|
+
const copy = useCopy();
|
|
8068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8069
|
+
"p",
|
|
8070
|
+
{
|
|
8071
|
+
ref: forwardedRef,
|
|
8072
|
+
className,
|
|
8073
|
+
"data-solvapay-auto-recharge-description": "",
|
|
8074
|
+
...rest,
|
|
8075
|
+
children: children ?? copy.autoRecharge.description
|
|
8076
|
+
}
|
|
8077
|
+
);
|
|
8078
|
+
}
|
|
8079
|
+
);
|
|
8080
|
+
var EnableSwitch = (0, import_react42.forwardRef)(
|
|
8081
|
+
function AutoRechargeEnableSwitch({ asChild, appearance = "switch", onChange, className, ...rest }, forwardedRef) {
|
|
8082
|
+
const ctx = useAutoRechargeCtx("EnableSwitch");
|
|
8083
|
+
const copy = useCopy();
|
|
8084
|
+
const commonProps = {
|
|
8085
|
+
"data-solvapay-auto-recharge-enable": "",
|
|
8086
|
+
"data-appearance": appearance,
|
|
8087
|
+
type: "checkbox",
|
|
8088
|
+
...appearance === "switch" ? { role: "switch", "aria-checked": ctx.form.enabled } : {},
|
|
8089
|
+
checked: ctx.form.enabled,
|
|
8090
|
+
"aria-label": copy.autoRecharge.enableLabel,
|
|
8091
|
+
disabled: ctx.loading || ctx.saving || ctx.disabling || !!ctx.setup,
|
|
8092
|
+
onChange: composeEventHandlers(onChange, (event) => {
|
|
8093
|
+
ctx.updateForm({ enabled: event.currentTarget.checked });
|
|
8094
|
+
}),
|
|
8095
|
+
className,
|
|
8096
|
+
...rest
|
|
8097
|
+
};
|
|
8098
|
+
if (asChild) {
|
|
8099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8100
|
+
Slot,
|
|
8101
|
+
{
|
|
8102
|
+
ref: forwardedRef,
|
|
8103
|
+
...commonProps
|
|
8104
|
+
}
|
|
8105
|
+
);
|
|
8106
|
+
}
|
|
8107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("input", { ref: forwardedRef, ...commonProps });
|
|
8108
|
+
}
|
|
8109
|
+
);
|
|
8110
|
+
var Fields = (0, import_react42.forwardRef)(
|
|
8111
|
+
function AutoRechargeFields({ className, children, ...rest }, forwardedRef) {
|
|
8112
|
+
const ctx = useAutoRechargeCtx("Fields");
|
|
8113
|
+
const copy = useCopy();
|
|
8114
|
+
if (!ctx.form.enabled) return null;
|
|
8115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
8116
|
+
"fieldset",
|
|
8117
|
+
{
|
|
8118
|
+
ref: forwardedRef,
|
|
8119
|
+
className,
|
|
8120
|
+
disabled: ctx.saving || ctx.disabling,
|
|
8121
|
+
"data-solvapay-auto-recharge-fields": "",
|
|
8122
|
+
"data-solvapay-auto-recharge-body": "",
|
|
8123
|
+
"data-state": "open",
|
|
8124
|
+
...rest,
|
|
8125
|
+
children: [
|
|
8126
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("legend", { className: "sr-only", children: copy.autoRecharge.heading }),
|
|
8127
|
+
children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
8128
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Summary3, {}),
|
|
8129
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThresholdField, {}),
|
|
8130
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TopupField, {}),
|
|
8131
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ValidationError, {})
|
|
8132
|
+
] })
|
|
8133
|
+
]
|
|
8134
|
+
}
|
|
8135
|
+
);
|
|
8136
|
+
}
|
|
8137
|
+
);
|
|
8138
|
+
var Setup = (0, import_react42.forwardRef)(
|
|
8139
|
+
function AutoRechargeSetup({ className, children, ...rest }, forwardedRef) {
|
|
8140
|
+
const ctx = useAutoRechargeCtx("Setup");
|
|
8141
|
+
if (!ctx.setup?.setupClientSecret) return null;
|
|
8142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8143
|
+
"div",
|
|
8144
|
+
{
|
|
8145
|
+
ref: forwardedRef,
|
|
8146
|
+
className,
|
|
8147
|
+
"data-solvapay-auto-recharge-setup-panel": "",
|
|
8148
|
+
...rest,
|
|
8149
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CardSetup, { setup: ctx.setup, onComplete: ctx.completeSetup })
|
|
8150
|
+
}
|
|
8151
|
+
);
|
|
8152
|
+
}
|
|
8153
|
+
);
|
|
8154
|
+
var Body = (0, import_react42.forwardRef)(
|
|
8155
|
+
function AutoRechargeBody({ className, children, ...rest }, forwardedRef) {
|
|
8156
|
+
const ctx = useAutoRechargeCtx("Body");
|
|
8157
|
+
if (ctx.setup?.setupClientSecret) {
|
|
8158
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Setup, { className });
|
|
8159
|
+
}
|
|
8160
|
+
if (!ctx.form.enabled) return null;
|
|
8161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Fields, { ref: forwardedRef, className, ...rest, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
8162
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Summary3, {}),
|
|
8163
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ThresholdField, {}),
|
|
8164
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TopupField, {}),
|
|
8165
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ValidationError, {}),
|
|
8166
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Actions, {})
|
|
8167
|
+
] }) });
|
|
8168
|
+
}
|
|
8169
|
+
);
|
|
8170
|
+
var Summary3 = (0, import_react42.forwardRef)(
|
|
8171
|
+
function AutoRechargeSummary({ className, children, ...rest }, forwardedRef) {
|
|
8172
|
+
const ctx = useAutoRechargeCtx("Summary");
|
|
8173
|
+
if (!ctx.summaryLine) return null;
|
|
8174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-summary": "", ...rest, children: children ?? ctx.summaryLine });
|
|
8175
|
+
}
|
|
8176
|
+
);
|
|
8177
|
+
var AmountField = (0, import_react42.forwardRef)(function AutoRechargeAmountField({ field, showLabel = true, asChild, onChange, className, ...rest }, forwardedRef) {
|
|
8178
|
+
const ctx = useAutoRechargeCtx("AmountField");
|
|
8179
|
+
const copy = useCopy();
|
|
8180
|
+
const fieldConfig = {
|
|
8181
|
+
threshold: {
|
|
8182
|
+
label: copy.autoRecharge.thresholdLabel,
|
|
8183
|
+
ariaLabel: copy.autoRecharge.thresholdAriaLabel,
|
|
8184
|
+
unitToggleLabel: "balance threshold",
|
|
8185
|
+
value: ctx.form.thresholdAmountMajor,
|
|
8186
|
+
unit: ctx.form.thresholdUnit,
|
|
8187
|
+
unitKey: "thresholdUnit",
|
|
8188
|
+
valueKey: "thresholdAmountMajor",
|
|
8189
|
+
baseValueKey: "thresholdBaseValue",
|
|
8190
|
+
baseUnitKey: "thresholdBaseUnit",
|
|
8191
|
+
mode: ctx.form.thresholdUnit === "currency" ? "currency" : "number",
|
|
8192
|
+
onValue: (value) => ctx.updateForm({
|
|
8193
|
+
thresholdAmountMajor: value,
|
|
8194
|
+
thresholdBaseValue: value,
|
|
8195
|
+
thresholdBaseUnit: ctx.form.thresholdUnit
|
|
8196
|
+
})
|
|
8197
|
+
},
|
|
8198
|
+
fixed: {
|
|
8199
|
+
label: copy.autoRecharge.fixedAmountLabel,
|
|
8200
|
+
ariaLabel: copy.autoRecharge.fixedAmountAriaLabel,
|
|
8201
|
+
unitToggleLabel: "fixed top-up amount",
|
|
8202
|
+
value: ctx.form.topupAmountMajor,
|
|
8203
|
+
unit: ctx.form.topupUnit,
|
|
8204
|
+
unitKey: "topupUnit",
|
|
8205
|
+
valueKey: "topupAmountMajor",
|
|
8206
|
+
baseValueKey: "topupBaseValue",
|
|
8207
|
+
baseUnitKey: "topupBaseUnit",
|
|
8208
|
+
mode: ctx.form.topupUnit === "currency" ? "currency" : "number",
|
|
8209
|
+
onValue: (value) => ctx.updateForm({
|
|
8210
|
+
topupAmountMajor: value,
|
|
8211
|
+
topupBaseValue: value,
|
|
8212
|
+
topupBaseUnit: ctx.form.topupUnit
|
|
8213
|
+
})
|
|
8214
|
+
}
|
|
8215
|
+
}[field];
|
|
8216
|
+
const inputId = (0, import_react42.useId)();
|
|
8217
|
+
const prefix = fieldConfig.mode === "currency" ? getCurrencySymbol2(ctx.currency) : void 0;
|
|
8218
|
+
const handleChange = (event) => {
|
|
8219
|
+
const raw = event.target.value;
|
|
8220
|
+
const next = fieldConfig.mode === "currency" ? raw.replace(/[^0-9.]/g, "") : raw.replace(/[^0-9]/g, "");
|
|
8221
|
+
fieldConfig.onValue(next);
|
|
8222
|
+
};
|
|
8223
|
+
const inputProps = {
|
|
8224
|
+
id: inputId,
|
|
8225
|
+
"data-solvapay-auto-recharge-amount": "",
|
|
8226
|
+
"data-field": field,
|
|
8227
|
+
type: "text",
|
|
8228
|
+
inputMode: fieldConfig.mode === "currency" ? "decimal" : "numeric",
|
|
8229
|
+
placeholder: fieldConfig.mode === "currency" ? "0.00" : "0",
|
|
8230
|
+
value: fieldConfig.value,
|
|
8231
|
+
"aria-label": fieldConfig.ariaLabel,
|
|
8232
|
+
onChange: composeEventHandlers(onChange, handleChange),
|
|
8233
|
+
className,
|
|
8234
|
+
...rest
|
|
8235
|
+
};
|
|
8236
|
+
const slotRef = forwardedRef;
|
|
8237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { "data-solvapay-auto-recharge-field": "", "data-field": field, children: [
|
|
8238
|
+
showLabel ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("label", { htmlFor: inputId, children: fieldConfig.label }) : null,
|
|
8239
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { "data-solvapay-auto-recharge-amount-row": "", children: [
|
|
8240
|
+
prefix ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "data-solvapay-auto-recharge-currency-prefix": "", "aria-hidden": "true", children: prefix }) : null,
|
|
8241
|
+
asChild ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Slot, { ref: slotRef, ...inputProps }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("input", { ref: forwardedRef, ...inputProps }),
|
|
8242
|
+
ctx.canToggleUnits ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8243
|
+
UnitToggle,
|
|
8244
|
+
{
|
|
8245
|
+
unit: fieldConfig.unit,
|
|
8246
|
+
fieldLabel: fieldConfig.unitToggleLabel,
|
|
8247
|
+
onToggle: () => ctx.flipUnit(
|
|
8248
|
+
fieldConfig.valueKey,
|
|
8249
|
+
fieldConfig.unitKey,
|
|
8250
|
+
fieldConfig.baseValueKey,
|
|
8251
|
+
fieldConfig.baseUnitKey,
|
|
8252
|
+
fieldConfig.unit
|
|
8253
|
+
)
|
|
8254
|
+
}
|
|
8255
|
+
) : null
|
|
8256
|
+
] })
|
|
8257
|
+
] });
|
|
8258
|
+
});
|
|
8259
|
+
var ThresholdField = (0, import_react42.forwardRef)(
|
|
8260
|
+
function AutoRechargeThresholdField({ className, ...rest }, ref) {
|
|
8261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("section", { ref, className, ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AmountField, { field: "threshold" }) });
|
|
8262
|
+
}
|
|
8263
|
+
);
|
|
8264
|
+
var TopupField = (0, import_react42.forwardRef)(
|
|
8265
|
+
function AutoRechargeTopupField({ className, ...rest }, ref) {
|
|
8266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
8267
|
+
"section",
|
|
8268
|
+
{
|
|
8269
|
+
ref,
|
|
8270
|
+
className,
|
|
8271
|
+
"data-solvapay-auto-recharge-topup-field": "",
|
|
8272
|
+
...rest,
|
|
8273
|
+
children: [
|
|
8274
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(AmountField, { field: "fixed" }),
|
|
8275
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Hint, {})
|
|
8276
|
+
]
|
|
8277
|
+
}
|
|
8278
|
+
);
|
|
8279
|
+
}
|
|
8280
|
+
);
|
|
8281
|
+
var UnitToggle = (0, import_react42.forwardRef)(function AutoRechargeUnitToggle({ unit, fieldLabel, onToggle, className, ...rest }, forwardedRef) {
|
|
8282
|
+
const ctx = useAutoRechargeCtx("UnitToggle");
|
|
8283
|
+
const targetUnitLabel = unit === "currency" ? "credits" : "currency";
|
|
8284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8285
|
+
"button",
|
|
8286
|
+
{
|
|
8287
|
+
ref: forwardedRef,
|
|
8288
|
+
type: "button",
|
|
8289
|
+
className,
|
|
8290
|
+
"data-solvapay-auto-recharge-unit-toggle": "",
|
|
8291
|
+
"aria-label": `Switch ${fieldLabel} to ${targetUnitLabel}`,
|
|
8292
|
+
onClick: onToggle,
|
|
8293
|
+
...rest,
|
|
8294
|
+
children: unit === "currency" ? ctx.currency.toUpperCase() : "credits"
|
|
8295
|
+
}
|
|
8296
|
+
);
|
|
8297
|
+
});
|
|
8298
|
+
var Hint = (0, import_react42.forwardRef)(
|
|
8299
|
+
function AutoRechargeHint({ className, ...rest }, forwardedRef) {
|
|
8300
|
+
const ctx = useAutoRechargeCtx("Hint");
|
|
8301
|
+
const copy = useCopy();
|
|
8302
|
+
const hint = ctx.fixedTopupHint;
|
|
8303
|
+
if (!hint) return null;
|
|
8304
|
+
const isCreditsHint = ctx.form.topupUnit === "currency";
|
|
8305
|
+
const text = isCreditsHint ? interpolate(
|
|
8306
|
+
ctx.isApproximate ? copy.autoRecharge.creditsPerRechargeApprox : copy.autoRecharge.creditsPerRecharge,
|
|
8307
|
+
{ credits: new Intl.NumberFormat().format(Number(hint)) }
|
|
8308
|
+
) : interpolate(
|
|
8309
|
+
ctx.isApproximate ? copy.autoRecharge.currencyPerRechargeApprox : copy.autoRecharge.currencyPerRecharge,
|
|
8310
|
+
{ amount: hint }
|
|
8311
|
+
);
|
|
8312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { ref: forwardedRef, className, "data-solvapay-auto-recharge-hint": "", ...rest, children: text });
|
|
8313
|
+
}
|
|
8314
|
+
);
|
|
8315
|
+
var ValidationError = (0, import_react42.forwardRef)(function AutoRechargeValidationError({ className, ...rest }, forwardedRef) {
|
|
8316
|
+
const ctx = useAutoRechargeCtx("ValidationError");
|
|
8317
|
+
if (!ctx.validationError) return null;
|
|
8318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8319
|
+
"p",
|
|
8320
|
+
{
|
|
8321
|
+
ref: forwardedRef,
|
|
8322
|
+
role: "alert",
|
|
8323
|
+
"aria-live": "polite",
|
|
8324
|
+
className,
|
|
8325
|
+
"data-solvapay-auto-recharge-validation-error": "",
|
|
8326
|
+
...rest,
|
|
8327
|
+
children: ctx.validationError
|
|
8328
|
+
}
|
|
8329
|
+
);
|
|
8330
|
+
});
|
|
8331
|
+
var Actions = (0, import_react42.forwardRef)(
|
|
8332
|
+
function AutoRechargeActions({ className, children, ...rest }, forwardedRef) {
|
|
8333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8334
|
+
"menu",
|
|
8335
|
+
{
|
|
8336
|
+
ref: forwardedRef,
|
|
8337
|
+
className,
|
|
8338
|
+
"data-solvapay-auto-recharge-actions": "",
|
|
8339
|
+
...rest,
|
|
8340
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
8341
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CancelButton, {}) }),
|
|
8342
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SaveButton, {}) })
|
|
8343
|
+
] })
|
|
8344
|
+
}
|
|
8345
|
+
);
|
|
8346
|
+
}
|
|
8347
|
+
);
|
|
8348
|
+
var SaveButton = (0, import_react42.forwardRef)(function AutoRechargeSaveButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
|
|
8349
|
+
const ctx = useAutoRechargeCtx("SaveButton");
|
|
8350
|
+
const copy = useCopy();
|
|
8351
|
+
const dataState = ctx.saving ? "processing" : ctx.validationError ? "disabled" : "idle";
|
|
8352
|
+
const commonProps = {
|
|
8353
|
+
"data-solvapay-auto-recharge-save": "",
|
|
8354
|
+
"data-state": dataState,
|
|
8355
|
+
type: "button",
|
|
8356
|
+
disabled: ctx.saving || ctx.disabling || !!ctx.validationError,
|
|
8357
|
+
"aria-busy": ctx.saving,
|
|
8358
|
+
onClick: composeEventHandlers(onClick, (event) => {
|
|
8359
|
+
event.preventDefault();
|
|
8360
|
+
void ctx.save();
|
|
8361
|
+
}),
|
|
8362
|
+
className,
|
|
8363
|
+
...rest
|
|
8364
|
+
};
|
|
8365
|
+
const content = ctx.saving ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
8366
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Spinner, { size: "sm" }),
|
|
8367
|
+
" ",
|
|
8368
|
+
copy.cta.processing
|
|
8369
|
+
] }) : children ?? copy.autoRecharge.saveButton;
|
|
8370
|
+
if (asChild) {
|
|
8371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8372
|
+
Slot,
|
|
8373
|
+
{
|
|
8374
|
+
ref: forwardedRef,
|
|
8375
|
+
...commonProps,
|
|
8376
|
+
children: content
|
|
8377
|
+
}
|
|
8378
|
+
);
|
|
8379
|
+
}
|
|
8380
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { ref: forwardedRef, ...commonProps, children: content });
|
|
8381
|
+
});
|
|
8382
|
+
var DisableButton = (0, import_react42.forwardRef)(
|
|
8383
|
+
function AutoRechargeDisableButton({ asChild, onClick, children, className, ...rest }, forwardedRef) {
|
|
8384
|
+
const ctx = useAutoRechargeCtx("DisableButton");
|
|
8385
|
+
const copy = useCopy();
|
|
8386
|
+
if (!ctx.config) return null;
|
|
8387
|
+
const commonProps = {
|
|
8388
|
+
"data-solvapay-auto-recharge-disable": "",
|
|
8389
|
+
type: "button",
|
|
8390
|
+
disabled: ctx.saving || ctx.disabling,
|
|
8391
|
+
"aria-busy": ctx.disabling,
|
|
8392
|
+
onClick: composeEventHandlers(onClick, (event) => {
|
|
8393
|
+
event.preventDefault();
|
|
8394
|
+
void ctx.disable();
|
|
8395
|
+
}),
|
|
8396
|
+
className,
|
|
8397
|
+
...rest
|
|
8398
|
+
};
|
|
8399
|
+
if (asChild) {
|
|
8400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8401
|
+
Slot,
|
|
8402
|
+
{
|
|
8403
|
+
ref: forwardedRef,
|
|
8404
|
+
...commonProps,
|
|
8405
|
+
children: children ?? copy.autoRecharge.disableButton
|
|
8406
|
+
}
|
|
8407
|
+
);
|
|
8408
|
+
}
|
|
8409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("button", { ref: forwardedRef, ...commonProps, children: children ?? copy.autoRecharge.disableButton });
|
|
8410
|
+
}
|
|
8411
|
+
);
|
|
8412
|
+
var ErrorSlot7 = (0, import_react42.forwardRef)(
|
|
8413
|
+
function AutoRechargeError({ className, children, ...rest }, forwardedRef) {
|
|
8414
|
+
const ctx = useAutoRechargeCtx("Error");
|
|
8415
|
+
if (!ctx.error) return null;
|
|
8416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8417
|
+
"p",
|
|
8418
|
+
{
|
|
8419
|
+
ref: forwardedRef,
|
|
8420
|
+
role: "alert",
|
|
8421
|
+
"aria-live": "polite",
|
|
8422
|
+
className,
|
|
8423
|
+
"data-solvapay-auto-recharge-error": "",
|
|
8424
|
+
...rest,
|
|
8425
|
+
children: children ?? ctx.error.message
|
|
8426
|
+
}
|
|
8427
|
+
);
|
|
8428
|
+
}
|
|
8429
|
+
);
|
|
8430
|
+
var StatusMessage = (0, import_react42.forwardRef)(
|
|
8431
|
+
function AutoRechargeStatusMessage({ className, children, ...rest }, forwardedRef) {
|
|
8432
|
+
const ctx = useAutoRechargeCtx("StatusMessage");
|
|
8433
|
+
if (!ctx.statusMessage) return null;
|
|
8434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8435
|
+
"p",
|
|
8436
|
+
{
|
|
8437
|
+
ref: forwardedRef,
|
|
8438
|
+
"aria-live": "polite",
|
|
8439
|
+
className,
|
|
8440
|
+
"data-solvapay-auto-recharge-status-message": "",
|
|
8441
|
+
...rest,
|
|
8442
|
+
children: children ?? ctx.statusMessage
|
|
8443
|
+
}
|
|
8444
|
+
);
|
|
8445
|
+
}
|
|
8446
|
+
);
|
|
8447
|
+
var Status = (0, import_react42.forwardRef)(
|
|
8448
|
+
function AutoRechargeStatus({ className, ...rest }, forwardedRef) {
|
|
8449
|
+
const ctx = useAutoRechargeCtx("Status");
|
|
8450
|
+
const copy = useCopy();
|
|
8451
|
+
const status = ctx.config?.status;
|
|
8452
|
+
if (!status || status === "active" || status === "disabled" || status === "pending_setup") {
|
|
8453
|
+
return null;
|
|
8454
|
+
}
|
|
8455
|
+
const label = status === "failed" ? copy.autoRecharge.statusFailed : null;
|
|
8456
|
+
if (!label) return null;
|
|
8457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8458
|
+
"span",
|
|
8459
|
+
{
|
|
8460
|
+
ref: forwardedRef,
|
|
8461
|
+
className,
|
|
8462
|
+
"data-solvapay-auto-recharge-status": "",
|
|
8463
|
+
"data-status": status,
|
|
8464
|
+
...rest,
|
|
8465
|
+
children: label
|
|
8466
|
+
}
|
|
8467
|
+
);
|
|
8468
|
+
}
|
|
8469
|
+
);
|
|
8470
|
+
function CardSetupInner({ onComplete }) {
|
|
8471
|
+
const copy = useCopy();
|
|
8472
|
+
const stripe = (0, import_react_stripe_js4.useStripe)();
|
|
8473
|
+
const elements = (0, import_react_stripe_js4.useElements)();
|
|
8474
|
+
const [processing, setProcessing] = (0, import_react42.useState)(false);
|
|
8475
|
+
const [error, setError] = (0, import_react42.useState)(null);
|
|
6989
8476
|
(0, import_react42.useEffect)(() => {
|
|
8477
|
+
if (!stripe) return;
|
|
8478
|
+
const clientSecret = readSetupIntentClientSecret(window.location.search);
|
|
8479
|
+
if (!clientSecret) return;
|
|
8480
|
+
let cancelled = false;
|
|
8481
|
+
void (async () => {
|
|
8482
|
+
setProcessing(true);
|
|
8483
|
+
const { setupIntent, error: retrieveError } = await stripe.retrieveSetupIntent(clientSecret);
|
|
8484
|
+
if (cancelled) return;
|
|
8485
|
+
stripSetupIntentParams();
|
|
8486
|
+
if (retrieveError || !setupIntent) {
|
|
8487
|
+
setError(copy.autoRecharge.setupAuthFailed);
|
|
8488
|
+
setProcessing(false);
|
|
8489
|
+
return;
|
|
8490
|
+
}
|
|
8491
|
+
if (setupIntent.status === "succeeded" || setupIntent.status === "processing") {
|
|
8492
|
+
await onComplete();
|
|
8493
|
+
} else {
|
|
8494
|
+
setError(copy.autoRecharge.setupAuthFailed);
|
|
8495
|
+
}
|
|
8496
|
+
if (!cancelled) setProcessing(false);
|
|
8497
|
+
})();
|
|
8498
|
+
return () => {
|
|
8499
|
+
cancelled = true;
|
|
8500
|
+
};
|
|
8501
|
+
}, [stripe, onComplete, copy.autoRecharge]);
|
|
8502
|
+
const handleSubmit = async (event) => {
|
|
8503
|
+
event.preventDefault();
|
|
8504
|
+
if (!stripe || !elements) {
|
|
8505
|
+
setError("Stripe is still loading. Please wait.");
|
|
8506
|
+
return;
|
|
8507
|
+
}
|
|
8508
|
+
setProcessing(true);
|
|
8509
|
+
setError(null);
|
|
8510
|
+
const { error: submitError } = await elements.submit();
|
|
8511
|
+
if (submitError) {
|
|
8512
|
+
setError(submitError.message ?? "Card authorization failed");
|
|
8513
|
+
setProcessing(false);
|
|
8514
|
+
return;
|
|
8515
|
+
}
|
|
8516
|
+
const { error: confirmError } = await stripe.confirmSetup({
|
|
8517
|
+
elements,
|
|
8518
|
+
confirmParams: {
|
|
8519
|
+
return_url: typeof window !== "undefined" ? window.location.href : "/"
|
|
8520
|
+
},
|
|
8521
|
+
redirect: "if_required"
|
|
8522
|
+
});
|
|
8523
|
+
if (confirmError) {
|
|
8524
|
+
setError(confirmError.message ?? "Card authorization failed");
|
|
8525
|
+
setProcessing(false);
|
|
8526
|
+
return;
|
|
8527
|
+
}
|
|
8528
|
+
await onComplete();
|
|
8529
|
+
setProcessing(false);
|
|
8530
|
+
};
|
|
8531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("form", { onSubmit: handleSubmit, "data-solvapay-auto-recharge-setup": "", children: [
|
|
8532
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h4", { children: copy.autoRecharge.setupHeading }),
|
|
8533
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { children: copy.autoRecharge.setupDescription }),
|
|
8534
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_stripe_js4.PaymentElement, { options: withPaymentElementDefaults() }),
|
|
8535
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { role: "alert", "aria-live": "polite", "data-solvapay-auto-recharge-setup-error": "", children: error }) : null,
|
|
8536
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8537
|
+
"button",
|
|
8538
|
+
{
|
|
8539
|
+
type: "submit",
|
|
8540
|
+
disabled: processing || !stripe,
|
|
8541
|
+
"data-solvapay-auto-recharge-setup-submit": "",
|
|
8542
|
+
children: processing ? copy.autoRecharge.setupProcessing : copy.autoRecharge.setupSubmit
|
|
8543
|
+
}
|
|
8544
|
+
)
|
|
8545
|
+
] });
|
|
8546
|
+
}
|
|
8547
|
+
function CardSetup({ setup, onComplete }) {
|
|
8548
|
+
const stripePromise = (0, import_react42.useMemo)(() => {
|
|
8549
|
+
if (!setup.publishableKey || !setup.setupClientSecret) return null;
|
|
8550
|
+
const options = {
|
|
8551
|
+
...setup.stripeAccountId ? { stripeAccount: setup.stripeAccountId } : {},
|
|
8552
|
+
developerTools: { assistant: { enabled: false } }
|
|
8553
|
+
};
|
|
8554
|
+
const cacheKey2 = getStripeCacheKey3(setup.publishableKey, setup.stripeAccountId);
|
|
8555
|
+
const cached = stripePromiseCache3.get(cacheKey2);
|
|
8556
|
+
if (cached) return cached;
|
|
8557
|
+
const promise = (0, import_stripe_js3.loadStripe)(setup.publishableKey, options);
|
|
8558
|
+
stripePromiseCache3.set(cacheKey2, promise);
|
|
8559
|
+
return promise;
|
|
8560
|
+
}, [setup.publishableKey, setup.setupClientSecret, setup.stripeAccountId]);
|
|
8561
|
+
if (!stripePromise || !setup.setupClientSecret) {
|
|
8562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("p", { "data-solvapay-auto-recharge-setup-loading": "", children: [
|
|
8563
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Spinner, { size: "sm" }),
|
|
8564
|
+
" Loading card form\u2026"
|
|
8565
|
+
] });
|
|
8566
|
+
}
|
|
8567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8568
|
+
import_react_stripe_js4.Elements,
|
|
8569
|
+
{
|
|
8570
|
+
stripe: stripePromise,
|
|
8571
|
+
options: { clientSecret: setup.setupClientSecret },
|
|
8572
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CardSetupInner, { onComplete })
|
|
8573
|
+
},
|
|
8574
|
+
setup.setupClientSecret
|
|
8575
|
+
);
|
|
8576
|
+
}
|
|
8577
|
+
var AutoRecharge = {
|
|
8578
|
+
Root: Root11,
|
|
8579
|
+
Loading: Loading8,
|
|
8580
|
+
Card: Card2,
|
|
8581
|
+
CardHeading,
|
|
8582
|
+
CardSummary,
|
|
8583
|
+
Trigger,
|
|
8584
|
+
Overlay,
|
|
8585
|
+
Content,
|
|
8586
|
+
Title,
|
|
8587
|
+
EnableQuestion,
|
|
8588
|
+
EnableSentence,
|
|
8589
|
+
EnableRow,
|
|
8590
|
+
CancelButton,
|
|
8591
|
+
Header,
|
|
8592
|
+
Description,
|
|
8593
|
+
EnableSwitch,
|
|
8594
|
+
Fields,
|
|
8595
|
+
Setup,
|
|
8596
|
+
Body,
|
|
8597
|
+
Summary: Summary3,
|
|
8598
|
+
ThresholdField,
|
|
8599
|
+
TopupField,
|
|
8600
|
+
AmountField,
|
|
8601
|
+
UnitToggle,
|
|
8602
|
+
Hint,
|
|
8603
|
+
ValidationError,
|
|
8604
|
+
Actions,
|
|
8605
|
+
SaveButton,
|
|
8606
|
+
DisableButton,
|
|
8607
|
+
Error: ErrorSlot7,
|
|
8608
|
+
StatusMessage,
|
|
8609
|
+
Status,
|
|
8610
|
+
CardSetup
|
|
8611
|
+
};
|
|
8612
|
+
|
|
8613
|
+
// src/components/AutoRecharge.tsx
|
|
8614
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
8615
|
+
function AutoRecharge2({
|
|
8616
|
+
currency = "USD",
|
|
8617
|
+
defaultThresholdAmountMajor,
|
|
8618
|
+
defaultTopupAmountMajor,
|
|
8619
|
+
onSetupRequired,
|
|
8620
|
+
onSaved,
|
|
8621
|
+
onDisabled,
|
|
8622
|
+
deferCardSetup,
|
|
8623
|
+
onPendingConfig,
|
|
8624
|
+
className
|
|
8625
|
+
}) {
|
|
8626
|
+
const rootClass = ["solvapay-auto-recharge", className].filter(Boolean).join(" ");
|
|
8627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
8628
|
+
AutoRecharge.Root,
|
|
8629
|
+
{
|
|
8630
|
+
currency,
|
|
8631
|
+
defaultThresholdAmountMajor,
|
|
8632
|
+
defaultTopupAmountMajor,
|
|
8633
|
+
onSetupRequired,
|
|
8634
|
+
onSaved,
|
|
8635
|
+
onDisabled,
|
|
8636
|
+
deferCardSetup,
|
|
8637
|
+
onPendingConfig,
|
|
8638
|
+
className: rootClass,
|
|
8639
|
+
children: [
|
|
8640
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Loading, { className: "solvapay-auto-recharge-loading" }),
|
|
8641
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AutoRecharge.Card, { className: "solvapay-auto-recharge-card", children: [
|
|
8642
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.CardHeading, { className: "solvapay-auto-recharge-card-heading" }),
|
|
8643
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.CardSummary, { className: "solvapay-auto-recharge-card-summary" }),
|
|
8644
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.StatusMessage, { className: "solvapay-auto-recharge-status-message" }),
|
|
8645
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Status, { className: "solvapay-auto-recharge-status" }),
|
|
8646
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Trigger, { className: "solvapay-auto-recharge-trigger" })
|
|
8647
|
+
] }),
|
|
8648
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Error, { className: "solvapay-auto-recharge-error" }),
|
|
8649
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AutoRecharge.Content, { className: "solvapay-auto-recharge-content", children: [
|
|
8650
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Title, { className: "solvapay-auto-recharge-title" }),
|
|
8651
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.EnableQuestion, { className: "solvapay-auto-recharge-question" }),
|
|
8652
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.EnableRow, { className: "solvapay-auto-recharge-enable-row" }),
|
|
8653
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AutoRecharge.Fields, { className: "solvapay-auto-recharge-fields", children: [
|
|
8654
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.ThresholdField, {}),
|
|
8655
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.TopupField, { className: "solvapay-auto-recharge-topup-field" }),
|
|
8656
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.ValidationError, { className: "solvapay-auto-recharge-validation-error" })
|
|
8657
|
+
] }),
|
|
8658
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.Setup, {}),
|
|
8659
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(AutoRecharge.Actions, { className: "solvapay-auto-recharge-actions", children: [
|
|
8660
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.CancelButton, { className: "solvapay-auto-recharge-cancel" }),
|
|
8661
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(AutoRecharge.SaveButton, { className: "solvapay-auto-recharge-save" })
|
|
8662
|
+
] })
|
|
8663
|
+
] })
|
|
8664
|
+
]
|
|
8665
|
+
}
|
|
8666
|
+
);
|
|
8667
|
+
}
|
|
8668
|
+
|
|
8669
|
+
// src/hooks/useLimits.ts
|
|
8670
|
+
var import_react43 = require("react");
|
|
8671
|
+
var CACHE_TTL_MS = 1e4;
|
|
8672
|
+
var OPTIMISTIC_GRACE_MS = 8e3;
|
|
8673
|
+
var limitsCache = /* @__PURE__ */ new Map();
|
|
8674
|
+
function cacheKey(customerRef, productRef, meterName) {
|
|
8675
|
+
return `${customerRef ?? "anonymous"}:${productRef}:${meterName}`;
|
|
8676
|
+
}
|
|
8677
|
+
function useLimits(options) {
|
|
8678
|
+
const { productRef, meterName: rawMeterName, enabled = true } = options;
|
|
8679
|
+
const meterName = rawMeterName || "requests";
|
|
8680
|
+
const transport = useTransport();
|
|
8681
|
+
const { customerRef } = useCustomer();
|
|
8682
|
+
const { purchase } = useSolvaPay();
|
|
8683
|
+
const currentKey = !productRef || !enabled ? null : cacheKey(customerRef, productRef, meterName);
|
|
8684
|
+
const [data, setData] = (0, import_react43.useState)(() => {
|
|
8685
|
+
if (!currentKey) return null;
|
|
8686
|
+
const cached = limitsCache.get(currentKey);
|
|
8687
|
+
if (!cached || Date.now() - cached.timestamp >= CACHE_TTL_MS) return null;
|
|
8688
|
+
return cached.data;
|
|
8689
|
+
});
|
|
8690
|
+
const [loading, setLoading] = (0, import_react43.useState)(() => {
|
|
8691
|
+
if (!currentKey) return false;
|
|
8692
|
+
const cached = limitsCache.get(currentKey);
|
|
8693
|
+
if (!cached) return true;
|
|
8694
|
+
if (cached.promise) return true;
|
|
8695
|
+
if (Date.now() - cached.timestamp >= CACHE_TTL_MS) return true;
|
|
8696
|
+
return false;
|
|
8697
|
+
});
|
|
8698
|
+
const [error, setError] = (0, import_react43.useState)(null);
|
|
8699
|
+
const [trackedKey, setTrackedKey] = (0, import_react43.useState)(currentKey);
|
|
8700
|
+
if (trackedKey !== currentKey) {
|
|
8701
|
+
setTrackedKey(currentKey);
|
|
8702
|
+
setData(null);
|
|
8703
|
+
}
|
|
8704
|
+
const optimisticTimerRef = (0, import_react43.useRef)(null);
|
|
8705
|
+
(0, import_react43.useEffect)(() => {
|
|
8706
|
+
return () => {
|
|
8707
|
+
if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
|
|
8708
|
+
};
|
|
8709
|
+
}, []);
|
|
8710
|
+
const attachToFetch = (0, import_react43.useCallback)(
|
|
8711
|
+
async (promise) => {
|
|
8712
|
+
setLoading(true);
|
|
8713
|
+
try {
|
|
8714
|
+
const fresh = await promise;
|
|
8715
|
+
setData(fresh);
|
|
8716
|
+
setError(null);
|
|
8717
|
+
return fresh;
|
|
8718
|
+
} catch (err) {
|
|
8719
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch limits"));
|
|
8720
|
+
return null;
|
|
8721
|
+
} finally {
|
|
8722
|
+
setLoading(false);
|
|
8723
|
+
}
|
|
8724
|
+
},
|
|
8725
|
+
[]
|
|
8726
|
+
);
|
|
8727
|
+
const fetchLimits = (0, import_react43.useCallback)(
|
|
8728
|
+
async (force) => {
|
|
8729
|
+
if (!productRef || !enabled || !transport.getLimits) {
|
|
8730
|
+
setLoading(false);
|
|
8731
|
+
return;
|
|
8732
|
+
}
|
|
8733
|
+
const key = cacheKey(customerRef, productRef, meterName);
|
|
8734
|
+
const cached = limitsCache.get(key);
|
|
8735
|
+
const now = Date.now();
|
|
8736
|
+
if (cached?.promise) {
|
|
8737
|
+
await attachToFetch(cached.promise);
|
|
8738
|
+
return;
|
|
8739
|
+
}
|
|
8740
|
+
if (!force && cached?.data && now - cached.timestamp < CACHE_TTL_MS) {
|
|
8741
|
+
setData(cached.data);
|
|
8742
|
+
setLoading(false);
|
|
8743
|
+
setError(null);
|
|
8744
|
+
return;
|
|
8745
|
+
}
|
|
8746
|
+
const promise = transport.getLimits({ productRef, meterName });
|
|
8747
|
+
limitsCache.set(key, { data: cached?.data ?? null, timestamp: now, promise });
|
|
8748
|
+
const fresh = await attachToFetch(promise);
|
|
8749
|
+
if (fresh !== null) {
|
|
8750
|
+
limitsCache.set(key, { data: fresh, timestamp: Date.now(), promise: null });
|
|
8751
|
+
} else {
|
|
8752
|
+
limitsCache.delete(key);
|
|
8753
|
+
}
|
|
8754
|
+
},
|
|
8755
|
+
[transport, customerRef, productRef, meterName, enabled, attachToFetch]
|
|
8756
|
+
);
|
|
8757
|
+
(0, import_react43.useEffect)(() => {
|
|
8758
|
+
fetchLimits(false);
|
|
8759
|
+
}, [fetchLimits]);
|
|
8760
|
+
const prevPurchasesRef = (0, import_react43.useRef)(null);
|
|
8761
|
+
(0, import_react43.useEffect)(() => {
|
|
8762
|
+
if (prevPurchasesRef.current !== null && prevPurchasesRef.current !== purchase.purchases) {
|
|
8763
|
+
fetchLimits(true).catch(() => {
|
|
8764
|
+
});
|
|
8765
|
+
}
|
|
8766
|
+
prevPurchasesRef.current = purchase.purchases;
|
|
8767
|
+
}, [purchase.purchases, fetchLimits]);
|
|
8768
|
+
const refetch = (0, import_react43.useCallback)(() => fetchLimits(true), [fetchLimits]);
|
|
8769
|
+
const adjustRemaining = (0, import_react43.useCallback)(
|
|
8770
|
+
(delta) => {
|
|
8771
|
+
if (!productRef || !enabled) return;
|
|
8772
|
+
const key = cacheKey(customerRef, productRef, meterName);
|
|
8773
|
+
setData((prev) => {
|
|
8774
|
+
const cached = limitsCache.get(key);
|
|
8775
|
+
const baseline = prev ?? cached?.data ?? null;
|
|
8776
|
+
if (!baseline) return prev;
|
|
8777
|
+
const next = {
|
|
8778
|
+
...baseline,
|
|
8779
|
+
remaining: Math.max(0, baseline.remaining + delta)
|
|
8780
|
+
// Don't optimistically flip `withinLimits` — paywall gating
|
|
8781
|
+
// can hinge on factors beyond `remaining > 0`
|
|
8782
|
+
// (activationRequired, etc.). Let the trailing refetch
|
|
8783
|
+
// confirm.
|
|
8784
|
+
};
|
|
8785
|
+
limitsCache.set(key, {
|
|
8786
|
+
data: next,
|
|
8787
|
+
timestamp: Date.now(),
|
|
8788
|
+
promise: cached?.promise ?? null
|
|
8789
|
+
});
|
|
8790
|
+
return next;
|
|
8791
|
+
});
|
|
8792
|
+
if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
|
|
8793
|
+
optimisticTimerRef.current = setTimeout(() => {
|
|
8794
|
+
optimisticTimerRef.current = null;
|
|
8795
|
+
fetchLimits(true).catch(() => {
|
|
8796
|
+
});
|
|
8797
|
+
}, OPTIMISTIC_GRACE_MS);
|
|
8798
|
+
},
|
|
8799
|
+
[customerRef, productRef, meterName, enabled, fetchLimits]
|
|
8800
|
+
);
|
|
8801
|
+
return {
|
|
8802
|
+
remaining: data?.remaining ?? null,
|
|
8803
|
+
withinLimits: data?.withinLimits ?? null,
|
|
8804
|
+
meterName: data?.meterName ?? null,
|
|
8805
|
+
activationRequired: data?.activationRequired ?? null,
|
|
8806
|
+
loading,
|
|
8807
|
+
error,
|
|
8808
|
+
refetch,
|
|
8809
|
+
adjustRemaining
|
|
8810
|
+
};
|
|
8811
|
+
}
|
|
8812
|
+
|
|
8813
|
+
// src/hooks/useAutoActivateFreePlan.ts
|
|
8814
|
+
var import_react44 = require("react");
|
|
8815
|
+
function useAutoActivateFreePlan(options) {
|
|
8816
|
+
const { productRef, enabled = true, onActivated } = options;
|
|
8817
|
+
const { customerRef } = useCustomer();
|
|
8818
|
+
const { activationRequired, refetch: refetchLimits } = useLimits({
|
|
8819
|
+
productRef,
|
|
8820
|
+
enabled
|
|
8821
|
+
});
|
|
8822
|
+
const { plans } = usePlans({ productRef });
|
|
8823
|
+
const { activate, error: activationError } = useActivation();
|
|
8824
|
+
const freePlan = (0, import_react44.useMemo)(
|
|
8825
|
+
() => plans.find((p) => p.requiresPayment === false && (p.freeUnits ?? 0) > 0),
|
|
8826
|
+
[plans]
|
|
8827
|
+
);
|
|
8828
|
+
const attemptedKeyRef = (0, import_react44.useRef)(null);
|
|
8829
|
+
const [activated, setActivated] = (0, import_react44.useState)(false);
|
|
8830
|
+
const onActivatedRef = (0, import_react44.useRef)(onActivated);
|
|
8831
|
+
(0, import_react44.useEffect)(() => {
|
|
8832
|
+
onActivatedRef.current = onActivated;
|
|
8833
|
+
}, [onActivated]);
|
|
8834
|
+
(0, import_react44.useEffect)(() => {
|
|
8835
|
+
attemptedKeyRef.current = null;
|
|
8836
|
+
setActivated(false);
|
|
8837
|
+
}, [customerRef, productRef]);
|
|
8838
|
+
const shouldActivate = enabled && activationRequired === true && Boolean(productRef) && Boolean(freePlan?.reference);
|
|
8839
|
+
(0, import_react44.useEffect)(() => {
|
|
6990
8840
|
if (!shouldActivate || !productRef || !freePlan?.reference) return;
|
|
6991
8841
|
const key = `${customerRef ?? "anonymous"}:${productRef}`;
|
|
6992
8842
|
if (attemptedKeyRef.current === key) return;
|
|
@@ -7011,7 +8861,7 @@ function useAutoActivateFreePlan(options) {
|
|
|
7011
8861
|
}
|
|
7012
8862
|
|
|
7013
8863
|
// src/hooks/usePaywallResolver.ts
|
|
7014
|
-
var
|
|
8864
|
+
var import_react45 = require("react");
|
|
7015
8865
|
function balanceCoversNextUnit(balance, credits) {
|
|
7016
8866
|
if (!balance) return false;
|
|
7017
8867
|
if (typeof balance.remainingUnits === "number" && balance.remainingUnits > 0) {
|
|
@@ -7025,7 +8875,7 @@ function balanceCoversNextUnit(balance, credits) {
|
|
|
7025
8875
|
function usePaywallResolver(content) {
|
|
7026
8876
|
const { activePurchase, hasPaidPurchase, refetch: refetchPurchase } = usePurchase();
|
|
7027
8877
|
const { credits, refetch: refetchBalance } = useBalance();
|
|
7028
|
-
const resolved = (0,
|
|
8878
|
+
const resolved = (0, import_react45.useMemo)(() => {
|
|
7029
8879
|
if (!content) return false;
|
|
7030
8880
|
const productMatches = !content.product || activePurchase?.productRef === content.product || activePurchase?.productName === content.product;
|
|
7031
8881
|
if (content.kind === "payment_required") {
|
|
@@ -7035,7 +8885,7 @@ function usePaywallResolver(content) {
|
|
|
7035
8885
|
if (balanceCoversNextUnit(content.balance, credits)) return true;
|
|
7036
8886
|
return Boolean(productMatches && activePurchase?.status === "active");
|
|
7037
8887
|
}, [content, hasPaidPurchase, activePurchase, credits]);
|
|
7038
|
-
const refetch = (0,
|
|
8888
|
+
const refetch = (0, import_react45.useCallback)(async () => {
|
|
7039
8889
|
await Promise.all([
|
|
7040
8890
|
refetchPurchase().catch(() => void 0),
|
|
7041
8891
|
refetchBalance().catch(() => void 0)
|
|
@@ -7045,7 +8895,7 @@ function usePaywallResolver(content) {
|
|
|
7045
8895
|
}
|
|
7046
8896
|
|
|
7047
8897
|
// src/hooks/useCheckoutFlow.ts
|
|
7048
|
-
var
|
|
8898
|
+
var import_react46 = require("react");
|
|
7049
8899
|
|
|
7050
8900
|
// src/primitives/checkout/shared.ts
|
|
7051
8901
|
function isPayg(plan) {
|
|
@@ -7108,10 +8958,10 @@ function useCheckoutFlow(opts) {
|
|
|
7108
8958
|
initialStep = "plan",
|
|
7109
8959
|
initialAmountMinor = null
|
|
7110
8960
|
} = opts;
|
|
7111
|
-
const onPlanSelectRef = (0,
|
|
7112
|
-
const onAmountSelectRef = (0,
|
|
7113
|
-
const onPurchaseSuccessRef = (0,
|
|
7114
|
-
const onErrorRef = (0,
|
|
8961
|
+
const onPlanSelectRef = (0, import_react46.useRef)(opts.onPlanSelect);
|
|
8962
|
+
const onAmountSelectRef = (0, import_react46.useRef)(opts.onAmountSelect);
|
|
8963
|
+
const onPurchaseSuccessRef = (0, import_react46.useRef)(opts.onPurchaseSuccess);
|
|
8964
|
+
const onErrorRef = (0, import_react46.useRef)(opts.onError);
|
|
7115
8965
|
onPlanSelectRef.current = opts.onPlanSelect;
|
|
7116
8966
|
onAmountSelectRef.current = opts.onAmountSelect;
|
|
7117
8967
|
onPurchaseSuccessRef.current = opts.onPurchaseSuccess;
|
|
@@ -7124,8 +8974,8 @@ function useCheckoutFlow(opts) {
|
|
|
7124
8974
|
const { creditsPerMinorUnit, displayExchangeRate, adjustBalance } = balance;
|
|
7125
8975
|
const { refetchPurchase } = useSolvaPay();
|
|
7126
8976
|
const { merchant } = useMerchant();
|
|
7127
|
-
const [topupCurrencyOverride, setTopupCurrencyOverride] = (0,
|
|
7128
|
-
const topupCurrencies = (0,
|
|
8977
|
+
const [topupCurrencyOverride, setTopupCurrencyOverride] = (0, import_react46.useState)(null);
|
|
8978
|
+
const topupCurrencies = (0, import_react46.useMemo)(() => {
|
|
7129
8979
|
const fromMerchant = (merchant?.supportedTopupCurrencies ?? []).map((code) => code.toUpperCase()).filter(Boolean);
|
|
7130
8980
|
const fallback = opts.topupCurrency?.toUpperCase() ?? merchant?.defaultCurrency?.toUpperCase() ?? null;
|
|
7131
8981
|
const list = fromMerchant.length > 0 ? fromMerchant : fallback ? [fallback] : [];
|
|
@@ -7135,25 +8985,25 @@ function useCheckoutFlow(opts) {
|
|
|
7135
8985
|
const planPickerCurrency = planCtx.preferredCurrency?.toUpperCase() ?? null;
|
|
7136
8986
|
const topupCurrency = (topupCurrencyOverride && topupCurrencies.includes(topupCurrencyOverride) ? topupCurrencyOverride : null) ?? (planPickerCurrency && topupCurrencies.includes(planPickerCurrency) ? planPickerCurrency : null) ?? resolvedDefaultTopupCurrency;
|
|
7137
8987
|
const topupCurrencyReady = topupCurrency != null;
|
|
7138
|
-
const setTopupCurrency = (0,
|
|
8988
|
+
const setTopupCurrency = (0, import_react46.useCallback)(
|
|
7139
8989
|
(code) => {
|
|
7140
8990
|
const normalized = code.toUpperCase();
|
|
7141
8991
|
setTopupCurrencyOverride(normalized);
|
|
7142
8992
|
},
|
|
7143
8993
|
[]
|
|
7144
8994
|
);
|
|
7145
|
-
const [step, setStep] = (0,
|
|
7146
|
-
const [status, setStatus] = (0,
|
|
7147
|
-
const [selectedAmountMinor, setSelectedAmountMinor] = (0,
|
|
7148
|
-
const [successMeta, setSuccessMeta] = (0,
|
|
7149
|
-
const [error, setError] = (0,
|
|
7150
|
-
const selectedAmountMinorRef = (0,
|
|
8995
|
+
const [step, setStep] = (0, import_react46.useState)(initialStep);
|
|
8996
|
+
const [status, setStatus] = (0, import_react46.useState)("idle");
|
|
8997
|
+
const [selectedAmountMinor, setSelectedAmountMinor] = (0, import_react46.useState)(initialAmountMinor);
|
|
8998
|
+
const [successMeta, setSuccessMeta] = (0, import_react46.useState)(null);
|
|
8999
|
+
const [error, setError] = (0, import_react46.useState)(null);
|
|
9000
|
+
const selectedAmountMinorRef = (0, import_react46.useRef)(initialAmountMinor);
|
|
7151
9001
|
const selectedPlan = planCtx.selectedPlan;
|
|
7152
9002
|
const selectedPlanRef = planCtx.selectedPlanRef;
|
|
7153
9003
|
const selectedPlanShape = selectedPlan;
|
|
7154
9004
|
const branch = selectedPlanShape ? isPayg(selectedPlanShape) ? "payg" : "recurring" : null;
|
|
7155
9005
|
const canGoBack = step === "amount" || step === "payment";
|
|
7156
|
-
const selectPlan = (0,
|
|
9006
|
+
const selectPlan = (0, import_react46.useCallback)(
|
|
7157
9007
|
(ref) => {
|
|
7158
9008
|
planCtx.select(ref);
|
|
7159
9009
|
const plan = planCtx.plans.find((p) => p.reference === ref) ?? null;
|
|
@@ -7163,7 +9013,7 @@ function useCheckoutFlow(opts) {
|
|
|
7163
9013
|
},
|
|
7164
9014
|
[planCtx]
|
|
7165
9015
|
);
|
|
7166
|
-
const selectAmount = (0,
|
|
9016
|
+
const selectAmount = (0, import_react46.useCallback)(
|
|
7167
9017
|
(amountMinor) => {
|
|
7168
9018
|
selectedAmountMinorRef.current = amountMinor;
|
|
7169
9019
|
setSelectedAmountMinor(amountMinor);
|
|
@@ -7172,7 +9022,7 @@ function useCheckoutFlow(opts) {
|
|
|
7172
9022
|
},
|
|
7173
9023
|
[topupCurrency]
|
|
7174
9024
|
);
|
|
7175
|
-
const runActivate = (0,
|
|
9025
|
+
const runActivate = (0, import_react46.useCallback)(async () => {
|
|
7176
9026
|
if (!selectedPlanShape || !selectedPlanRef) return false;
|
|
7177
9027
|
setError(null);
|
|
7178
9028
|
setStatus("activating");
|
|
@@ -7189,7 +9039,7 @@ function useCheckoutFlow(opts) {
|
|
|
7189
9039
|
return false;
|
|
7190
9040
|
}
|
|
7191
9041
|
}, [productRef, selectedPlanRef, selectedPlanShape, transport]);
|
|
7192
|
-
const advanceFromPlan = (0,
|
|
9042
|
+
const advanceFromPlan = (0, import_react46.useCallback)(async () => {
|
|
7193
9043
|
if (!selectedPlanShape || !selectedPlanRef) return;
|
|
7194
9044
|
if (branch === "payg") {
|
|
7195
9045
|
if (planCtx.currentPlanRef === selectedPlanRef) {
|
|
@@ -7203,7 +9053,7 @@ function useCheckoutFlow(opts) {
|
|
|
7203
9053
|
setError(null);
|
|
7204
9054
|
setStep("payment");
|
|
7205
9055
|
}, [branch, planCtx.currentPlanRef, runActivate, selectedPlanRef, selectedPlanShape]);
|
|
7206
|
-
const recordPaygSuccess = (0,
|
|
9056
|
+
const recordPaygSuccess = (0, import_react46.useCallback)(
|
|
7207
9057
|
(creditsAddedFromBackend) => {
|
|
7208
9058
|
if (!selectedPlanShape || selectedAmountMinor == null) return;
|
|
7209
9059
|
const currency = topupCurrency ?? "USD";
|
|
@@ -7237,7 +9087,7 @@ function useCheckoutFlow(opts) {
|
|
|
7237
9087
|
topupCurrency
|
|
7238
9088
|
]
|
|
7239
9089
|
);
|
|
7240
|
-
const recordRecurringSuccess = (0,
|
|
9090
|
+
const recordRecurringSuccess = (0, import_react46.useCallback)(() => {
|
|
7241
9091
|
if (!selectedPlanShape) return;
|
|
7242
9092
|
const pricingOption = selectedPlan ? resolvePlanPricingOption(selectedPlan, planSelection?.selectedCurrency) : {
|
|
7243
9093
|
currency: selectedPlanShape.currency ?? "USD",
|
|
@@ -7256,7 +9106,7 @@ function useCheckoutFlow(opts) {
|
|
|
7256
9106
|
setStep("success");
|
|
7257
9107
|
onPurchaseSuccessRef.current?.(meta);
|
|
7258
9108
|
}, [selectedPlanShape, selectedPlan, planSelection?.selectedCurrency]);
|
|
7259
|
-
const advance = (0,
|
|
9109
|
+
const advance = (0, import_react46.useCallback)(async () => {
|
|
7260
9110
|
if (step === "plan") {
|
|
7261
9111
|
await advanceFromPlan();
|
|
7262
9112
|
return;
|
|
@@ -7283,7 +9133,7 @@ function useCheckoutFlow(opts) {
|
|
|
7283
9133
|
selectedAmountMinor,
|
|
7284
9134
|
step
|
|
7285
9135
|
]);
|
|
7286
|
-
const back = (0,
|
|
9136
|
+
const back = (0, import_react46.useCallback)(() => {
|
|
7287
9137
|
setError(null);
|
|
7288
9138
|
if (step === "amount") {
|
|
7289
9139
|
setStep("plan");
|
|
@@ -7294,7 +9144,7 @@ function useCheckoutFlow(opts) {
|
|
|
7294
9144
|
return;
|
|
7295
9145
|
}
|
|
7296
9146
|
}, [branch, step]);
|
|
7297
|
-
const reset = (0,
|
|
9147
|
+
const reset = (0, import_react46.useCallback)(() => {
|
|
7298
9148
|
setStep("plan");
|
|
7299
9149
|
selectedAmountMinorRef.current = null;
|
|
7300
9150
|
setSelectedAmountMinor(null);
|
|
@@ -7303,13 +9153,13 @@ function useCheckoutFlow(opts) {
|
|
|
7303
9153
|
setStatus("idle");
|
|
7304
9154
|
setTopupCurrencyOverride(null);
|
|
7305
9155
|
}, []);
|
|
7306
|
-
const retry = (0,
|
|
9156
|
+
const retry = (0, import_react46.useCallback)(async () => {
|
|
7307
9157
|
if (status !== "error") return;
|
|
7308
9158
|
if (step === "plan" && branch === "payg") {
|
|
7309
9159
|
await runActivate();
|
|
7310
9160
|
}
|
|
7311
9161
|
}, [branch, runActivate, status, step]);
|
|
7312
|
-
const notifyPaymentSuccess = (0,
|
|
9162
|
+
const notifyPaymentSuccess = (0, import_react46.useCallback)(
|
|
7313
9163
|
(_intent, extras) => {
|
|
7314
9164
|
if (branch === "payg") {
|
|
7315
9165
|
recordPaygSuccess(extras?.creditsAdded);
|
|
@@ -7319,7 +9169,7 @@ function useCheckoutFlow(opts) {
|
|
|
7319
9169
|
},
|
|
7320
9170
|
[branch, recordPaygSuccess, recordRecurringSuccess]
|
|
7321
9171
|
);
|
|
7322
|
-
return (0,
|
|
9172
|
+
return (0, import_react46.useMemo)(
|
|
7323
9173
|
() => ({
|
|
7324
9174
|
step,
|
|
7325
9175
|
status,
|
|
@@ -7368,36 +9218,36 @@ function useCheckoutFlow(opts) {
|
|
|
7368
9218
|
}
|
|
7369
9219
|
|
|
7370
9220
|
// src/primitives/checkout/index.tsx
|
|
7371
|
-
var
|
|
9221
|
+
var import_react48 = require("react");
|
|
7372
9222
|
|
|
7373
9223
|
// src/primitives/PaywallNotice.tsx
|
|
7374
|
-
var
|
|
7375
|
-
var
|
|
7376
|
-
var PaywallNoticeContext = (0,
|
|
9224
|
+
var import_react47 = require("react");
|
|
9225
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
9226
|
+
var PaywallNoticeContext = (0, import_react47.createContext)(null);
|
|
7377
9227
|
function usePaywallNoticeCtx(part) {
|
|
7378
|
-
const ctx = (0,
|
|
9228
|
+
const ctx = (0, import_react47.useContext)(PaywallNoticeContext);
|
|
7379
9229
|
if (!ctx) {
|
|
7380
9230
|
throw new Error(`PaywallNotice.${part} must be rendered inside <PaywallNotice.Root>.`);
|
|
7381
9231
|
}
|
|
7382
9232
|
return ctx;
|
|
7383
9233
|
}
|
|
7384
|
-
var
|
|
9234
|
+
var Root12 = (0, import_react47.forwardRef)(function PaywallNoticeRoot({ content, onResolved, classNames, asChild, children, ...rest }, forwardedRef) {
|
|
7385
9235
|
const { resolved, refetch } = usePaywallResolver(content);
|
|
7386
|
-
const classNamesResolved = (0,
|
|
7387
|
-
const onResolvedRef = (0,
|
|
7388
|
-
(0,
|
|
9236
|
+
const classNamesResolved = (0, import_react47.useMemo)(() => classNames ?? {}, [classNames]);
|
|
9237
|
+
const onResolvedRef = (0, import_react47.useRef)(onResolved);
|
|
9238
|
+
(0, import_react47.useEffect)(() => {
|
|
7389
9239
|
onResolvedRef.current = onResolved;
|
|
7390
9240
|
}, [onResolved]);
|
|
7391
|
-
const hasResolvedRef = (0,
|
|
7392
|
-
const signalResolved = (0,
|
|
9241
|
+
const hasResolvedRef = (0, import_react47.useRef)(false);
|
|
9242
|
+
const signalResolved = (0, import_react47.useCallback)(() => {
|
|
7393
9243
|
if (hasResolvedRef.current) return;
|
|
7394
9244
|
hasResolvedRef.current = true;
|
|
7395
9245
|
onResolvedRef.current?.();
|
|
7396
9246
|
}, []);
|
|
7397
|
-
(0,
|
|
9247
|
+
(0, import_react47.useEffect)(() => {
|
|
7398
9248
|
if (resolved) signalResolved();
|
|
7399
9249
|
}, [resolved, signalResolved]);
|
|
7400
|
-
const ctx = (0,
|
|
9250
|
+
const ctx = (0, import_react47.useMemo)(
|
|
7401
9251
|
() => ({
|
|
7402
9252
|
content,
|
|
7403
9253
|
resolved,
|
|
@@ -7408,7 +9258,7 @@ var Root11 = (0, import_react45.forwardRef)(function PaywallNoticeRoot({ content
|
|
|
7408
9258
|
[content, resolved, refetch, signalResolved, classNamesResolved]
|
|
7409
9259
|
);
|
|
7410
9260
|
const Comp = asChild ? Slot : "div";
|
|
7411
|
-
return /* @__PURE__ */ (0,
|
|
9261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaywallNoticeContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7412
9262
|
Comp,
|
|
7413
9263
|
{
|
|
7414
9264
|
ref: forwardedRef,
|
|
@@ -7421,12 +9271,12 @@ var Root11 = (0, import_react45.forwardRef)(function PaywallNoticeRoot({ content
|
|
|
7421
9271
|
}
|
|
7422
9272
|
) });
|
|
7423
9273
|
});
|
|
7424
|
-
var Heading4 = (0,
|
|
9274
|
+
var Heading4 = (0, import_react47.forwardRef)(function PaywallNoticeHeading({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7425
9275
|
const ctx = usePaywallNoticeCtx("Heading");
|
|
7426
9276
|
const copy = useCopy();
|
|
7427
9277
|
const defaultText = ctx.resolved ? copy.paywall.resolvedHeading : ctx.content.kind === "payment_required" ? copy.paywall.paymentRequiredHeading : isTopupGate(ctx.content) ? copy.paywall.topupRequiredHeading : copy.paywall.activationRequiredHeading;
|
|
7428
9278
|
const Comp = asChild ? Slot : "h2";
|
|
7429
|
-
return /* @__PURE__ */ (0,
|
|
9279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7430
9280
|
Comp,
|
|
7431
9281
|
{
|
|
7432
9282
|
ref: forwardedRef,
|
|
@@ -7437,12 +9287,12 @@ var Heading4 = (0, import_react45.forwardRef)(function PaywallNoticeHeading({ as
|
|
|
7437
9287
|
}
|
|
7438
9288
|
);
|
|
7439
9289
|
});
|
|
7440
|
-
var Message = (0,
|
|
9290
|
+
var Message = (0, import_react47.forwardRef)(function PaywallNoticeMessage({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7441
9291
|
const ctx = usePaywallNoticeCtx("Message");
|
|
7442
9292
|
const copy = useCopy();
|
|
7443
9293
|
const Comp = asChild ? Slot : "p";
|
|
7444
9294
|
const defaultText = resolvePaywallMessage(ctx.content, copy.paywall);
|
|
7445
|
-
return /* @__PURE__ */ (0,
|
|
9295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7446
9296
|
Comp,
|
|
7447
9297
|
{
|
|
7448
9298
|
ref: forwardedRef,
|
|
@@ -7485,14 +9335,14 @@ function resolvePaywallMessage(content, paywallCopy) {
|
|
|
7485
9335
|
}
|
|
7486
9336
|
return content.message ?? "";
|
|
7487
9337
|
}
|
|
7488
|
-
var ProductContext = (0,
|
|
9338
|
+
var ProductContext = (0, import_react47.forwardRef)(function PaywallNoticeProductContext({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7489
9339
|
const ctx = usePaywallNoticeCtx("ProductContext");
|
|
7490
9340
|
const copy = useCopy();
|
|
7491
9341
|
const product = ctx.content.kind === "activation_required" ? ctx.content.productDetails : void 0;
|
|
7492
9342
|
if (!product?.name) return null;
|
|
7493
9343
|
const label = interpolate(copy.paywall.productContext, { product: product.name });
|
|
7494
9344
|
const Comp = asChild ? Slot : "div";
|
|
7495
|
-
return /* @__PURE__ */ (0,
|
|
9345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7496
9346
|
Comp,
|
|
7497
9347
|
{
|
|
7498
9348
|
ref: forwardedRef,
|
|
@@ -7503,7 +9353,7 @@ var ProductContext = (0, import_react45.forwardRef)(function PaywallNoticeProduc
|
|
|
7503
9353
|
}
|
|
7504
9354
|
);
|
|
7505
9355
|
});
|
|
7506
|
-
var Balance = (0,
|
|
9356
|
+
var Balance = (0, import_react47.forwardRef)(function PaywallNoticeBalance({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7507
9357
|
const ctx = usePaywallNoticeCtx("Balance");
|
|
7508
9358
|
const copy = useCopy();
|
|
7509
9359
|
const balance = ctx.content.balance;
|
|
@@ -7513,7 +9363,7 @@ var Balance = (0, import_react45.forwardRef)(function PaywallNoticeBalance({ asC
|
|
|
7513
9363
|
required: String(balance.creditsPerUnit ?? 1)
|
|
7514
9364
|
});
|
|
7515
9365
|
const Comp = asChild ? Slot : "div";
|
|
7516
|
-
return /* @__PURE__ */ (0,
|
|
9366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7517
9367
|
Comp,
|
|
7518
9368
|
{
|
|
7519
9369
|
ref: forwardedRef,
|
|
@@ -7529,27 +9379,27 @@ function Plans({ className, children }) {
|
|
|
7529
9379
|
if (ctx.content.kind !== "activation_required") return null;
|
|
7530
9380
|
if (!ctx.content.product) return null;
|
|
7531
9381
|
const defaultClass = className ?? ctx.classNames.plans ?? "solvapay-paywall-plans";
|
|
7532
|
-
return /* @__PURE__ */ (0,
|
|
7533
|
-
/* @__PURE__ */ (0,
|
|
7534
|
-
/* @__PURE__ */ (0,
|
|
7535
|
-
/* @__PURE__ */ (0,
|
|
7536
|
-
/* @__PURE__ */ (0,
|
|
7537
|
-
/* @__PURE__ */ (0,
|
|
9382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { "data-solvapay-paywall-plans": "", className: defaultClass, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Root, { productRef: ctx.content.product, filter: hidesFreePlan, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
9383
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Grid, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(PlanSelector.Card, { children: [
|
|
9384
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.CardBadge, {}),
|
|
9385
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.CardName, {}),
|
|
9386
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.CardPrice, {}),
|
|
9387
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.CardInterval, {})
|
|
7538
9388
|
] }) }),
|
|
7539
|
-
/* @__PURE__ */ (0,
|
|
7540
|
-
/* @__PURE__ */ (0,
|
|
9389
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Loading, {}),
|
|
9390
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Error, {})
|
|
7541
9391
|
] }) }) });
|
|
7542
9392
|
}
|
|
7543
9393
|
function hidesFreePlan(plan) {
|
|
7544
9394
|
return plan.requiresPayment !== false;
|
|
7545
9395
|
}
|
|
7546
|
-
var HostedCheckoutLink = (0,
|
|
9396
|
+
var HostedCheckoutLink = (0, import_react47.forwardRef)(function PaywallNoticeHostedCheckoutLink({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7547
9397
|
const ctx = usePaywallNoticeCtx("HostedCheckoutLink");
|
|
7548
9398
|
const copy = useCopy();
|
|
7549
9399
|
const href = ctx.content.checkoutUrl;
|
|
7550
9400
|
if (!href) return null;
|
|
7551
9401
|
const Comp = asChild ? Slot : "a";
|
|
7552
|
-
return /* @__PURE__ */ (0,
|
|
9402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7553
9403
|
Comp,
|
|
7554
9404
|
{
|
|
7555
9405
|
ref: forwardedRef,
|
|
@@ -7567,12 +9417,12 @@ function EmbeddedCheckout({ returnUrl, topupCurrency, className }) {
|
|
|
7567
9417
|
const ctx = usePaywallNoticeCtx("EmbeddedCheckout");
|
|
7568
9418
|
const productRef = ctx.content.product;
|
|
7569
9419
|
const { plans } = usePlans({ productRef: productRef ?? void 0 });
|
|
7570
|
-
const filter = (0,
|
|
9420
|
+
const filter = (0, import_react47.useMemo)(() => buildDefaultCheckoutPlanFilter(plans), [plans]);
|
|
7571
9421
|
if (!productRef) return null;
|
|
7572
9422
|
const resolvedClassName = className ?? ctx.classNames.embeddedCheckout ?? "solvapay-paywall-embedded-checkout";
|
|
7573
9423
|
const headingClassName = ctx.classNames.heading ?? "solvapay-paywall-step-heading";
|
|
7574
9424
|
const messageClassName = ctx.classNames.message ?? "solvapay-paywall-step-message";
|
|
7575
|
-
return /* @__PURE__ */ (0,
|
|
9425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
7576
9426
|
CheckoutSteps.Root,
|
|
7577
9427
|
{
|
|
7578
9428
|
productRef,
|
|
@@ -7585,33 +9435,33 @@ function EmbeddedCheckout({ returnUrl, topupCurrency, className }) {
|
|
|
7585
9435
|
},
|
|
7586
9436
|
className: resolvedClassName,
|
|
7587
9437
|
children: [
|
|
7588
|
-
/* @__PURE__ */ (0,
|
|
7589
|
-
/* @__PURE__ */ (0,
|
|
7590
|
-
/* @__PURE__ */ (0,
|
|
7591
|
-
/* @__PURE__ */ (0,
|
|
7592
|
-
/* @__PURE__ */ (0,
|
|
7593
|
-
/* @__PURE__ */ (0,
|
|
7594
|
-
/* @__PURE__ */ (0,
|
|
9438
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.StepHeading, { className: headingClassName }),
|
|
9439
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.StepMessage, { className: messageClassName }),
|
|
9440
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(CheckoutSteps.IfStep, { step: "plan", children: [
|
|
9441
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.PlanGrid, {}),
|
|
9442
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Loading, {}),
|
|
9443
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PlanSelector.Error, {}),
|
|
9444
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.PlanContinueButton, {})
|
|
7595
9445
|
] }),
|
|
7596
|
-
/* @__PURE__ */ (0,
|
|
7597
|
-
/* @__PURE__ */ (0,
|
|
7598
|
-
/* @__PURE__ */ (0,
|
|
7599
|
-
/* @__PURE__ */ (0,
|
|
9446
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(CheckoutSteps.IfStep, { step: "amount", children: [
|
|
9447
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.BackLink, {}),
|
|
9448
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.AmountPicker, {}),
|
|
9449
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.AmountContinueButton, {})
|
|
7600
9450
|
] }),
|
|
7601
|
-
/* @__PURE__ */ (0,
|
|
7602
|
-
/* @__PURE__ */ (0,
|
|
7603
|
-
/* @__PURE__ */ (0,
|
|
9451
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(CheckoutSteps.IfStep, { step: "payment", children: [
|
|
9452
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.BackLink, {}),
|
|
9453
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.Payment, {})
|
|
7604
9454
|
] }),
|
|
7605
|
-
/* @__PURE__ */ (0,
|
|
9455
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.IfStep, { step: "success", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CheckoutSteps.Success, {}) })
|
|
7606
9456
|
]
|
|
7607
9457
|
}
|
|
7608
9458
|
);
|
|
7609
9459
|
}
|
|
7610
|
-
var Retry = (0,
|
|
9460
|
+
var Retry = (0, import_react47.forwardRef)(function PaywallNoticeRetry({ asChild, children, className, onClick, ...rest }, forwardedRef) {
|
|
7611
9461
|
const ctx = usePaywallNoticeCtx("Retry");
|
|
7612
9462
|
const copy = useCopy();
|
|
7613
9463
|
const Comp = asChild ? Slot : "button";
|
|
7614
|
-
return /* @__PURE__ */ (0,
|
|
9464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
7615
9465
|
Comp,
|
|
7616
9466
|
{
|
|
7617
9467
|
ref: forwardedRef,
|
|
@@ -7629,8 +9479,8 @@ var Retry = (0, import_react45.forwardRef)(function PaywallNoticeRetry({ asChild
|
|
|
7629
9479
|
}
|
|
7630
9480
|
);
|
|
7631
9481
|
});
|
|
7632
|
-
var PaywallNotice = Object.assign(
|
|
7633
|
-
Root:
|
|
9482
|
+
var PaywallNotice = Object.assign(Root12, {
|
|
9483
|
+
Root: Root12,
|
|
7634
9484
|
Heading: Heading4,
|
|
7635
9485
|
Message,
|
|
7636
9486
|
ProductContext,
|
|
@@ -7641,14 +9491,14 @@ var PaywallNotice = Object.assign(Root11, {
|
|
|
7641
9491
|
Retry
|
|
7642
9492
|
});
|
|
7643
9493
|
function usePaywallNoticeOptional() {
|
|
7644
|
-
return (0,
|
|
9494
|
+
return (0, import_react47.useContext)(PaywallNoticeContext);
|
|
7645
9495
|
}
|
|
7646
9496
|
|
|
7647
9497
|
// src/primitives/checkout/index.tsx
|
|
7648
|
-
var
|
|
7649
|
-
var CheckoutContext = (0,
|
|
9498
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
9499
|
+
var CheckoutContext = (0, import_react48.createContext)(null);
|
|
7650
9500
|
function useCheckoutContext(part) {
|
|
7651
|
-
const ctx = (0,
|
|
9501
|
+
const ctx = (0, import_react48.useContext)(CheckoutContext);
|
|
7652
9502
|
if (!ctx) {
|
|
7653
9503
|
throw new Error(`CheckoutSteps.${part} must be rendered inside <CheckoutSteps.Root>.`);
|
|
7654
9504
|
}
|
|
@@ -7657,7 +9507,7 @@ function useCheckoutContext(part) {
|
|
|
7657
9507
|
function useCheckoutSteps() {
|
|
7658
9508
|
return useCheckoutContext("useCheckoutSteps");
|
|
7659
9509
|
}
|
|
7660
|
-
var
|
|
9510
|
+
var Root13 = (0, import_react48.forwardRef)(function CheckoutStepsRoot(props, forwardedRef) {
|
|
7661
9511
|
const {
|
|
7662
9512
|
productRef,
|
|
7663
9513
|
returnUrl: _returnUrl,
|
|
@@ -7679,9 +9529,9 @@ var Root12 = (0, import_react46.forwardRef)(function CheckoutStepsRoot(props, fo
|
|
|
7679
9529
|
children
|
|
7680
9530
|
} = props;
|
|
7681
9531
|
if (externalFlow) {
|
|
7682
|
-
return /* @__PURE__ */ (0,
|
|
9532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", className, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CheckoutContext.Provider, { value: externalFlow, children }) });
|
|
7683
9533
|
}
|
|
7684
|
-
return /* @__PURE__ */ (0,
|
|
9534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7685
9535
|
RootWithPlanSelector,
|
|
7686
9536
|
{
|
|
7687
9537
|
productRef,
|
|
@@ -7724,11 +9574,11 @@ function RootWithPlanSelector({
|
|
|
7724
9574
|
children
|
|
7725
9575
|
}) {
|
|
7726
9576
|
const { plans } = usePlans({ productRef });
|
|
7727
|
-
const resolvedFilter = (0,
|
|
9577
|
+
const resolvedFilter = (0, import_react48.useMemo)(
|
|
7728
9578
|
() => filter ?? buildDefaultCheckoutPlanFilter(plans),
|
|
7729
9579
|
[filter, plans]
|
|
7730
9580
|
);
|
|
7731
|
-
return /* @__PURE__ */ (0,
|
|
9581
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7732
9582
|
PlanSelector.Root,
|
|
7733
9583
|
{
|
|
7734
9584
|
productRef,
|
|
@@ -7738,7 +9588,7 @@ function RootWithPlanSelector({
|
|
|
7738
9588
|
currentPlanRef,
|
|
7739
9589
|
autoSelectFirstPaid,
|
|
7740
9590
|
initialPlanRef,
|
|
7741
|
-
children: /* @__PURE__ */ (0,
|
|
9591
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7742
9592
|
FlowProvider,
|
|
7743
9593
|
{
|
|
7744
9594
|
productRef,
|
|
@@ -7780,22 +9630,22 @@ function FlowProvider({
|
|
|
7780
9630
|
onPurchaseSuccess,
|
|
7781
9631
|
onError
|
|
7782
9632
|
});
|
|
7783
|
-
return /* @__PURE__ */ (0,
|
|
9633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { ref: forwardedRef, "data-solvapay-checkout": "", "data-step": flow.step, className, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CheckoutContext.Provider, { value: flow, children }) });
|
|
7784
9634
|
}
|
|
7785
9635
|
function IfStep({ step, children }) {
|
|
7786
9636
|
const flow = useCheckoutContext("IfStep");
|
|
7787
9637
|
const matches = Array.isArray(step) ? step.includes(flow.step) : flow.step === step;
|
|
7788
9638
|
if (!matches) return null;
|
|
7789
|
-
return /* @__PURE__ */ (0,
|
|
9639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_jsx_runtime39.Fragment, { children });
|
|
7790
9640
|
}
|
|
7791
|
-
var StepHeading = (0,
|
|
9641
|
+
var StepHeading = (0, import_react48.forwardRef)(function CheckoutStepsStepHeading({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7792
9642
|
const flow = useCheckoutContext("StepHeading");
|
|
7793
9643
|
const copy = useCopy();
|
|
7794
9644
|
const paywallCtx = usePaywallNoticeOptional();
|
|
7795
9645
|
if (flow.step === "success") return null;
|
|
7796
9646
|
const defaultText = resolveStepHeading(flow.step, copy, paywallCtx?.content ?? null);
|
|
7797
9647
|
const Comp = asChild ? Slot : "h3";
|
|
7798
|
-
return /* @__PURE__ */ (0,
|
|
9648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7799
9649
|
Comp,
|
|
7800
9650
|
{
|
|
7801
9651
|
ref: forwardedRef,
|
|
@@ -7807,7 +9657,7 @@ var StepHeading = (0, import_react46.forwardRef)(function CheckoutStepsStepHeadi
|
|
|
7807
9657
|
}
|
|
7808
9658
|
);
|
|
7809
9659
|
});
|
|
7810
|
-
var StepMessage = (0,
|
|
9660
|
+
var StepMessage = (0, import_react48.forwardRef)(function CheckoutStepsStepMessage({ asChild, children, className, ...rest }, forwardedRef) {
|
|
7811
9661
|
const flow = useCheckoutContext("StepMessage");
|
|
7812
9662
|
const copy = useCopy();
|
|
7813
9663
|
const paywallCtx = usePaywallNoticeOptional();
|
|
@@ -7815,7 +9665,7 @@ var StepMessage = (0, import_react46.forwardRef)(function CheckoutStepsStepMessa
|
|
|
7815
9665
|
const defaultText = resolveStepMessage(flow, copy, paywallCtx?.content ?? null);
|
|
7816
9666
|
if (!defaultText && children == null) return null;
|
|
7817
9667
|
const Comp = asChild ? Slot : "p";
|
|
7818
|
-
return /* @__PURE__ */ (0,
|
|
9668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7819
9669
|
Comp,
|
|
7820
9670
|
{
|
|
7821
9671
|
ref: forwardedRef,
|
|
@@ -7862,21 +9712,21 @@ function resolveStepMessage(flow, copy, content) {
|
|
|
7862
9712
|
return "";
|
|
7863
9713
|
}
|
|
7864
9714
|
function PlanGrid({ className, children }) {
|
|
7865
|
-
return /* @__PURE__ */ (0,
|
|
7866
|
-
/* @__PURE__ */ (0,
|
|
7867
|
-
/* @__PURE__ */ (0,
|
|
7868
|
-
/* @__PURE__ */ (0,
|
|
7869
|
-
/* @__PURE__ */ (0,
|
|
9715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PlanSelector.Grid, { className: className ?? "solvapay-checkout-plan-grid", children: children ?? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(PlanSelector.Card, { className: "solvapay-checkout-plan-card", children: [
|
|
9716
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PlanSelector.CardBadge, { className: "solvapay-checkout-plan-card-badge" }),
|
|
9717
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PlanSelector.CardName, { className: "solvapay-checkout-plan-card-name" }),
|
|
9718
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PlanSelector.CardPrice, { className: "solvapay-checkout-plan-card-price" }),
|
|
9719
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PlanSelector.CardInterval, { className: "solvapay-checkout-plan-card-interval" })
|
|
7870
9720
|
] }) });
|
|
7871
9721
|
}
|
|
7872
|
-
var PlanContinueButton = (0,
|
|
9722
|
+
var PlanContinueButton = (0, import_react48.forwardRef)(
|
|
7873
9723
|
function PlanContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
|
|
7874
9724
|
const flow = useCheckoutContext("PlanContinueButton");
|
|
7875
9725
|
const locale = useLocale();
|
|
7876
9726
|
const selectedPlanShape = flow.selectedPlan;
|
|
7877
9727
|
const isDisabled = disabled || !flow.selectedPlanRef || flow.status === "activating";
|
|
7878
9728
|
const label = children ?? formatContinueLabel(selectedPlanShape, locale);
|
|
7879
|
-
return /* @__PURE__ */ (0,
|
|
9729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7880
9730
|
"button",
|
|
7881
9731
|
{
|
|
7882
9732
|
ref,
|
|
@@ -7899,13 +9749,13 @@ var PlanContinueButton = (0, import_react46.forwardRef)(
|
|
|
7899
9749
|
function AmountPicker3({ className, children }) {
|
|
7900
9750
|
const flow = useCheckoutContext("AmountPicker");
|
|
7901
9751
|
if (!flow.topupCurrencyReady || flow.topupCurrency == null) {
|
|
7902
|
-
return /* @__PURE__ */ (0,
|
|
9752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7903
9753
|
"div",
|
|
7904
9754
|
{
|
|
7905
9755
|
className: className ?? "solvapay-amount-picker",
|
|
7906
9756
|
"data-state": "loading",
|
|
7907
9757
|
"aria-busy": "true",
|
|
7908
|
-
children: /* @__PURE__ */ (0,
|
|
9758
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-amount-picker-pills", children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7909
9759
|
"span",
|
|
7910
9760
|
{
|
|
7911
9761
|
className: "solvapay-amount-picker-pill",
|
|
@@ -7917,7 +9767,7 @@ function AmountPicker3({ className, children }) {
|
|
|
7917
9767
|
}
|
|
7918
9768
|
);
|
|
7919
9769
|
}
|
|
7920
|
-
return /* @__PURE__ */ (0,
|
|
9770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7921
9771
|
AmountPicker.Root,
|
|
7922
9772
|
{
|
|
7923
9773
|
currency: flow.topupCurrency,
|
|
@@ -7928,16 +9778,16 @@ function AmountPicker3({ className, children }) {
|
|
|
7928
9778
|
flow.selectAmount(value);
|
|
7929
9779
|
}
|
|
7930
9780
|
},
|
|
7931
|
-
children: children ?? /* @__PURE__ */ (0,
|
|
9781
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(DefaultAmountTree, {})
|
|
7932
9782
|
}
|
|
7933
9783
|
);
|
|
7934
9784
|
}
|
|
7935
9785
|
function DefaultAmountTree() {
|
|
7936
9786
|
const ctx = useAmountPicker();
|
|
7937
9787
|
const { selectAmountLabel, customAmountLabel, creditEstimate } = useAmountPickerCopy();
|
|
7938
|
-
return /* @__PURE__ */ (0,
|
|
7939
|
-
/* @__PURE__ */ (0,
|
|
7940
|
-
/* @__PURE__ */ (0,
|
|
9788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_jsx_runtime39.Fragment, { children: [
|
|
9789
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "solvapay-amount-picker-label", children: selectAmountLabel }),
|
|
9790
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-amount-picker-pills", children: ctx.quickAmounts.map((amount) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7941
9791
|
AmountPicker.Option,
|
|
7942
9792
|
{
|
|
7943
9793
|
amount,
|
|
@@ -7945,11 +9795,11 @@ function DefaultAmountTree() {
|
|
|
7945
9795
|
},
|
|
7946
9796
|
amount
|
|
7947
9797
|
)) }),
|
|
7948
|
-
/* @__PURE__ */ (0,
|
|
7949
|
-
/* @__PURE__ */ (0,
|
|
7950
|
-
/* @__PURE__ */ (0,
|
|
7951
|
-
/* @__PURE__ */ (0,
|
|
7952
|
-
/* @__PURE__ */ (0,
|
|
9798
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-amount-picker-custom-wrapper", children: [
|
|
9799
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "solvapay-amount-picker-custom-label", children: customAmountLabel }),
|
|
9800
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-amount-picker-custom-row", children: [
|
|
9801
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "solvapay-amount-picker-currency-symbol", children: ctx.currencySymbol }),
|
|
9802
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7953
9803
|
AmountPicker.Custom,
|
|
7954
9804
|
{
|
|
7955
9805
|
className: "solvapay-amount-picker-custom-input",
|
|
@@ -7958,7 +9808,7 @@ function DefaultAmountTree() {
|
|
|
7958
9808
|
)
|
|
7959
9809
|
] })
|
|
7960
9810
|
] }),
|
|
7961
|
-
/* @__PURE__ */ (0,
|
|
9811
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7962
9812
|
"p",
|
|
7963
9813
|
{
|
|
7964
9814
|
className: "solvapay-amount-picker-credit-estimate",
|
|
@@ -7968,7 +9818,7 @@ function DefaultAmountTree() {
|
|
|
7968
9818
|
)
|
|
7969
9819
|
] });
|
|
7970
9820
|
}
|
|
7971
|
-
var AmountContinueButton = (0,
|
|
9821
|
+
var AmountContinueButton = (0, import_react48.forwardRef)(
|
|
7972
9822
|
function AmountContinueButton2({ className, children, onClick, disabled, ...rest }, ref) {
|
|
7973
9823
|
const flow = useCheckoutContext("AmountContinueButton");
|
|
7974
9824
|
const locale = useLocale();
|
|
@@ -7977,7 +9827,7 @@ var AmountContinueButton = (0, import_react46.forwardRef)(
|
|
|
7977
9827
|
const ready = flow.topupCurrencyReady && currency != null;
|
|
7978
9828
|
const isDisabled = disabled || !ready || amountMinor == null;
|
|
7979
9829
|
const label = children ?? (ready && currency != null && amountMinor != null ? `Continue \u2014 ${formatPrice(amountMinor, currency, { locale })}` : "Continue");
|
|
7980
|
-
return /* @__PURE__ */ (0,
|
|
9830
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
7981
9831
|
"button",
|
|
7982
9832
|
{
|
|
7983
9833
|
ref,
|
|
@@ -8000,10 +9850,10 @@ var AmountContinueButton = (0, import_react46.forwardRef)(
|
|
|
8000
9850
|
function Payment({ className }) {
|
|
8001
9851
|
const flow = useCheckoutContext("Payment");
|
|
8002
9852
|
if (flow.branch === "payg") {
|
|
8003
|
-
return /* @__PURE__ */ (0,
|
|
9853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaygPayment, { className });
|
|
8004
9854
|
}
|
|
8005
9855
|
if (flow.branch === "recurring") {
|
|
8006
|
-
return /* @__PURE__ */ (0,
|
|
9856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RecurringPayment, { className });
|
|
8007
9857
|
}
|
|
8008
9858
|
return null;
|
|
8009
9859
|
}
|
|
@@ -8017,12 +9867,12 @@ function PaygPayment({ className }) {
|
|
|
8017
9867
|
const currency = flow.topupCurrency;
|
|
8018
9868
|
if (!selectedPlanShape || amountMinor == null || currency == null) return null;
|
|
8019
9869
|
const creditsAdded = creditsPerMinorUnit != null && creditsPerMinorUnit > 0 ? Math.floor(amountMinor / (displayExchangeRate ?? 1) * creditsPerMinorUnit) : null;
|
|
8020
|
-
return /* @__PURE__ */ (0,
|
|
8021
|
-
/* @__PURE__ */ (0,
|
|
8022
|
-
/* @__PURE__ */ (0,
|
|
8023
|
-
creditsAdded != null ? /* @__PURE__ */ (0,
|
|
9870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "payg", children: [
|
|
9871
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "payg", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
|
|
9872
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: creditsAdded != null ? `${creditsAdded.toLocaleString(locale)} credits` : formatPrice(amountMinor, currency, { locale }) }),
|
|
9873
|
+
creditsAdded != null ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: formatPrice(amountMinor, currency, { locale }) }) : null
|
|
8024
9874
|
] }) }),
|
|
8025
|
-
/* @__PURE__ */ (0,
|
|
9875
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8026
9876
|
TopupForm.Root,
|
|
8027
9877
|
{
|
|
8028
9878
|
amount: amountMinor,
|
|
@@ -8031,11 +9881,11 @@ function PaygPayment({ className }) {
|
|
|
8031
9881
|
className: "solvapay-checkout-topup-form",
|
|
8032
9882
|
onSuccess: (intent, extras) => flow.notifyPaymentSuccess(intent, extras),
|
|
8033
9883
|
children: [
|
|
8034
|
-
/* @__PURE__ */ (0,
|
|
8035
|
-
/* @__PURE__ */ (0,
|
|
8036
|
-
/* @__PURE__ */ (0,
|
|
8037
|
-
/* @__PURE__ */ (0,
|
|
8038
|
-
/* @__PURE__ */ (0,
|
|
9884
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(TopupForm.Loading, {}),
|
|
9885
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(TopupForm.PaymentElement, {}),
|
|
9886
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(TopupForm.Error, { className: "solvapay-checkout-error" }),
|
|
9887
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(MandateText, { mode: "topup", amountMinor, currency }),
|
|
9888
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(TopupForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: [
|
|
8039
9889
|
"Pay ",
|
|
8040
9890
|
formatPrice(amountMinor, currency, { locale })
|
|
8041
9891
|
] })
|
|
@@ -8058,12 +9908,12 @@ function RecurringPayment({ className }) {
|
|
|
8058
9908
|
const isRecurring = !!cycle;
|
|
8059
9909
|
const formattedAmount = formatPrice(amountMinor, currency, { locale });
|
|
8060
9910
|
const priceLine = isRecurring ? `${formattedAmount}/${shortCycle(cycle)}` : formattedAmount;
|
|
8061
|
-
return /* @__PURE__ */ (0,
|
|
8062
|
-
/* @__PURE__ */ (0,
|
|
8063
|
-
/* @__PURE__ */ (0,
|
|
8064
|
-
/* @__PURE__ */ (0,
|
|
9911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: className ?? "solvapay-checkout-payment", "data-branch": "recurring", children: [
|
|
9912
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-checkout-order-summary", "data-variant": "recurring", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-order-summary-row", children: [
|
|
9913
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: planName }),
|
|
9914
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: priceLine })
|
|
8065
9915
|
] }) }),
|
|
8066
|
-
/* @__PURE__ */ (0,
|
|
9916
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8067
9917
|
PaymentForm.Root,
|
|
8068
9918
|
{
|
|
8069
9919
|
planRef: flow.selectedPlanRef,
|
|
@@ -8072,28 +9922,28 @@ function RecurringPayment({ className }) {
|
|
|
8072
9922
|
requireTermsAcceptance: false,
|
|
8073
9923
|
onSuccess: (intent) => flow.notifyPaymentSuccess(intent),
|
|
8074
9924
|
children: [
|
|
8075
|
-
/* @__PURE__ */ (0,
|
|
8076
|
-
/* @__PURE__ */ (0,
|
|
8077
|
-
/* @__PURE__ */ (0,
|
|
8078
|
-
/* @__PURE__ */ (0,
|
|
8079
|
-
/* @__PURE__ */ (0,
|
|
9925
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentForm.Loading, {}),
|
|
9926
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentForm.PaymentElement, {}),
|
|
9927
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentForm.Error, { className: "solvapay-checkout-error" }),
|
|
9928
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentForm.MandateText, {}),
|
|
9929
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PaymentForm.SubmitButton, { className: "solvapay-checkout-pay-button", children: isRecurring ? `Subscribe \u2014 ${priceLine}` : `Pay ${formattedAmount}` })
|
|
8080
9930
|
]
|
|
8081
9931
|
}
|
|
8082
9932
|
)
|
|
8083
9933
|
] });
|
|
8084
9934
|
}
|
|
8085
|
-
var CheckoutEnvContext = (0,
|
|
9935
|
+
var CheckoutEnvContext = (0, import_react48.createContext)(null);
|
|
8086
9936
|
function useReturnUrl() {
|
|
8087
|
-
return (0,
|
|
9937
|
+
return (0, import_react48.useContext)(CheckoutEnvContext)?.returnUrl ?? "";
|
|
8088
9938
|
}
|
|
8089
9939
|
function useProductRef() {
|
|
8090
|
-
return (0,
|
|
9940
|
+
return (0, import_react48.useContext)(CheckoutEnvContext)?.productRef ?? "";
|
|
8091
9941
|
}
|
|
8092
|
-
var BackLink = (0,
|
|
9942
|
+
var BackLink = (0, import_react48.forwardRef)(function CheckoutStepsBackLink({ label, glyph = "\u2190", className, onClick, ...rest }, ref) {
|
|
8093
9943
|
const flow = useCheckoutContext("BackLink");
|
|
8094
9944
|
if (!flow.canGoBack) return null;
|
|
8095
9945
|
const resolvedLabel = label ?? (flow.step === "payment" && flow.branch === "payg" ? "Change amount" : flow.step === "payment" && flow.branch === "recurring" ? "Change plan" : "Back");
|
|
8096
|
-
return /* @__PURE__ */ (0,
|
|
9946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
8097
9947
|
"button",
|
|
8098
9948
|
{
|
|
8099
9949
|
ref,
|
|
@@ -8107,8 +9957,8 @@ var BackLink = (0, import_react46.forwardRef)(function CheckoutStepsBackLink({ l
|
|
|
8107
9957
|
},
|
|
8108
9958
|
...rest,
|
|
8109
9959
|
children: [
|
|
8110
|
-
/* @__PURE__ */ (0,
|
|
8111
|
-
/* @__PURE__ */ (0,
|
|
9960
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "solvapay-checkout-back-link-glyph", "aria-hidden": "true", children: glyph }),
|
|
9961
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "solvapay-checkout-back-link-label", children: resolvedLabel })
|
|
8112
9962
|
]
|
|
8113
9963
|
}
|
|
8114
9964
|
);
|
|
@@ -8118,74 +9968,74 @@ function Success({ className, children }) {
|
|
|
8118
9968
|
const locale = useLocale();
|
|
8119
9969
|
if (flow.step !== "success" || !flow.successMeta) return null;
|
|
8120
9970
|
if (children) {
|
|
8121
|
-
return /* @__PURE__ */ (0,
|
|
9971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: className ?? "solvapay-checkout-success", children });
|
|
8122
9972
|
}
|
|
8123
9973
|
const meta = flow.successMeta;
|
|
8124
9974
|
if (meta.branch === "payg") {
|
|
8125
|
-
return /* @__PURE__ */ (0,
|
|
8126
|
-
/* @__PURE__ */ (0,
|
|
8127
|
-
/* @__PURE__ */ (0,
|
|
8128
|
-
/* @__PURE__ */ (0,
|
|
8129
|
-
/* @__PURE__ */ (0,
|
|
8130
|
-
/* @__PURE__ */ (0,
|
|
8131
|
-
/* @__PURE__ */ (0,
|
|
8132
|
-
/* @__PURE__ */ (0,
|
|
9975
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "payg", children: [
|
|
9976
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
|
|
9977
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("h2", { className: "solvapay-checkout-success-heading", children: "Credits added" }),
|
|
9978
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Pay as you go plan is active." }),
|
|
9979
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "payg", children: [
|
|
9980
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
9981
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Amount" }),
|
|
9982
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: formatPrice(meta.amountMinor, meta.currency, { locale }) })
|
|
8133
9983
|
] }),
|
|
8134
|
-
/* @__PURE__ */ (0,
|
|
8135
|
-
/* @__PURE__ */ (0,
|
|
8136
|
-
/* @__PURE__ */ (0,
|
|
9984
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
9985
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Credits" }),
|
|
9986
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("dd", { children: [
|
|
8137
9987
|
"+",
|
|
8138
9988
|
meta.creditsAdded.toLocaleString(locale)
|
|
8139
9989
|
] })
|
|
8140
9990
|
] }),
|
|
8141
|
-
/* @__PURE__ */ (0,
|
|
8142
|
-
/* @__PURE__ */ (0,
|
|
8143
|
-
/* @__PURE__ */ (0,
|
|
9991
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
9992
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Plan" }),
|
|
9993
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: meta.plan.name ?? "Pay as you go" })
|
|
8144
9994
|
] }),
|
|
8145
|
-
/* @__PURE__ */ (0,
|
|
8146
|
-
/* @__PURE__ */ (0,
|
|
8147
|
-
/* @__PURE__ */ (0,
|
|
9995
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
9996
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Rate" }),
|
|
9997
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: meta.rateLabel })
|
|
8148
9998
|
] })
|
|
8149
9999
|
] })
|
|
8150
10000
|
] });
|
|
8151
10001
|
}
|
|
8152
|
-
return /* @__PURE__ */ (0,
|
|
8153
|
-
/* @__PURE__ */ (0,
|
|
8154
|
-
/* @__PURE__ */ (0,
|
|
10002
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: className ?? "solvapay-checkout-success", "data-branch": "recurring", children: [
|
|
10003
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "solvapay-checkout-success-check", "aria-hidden": "true", children: "\u2713" }),
|
|
10004
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("h2", { className: "solvapay-checkout-success-heading", children: [
|
|
8155
10005
|
meta.plan.name ?? "Plan",
|
|
8156
10006
|
" active"
|
|
8157
10007
|
] }),
|
|
8158
|
-
/* @__PURE__ */ (0,
|
|
8159
|
-
/* @__PURE__ */ (0,
|
|
8160
|
-
/* @__PURE__ */ (0,
|
|
8161
|
-
/* @__PURE__ */ (0,
|
|
8162
|
-
/* @__PURE__ */ (0,
|
|
10008
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "solvapay-checkout-success-subheading", children: "Subscription is live and credits are ready." }),
|
|
10009
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("dl", { className: "solvapay-checkout-receipt", "data-variant": "recurring", children: [
|
|
10010
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
10011
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Plan" }),
|
|
10012
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: meta.plan.name ?? "Plan" })
|
|
8163
10013
|
] }),
|
|
8164
|
-
meta.creditsIncluded > 0 ? /* @__PURE__ */ (0,
|
|
8165
|
-
/* @__PURE__ */ (0,
|
|
8166
|
-
/* @__PURE__ */ (0,
|
|
10014
|
+
meta.creditsIncluded > 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
10015
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Credits" }),
|
|
10016
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("dd", { children: [
|
|
8167
10017
|
"+",
|
|
8168
10018
|
meta.creditsIncluded.toLocaleString(locale)
|
|
8169
10019
|
] })
|
|
8170
10020
|
] }) : null,
|
|
8171
|
-
/* @__PURE__ */ (0,
|
|
8172
|
-
/* @__PURE__ */ (0,
|
|
8173
|
-
/* @__PURE__ */ (0,
|
|
10021
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
10022
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Charged today" }),
|
|
10023
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: formatPrice(meta.chargedTodayMinor, meta.currency, { locale }) })
|
|
8174
10024
|
] }),
|
|
8175
|
-
meta.nextRenewalLabel ? /* @__PURE__ */ (0,
|
|
8176
|
-
/* @__PURE__ */ (0,
|
|
8177
|
-
/* @__PURE__ */ (0,
|
|
10025
|
+
meta.nextRenewalLabel ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "solvapay-checkout-receipt-row", children: [
|
|
10026
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dt", { children: "Next renewal" }),
|
|
10027
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("dd", { children: meta.nextRenewalLabel })
|
|
8178
10028
|
] }) : null
|
|
8179
10029
|
] })
|
|
8180
10030
|
] });
|
|
8181
10031
|
}
|
|
8182
|
-
var RootWithEnv = (0,
|
|
10032
|
+
var RootWithEnv = (0, import_react48.forwardRef)(
|
|
8183
10033
|
function CheckoutStepsRootWithEnv(props, forwardedRef) {
|
|
8184
|
-
const env = (0,
|
|
10034
|
+
const env = (0, import_react48.useMemo)(
|
|
8185
10035
|
() => ({ returnUrl: props.returnUrl, productRef: props.productRef }),
|
|
8186
10036
|
[props.returnUrl, props.productRef]
|
|
8187
10037
|
);
|
|
8188
|
-
return /* @__PURE__ */ (0,
|
|
10038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CheckoutEnvContext.Provider, { value: env, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Root13, { ...props, ref: forwardedRef }) });
|
|
8189
10039
|
}
|
|
8190
10040
|
);
|
|
8191
10041
|
var CheckoutSteps = {
|
|
@@ -8237,6 +10087,7 @@ var UnsupportedTransportMethodError = class extends Error {
|
|
|
8237
10087
|
0 && (module.exports = {
|
|
8238
10088
|
ActivationFlow,
|
|
8239
10089
|
AmountPicker,
|
|
10090
|
+
AutoRecharge,
|
|
8240
10091
|
BalanceBadge,
|
|
8241
10092
|
CancelPlanButton,
|
|
8242
10093
|
CancelledPlanNotice,
|
|
@@ -8263,6 +10114,7 @@ var UnsupportedTransportMethodError = class extends Error {
|
|
|
8263
10114
|
TopupForm,
|
|
8264
10115
|
UnsupportedTransportMethodError,
|
|
8265
10116
|
UpdatePaymentMethodButton,
|
|
10117
|
+
configToAutoRechargeInput,
|
|
8266
10118
|
confirmPayment,
|
|
8267
10119
|
createAnonymousAuthAdapter,
|
|
8268
10120
|
createHttpTransport,
|
|
@@ -8288,6 +10140,7 @@ var UnsupportedTransportMethodError = class extends Error {
|
|
|
8288
10140
|
toMajorUnits,
|
|
8289
10141
|
useActivation,
|
|
8290
10142
|
useAutoActivateFreePlan,
|
|
10143
|
+
useAutoRecharge,
|
|
8291
10144
|
useBalance,
|
|
8292
10145
|
useCheckout,
|
|
8293
10146
|
useCheckoutFlow,
|