@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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @solvapay/react changelog
2
2
 
3
+ ## 1.4.0-preview-ecd61384a4e849717e13d47ab2daa086cdcd91c5
4
+
5
+ ### Minor Changes
6
+
7
+ - 6e4f5cf: Collapse auto-recharge transport route overrides to a single `api.autoRecharge` key (replaces `getAutoRecharge`, `saveAutoRecharge`, and `disableAutoRecharge` route keys).
8
+ - 349777e: Auto-recharge can now be configured in the same top-up payment as the initial card charge, so integrators do not need a separate SetupIntent step before checkout.
9
+ - **`@solvapay/react`**: `AutoRecharge` adds `deferCardSetup` and `onPendingConfig` to stage settings until payment; `useTopup`, `TopupForm`, and `createTopupPayment` accept optional `autoRecharge`; `balance.reconcileAfterUsageDebit()` starts post-debit polling without false bumps from optimistic debits alone.
10
+ - **`@solvapay/server`**: `createTopupPaymentIntentCore` forwards optional `autoRecharge` to the SDK payment-intent API.
11
+ - **`@solvapay/next`**: `createTopupPaymentIntent` route helper accepts the same `autoRecharge` body field.
12
+
13
+ ### Patch Changes
14
+
15
+ - 2644836: Fix balance reconciliation stopping after the first auto-recharge when multiple usage debits trigger back-to-back.
16
+ - **`balance.reconcileAfterUsageDebit`**: tracks a pending recharge count so each expected top-up is polled and applied before reconciliation finishes, instead of clearing after the first observed increase.
17
+
18
+ - 5aa4aee: Fix lossy credit↔currency rounding when toggling auto-recharge amount units.
19
+ - **`estimateCredits`** now uses `Math.round` (matching credits→currency) instead of `Math.floor`.
20
+ - **Unit toggle** snaps back to the last user-entered value instead of re-deriving from the rounded display, so repeated flips no longer drift by a minor unit.
21
+
22
+ - 349777e: Financial boundary hardening: backend `display.*` blocks are the source of truth for credit and currency rendering.
23
+ - **`@solvapay/core`**: conversion-contract e2e extended to pin backend display formulas against the core reference.
24
+ - **`@solvapay/react`**: `TransportBalanceResult` and `BalanceStatus` accept optional `display` from the balance API; negative `adjustBalance` schedules a grace refetch; usage demo refetches after debit.
25
+ - **`@solvapay/server`**: `AutoRechargeConfig`, balance, and credit-debit types document backend-computed `display` blocks and `autoRecharge.triggered` as charge-initiated (not credits booked inline).
26
+
27
+ - Updated dependencies [349777e]
28
+ - @solvapay/core@1.1.1-preview-ecd61384a4e849717e13d47ab2daa086cdcd91c5
29
+ - @solvapay/mcp-core@0.2.7-preview-ecd61384a4e849717e13d47ab2daa086cdcd91c5
30
+
3
31
  ## 1.3.0
4
32
 
5
33
  ### Minor Changes
@@ -4,6 +4,7 @@ import {
4
4
  getOrCreateAnonymousCustomerRef,
5
5
  resetAnonymousCustomerRef
6
6
  } from "../chunk-UMXOAUW7.js";
7
+ import "../chunk-MLKGABMK.js";
7
8
  export {
8
9
  createAnonymousAuthAdapter,
9
10
  defaultAuthAdapter,
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createSessionAuthAdapter
3
3
  } from "../chunk-JTW665JR.js";
4
+ import "../chunk-MLKGABMK.js";
4
5
 
5
6
  // src/adapters/auth0.ts
6
7
  function createAuth0ClientAuthAdapter(options) {
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createSessionAuthAdapter
3
3
  } from "../chunk-JTW665JR.js";
4
+ import "../chunk-MLKGABMK.js";
4
5
  export {
5
6
  createSessionAuthAdapter
6
7
  };
@@ -149,6 +149,7 @@ var DEFAULT_ROUTES = {
149
149
  getProduct: "/api/get-product",
150
150
  listPlans: "/api/list-plans",
151
151
  getPaymentMethod: "/api/payment-method",
152
+ autoRecharge: "/api/auto-recharge",
152
153
  getUsage: "/api/usage",
153
154
  getLimits: "/api/limits"
154
155
  };
@@ -186,7 +187,11 @@ function createHttpTransport(config) {
186
187
  }),
187
188
  createTopupPayment: (params) => request(config, routeFor(config, "createTopupPayment"), {
188
189
  method: "POST",
189
- body: { amount: params.amount, currency: params.currency },
190
+ body: {
191
+ amount: params.amount,
192
+ currency: params.currency,
193
+ ...params.autoRecharge ? { autoRecharge: params.autoRecharge } : {}
194
+ },
190
195
  onErrorContext: "createTopupPayment",
191
196
  errorPrefix: "Failed to create topup payment"
192
197
  }),
@@ -235,16 +240,12 @@ function createHttpTransport(config) {
235
240
  }
236
241
  );
237
242
  },
238
- createCustomerSession: () => request(
239
- config,
240
- routeFor(config, "createCustomerSession"),
241
- {
242
- method: "POST",
243
- body: {},
244
- onErrorContext: "createCustomerSession",
245
- errorPrefix: "Failed to create customer session"
246
- }
247
- ),
243
+ createCustomerSession: () => request(config, routeFor(config, "createCustomerSession"), {
244
+ method: "POST",
245
+ body: {},
246
+ onErrorContext: "createCustomerSession",
247
+ errorPrefix: "Failed to create customer session"
248
+ }),
248
249
  getMerchant: () => request(config, routeFor(config, "getMerchant"), {
249
250
  method: "GET",
250
251
  onErrorContext: "getMerchant",
@@ -274,6 +275,22 @@ function createHttpTransport(config) {
274
275
  onErrorContext: "getPaymentMethod",
275
276
  errorPrefix: "Failed to load payment method"
276
277
  }),
278
+ getAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
279
+ method: "GET",
280
+ onErrorContext: "getAutoRecharge",
281
+ errorPrefix: "Failed to load auto-recharge"
282
+ }),
283
+ saveAutoRecharge: (input) => request(config, routeFor(config, "autoRecharge"), {
284
+ method: "PUT",
285
+ body: input,
286
+ onErrorContext: "saveAutoRecharge",
287
+ errorPrefix: "Failed to save auto-recharge"
288
+ }),
289
+ disableAutoRecharge: () => request(config, routeFor(config, "autoRecharge"), {
290
+ method: "DELETE",
291
+ onErrorContext: "disableAutoRecharge",
292
+ errorPrefix: "Failed to disable auto-recharge"
293
+ }),
277
294
  getUsage: () => request(config, routeFor(config, "getUsage"), {
278
295
  method: "GET",
279
296
  onErrorContext: "getUsage",
@@ -409,6 +426,42 @@ var enCopy = {
409
426
  creditEstimateExact: "= {credits} credits",
410
427
  creditEstimateApprox: "~ {credits} credits"
411
428
  },
429
+ autoRecharge: {
430
+ heading: "Auto recharge",
431
+ description: "Automatically top up so you never run out \u2014 recommended for production. You can turn this off anytime.",
432
+ settingsHeading: "Auto recharge settings",
433
+ setupTriggerLabel: "Set up auto-recharge",
434
+ modifyTriggerLabel: "Modify",
435
+ notConfiguredHint: "Automatic top-ups are off. Set up auto-recharge if you want credits added when your balance runs low.",
436
+ enableLabel: "Enable auto-recharge",
437
+ enableQuestion: "Would you like to set up automatic recharge?",
438
+ enableSentence: "Yes, automatically recharge my card when my credit balance falls below a threshold",
439
+ thresholdLabel: "When balance falls below",
440
+ thresholdAriaLabel: "Balance threshold",
441
+ fixedAmountLabel: "Add this amount",
442
+ fixedAmountAriaLabel: "Fixed top-up amount",
443
+ saveButton: "Save settings",
444
+ cancelButton: "Cancel",
445
+ disableButton: "Disable automatic top-up",
446
+ savedMessage: "Automatic top-up settings saved.",
447
+ disabledMessage: "Automatic top-ups disabled.",
448
+ setupRequiredMessage: "Confirm your card to activate automatic top-ups.",
449
+ setupHeading: "Authorize card",
450
+ setupDescription: "Authorize a card for automatic top-ups. You will not be charged now.",
451
+ setupSubmit: "Save card for auto-recharge",
452
+ setupProcessing: "Authorizing...",
453
+ setupAwaitingConfirmation: "Card authorized. Finishing activation \u2014 this can take a moment.",
454
+ setupAuthFailed: "Card authentication failed. Please try a different card.",
455
+ invalidThreshold: "Enter a valid balance threshold.",
456
+ thresholdTooLow: "Balance threshold must be greater than zero.",
457
+ minTopupAmount: "Top-up amount must be at least {amount}.",
458
+ topupBelowThreshold: "Top-up amount must be at least your balance threshold ({amount}).",
459
+ creditsPerRecharge: "\u2248 {credits} credits per recharge",
460
+ creditsPerRechargeApprox: "~ {credits} credits per recharge",
461
+ currencyPerRecharge: "\u2248 {amount} per recharge",
462
+ currencyPerRechargeApprox: "~ {amount} per recharge",
463
+ statusFailed: "Payment failed \u2014 update your card to resume"
464
+ },
412
465
  activationFlow: {
413
466
  heading: "Confirm your plan",
414
467
  activateButton: "Activate",
@@ -592,6 +645,31 @@ function useCopyContext() {
592
645
 
593
646
  // src/SolvaPayProvider.tsx
594
647
  import { createContext as createContext2, useState, useEffect, useCallback, useMemo as useMemo2, useRef } from "react";
648
+
649
+ // ../server/src/index.ts
650
+ import crypto from "crypto";
651
+ import { SolvaPayError } from "@solvapay/core";
652
+
653
+ // ../server/src/helpers/balance-poll.ts
654
+ var BALANCE_RECONCILE_DELAYS_MS = [500, 1e3, 2e3, 4e3, 8e3, 16e3];
655
+ async function pollBalanceUntilIncreased(getBalance, baseline, delays = BALANCE_RECONCILE_DELAYS_MS) {
656
+ for (const delay of delays) {
657
+ await new Promise((resolve) => setTimeout(resolve, delay));
658
+ try {
659
+ const post = await getBalance();
660
+ if (post.credits > baseline) {
661
+ return { creditsAdded: post.credits - baseline };
662
+ }
663
+ } catch {
664
+ }
665
+ }
666
+ return null;
667
+ }
668
+
669
+ // src/helpers/auto-recharge-cache.ts
670
+ var BALANCE_RECONCILE_GRACE_MS = BALANCE_RECONCILE_DELAYS_MS.reduce((sum, delay) => sum + delay, 0) + 1e3;
671
+
672
+ // src/SolvaPayProvider.tsx
595
673
  import { jsx as jsx2 } from "react/jsx-runtime";
596
674
  var SolvaPayContext = createContext2(null);
597
675
  function resolveTransport(config) {
@@ -638,12 +716,18 @@ var SolvaPayProvider = ({ config, children }) => {
638
716
  const [displayExchangeRateValue, setDisplayExchangeRateValue] = useState(
639
717
  initial?.balance?.displayExchangeRate ?? null
640
718
  );
719
+ const [displayBlockValue, setDisplayBlockValue] = useState(
720
+ initial?.balance?.display ?? null
721
+ );
641
722
  const [balanceLoading, setBalanceLoading] = useState(false);
642
723
  const balanceInFlightRef = useRef(false);
643
724
  const balanceLoadedRef = useRef(!!initial?.balance);
725
+ const creditsValueRef = useRef(initial?.balance?.credits ?? null);
644
726
  const optimisticUntilRef = useRef(0);
645
727
  const optimisticTimerRef = useRef(null);
646
728
  const fetchBalanceRef = useRef(null);
729
+ const reconcileRunningRef = useRef(false);
730
+ const reconcilePollRef = useRef(null);
647
731
  const inFlightRef = useRef(null);
648
732
  const loadedCacheKeysRef = useRef(
649
733
  new Set(initial?.customerRef ? [initial.customerRef] : [])
@@ -661,10 +745,12 @@ var SolvaPayProvider = ({ config, children }) => {
661
745
  const fetchBalanceImpl = useCallback(async () => {
662
746
  if (optimisticUntilRef.current > Date.now()) return;
663
747
  if (!isAuthenticated && !internalCustomerRef) {
748
+ creditsValueRef.current = null;
664
749
  setCreditsValue(null);
665
750
  setDisplayCurrencyValue(null);
666
751
  setCreditsPerMinorUnitValue(null);
667
752
  setDisplayExchangeRateValue(null);
753
+ setDisplayBlockValue(null);
668
754
  setBalanceLoading(false);
669
755
  balanceLoadedRef.current = false;
670
756
  return;
@@ -681,10 +767,12 @@ var SolvaPayProvider = ({ config, children }) => {
681
767
  return;
682
768
  }
683
769
  const data = await transportRef.current.getBalance();
770
+ creditsValueRef.current = data.credits ?? null;
684
771
  setCreditsValue(data.credits ?? null);
685
772
  setDisplayCurrencyValue(data.displayCurrency ?? null);
686
773
  setCreditsPerMinorUnitValue(data.creditsPerMinorUnit ?? null);
687
774
  setDisplayExchangeRateValue(data.displayExchangeRate ?? null);
775
+ setDisplayBlockValue(data.display ?? null);
688
776
  balanceLoadedRef.current = true;
689
777
  } catch (error) {
690
778
  console.error("[SolvaPayProvider] Failed to fetch balance:", error);
@@ -699,18 +787,112 @@ var SolvaPayProvider = ({ config, children }) => {
699
787
  useEffect(() => {
700
788
  return () => {
701
789
  if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
790
+ reconcilePollRef.current = null;
791
+ reconcileRunningRef.current = false;
702
792
  };
703
793
  }, []);
704
794
  const OPTIMISTIC_GRACE_MS = 8e3;
705
- const adjustBalanceImpl = useCallback((credits) => {
706
- setCreditsValue((prev) => (prev ?? 0) + credits);
707
- optimisticUntilRef.current = Date.now() + OPTIMISTIC_GRACE_MS;
795
+ const DEBIT_GRACE_MS = 2e3;
796
+ const clearOptimisticGrace = useCallback(() => {
797
+ optimisticUntilRef.current = 0;
798
+ if (optimisticTimerRef.current) {
799
+ clearTimeout(optimisticTimerRef.current);
800
+ optimisticTimerRef.current = null;
801
+ }
802
+ }, []);
803
+ const applyBalanceSnapshot = useCallback(
804
+ (data) => {
805
+ creditsValueRef.current = data.credits ?? null;
806
+ setCreditsValue(data.credits ?? null);
807
+ setDisplayCurrencyValue(data.displayCurrency ?? null);
808
+ setCreditsPerMinorUnitValue(data.creditsPerMinorUnit ?? null);
809
+ setDisplayExchangeRateValue(data.displayExchangeRate ?? null);
810
+ setDisplayBlockValue(data.display ?? null);
811
+ balanceLoadedRef.current = true;
812
+ },
813
+ []
814
+ );
815
+ const reconcileBalanceIncreaseImpl = useCallback(async () => {
816
+ if (!transportRef.current.getBalance) return;
817
+ const finishReconcilePoll = () => {
818
+ reconcilePollRef.current = null;
819
+ clearOptimisticGrace();
820
+ };
821
+ reconcileRunningRef.current = true;
822
+ try {
823
+ while (reconcilePollRef.current) {
824
+ const { baseline: activeBaseline, generation: activeGeneration } = reconcilePollRef.current;
825
+ const pollResult = await pollBalanceUntilIncreased(
826
+ async () => {
827
+ const data = await transportRef.current.getBalance();
828
+ return { credits: data.credits ?? 0 };
829
+ },
830
+ activeBaseline,
831
+ BALANCE_RECONCILE_DELAYS_MS
832
+ );
833
+ const pollState = reconcilePollRef.current;
834
+ if (!pollState || pollState.generation !== activeGeneration) {
835
+ continue;
836
+ }
837
+ if (!pollResult) {
838
+ finishReconcilePoll();
839
+ break;
840
+ }
841
+ try {
842
+ const data = await transportRef.current.getBalance();
843
+ applyBalanceSnapshot(data);
844
+ pollState.pending -= 1;
845
+ if (pollState.pending > 0) {
846
+ pollState.baseline = data.credits ?? 0;
847
+ continue;
848
+ }
849
+ } catch (error) {
850
+ console.error("[SolvaPayProvider] Failed to reconcile balance after auto-recharge:", error);
851
+ }
852
+ finishReconcilePoll();
853
+ break;
854
+ }
855
+ } finally {
856
+ reconcileRunningRef.current = false;
857
+ }
858
+ }, [applyBalanceSnapshot, clearOptimisticGrace]);
859
+ const scheduleGraceRefetch = useCallback((graceMs) => {
860
+ optimisticUntilRef.current = Date.now() + graceMs;
708
861
  if (optimisticTimerRef.current) clearTimeout(optimisticTimerRef.current);
709
862
  optimisticTimerRef.current = setTimeout(() => {
710
863
  optimisticUntilRef.current = 0;
711
864
  fetchBalanceRef.current?.();
712
- }, OPTIMISTIC_GRACE_MS);
865
+ }, graceMs);
713
866
  }, []);
867
+ const adjustBalanceImpl = useCallback(
868
+ (credits) => {
869
+ const nextCredits = (creditsValueRef.current ?? 0) + credits;
870
+ creditsValueRef.current = nextCredits;
871
+ setCreditsValue(nextCredits);
872
+ if (credits >= 0) {
873
+ scheduleGraceRefetch(OPTIMISTIC_GRACE_MS);
874
+ } else {
875
+ scheduleGraceRefetch(DEBIT_GRACE_MS);
876
+ }
877
+ },
878
+ [scheduleGraceRefetch]
879
+ );
880
+ const reconcileAfterUsageDebitImpl = useCallback(
881
+ (opts) => {
882
+ if (opts?.expectIncrease !== true) {
883
+ return;
884
+ }
885
+ const nextCredits = creditsValueRef.current ?? 0;
886
+ const generation = (reconcilePollRef.current?.generation ?? 0) + 1;
887
+ const pending = (reconcilePollRef.current?.pending ?? 0) + 1;
888
+ reconcilePollRef.current = { baseline: nextCredits, generation, pending };
889
+ scheduleGraceRefetch(BALANCE_RECONCILE_GRACE_MS);
890
+ if (!reconcileRunningRef.current) {
891
+ void reconcileBalanceIncreaseImpl();
892
+ }
893
+ },
894
+ [reconcileBalanceIncreaseImpl, scheduleGraceRefetch]
895
+ );
714
896
  const createPayment = useCallback(
715
897
  (params) => transportRef.current.createPayment(params),
716
898
  []
@@ -882,6 +1064,7 @@ var SolvaPayProvider = ({ config, children }) => {
882
1064
  setDisplayCurrencyValue(next.balance?.displayCurrency ?? null);
883
1065
  setCreditsPerMinorUnitValue(next.balance?.creditsPerMinorUnit ?? null);
884
1066
  setDisplayExchangeRateValue(next.balance?.displayExchangeRate ?? null);
1067
+ setDisplayBlockValue(next.balance?.display ?? null);
885
1068
  balanceLoadedRef.current = !!next.balance;
886
1069
  }, []);
887
1070
  useEffect(() => {
@@ -986,8 +1169,10 @@ var SolvaPayProvider = ({ config, children }) => {
986
1169
  displayCurrency: displayCurrencyValue,
987
1170
  creditsPerMinorUnit: creditsPerMinorUnitValue,
988
1171
  displayExchangeRate: displayExchangeRateValue,
1172
+ display: displayBlockValue,
989
1173
  refetch: fetchBalanceImpl,
990
- adjustBalance: adjustBalanceImpl
1174
+ adjustBalance: adjustBalanceImpl,
1175
+ reconcileAfterUsageDebit: reconcileAfterUsageDebitImpl
991
1176
  }),
992
1177
  [
993
1178
  balanceLoading,
@@ -995,8 +1180,10 @@ var SolvaPayProvider = ({ config, children }) => {
995
1180
  displayCurrencyValue,
996
1181
  creditsPerMinorUnitValue,
997
1182
  displayExchangeRateValue,
1183
+ displayBlockValue,
998
1184
  fetchBalanceImpl,
999
- adjustBalanceImpl
1185
+ adjustBalanceImpl,
1186
+ reconcileAfterUsageDebitImpl
1000
1187
  ]
1001
1188
  );
1002
1189
  const contextValue = useMemo2(
@@ -1974,7 +2161,7 @@ import { createContext as createContext5, forwardRef as forwardRef2, useContext
1974
2161
 
1975
2162
  // src/utils/errors.ts
1976
2163
  var DOCS_BASE_URL = "https://solvapay.com/docs";
1977
- var SolvaPayError = class extends Error {
2164
+ var SolvaPayError2 = class extends Error {
1978
2165
  code;
1979
2166
  docsUrl;
1980
2167
  constructor(code, message, docsUrl) {
@@ -1984,7 +2171,7 @@ var SolvaPayError = class extends Error {
1984
2171
  this.docsUrl = docsUrl;
1985
2172
  }
1986
2173
  };
1987
- var MissingProviderError = class extends SolvaPayError {
2174
+ var MissingProviderError = class extends SolvaPayError2 {
1988
2175
  constructor(primitiveName) {
1989
2176
  const docsUrl = `${DOCS_BASE_URL}/troubleshooting/missing-provider`;
1990
2177
  super(
@@ -1995,7 +2182,7 @@ var MissingProviderError = class extends SolvaPayError {
1995
2182
  this.name = "MissingProviderError";
1996
2183
  }
1997
2184
  };
1998
- var MissingProductRefError = class extends SolvaPayError {
2185
+ var MissingProductRefError = class extends SolvaPayError2 {
1999
2186
  constructor(primitiveName) {
2000
2187
  const docsUrl = `${DOCS_BASE_URL}/primitives/product-ref`;
2001
2188
  super(
@@ -3509,7 +3696,7 @@ function getStripeCacheKey2(publishableKey, accountId) {
3509
3696
  return accountId ? `${publishableKey}:${accountId}` : publishableKey;
3510
3697
  }
3511
3698
  function useTopup(options) {
3512
- const { amount, currency } = options;
3699
+ const { amount, currency, autoRecharge } = options;
3513
3700
  const { createTopupPayment, customerRef, updateCustomerRef } = useSolvaPay();
3514
3701
  const [loading, setLoading] = useState10(false);
3515
3702
  const [error, setError] = useState10(null);
@@ -3528,7 +3715,7 @@ function useTopup(options) {
3528
3715
  setLoading(true);
3529
3716
  setError(null);
3530
3717
  try {
3531
- const result = await createTopupPayment({ amount, currency });
3718
+ const result = await createTopupPayment({ amount, currency, autoRecharge });
3532
3719
  if (!result || typeof result !== "object") {
3533
3720
  throw new Error("Invalid topup payment intent response from server");
3534
3721
  }
@@ -3560,7 +3747,7 @@ function useTopup(options) {
3560
3747
  setLoading(false);
3561
3748
  isStartingRef.current = false;
3562
3749
  }
3563
- }, [amount, currency, createTopupPayment, customerRef, updateCustomerRef, loading]);
3750
+ }, [amount, currency, autoRecharge, createTopupPayment, customerRef, updateCustomerRef, loading]);
3564
3751
  const reset = useCallback11(() => {
3565
3752
  isStartingRef.current = false;
3566
3753
  setLoading(false);
@@ -3608,6 +3795,7 @@ var Root4 = forwardRef6(function TopupFormRoot(props, forwardedRef) {
3608
3795
  const {
3609
3796
  amount,
3610
3797
  currency,
3798
+ autoRecharge,
3611
3799
  onSuccess,
3612
3800
  onError,
3613
3801
  returnUrl,
@@ -3631,7 +3819,8 @@ var Root4 = forwardRef6(function TopupFormRoot(props, forwardedRef) {
3631
3819
  stripePromise
3632
3820
  } = useTopup({
3633
3821
  amount,
3634
- currency
3822
+ currency,
3823
+ autoRecharge
3635
3824
  });
3636
3825
  const hasInitializedRef = useRef6(false);
3637
3826
  const hasAmount = amount > 0;
@@ -5410,6 +5599,7 @@ export {
5410
5599
  useCopy,
5411
5600
  useLocale,
5412
5601
  LegalFooter,
5602
+ withPaymentElementDefaults,
5413
5603
  MissingProviderError,
5414
5604
  MissingProductRefError,
5415
5605
  useSolvaPay,