@superlogic/spree-pay 0.4.2 → 0.4.6

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Iframe3ds
3
- } from "./chunk-4ELDS4N4.js";
3
+ } from "./chunk-7I6EBCSI.js";
4
4
  import {
5
5
  InfoBanner,
6
6
  Legal,
@@ -12,7 +12,7 @@ import {
12
12
  useSpreePayRegister,
13
13
  useSpreePaymentMethod,
14
14
  useStaticConfig
15
- } from "./chunk-I35SE3K2.js";
15
+ } from "./chunk-AGTOSFMT.js";
16
16
 
17
17
  // src/components/CryptoComTab/CryptoComTab.tsx
18
18
  import { useCallback, useEffect } from "react";
@@ -2,7 +2,7 @@ import {
2
2
  CheckoutButton,
3
3
  PointsSwitch,
4
4
  cn as cn2
5
- } from "./chunk-LXX5P2LL.js";
5
+ } from "./chunk-FKAVWVFL.js";
6
6
  import {
7
7
  Dialog,
8
8
  DialogContent,
@@ -16,7 +16,7 @@ import {
16
16
  useSpreePayConfig,
17
17
  useSpreePayRegister,
18
18
  useSpreePaymentMethod
19
- } from "./chunk-I35SE3K2.js";
19
+ } from "./chunk-AGTOSFMT.js";
20
20
 
21
21
  // src/components/CryptoTab/Crypto/CryptoWrapper.tsx
22
22
  import { useMemo as useMemo2 } from "react";
@@ -409,7 +409,7 @@ function Input({ className, type, ...props }) {
409
409
  type,
410
410
  "data-slot": "input",
411
411
  className: cn2(
412
- "file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base text-(--primary) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-(--tertiary) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
412
+ "file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input px-universal-2xs py-universal-6xs rounded-radius-universal-xs text-body-m file:text-label-s file:font-label-primary flex h-9 w-full min-w-0 border bg-transparent text-(--color-text-icons-primary-default) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent placeholder:text-(--color-text-icons-tertiary-default) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
413
413
  "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
414
414
  "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
415
415
  className
@@ -501,7 +501,7 @@ function Separator2({
501
501
  decorative,
502
502
  orientation,
503
503
  className: cn2(
504
- "shrink-0 bg-(--b-secondary) data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
504
+ "shrink-0 bg-(--color-border-default) data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
505
505
  className
506
506
  ),
507
507
  ...props
@@ -2,7 +2,7 @@ import {
2
2
  Dialog,
3
3
  DialogContent,
4
4
  DialogTitle
5
- } from "./chunk-I35SE3K2.js";
5
+ } from "./chunk-AGTOSFMT.js";
6
6
 
7
7
  // src/modals/Iframe3ds.tsx
8
8
  import { useEffect } from "react";
@@ -1,4 +1,5 @@
1
1
  // src/types/payments.ts
2
+ var isNewCard = (card) => !("cardId" in card);
2
3
  var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
3
4
  PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
4
5
  PaymentType2["CRYPTO"] = "CRYPTO";
@@ -9,7 +10,7 @@ var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
9
10
  })(PaymentType || {});
10
11
 
11
12
  // package.json
12
- var version = "0.4.2";
13
+ var version = "0.4.6";
13
14
 
14
15
  // src/utils/logger.ts
15
16
  var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
@@ -775,6 +776,7 @@ function DialogDescription({ className, ...props }) {
775
776
 
776
777
  export {
777
778
  PaymentError,
779
+ isNewCard,
778
780
  PaymentType,
779
781
  LogLevel,
780
782
  logger,
@@ -6,7 +6,7 @@ import {
6
6
  useSpreePayEnv,
7
7
  useSpreePaymentMethod,
8
8
  useStaticConfig
9
- } from "./chunk-I35SE3K2.js";
9
+ } from "./chunk-AGTOSFMT.js";
10
10
 
11
11
  // src/components/common/PointsSwitch.tsx
12
12
  import { useId } from "react";
@@ -283,7 +283,56 @@ var CheckoutButton = ({ isLoggedIn }) => {
283
283
 
284
284
  // ../ui/src/lib/utils.ts
285
285
  import { clsx } from "clsx";
286
- import { twMerge } from "tailwind-merge";
286
+ import { extendTailwindMerge } from "tailwind-merge";
287
+ var isUniversalSpacing = (value) => value.startsWith("universal-");
288
+ var isLayoutToken = (value) => value.startsWith("universal-") || value.startsWith("layout-");
289
+ var isUniversalRadius = (value) => value.startsWith("radius-universal-");
290
+ var isTypography = (value) => value.startsWith("heading-") || value.startsWith("body-") || value.startsWith("label-") || value.startsWith("menu-");
291
+ var twMerge = extendTailwindMerge({
292
+ extend: {
293
+ classGroups: {
294
+ "font-size": [{ text: [isTypography] }],
295
+ leading: [{ leading: [isTypography] }],
296
+ "font-weight": [{ font: [isTypography] }],
297
+ p: [{ p: [isUniversalSpacing] }],
298
+ px: [{ px: [isUniversalSpacing] }],
299
+ py: [{ py: [isUniversalSpacing] }],
300
+ pt: [{ pt: [isUniversalSpacing] }],
301
+ pb: [{ pb: [isUniversalSpacing] }],
302
+ pl: [{ pl: [isUniversalSpacing] }],
303
+ pr: [{ pr: [isUniversalSpacing] }],
304
+ m: [{ m: [isUniversalSpacing] }],
305
+ mx: [{ mx: [isUniversalSpacing] }],
306
+ my: [{ my: [isUniversalSpacing] }],
307
+ mt: [{ mt: [isUniversalSpacing] }],
308
+ mb: [{ mb: [isUniversalSpacing] }],
309
+ ml: [{ ml: [isUniversalSpacing] }],
310
+ mr: [{ mr: [isUniversalSpacing] }],
311
+ gap: [{ gap: [isUniversalSpacing] }],
312
+ "gap-x": [{ "gap-x": [isUniversalSpacing] }],
313
+ "gap-y": [{ "gap-y": [isUniversalSpacing] }],
314
+ "space-x": [{ "space-x": [isUniversalSpacing] }],
315
+ "space-y": [{ "space-y": [isUniversalSpacing] }],
316
+ w: [{ w: [isLayoutToken] }],
317
+ "min-w": [{ "min-w": [isLayoutToken] }],
318
+ "max-w": [{ "max-w": [isLayoutToken] }],
319
+ h: [{ h: [isLayoutToken] }],
320
+ "min-h": [{ "min-h": [isLayoutToken] }],
321
+ "max-h": [{ "max-h": [isLayoutToken] }],
322
+ rounded: [{ rounded: [isUniversalRadius] }],
323
+ "rounded-s": [{ "rounded-s": [isUniversalRadius] }],
324
+ "rounded-e": [{ "rounded-e": [isUniversalRadius] }],
325
+ "rounded-t": [{ "rounded-t": [isUniversalRadius] }],
326
+ "rounded-r": [{ "rounded-r": [isUniversalRadius] }],
327
+ "rounded-b": [{ "rounded-b": [isUniversalRadius] }],
328
+ "rounded-l": [{ "rounded-l": [isUniversalRadius] }],
329
+ "rounded-tl": [{ "rounded-tl": [isUniversalRadius] }],
330
+ "rounded-tr": [{ "rounded-tr": [isUniversalRadius] }],
331
+ "rounded-br": [{ "rounded-br": [isUniversalRadius] }],
332
+ "rounded-bl": [{ "rounded-bl": [isUniversalRadius] }]
333
+ }
334
+ }
335
+ });
287
336
  function cn2(...inputs) {
288
337
  return twMerge(clsx(inputs));
289
338
  }
package/build/index.cjs CHANGED
@@ -49,10 +49,11 @@ var init_errors = __esm({
49
49
  });
50
50
 
51
51
  // src/types/payments.ts
52
- var PaymentType;
52
+ var isNewCard, PaymentType;
53
53
  var init_payments = __esm({
54
54
  "src/types/payments.ts"() {
55
55
  "use strict";
56
+ isNewCard = (card) => !("cardId" in card);
56
57
  PaymentType = /* @__PURE__ */ ((PaymentType2) => {
57
58
  PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
58
59
  PaymentType2["CRYPTO"] = "CRYPTO";
@@ -68,7 +69,7 @@ var init_payments = __esm({
68
69
  var version;
69
70
  var init_package = __esm({
70
71
  "package.json"() {
71
- version = "0.4.2";
72
+ version = "0.4.6";
72
73
  }
73
74
  });
74
75
 
@@ -1128,11 +1129,11 @@ var init_InfoBanner = __esm({
1128
1129
  });
1129
1130
 
1130
1131
  // src/components/common/PointsSwitch.tsx
1131
- var import_react5, import_jsx_runtime9, PointsSwitch;
1132
+ var import_react6, import_jsx_runtime9, PointsSwitch;
1132
1133
  var init_PointsSwitch = __esm({
1133
1134
  "src/components/common/PointsSwitch.tsx"() {
1134
1135
  "use strict";
1135
- import_react5 = require("react");
1136
+ import_react6 = require("react");
1136
1137
  init_StaticConfigContext();
1137
1138
  init_useSlapiBalance();
1138
1139
  init_useSpreePayConfig();
@@ -1149,7 +1150,7 @@ var init_PointsSwitch = __esm({
1149
1150
  const { balance } = useSlapiBalance();
1150
1151
  const hasForeignCurrency = !!(currencyCode && exchangeRate && foreignCurrencyAmount);
1151
1152
  const formatPointsValue = (usd) => hasForeignCurrency ? formatCurrency(usd / exchangeRate, currencyCode) : formatCurrency(usd);
1152
- const id = (0, import_react5.useId)();
1153
+ const id = (0, import_react6.useId)();
1153
1154
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-6", children: [
1154
1155
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
1155
1156
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3", children: [
@@ -1321,14 +1322,63 @@ var init_CheckoutButton = __esm({
1321
1322
 
1322
1323
  // ../ui/src/lib/utils.ts
1323
1324
  function cn2(...inputs) {
1324
- return (0, import_tailwind_merge2.twMerge)((0, import_clsx2.clsx)(inputs));
1325
+ return twMerge2((0, import_clsx2.clsx)(inputs));
1325
1326
  }
1326
- var import_clsx2, import_tailwind_merge2;
1327
+ var import_clsx2, import_tailwind_merge2, isUniversalSpacing, isLayoutToken, isUniversalRadius, isTypography, twMerge2;
1327
1328
  var init_utils2 = __esm({
1328
1329
  "../ui/src/lib/utils.ts"() {
1329
1330
  "use strict";
1330
1331
  import_clsx2 = require("clsx");
1331
1332
  import_tailwind_merge2 = require("tailwind-merge");
1333
+ isUniversalSpacing = (value) => value.startsWith("universal-");
1334
+ isLayoutToken = (value) => value.startsWith("universal-") || value.startsWith("layout-");
1335
+ isUniversalRadius = (value) => value.startsWith("radius-universal-");
1336
+ isTypography = (value) => value.startsWith("heading-") || value.startsWith("body-") || value.startsWith("label-") || value.startsWith("menu-");
1337
+ twMerge2 = (0, import_tailwind_merge2.extendTailwindMerge)({
1338
+ extend: {
1339
+ classGroups: {
1340
+ "font-size": [{ text: [isTypography] }],
1341
+ leading: [{ leading: [isTypography] }],
1342
+ "font-weight": [{ font: [isTypography] }],
1343
+ p: [{ p: [isUniversalSpacing] }],
1344
+ px: [{ px: [isUniversalSpacing] }],
1345
+ py: [{ py: [isUniversalSpacing] }],
1346
+ pt: [{ pt: [isUniversalSpacing] }],
1347
+ pb: [{ pb: [isUniversalSpacing] }],
1348
+ pl: [{ pl: [isUniversalSpacing] }],
1349
+ pr: [{ pr: [isUniversalSpacing] }],
1350
+ m: [{ m: [isUniversalSpacing] }],
1351
+ mx: [{ mx: [isUniversalSpacing] }],
1352
+ my: [{ my: [isUniversalSpacing] }],
1353
+ mt: [{ mt: [isUniversalSpacing] }],
1354
+ mb: [{ mb: [isUniversalSpacing] }],
1355
+ ml: [{ ml: [isUniversalSpacing] }],
1356
+ mr: [{ mr: [isUniversalSpacing] }],
1357
+ gap: [{ gap: [isUniversalSpacing] }],
1358
+ "gap-x": [{ "gap-x": [isUniversalSpacing] }],
1359
+ "gap-y": [{ "gap-y": [isUniversalSpacing] }],
1360
+ "space-x": [{ "space-x": [isUniversalSpacing] }],
1361
+ "space-y": [{ "space-y": [isUniversalSpacing] }],
1362
+ w: [{ w: [isLayoutToken] }],
1363
+ "min-w": [{ "min-w": [isLayoutToken] }],
1364
+ "max-w": [{ "max-w": [isLayoutToken] }],
1365
+ h: [{ h: [isLayoutToken] }],
1366
+ "min-h": [{ "min-h": [isLayoutToken] }],
1367
+ "max-h": [{ "max-h": [isLayoutToken] }],
1368
+ rounded: [{ rounded: [isUniversalRadius] }],
1369
+ "rounded-s": [{ "rounded-s": [isUniversalRadius] }],
1370
+ "rounded-e": [{ "rounded-e": [isUniversalRadius] }],
1371
+ "rounded-t": [{ "rounded-t": [isUniversalRadius] }],
1372
+ "rounded-r": [{ "rounded-r": [isUniversalRadius] }],
1373
+ "rounded-b": [{ "rounded-b": [isUniversalRadius] }],
1374
+ "rounded-l": [{ "rounded-l": [isUniversalRadius] }],
1375
+ "rounded-tl": [{ "rounded-tl": [isUniversalRadius] }],
1376
+ "rounded-tr": [{ "rounded-tr": [isUniversalRadius] }],
1377
+ "rounded-br": [{ "rounded-br": [isUniversalRadius] }],
1378
+ "rounded-bl": [{ "rounded-bl": [isUniversalRadius] }]
1379
+ }
1380
+ }
1381
+ });
1332
1382
  }
1333
1383
  });
1334
1384
 
@@ -1764,7 +1814,7 @@ function Input2({ className, type, ...props }) {
1764
1814
  type,
1765
1815
  "data-slot": "input",
1766
1816
  className: cn2(
1767
- "file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base text-(--primary) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-(--tertiary) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1817
+ "file:text-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input px-universal-2xs py-universal-6xs rounded-radius-universal-xs text-body-m file:text-label-s file:font-label-primary flex h-9 w-full min-w-0 border bg-transparent text-(--color-text-icons-primary-default) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent placeholder:text-(--color-text-icons-tertiary-default) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
1768
1818
  "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
1769
1819
  "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
1770
1820
  className
@@ -1874,7 +1924,7 @@ function Separator2({
1874
1924
  decorative,
1875
1925
  orientation,
1876
1926
  className: cn2(
1877
- "shrink-0 bg-(--b-secondary) data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
1927
+ "shrink-0 bg-(--color-border-default) data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
1878
1928
  className
1879
1929
  ),
1880
1930
  ...props
@@ -2004,11 +2054,11 @@ var init_useBaseTokens = __esm({
2004
2054
  });
2005
2055
 
2006
2056
  // src/modals/CryptoSelectModal.tsx
2007
- var import_react15, import_nice_modal_react5, import_jsx_runtime37, CryptoSelectModal;
2057
+ var import_react16, import_nice_modal_react5, import_jsx_runtime37, CryptoSelectModal;
2008
2058
  var init_CryptoSelectModal = __esm({
2009
2059
  "src/modals/CryptoSelectModal.tsx"() {
2010
2060
  "use strict";
2011
- import_react15 = require("react");
2061
+ import_react16 = require("react");
2012
2062
  import_nice_modal_react5 = __toESM(require("@ebay/nice-modal-react"), 1);
2013
2063
  init_input();
2014
2064
  init_separator();
@@ -2024,8 +2074,8 @@ var init_CryptoSelectModal = __esm({
2024
2074
  const { isLoading, error, erc20Balances } = useBaseERC20Token();
2025
2075
  const { isLoadingNative, nativeError, nativeBalance } = useBaseNativeToken();
2026
2076
  const { tokens, tokensIsLoading } = useBaseTokens();
2027
- const [search, setSearch] = (0, import_react15.useState)("");
2028
- const filteredCoins = (0, import_react15.useMemo)(() => {
2077
+ const [search, setSearch] = (0, import_react16.useState)("");
2078
+ const filteredCoins = (0, import_react16.useMemo)(() => {
2029
2079
  return tokens.filter(
2030
2080
  (coin) => coin.name.toLowerCase().includes(search.toLowerCase()) || coin.symbol.toLowerCase().includes(search.toLowerCase())
2031
2081
  );
@@ -2187,11 +2237,11 @@ var init_SelectedCoin = __esm({
2187
2237
  });
2188
2238
 
2189
2239
  // src/components/CryptoTab/Crypto/Crypto.tsx
2190
- var import_react16, import_wagmi4, import_jsx_runtime40, Crypto;
2240
+ var import_react17, import_wagmi4, import_jsx_runtime40, Crypto;
2191
2241
  var init_Crypto = __esm({
2192
2242
  "src/components/CryptoTab/Crypto/Crypto.tsx"() {
2193
2243
  "use strict";
2194
- import_react16 = require("react");
2244
+ import_react17 = require("react");
2195
2245
  import_wagmi4 = require("wagmi");
2196
2246
  init_SpreePayActionsContext();
2197
2247
  init_useCryptoPayment();
@@ -2210,7 +2260,7 @@ var init_Crypto = __esm({
2210
2260
  const { spreePayConfig } = useSpreePayConfig();
2211
2261
  const isWalletConnected = Boolean(address);
2212
2262
  const { register } = useSpreePayRegister();
2213
- const handlePay = (0, import_react16.useCallback)(
2263
+ const handlePay = (0, import_react17.useCallback)(
2214
2264
  async (data) => {
2215
2265
  try {
2216
2266
  const res = await cryptoPayment(data);
@@ -2224,7 +2274,7 @@ var init_Crypto = __esm({
2224
2274
  },
2225
2275
  [cryptoPayment]
2226
2276
  );
2227
- (0, import_react16.useEffect)(() => {
2277
+ (0, import_react17.useEffect)(() => {
2228
2278
  register(handlePay);
2229
2279
  }, [register, handlePay]);
2230
2280
  return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "flex flex-col items-baseline gap-4", children: [
@@ -2260,11 +2310,11 @@ function getCachedWagmiConfig(projectId, appName) {
2260
2310
  }
2261
2311
  return cfg2;
2262
2312
  }
2263
- var import_react17, import_react_query, import_nice_modal_react7, import_rainbowkit2, import_styles, import_wagmi5, import_chains, import_jsx_runtime41, queryClient, CHAINS, wagmiConfigCache, CryptoWrapper;
2313
+ var import_react18, import_react_query, import_nice_modal_react7, import_rainbowkit2, import_styles, import_wagmi5, import_chains, import_jsx_runtime41, queryClient, CHAINS, wagmiConfigCache, CryptoWrapper;
2264
2314
  var init_CryptoWrapper = __esm({
2265
2315
  "src/components/CryptoTab/Crypto/CryptoWrapper.tsx"() {
2266
2316
  "use strict";
2267
- import_react17 = require("react");
2317
+ import_react18 = require("react");
2268
2318
  import_react_query = require("@tanstack/react-query");
2269
2319
  import_nice_modal_react7 = __toESM(require("@ebay/nice-modal-react"), 1);
2270
2320
  import_rainbowkit2 = require("@rainbow-me/rainbowkit");
@@ -2279,7 +2329,7 @@ var init_CryptoWrapper = __esm({
2279
2329
  wagmiConfigCache = /* @__PURE__ */ new Map();
2280
2330
  CryptoWrapper = () => {
2281
2331
  const { spreePayConfig, configIsLoading } = useSpreePayConfig();
2282
- const wagmiConfig = (0, import_react17.useMemo)(() => {
2332
+ const wagmiConfig = (0, import_react18.useMemo)(() => {
2283
2333
  if (!spreePayConfig) return null;
2284
2334
  return getCachedWagmiConfig(spreePayConfig.rainbowProjectId, spreePayConfig.rainbowAppName);
2285
2335
  }, [spreePayConfig]);
@@ -2466,11 +2516,11 @@ var init_Checkout = __esm({
2466
2516
  });
2467
2517
 
2468
2518
  // src/components/CryptoComTab/CryptoComTab.tsx
2469
- var import_react18, import_jsx_runtime44, CryptoComTab;
2519
+ var import_react19, import_jsx_runtime44, CryptoComTab;
2470
2520
  var init_CryptoComTab = __esm({
2471
2521
  "src/components/CryptoComTab/CryptoComTab.tsx"() {
2472
2522
  "use strict";
2473
- import_react18 = require("react");
2523
+ import_react19 = require("react");
2474
2524
  init_SpreePayActionsContext();
2475
2525
  init_useCryptoComPayment();
2476
2526
  init_useSpreePayConfig();
@@ -2482,7 +2532,7 @@ var init_CryptoComTab = __esm({
2482
2532
  const { register } = useSpreePayRegister();
2483
2533
  const { cryptoComPayment } = useCryptoComPayment();
2484
2534
  const { spreePayConfig } = useSpreePayConfig();
2485
- const handlePay = (0, import_react18.useCallback)(
2535
+ const handlePay = (0, import_react19.useCallback)(
2486
2536
  async (data) => {
2487
2537
  try {
2488
2538
  const res = await cryptoComPayment(data);
@@ -2496,7 +2546,7 @@ var init_CryptoComTab = __esm({
2496
2546
  },
2497
2547
  [cryptoComPayment]
2498
2548
  );
2499
- (0, import_react18.useEffect)(() => {
2549
+ (0, import_react19.useEffect)(() => {
2500
2550
  register(handlePay);
2501
2551
  }, [register, handlePay]);
2502
2552
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex w-full flex-col gap-4 border-b border-b-(--border-component-specific-card) px-5 py-5 md:px-7 md:py-6", children: [
@@ -2535,15 +2585,15 @@ __export(index_exports, {
2535
2585
  module.exports = __toCommonJS(index_exports);
2536
2586
 
2537
2587
  // src/SpreePay.tsx
2538
- var import_react22 = require("react");
2588
+ var import_react23 = require("react");
2539
2589
  var import_nice_modal_react9 = __toESM(require("@ebay/nice-modal-react"), 1);
2540
2590
  var import_swr5 = require("swr");
2541
2591
 
2542
2592
  // src/SpreePayContent.tsx
2543
- var import_react19 = require("react");
2593
+ var import_react20 = require("react");
2544
2594
 
2545
2595
  // src/components/CreditCardTab/CreditCardTab.tsx
2546
- var import_react14 = require("react");
2596
+ var import_react15 = require("react");
2547
2597
  init_SpreePayActionsContext();
2548
2598
  init_StaticConfigContext();
2549
2599
 
@@ -3068,14 +3118,16 @@ var useSplitCardPayments = (mode = "web2") => {
3068
3118
  };
3069
3119
 
3070
3120
  // src/hooks/useCards.ts
3121
+ var import_react5 = require("react");
3071
3122
  var import_swr2 = __toESM(require("swr"), 1);
3072
3123
  init_SpreePayActionsContext();
3073
3124
  var URL2 = "/v1/payments/cards";
3074
3125
  var useCards = () => {
3075
3126
  const { origin } = useSpreePayEnv();
3076
3127
  const { data, isLoading, mutate } = (0, import_swr2.default)(origin ? `${URL2}?origin=${origin}` : URL2);
3128
+ const cards = (0, import_react5.useMemo)(() => data?.data.filter((c) => c.active) ?? [], [data]);
3077
3129
  return {
3078
- cards: data?.data.filter((c) => c.active) || [],
3130
+ cards,
3079
3131
  cardsIsLoading: isLoading,
3080
3132
  mutateCards: mutate
3081
3133
  };
@@ -3089,7 +3141,7 @@ init_split();
3089
3141
  init_CheckoutButton();
3090
3142
 
3091
3143
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
3092
- var import_react8 = require("react");
3144
+ var import_react9 = require("react");
3093
3145
  var import_react_stripe_js2 = require("@stripe/react-stripe-js");
3094
3146
  var import_stripe_js = require("@stripe/stripe-js");
3095
3147
  init_SpreePayActionsContext();
@@ -3097,12 +3149,13 @@ init_useSpreePayConfig();
3097
3149
  init_InfoBanner();
3098
3150
 
3099
3151
  // src/components/CreditCardTab/CreditCard/CardsList.tsx
3100
- var import_react6 = require("react");
3152
+ var import_react7 = require("react");
3101
3153
  init_utils();
3102
3154
  init_slapi();
3155
+ init_payments();
3103
3156
  var import_jsx_runtime12 = require("react/jsx-runtime");
3104
3157
  var CardListItem = ({ card, isSelected, onSelect, onRemove }) => {
3105
- const [isRemoving, setIsRemoving] = (0, import_react6.useState)(false);
3158
+ const [isRemoving, setIsRemoving] = (0, import_react7.useState)(false);
3106
3159
  const removeDisabled = isSelected || isRemoving;
3107
3160
  const handleRemove = async (e) => {
3108
3161
  e.stopPropagation();
@@ -3165,19 +3218,22 @@ var CardListItem = ({ card, isSelected, onSelect, onRemove }) => {
3165
3218
  }
3166
3219
  );
3167
3220
  };
3168
- var CardsList = ({ selectedCard, setCard }) => {
3221
+ var CardsList = ({ selectedCard, setCard, newCards, onRemoveNewCard }) => {
3169
3222
  const { cards, cardsIsLoading, mutateCards } = useCards();
3223
+ const allCards = (0, import_react7.useMemo)(() => [...cards, ...newCards], [cards, newCards]);
3170
3224
  const handleRemove = async (card) => {
3171
- if ("cardId" in card) {
3225
+ if (isNewCard(card)) {
3226
+ onRemoveNewCard(card);
3227
+ } else {
3172
3228
  await SlapiPaymentService.removeCard({ cardId: card.id });
3229
+ mutateCards((data) => ({ ...data, data: (data?.data ?? []).filter((c) => c.id !== card.id) }));
3173
3230
  }
3174
- mutateCards((data) => ({ ...data, data: (data?.data ?? []).filter((c) => c.id !== card.id) }));
3175
3231
  };
3176
3232
  if (cardsIsLoading) {
3177
3233
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex w-full flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "h-11 animate-pulse rounded-sm bg-(--s-primary)" }) });
3178
3234
  }
3179
- if (cards.length === 0) return null;
3180
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex w-full flex-col gap-4", children: cards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3235
+ if (allCards.length === 0) return null;
3236
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex w-full flex-col gap-4", children: allCards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3181
3237
  CardListItem,
3182
3238
  {
3183
3239
  isSelected: selectedCard?.id === card.id,
@@ -3190,7 +3246,7 @@ var CardsList = ({ selectedCard, setCard }) => {
3190
3246
  };
3191
3247
 
3192
3248
  // src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
3193
- var import_react7 = require("react");
3249
+ var import_react8 = require("react");
3194
3250
  var import_react_stripe_js = require("@stripe/react-stripe-js");
3195
3251
 
3196
3252
  // src/ui/button.tsx
@@ -3246,7 +3302,7 @@ function Checkbox({ className, ...props }) {
3246
3302
  {
3247
3303
  "data-slot": "checkbox",
3248
3304
  className: cn(
3249
- "peer border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-sm border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-(--primary) data-[state=checked]:bg-(--primary) data-[state=checked]:text-(--inverse) dark:data-[state=checked]:bg-(--primary)",
3305
+ "peer border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-sm border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-(--s-brand) data-[state=checked]:bg-(--s-brand) data-[state=checked]:text-(--inverse)",
3250
3306
  className
3251
3307
  ),
3252
3308
  ...props,
@@ -3273,14 +3329,14 @@ var stripeElementClasses = {
3273
3329
  focus: "border-ring ring-ring/50 ring-2"
3274
3330
  };
3275
3331
  var CreditCardForm = ({ cancel, saveCard }) => {
3276
- const [cardError, setCardError] = (0, import_react7.useState)(void 0);
3277
- const [stripeStyles, setStripeStyles] = (0, import_react7.useState)({});
3278
- const [shouldSaveCard, setShouldSaveCard] = (0, import_react7.useState)(true);
3279
- const formRef = (0, import_react7.useRef)(null);
3332
+ const [cardError, setCardError] = (0, import_react8.useState)(void 0);
3333
+ const [stripeStyles, setStripeStyles] = (0, import_react8.useState)({});
3334
+ const [shouldSaveCard, setShouldSaveCard] = (0, import_react8.useState)(true);
3335
+ const formRef = (0, import_react8.useRef)(null);
3280
3336
  const elements = (0, import_react_stripe_js.useElements)();
3281
3337
  const stripe = (0, import_react_stripe_js.useStripe)();
3282
- const id = (0, import_react7.useId)();
3283
- const computeStripeStyles = (0, import_react7.useCallback)(() => {
3338
+ const [id] = (0, import_react8.useState)(() => crypto.randomUUID());
3339
+ const computeStripeStyles = (0, import_react8.useCallback)(() => {
3284
3340
  const formRefCurrent = formRef.current;
3285
3341
  if (typeof window === "undefined" || !formRefCurrent) return {};
3286
3342
  const container = formRefCurrent.closest(".sl-spreepay");
@@ -3301,7 +3357,7 @@ var CreditCardForm = ({ cancel, saveCard }) => {
3301
3357
  }
3302
3358
  };
3303
3359
  }, []);
3304
- (0, import_react7.useEffect)(() => {
3360
+ (0, import_react8.useEffect)(() => {
3305
3361
  setStripeStyles(computeStripeStyles());
3306
3362
  }, [computeStripeStyles]);
3307
3363
  const handleSaveCard = async () => {
@@ -3404,13 +3460,13 @@ var CreditCardForm = ({ cancel, saveCard }) => {
3404
3460
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
3405
3461
  var import_jsx_runtime16 = require("react/jsx-runtime");
3406
3462
  var StripeWrapper = ({ onCancel, saveNewCard, publicKey }) => {
3407
- const stripePromise = (0, import_react8.useMemo)(() => (0, import_stripe_js.loadStripe)(publicKey), [publicKey]);
3463
+ const stripePromise = (0, import_react9.useMemo)(() => (0, import_stripe_js.loadStripe)(publicKey), [publicKey]);
3408
3464
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_stripe_js2.Elements, { stripe: stripePromise, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CreditCardForm, { cancel: onCancel, saveCard: saveNewCard }) });
3409
3465
  };
3410
3466
  var CreditCard = () => {
3411
- const [showForm, setShowForm] = (0, import_react8.useState)(false);
3467
+ const [showForm, setShowForm] = (0, import_react9.useState)(false);
3468
+ const [newCards, setNewCards] = (0, import_react9.useState)([]);
3412
3469
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
3413
- const { mutateCards } = useCards();
3414
3470
  const { spreePayConfig } = useSpreePayConfig();
3415
3471
  const setCard = (card) => {
3416
3472
  const isAlreadySelected = selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ && selectedPaymentMethod.method?.id === card.id;
@@ -3421,10 +3477,13 @@ var CreditCard = () => {
3421
3477
  });
3422
3478
  };
3423
3479
  const saveNewCard = (newCard) => {
3424
- mutateCards((data) => ({ ...data, data: [...data?.data ?? [], newCard] }), { revalidate: false });
3480
+ setNewCards((prev) => [...prev, newCard]);
3425
3481
  setCard(newCard);
3426
3482
  setShowForm(false);
3427
3483
  };
3484
+ const removeNewCard = (0, import_react9.useCallback)((card) => {
3485
+ setNewCards((prev) => prev.filter((c) => c.id !== card.id));
3486
+ }, []);
3428
3487
  const handleCancel = () => {
3429
3488
  setShowForm(false);
3430
3489
  };
@@ -3435,7 +3494,9 @@ var CreditCard = () => {
3435
3494
  CardsList,
3436
3495
  {
3437
3496
  selectedCard: selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ ? selectedPaymentMethod.method : null,
3438
- setCard
3497
+ setCard,
3498
+ newCards,
3499
+ onRemoveNewCard: removeNewCard
3439
3500
  }
3440
3501
  ),
3441
3502
  spreePayConfig?.creditCard.infoMessage && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(InfoBanner, { message: spreePayConfig.creditCard.infoMessage }),
@@ -3454,14 +3515,14 @@ var CreditCard = () => {
3454
3515
  };
3455
3516
 
3456
3517
  // src/components/CreditCardTab/Points/Points.tsx
3457
- var import_react13 = require("react");
3518
+ var import_react14 = require("react");
3458
3519
  init_SpreePayActionsContext();
3459
3520
  init_StaticConfigContext();
3460
3521
  init_useSpreePayConfig();
3461
3522
  init_common();
3462
3523
 
3463
3524
  // src/components/CreditCardTab/Points/SplitBlock.tsx
3464
- var import_react12 = require("react");
3525
+ var import_react13 = require("react");
3465
3526
  var import_airkit2 = require("@mocanetwork/airkit");
3466
3527
  init_SpreePayActionsContext();
3467
3528
  init_StaticConfigContext();
@@ -3471,7 +3532,7 @@ init_format();
3471
3532
  init_logger();
3472
3533
 
3473
3534
  // src/components/CreditCardTab/Points/PointsSelector.tsx
3474
- var import_react11 = require("react");
3535
+ var import_react12 = require("react");
3475
3536
  init_SpreePayActionsContext();
3476
3537
  init_StaticConfigContext();
3477
3538
  init_useSlapiBalance();
@@ -3791,10 +3852,10 @@ var Primitive = NODES.reduce((primitive, node) => {
3791
3852
  }, {});
3792
3853
 
3793
3854
  // ../../node_modules/@radix-ui/react-collection/dist/index.mjs
3794
- var import_react9 = __toESM(require("react"), 1);
3855
+ var import_react10 = __toESM(require("react"), 1);
3795
3856
  var import_react_slot3 = require("@radix-ui/react-slot");
3796
3857
  var import_jsx_runtime21 = require("react/jsx-runtime");
3797
- var import_react10 = __toESM(require("react"), 1);
3858
+ var import_react11 = __toESM(require("react"), 1);
3798
3859
  var import_react_slot4 = require("@radix-ui/react-slot");
3799
3860
  var import_jsx_runtime22 = require("react/jsx-runtime");
3800
3861
  function createCollection(name) {
@@ -3806,14 +3867,14 @@ function createCollection(name) {
3806
3867
  );
3807
3868
  const CollectionProvider = (props) => {
3808
3869
  const { scope, children } = props;
3809
- const ref = import_react9.default.useRef(null);
3810
- const itemMap = import_react9.default.useRef(/* @__PURE__ */ new Map()).current;
3870
+ const ref = import_react10.default.useRef(null);
3871
+ const itemMap = import_react10.default.useRef(/* @__PURE__ */ new Map()).current;
3811
3872
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CollectionProviderImpl, { scope, itemMap, collectionRef: ref, children });
3812
3873
  };
3813
3874
  CollectionProvider.displayName = PROVIDER_NAME;
3814
3875
  const COLLECTION_SLOT_NAME = name + "CollectionSlot";
3815
3876
  const CollectionSlotImpl = (0, import_react_slot3.createSlot)(COLLECTION_SLOT_NAME);
3816
- const CollectionSlot = import_react9.default.forwardRef(
3877
+ const CollectionSlot = import_react10.default.forwardRef(
3817
3878
  (props, forwardedRef) => {
3818
3879
  const { scope, children } = props;
3819
3880
  const context = useCollectionContext(COLLECTION_SLOT_NAME, scope);
@@ -3825,13 +3886,13 @@ function createCollection(name) {
3825
3886
  const ITEM_SLOT_NAME = name + "CollectionItemSlot";
3826
3887
  const ITEM_DATA_ATTR = "data-radix-collection-item";
3827
3888
  const CollectionItemSlotImpl = (0, import_react_slot3.createSlot)(ITEM_SLOT_NAME);
3828
- const CollectionItemSlot = import_react9.default.forwardRef(
3889
+ const CollectionItemSlot = import_react10.default.forwardRef(
3829
3890
  (props, forwardedRef) => {
3830
3891
  const { scope, children, ...itemData } = props;
3831
- const ref = import_react9.default.useRef(null);
3892
+ const ref = import_react10.default.useRef(null);
3832
3893
  const composedRefs = useComposedRefs(forwardedRef, ref);
3833
3894
  const context = useCollectionContext(ITEM_SLOT_NAME, scope);
3834
- import_react9.default.useEffect(() => {
3895
+ import_react10.default.useEffect(() => {
3835
3896
  context.itemMap.set(ref, { ref, ...itemData });
3836
3897
  return () => void context.itemMap.delete(ref);
3837
3898
  });
@@ -3841,7 +3902,7 @@ function createCollection(name) {
3841
3902
  CollectionItemSlot.displayName = ITEM_SLOT_NAME;
3842
3903
  function useCollection2(scope) {
3843
3904
  const context = useCollectionContext(name + "CollectionConsumer", scope);
3844
- const getItems = import_react9.default.useCallback(() => {
3905
+ const getItems = import_react10.default.useCallback(() => {
3845
3906
  const collectionNode = context.collectionRef.current;
3846
3907
  if (!collectionNode) return [];
3847
3908
  const orderedNodes = Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));
@@ -4474,7 +4535,7 @@ var PointsSelector = (props) => {
4474
4535
  const maxByAmount = pointsConversionRatio && pointsConversionRatio > 0 ? (amount ?? 0) / pointsConversionRatio : 0;
4475
4536
  const max = Math.min(maxByAmount, balance?.availablePoints ?? 0);
4476
4537
  const step = 10;
4477
- const [splitTokens, setSplitTokens] = (0, import_react11.useState)(0);
4538
+ const [splitTokens, setSplitTokens] = (0, import_react12.useState)(0);
4478
4539
  const usdAmount = getSplitAmount(amount ?? 0, splitTokens, pointsConversionRatio);
4479
4540
  const pointsValue = String(Math.round(splitTokens));
4480
4541
  const usdWithFee = usdAmount + getTransactionFee(usdAmount, transactionFeePercentage);
@@ -4572,14 +4633,14 @@ var SplitBlock = (props) => {
4572
4633
  const { spreePayConfig } = useSpreePayConfig();
4573
4634
  const { appProps } = useStaticConfig();
4574
4635
  const { currencyCode, exchangeRate, foreignCurrencyAmount } = appProps;
4575
- const [address, setAddress] = (0, import_react12.useState)(null);
4576
- const [walletReady, setWalletReady] = (0, import_react12.useState)(false);
4636
+ const [address, setAddress] = (0, import_react13.useState)(null);
4637
+ const [walletReady, setWalletReady] = (0, import_react13.useState)(false);
4577
4638
  const { pointsConversionRatio, pointsTitle } = spreePayConfig || {};
4578
4639
  const { useWeb3Points, environment } = useSpreePayEnv();
4579
4640
  const hasForeignCurrency = !!(currencyCode && exchangeRate && foreignCurrencyAmount);
4580
4641
  const formatPointsValue = (usd) => hasForeignCurrency ? formatCurrency(usd / exchangeRate, currencyCode) : formatCurrency(usd);
4581
- const prevPointsChainRef = (0, import_react12.useRef)(spreePayConfig?.pointsChain);
4582
- const initWallet = (0, import_react12.useCallback)(
4642
+ const prevPointsChainRef = (0, import_react13.useRef)(spreePayConfig?.pointsChain);
4643
+ const initWallet = (0, import_react13.useCallback)(
4583
4644
  async (pointsChain) => {
4584
4645
  if (!pointsChain) return;
4585
4646
  try {
@@ -4602,7 +4663,7 @@ var SplitBlock = (props) => {
4602
4663
  },
4603
4664
  [onToggle, environment]
4604
4665
  );
4605
- (0, import_react12.useEffect)(() => {
4666
+ (0, import_react13.useEffect)(() => {
4606
4667
  if (!useWeb3Points) return;
4607
4668
  const pointsChainChanged = prevPointsChainRef.current !== spreePayConfig?.pointsChain;
4608
4669
  prevPointsChainRef.current = spreePayConfig?.pointsChain;
@@ -4632,8 +4693,8 @@ var SplitBlock = (props) => {
4632
4693
  // src/components/CreditCardTab/Points/Points.tsx
4633
4694
  var import_jsx_runtime27 = require("react/jsx-runtime");
4634
4695
  var Points = () => {
4635
- const [usePoints, setUsePoints] = (0, import_react13.useState)(false);
4636
- const [selectedPointsType, setSelectedPointsType] = (0, import_react13.useState)(null);
4696
+ const [usePoints, setUsePoints] = (0, import_react14.useState)(false);
4697
+ const [selectedPointsType, setSelectedPointsType] = (0, import_react14.useState)(null);
4637
4698
  const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
4638
4699
  const { spreePayConfig } = useSpreePayConfig();
4639
4700
  const { appProps } = useStaticConfig();
@@ -4679,7 +4740,7 @@ var CreditCardTab = ({ isLoggedIn }) => {
4679
4740
  const { cardPayment } = useCardPayment();
4680
4741
  const { splitPayment } = useSplitCardPayments(isWeb3Enabled ? "web3" : "web2");
4681
4742
  const { pointsPayment } = usePointsPayment(isWeb3Enabled ? "web3" : "web2");
4682
- const handlePay = (0, import_react14.useCallback)(
4743
+ const handlePay = (0, import_react15.useCallback)(
4683
4744
  async (data) => {
4684
4745
  try {
4685
4746
  let res = null;
@@ -4718,7 +4779,7 @@ var CreditCardTab = ({ isLoggedIn }) => {
4718
4779
  mutateBalance
4719
4780
  ]
4720
4781
  );
4721
- (0, import_react14.useEffect)(() => {
4782
+ (0, import_react15.useEffect)(() => {
4722
4783
  register(handlePay);
4723
4784
  }, [register, handlePay]);
4724
4785
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { children: [
@@ -4803,8 +4864,8 @@ var TabButtons = (props) => {
4803
4864
  // src/SpreePayContent.tsx
4804
4865
  init_SpreePayActionsContext();
4805
4866
  var import_jsx_runtime45 = require("react/jsx-runtime");
4806
- var CryptoTab2 = (0, import_react19.lazy)(() => Promise.resolve().then(() => (init_CryptoTab2(), CryptoTab_exports)).then((module2) => ({ default: module2.CryptoTab })));
4807
- var CryptoComTab2 = (0, import_react19.lazy)(
4867
+ var CryptoTab2 = (0, import_react20.lazy)(() => Promise.resolve().then(() => (init_CryptoTab2(), CryptoTab_exports)).then((module2) => ({ default: module2.CryptoTab })));
4868
+ var CryptoComTab2 = (0, import_react20.lazy)(
4808
4869
  () => Promise.resolve().then(() => (init_CryptoComTab2(), CryptoComTab_exports)).then((module2) => ({ default: module2.CryptoComTab }))
4809
4870
  );
4810
4871
  var TabLoadingFallback = () => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex items-center justify-center px-5 py-8 md:px-7", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
@@ -4819,7 +4880,7 @@ var SpreePayContent = ({ isLoggedIn }) => {
4819
4880
  /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
4820
4881
  ] }),
4821
4882
  selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(CreditCardTab, { isLoggedIn }),
4822
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react19.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TabLoadingFallback, {}), children: [
4883
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react20.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TabLoadingFallback, {}), children: [
4823
4884
  selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(CryptoTab2, { isLoggedIn }),
4824
4885
  selectedPaymentMethod.type === "CDC" /* CDC */ && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(CryptoComTab2, {})
4825
4886
  ] })
@@ -4827,10 +4888,11 @@ var SpreePayContent = ({ isLoggedIn }) => {
4827
4888
  };
4828
4889
 
4829
4890
  // src/components/ErrorBoundary.tsx
4830
- var import_react20 = require("react");
4891
+ var import_react21 = require("react");
4892
+ init_utils();
4831
4893
  init_logger();
4832
4894
  var import_jsx_runtime46 = require("react/jsx-runtime");
4833
- var ErrorBoundary = class extends import_react20.Component {
4895
+ var ErrorBoundary = class extends import_react21.Component {
4834
4896
  constructor(props) {
4835
4897
  super(props);
4836
4898
  this.state = { hasError: false, error: null };
@@ -4848,8 +4910,8 @@ var ErrorBoundary = class extends import_react20.Component {
4848
4910
  if (this.props.fallback) {
4849
4911
  return this.props.fallback;
4850
4912
  }
4851
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex w-full flex-col items-center justify-center rounded-3xl border border-(--b-inverse) bg-(--s-primary) p-8", children: [
4852
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "mb-4 flex size-12 items-center justify-center rounded-full bg-(--s-secondary)", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4913
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("sl-spreepay", this.props.className), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex w-full flex-col items-center justify-center rounded-3xl border border-(--border-component-specific-card) bg-(--surface-component-specific-card-default-card) p-8 shadow-[0_6.25px_25px_0_var(--shadow-component-specific-card)]", children: [
4914
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "mb-4 flex size-12 items-center justify-center rounded-full bg-(--s-warning-subtle)", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4853
4915
  "svg",
4854
4916
  {
4855
4917
  xmlns: "http://www.w3.org/2000/svg",
@@ -4867,9 +4929,9 @@ var ErrorBoundary = class extends import_react20.Component {
4867
4929
  ]
4868
4930
  }
4869
4931
  ) }),
4870
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h3", { className: "mb-2 text-lg font-semibold text-(--primary)", children: "Payment Widget Error" }),
4871
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-center text-sm text-(--secondary)", children: "Something went wrong loading the payment widget. Please refresh the page and try again." })
4872
- ] });
4932
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h3", { className: "mb-2 text-lg font-semibold text-(--brand-primary)", children: "Payment Widget Error" }),
4933
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-center text-sm text-(--text-tertiary)", children: "Something went wrong loading the payment widget. Please refresh the page and try again." })
4934
+ ] }) });
4873
4935
  }
4874
4936
  return this.props.children;
4875
4937
  }
@@ -4881,22 +4943,22 @@ init_StaticConfigContext();
4881
4943
  init_client();
4882
4944
 
4883
4945
  // src/hooks/useKeycloakSSO.ts
4884
- var import_react21 = require("react");
4946
+ var import_react22 = require("react");
4885
4947
  var import_keycloak_js = __toESM(require("keycloak-js"), 1);
4886
4948
  init_logger();
4887
4949
  var refreshAheadSeconds = 60;
4888
4950
  var keycloakLogger = logger.child("keycloak");
4889
4951
  function useKeycloakSSO(config2) {
4890
4952
  const { url, realm, clientId, ssoPageURI, enabled } = config2;
4891
- const initRef = (0, import_react21.useRef)(false);
4892
- const kcRef = (0, import_react21.useRef)(null);
4893
- const refreshTimerRef = (0, import_react21.useRef)(null);
4894
- const scheduleRefreshRef = (0, import_react21.useRef)(() => {
4953
+ const initRef = (0, import_react22.useRef)(false);
4954
+ const kcRef = (0, import_react22.useRef)(null);
4955
+ const refreshTimerRef = (0, import_react22.useRef)(null);
4956
+ const scheduleRefreshRef = (0, import_react22.useRef)(() => {
4895
4957
  });
4896
- const [error, setError] = (0, import_react21.useState)(null);
4897
- const [isChecking, setIsChecking] = (0, import_react21.useState)(enabled);
4898
- const [accessToken, setAccessToken] = (0, import_react21.useState)(null);
4899
- const scheduleRefresh = (0, import_react21.useCallback)(() => {
4958
+ const [error, setError] = (0, import_react22.useState)(null);
4959
+ const [isChecking, setIsChecking] = (0, import_react22.useState)(enabled);
4960
+ const [accessToken, setAccessToken] = (0, import_react22.useState)(null);
4961
+ const scheduleRefresh = (0, import_react22.useCallback)(() => {
4900
4962
  const kc = kcRef.current;
4901
4963
  if (!kc || !kc.tokenParsed || !kc.tokenParsed.exp) {
4902
4964
  return;
@@ -4920,10 +4982,10 @@ function useKeycloakSSO(config2) {
4920
4982
  });
4921
4983
  }, delayMs);
4922
4984
  }, []);
4923
- (0, import_react21.useEffect)(() => {
4985
+ (0, import_react22.useEffect)(() => {
4924
4986
  scheduleRefreshRef.current = scheduleRefresh;
4925
4987
  }, [scheduleRefresh]);
4926
- (0, import_react21.useEffect)(() => {
4988
+ (0, import_react22.useEffect)(() => {
4927
4989
  if (initRef.current || !enabled) return;
4928
4990
  initRef.current = true;
4929
4991
  const kc = new import_keycloak_js.default({ url, realm, clientId });
@@ -4960,30 +5022,44 @@ function useKeycloakSSO(config2) {
4960
5022
  init_utils();
4961
5023
  init_portal();
4962
5024
  init_logger();
5025
+
5026
+ // src/utils/token.ts
5027
+ var import_jwt_decode = require("jwt-decode");
5028
+ var isTokenExpired = (token) => {
5029
+ try {
5030
+ const { exp } = (0, import_jwt_decode.jwtDecode)(token);
5031
+ return typeof exp === "number" && exp < Math.floor(Date.now() / 1e3);
5032
+ } catch {
5033
+ return true;
5034
+ }
5035
+ };
5036
+
5037
+ // src/SpreePay.tsx
4963
5038
  var import_jsx_runtime47 = require("react/jsx-runtime");
4964
5039
  var SpreePayInner = () => {
4965
- const [portalEl, setPortalEl] = (0, import_react22.useState)(null);
4966
- const rootRef = (0, import_react22.useCallback)((node) => {
5040
+ const [portalEl, setPortalEl] = (0, import_react23.useState)(null);
5041
+ const rootRef = (0, import_react23.useCallback)((node) => {
4967
5042
  if (!node) return;
4968
5043
  const el = node.querySelector(":scope > .sl-spreepay__portal");
4969
5044
  setPortalEl(el ?? null);
4970
5045
  }, []);
4971
5046
  const { environment, tenantId, keycloakClientId, accessToken: envAccessToken, ssoPageURI } = useSpreePayEnv();
4972
- (0, import_react22.useEffect)(() => {
5047
+ (0, import_react23.useEffect)(() => {
4973
5048
  configureLogger({ environment });
4974
5049
  logger.logVersion();
4975
5050
  }, [environment]);
4976
5051
  const { staticConfig, appProps } = useStaticConfig();
5052
+ const envTokenValid = Boolean(envAccessToken && !isTokenExpired(envAccessToken));
4977
5053
  const { isChecking, accessToken } = useKeycloakSSO({
4978
5054
  realm: tenantId,
4979
5055
  url: staticConfig.keycloakUrl,
4980
5056
  clientId: keycloakClientId ?? "oneof-next",
4981
5057
  ssoPageURI,
4982
- enabled: !envAccessToken
5058
+ enabled: !envTokenValid
4983
5059
  });
4984
- const _accessToken = envAccessToken ?? accessToken;
4985
- const unauthenticatedFetcher = (0, import_react22.useCallback)(() => Promise.resolve(null), []);
4986
- const slapiFetcher = (0, import_react22.useMemo)(() => {
5060
+ const _accessToken = envTokenValid ? envAccessToken : accessToken;
5061
+ const unauthenticatedFetcher = (0, import_react23.useCallback)(() => Promise.resolve(null), []);
5062
+ const slapiFetcher = (0, import_react23.useMemo)(() => {
4987
5063
  if (_accessToken) {
4988
5064
  return registerApi({
4989
5065
  accessToken: _accessToken,
@@ -5019,13 +5095,13 @@ var SpreePayInner = () => {
5019
5095
  ] });
5020
5096
  };
5021
5097
  var SpreePay = (props) => {
5022
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(StaticConfigProvider, { props, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SpreePayInner, {}) }) });
5098
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ErrorBoundary, { className: props.className, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(StaticConfigProvider, { props, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SpreePayInner, {}) }) });
5023
5099
  };
5024
5100
 
5025
5101
  // src/hooks/useCapture3DS.ts
5026
- var import_react23 = require("react");
5102
+ var import_react24 = require("react");
5027
5103
  var useCapture3DS = (searchParams) => {
5028
- (0, import_react23.useEffect)(() => {
5104
+ (0, import_react24.useEffect)(() => {
5029
5105
  if (typeof window !== "undefined" && window.parent && searchParams?.paymentIntent) {
5030
5106
  window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
5031
5107
  }
package/build/index.css CHANGED
@@ -695,6 +695,9 @@
695
695
  background-color: color-mix(in oklab, var(--s-warning) 10%, transparent);
696
696
  }
697
697
  }
698
+ .sl-spreepay .bg-\(--s-warning-subtle\) {
699
+ background-color: var(--s-warning-subtle);
700
+ }
698
701
  .sl-spreepay .bg-\(--secondary\) {
699
702
  background-color: var(--secondary);
700
703
  }
@@ -1408,14 +1411,9 @@
1408
1411
  translate: var(--tw-translate-x) var(--tw-translate-y);
1409
1412
  }
1410
1413
  }
1411
- .sl-spreepay .data-\[state\=checked\]\:border-\(--primary\) {
1414
+ .sl-spreepay .data-\[state\=checked\]\:border-\(--s-brand\) {
1412
1415
  &[data-state=checked] {
1413
- border-color: var(--primary);
1414
- }
1415
- }
1416
- .sl-spreepay .data-\[state\=checked\]\:bg-\(--primary\) {
1417
- &[data-state=checked] {
1418
- background-color: var(--primary);
1416
+ border-color: var(--s-brand);
1419
1417
  }
1420
1418
  }
1421
1419
  .sl-spreepay .data-\[state\=checked\]\:bg-\(--s-brand\) {
@@ -1592,13 +1590,6 @@
1592
1590
  }
1593
1591
  }
1594
1592
  }
1595
- .sl-spreepay .dark\:data-\[state\=checked\]\:bg-\(--primary\) {
1596
- &:is(.dark *) {
1597
- &[data-state=checked] {
1598
- background-color: var(--primary);
1599
- }
1600
- }
1601
- }
1602
1593
  .sl-spreepay .\[\&_a\]\:underline {
1603
1594
  & a {
1604
1595
  text-decoration-line: underline;
package/build/index.js CHANGED
@@ -8,10 +8,10 @@ import {
8
8
  getSplitAmount,
9
9
  getTransactionFee,
10
10
  useSlapiBalance
11
- } from "./chunk-LXX5P2LL.js";
11
+ } from "./chunk-FKAVWVFL.js";
12
12
  import {
13
13
  Iframe3ds
14
- } from "./chunk-4ELDS4N4.js";
14
+ } from "./chunk-7I6EBCSI.js";
15
15
  import {
16
16
  InfoBanner,
17
17
  LogLevel,
@@ -23,6 +23,7 @@ import {
23
23
  StaticConfigProvider,
24
24
  cn,
25
25
  configureLogger,
26
+ isNewCard,
26
27
  logger,
27
28
  registerApi,
28
29
  useSpreePay,
@@ -31,10 +32,10 @@ import {
31
32
  useSpreePayRegister,
32
33
  useSpreePaymentMethod,
33
34
  useStaticConfig
34
- } from "./chunk-I35SE3K2.js";
35
+ } from "./chunk-AGTOSFMT.js";
35
36
 
36
37
  // src/SpreePay.tsx
37
- import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo7, useState as useState11 } from "react";
38
+ import { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo9, useState as useState11 } from "react";
38
39
  import NiceModal4 from "@ebay/nice-modal-react";
39
40
  import { SWRConfig } from "swr";
40
41
 
@@ -42,7 +43,7 @@ import { SWRConfig } from "swr";
42
43
  import { Suspense, lazy } from "react";
43
44
 
44
45
  // src/components/CreditCardTab/CreditCardTab.tsx
45
- import { useCallback as useCallback5, useEffect as useEffect6 } from "react";
46
+ import { useCallback as useCallback6, useEffect as useEffect6 } from "react";
46
47
 
47
48
  // src/hooks/payments/useCardPayment.ts
48
49
  import NiceModal from "@ebay/nice-modal-react";
@@ -540,25 +541,27 @@ var useSplitCardPayments = (mode = "web2") => {
540
541
  };
541
542
 
542
543
  // src/hooks/useCards.ts
544
+ import { useMemo } from "react";
543
545
  import useSWR from "swr";
544
546
  var URL = "/v1/payments/cards";
545
547
  var useCards = () => {
546
548
  const { origin } = useSpreePayEnv();
547
549
  const { data, isLoading, mutate } = useSWR(origin ? `${URL}?origin=${origin}` : URL);
550
+ const cards = useMemo(() => data?.data.filter((c) => c.active) ?? [], [data]);
548
551
  return {
549
- cards: data?.data.filter((c) => c.active) || [],
552
+ cards,
550
553
  cardsIsLoading: isLoading,
551
554
  mutateCards: mutate
552
555
  };
553
556
  };
554
557
 
555
558
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
556
- import { useMemo, useState as useState3 } from "react";
559
+ import { useCallback as useCallback2, useMemo as useMemo3, useState as useState3 } from "react";
557
560
  import { Elements } from "@stripe/react-stripe-js";
558
561
  import { loadStripe } from "@stripe/stripe-js";
559
562
 
560
563
  // src/components/CreditCardTab/CreditCard/CardsList.tsx
561
- import { useState } from "react";
564
+ import { useMemo as useMemo2, useState } from "react";
562
565
  import { jsx, jsxs } from "react/jsx-runtime";
563
566
  var CardListItem = ({ card, isSelected, onSelect, onRemove }) => {
564
567
  const [isRemoving, setIsRemoving] = useState(false);
@@ -624,19 +627,22 @@ var CardListItem = ({ card, isSelected, onSelect, onRemove }) => {
624
627
  }
625
628
  );
626
629
  };
627
- var CardsList = ({ selectedCard, setCard }) => {
630
+ var CardsList = ({ selectedCard, setCard, newCards, onRemoveNewCard }) => {
628
631
  const { cards, cardsIsLoading, mutateCards } = useCards();
632
+ const allCards = useMemo2(() => [...cards, ...newCards], [cards, newCards]);
629
633
  const handleRemove = async (card) => {
630
- if ("cardId" in card) {
634
+ if (isNewCard(card)) {
635
+ onRemoveNewCard(card);
636
+ } else {
631
637
  await SlapiPaymentService.removeCard({ cardId: card.id });
638
+ mutateCards((data) => ({ ...data, data: (data?.data ?? []).filter((c) => c.id !== card.id) }));
632
639
  }
633
- mutateCards((data) => ({ ...data, data: (data?.data ?? []).filter((c) => c.id !== card.id) }));
634
640
  };
635
641
  if (cardsIsLoading) {
636
642
  return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col", children: /* @__PURE__ */ jsx("div", { className: "h-11 animate-pulse rounded-sm bg-(--s-primary)" }) });
637
643
  }
638
- if (cards.length === 0) return null;
639
- return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-4", children: cards.map((card) => /* @__PURE__ */ jsx(
644
+ if (allCards.length === 0) return null;
645
+ return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-4", children: allCards.map((card) => /* @__PURE__ */ jsx(
640
646
  CardListItem,
641
647
  {
642
648
  isSelected: selectedCard?.id === card.id,
@@ -649,7 +655,7 @@ var CardsList = ({ selectedCard, setCard }) => {
649
655
  };
650
656
 
651
657
  // src/components/CreditCardTab/CreditCard/CreditCardForm.tsx
652
- import { useCallback, useEffect, useId, useRef, useState as useState2 } from "react";
658
+ import { useCallback, useEffect, useRef, useState as useState2 } from "react";
653
659
  import { CardCvcElement, CardExpiryElement, CardNumberElement, useElements, useStripe } from "@stripe/react-stripe-js";
654
660
 
655
661
  // src/ui/button.tsx
@@ -703,7 +709,7 @@ function Checkbox({ className, ...props }) {
703
709
  {
704
710
  "data-slot": "checkbox",
705
711
  className: cn(
706
- "peer border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-sm border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-(--primary) data-[state=checked]:bg-(--primary) data-[state=checked]:text-(--inverse) dark:data-[state=checked]:bg-(--primary)",
712
+ "peer border-input dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-sm border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-(--s-brand) data-[state=checked]:bg-(--s-brand) data-[state=checked]:text-(--inverse)",
707
713
  className
708
714
  ),
709
715
  ...props,
@@ -734,7 +740,7 @@ var CreditCardForm = ({ cancel, saveCard }) => {
734
740
  const formRef = useRef(null);
735
741
  const elements = useElements();
736
742
  const stripe = useStripe();
737
- const id = useId();
743
+ const [id] = useState2(() => crypto.randomUUID());
738
744
  const computeStripeStyles = useCallback(() => {
739
745
  const formRefCurrent = formRef.current;
740
746
  if (typeof window === "undefined" || !formRefCurrent) return {};
@@ -859,13 +865,13 @@ var CreditCardForm = ({ cancel, saveCard }) => {
859
865
  // src/components/CreditCardTab/CreditCard/CreditCard.tsx
860
866
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
861
867
  var StripeWrapper = ({ onCancel, saveNewCard, publicKey }) => {
862
- const stripePromise = useMemo(() => loadStripe(publicKey), [publicKey]);
868
+ const stripePromise = useMemo3(() => loadStripe(publicKey), [publicKey]);
863
869
  return /* @__PURE__ */ jsx5(Elements, { stripe: stripePromise, children: /* @__PURE__ */ jsx5(CreditCardForm, { cancel: onCancel, saveCard: saveNewCard }) });
864
870
  };
865
871
  var CreditCard = () => {
866
872
  const [showForm, setShowForm] = useState3(false);
873
+ const [newCards, setNewCards] = useState3([]);
867
874
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
868
- const { mutateCards } = useCards();
869
875
  const { spreePayConfig } = useSpreePayConfig();
870
876
  const setCard = (card) => {
871
877
  const isAlreadySelected = selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ && selectedPaymentMethod.method?.id === card.id;
@@ -876,10 +882,13 @@ var CreditCard = () => {
876
882
  });
877
883
  };
878
884
  const saveNewCard = (newCard) => {
879
- mutateCards((data) => ({ ...data, data: [...data?.data ?? [], newCard] }), { revalidate: false });
885
+ setNewCards((prev) => [...prev, newCard]);
880
886
  setCard(newCard);
881
887
  setShowForm(false);
882
888
  };
889
+ const removeNewCard = useCallback2((card) => {
890
+ setNewCards((prev) => prev.filter((c) => c.id !== card.id));
891
+ }, []);
883
892
  const handleCancel = () => {
884
893
  setShowForm(false);
885
894
  };
@@ -890,7 +899,9 @@ var CreditCard = () => {
890
899
  CardsList,
891
900
  {
892
901
  selectedCard: selectedPaymentMethod?.type === "CREDIT_CARD" /* CREDIT_CARD */ ? selectedPaymentMethod.method : null,
893
- setCard
902
+ setCard,
903
+ newCards,
904
+ onRemoveNewCard: removeNewCard
894
905
  }
895
906
  ),
896
907
  spreePayConfig?.creditCard.infoMessage && /* @__PURE__ */ jsx5(InfoBanner, { message: spreePayConfig.creditCard.infoMessage }),
@@ -912,7 +923,7 @@ var CreditCard = () => {
912
923
  import { useState as useState9 } from "react";
913
924
 
914
925
  // src/components/CreditCardTab/Points/SplitBlock.tsx
915
- import { useCallback as useCallback4, useEffect as useEffect5, useRef as useRef6, useState as useState8 } from "react";
926
+ import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef6, useState as useState8 } from "react";
916
927
  import { BUILD_ENV as BUILD_ENV2 } from "@mocanetwork/airkit";
917
928
 
918
929
  // src/components/CreditCardTab/Points/PointsSelector.tsx
@@ -2014,7 +2025,7 @@ var SplitBlock = (props) => {
2014
2025
  const hasForeignCurrency = !!(currencyCode && exchangeRate && foreignCurrencyAmount);
2015
2026
  const formatPointsValue = (usd) => hasForeignCurrency ? formatCurrency(usd / exchangeRate, currencyCode) : formatCurrency(usd);
2016
2027
  const prevPointsChainRef = useRef6(spreePayConfig?.pointsChain);
2017
- const initWallet = useCallback4(
2028
+ const initWallet = useCallback5(
2018
2029
  async (pointsChain) => {
2019
2030
  if (!pointsChain) return;
2020
2031
  try {
@@ -2114,7 +2125,7 @@ var CreditCardTab = ({ isLoggedIn }) => {
2114
2125
  const { cardPayment } = useCardPayment();
2115
2126
  const { splitPayment } = useSplitCardPayments(isWeb3Enabled ? "web3" : "web2");
2116
2127
  const { pointsPayment } = usePointsPayment(isWeb3Enabled ? "web3" : "web2");
2117
- const handlePay = useCallback5(
2128
+ const handlePay = useCallback6(
2118
2129
  async (data) => {
2119
2130
  try {
2120
2131
  let res = null;
@@ -2235,9 +2246,9 @@ var TabButtons = (props) => {
2235
2246
 
2236
2247
  // src/SpreePayContent.tsx
2237
2248
  import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
2238
- var CryptoTab = lazy(() => import("./CryptoTab-RY2NTNZJ.js").then((module) => ({ default: module.CryptoTab })));
2249
+ var CryptoTab = lazy(() => import("./CryptoTab-7EG23TQW.js").then((module) => ({ default: module.CryptoTab })));
2239
2250
  var CryptoComTab = lazy(
2240
- () => import("./CryptoComTab-GNJ4XACU.js").then((module) => ({ default: module.CryptoComTab }))
2251
+ () => import("./CryptoComTab-5662XFNI.js").then((module) => ({ default: module.CryptoComTab }))
2241
2252
  );
2242
2253
  var TabLoadingFallback = () => /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center px-5 py-8 md:px-7", children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center gap-3", children: [
2243
2254
  /* @__PURE__ */ jsx18("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-(--border-component-specific-card) border-t-(--brand-primary)" }),
@@ -2279,8 +2290,8 @@ var ErrorBoundary = class extends Component {
2279
2290
  if (this.props.fallback) {
2280
2291
  return this.props.fallback;
2281
2292
  }
2282
- return /* @__PURE__ */ jsxs12("div", { className: "flex w-full flex-col items-center justify-center rounded-3xl border border-(--b-inverse) bg-(--s-primary) p-8", children: [
2283
- /* @__PURE__ */ jsx19("div", { className: "mb-4 flex size-12 items-center justify-center rounded-full bg-(--s-secondary)", children: /* @__PURE__ */ jsxs12(
2293
+ return /* @__PURE__ */ jsx19("div", { className: cn("sl-spreepay", this.props.className), children: /* @__PURE__ */ jsxs12("div", { className: "flex w-full flex-col items-center justify-center rounded-3xl border border-(--border-component-specific-card) bg-(--surface-component-specific-card-default-card) p-8 shadow-[0_6.25px_25px_0_var(--shadow-component-specific-card)]", children: [
2294
+ /* @__PURE__ */ jsx19("div", { className: "mb-4 flex size-12 items-center justify-center rounded-full bg-(--s-warning-subtle)", children: /* @__PURE__ */ jsxs12(
2284
2295
  "svg",
2285
2296
  {
2286
2297
  xmlns: "http://www.w3.org/2000/svg",
@@ -2298,16 +2309,16 @@ var ErrorBoundary = class extends Component {
2298
2309
  ]
2299
2310
  }
2300
2311
  ) }),
2301
- /* @__PURE__ */ jsx19("h3", { className: "mb-2 text-lg font-semibold text-(--primary)", children: "Payment Widget Error" }),
2302
- /* @__PURE__ */ jsx19("p", { className: "text-center text-sm text-(--secondary)", children: "Something went wrong loading the payment widget. Please refresh the page and try again." })
2303
- ] });
2312
+ /* @__PURE__ */ jsx19("h3", { className: "mb-2 text-lg font-semibold text-(--brand-primary)", children: "Payment Widget Error" }),
2313
+ /* @__PURE__ */ jsx19("p", { className: "text-center text-sm text-(--text-tertiary)", children: "Something went wrong loading the payment widget. Please refresh the page and try again." })
2314
+ ] }) });
2304
2315
  }
2305
2316
  return this.props.children;
2306
2317
  }
2307
2318
  };
2308
2319
 
2309
2320
  // src/hooks/useKeycloakSSO.ts
2310
- import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState10 } from "react";
2321
+ import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef7, useState as useState10 } from "react";
2311
2322
  import Keycloak from "keycloak-js";
2312
2323
  var refreshAheadSeconds = 60;
2313
2324
  var keycloakLogger = logger.child("keycloak");
@@ -2321,7 +2332,7 @@ function useKeycloakSSO(config) {
2321
2332
  const [error, setError] = useState10(null);
2322
2333
  const [isChecking, setIsChecking] = useState10(enabled);
2323
2334
  const [accessToken, setAccessToken] = useState10(null);
2324
- const scheduleRefresh = useCallback6(() => {
2335
+ const scheduleRefresh = useCallback7(() => {
2325
2336
  const kc = kcRef.current;
2326
2337
  if (!kc || !kc.tokenParsed || !kc.tokenParsed.exp) {
2327
2338
  return;
@@ -2381,11 +2392,22 @@ function useKeycloakSSO(config) {
2381
2392
  return { isChecking, accessToken, error };
2382
2393
  }
2383
2394
 
2395
+ // src/utils/token.ts
2396
+ import { jwtDecode } from "jwt-decode";
2397
+ var isTokenExpired = (token) => {
2398
+ try {
2399
+ const { exp } = jwtDecode(token);
2400
+ return typeof exp === "number" && exp < Math.floor(Date.now() / 1e3);
2401
+ } catch {
2402
+ return true;
2403
+ }
2404
+ };
2405
+
2384
2406
  // src/SpreePay.tsx
2385
2407
  import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
2386
2408
  var SpreePayInner = () => {
2387
2409
  const [portalEl, setPortalEl] = useState11(null);
2388
- const rootRef = useCallback7((node) => {
2410
+ const rootRef = useCallback8((node) => {
2389
2411
  if (!node) return;
2390
2412
  const el = node.querySelector(":scope > .sl-spreepay__portal");
2391
2413
  setPortalEl(el ?? null);
@@ -2396,16 +2418,17 @@ var SpreePayInner = () => {
2396
2418
  logger.logVersion();
2397
2419
  }, [environment]);
2398
2420
  const { staticConfig, appProps } = useStaticConfig();
2421
+ const envTokenValid = Boolean(envAccessToken && !isTokenExpired(envAccessToken));
2399
2422
  const { isChecking, accessToken } = useKeycloakSSO({
2400
2423
  realm: tenantId,
2401
2424
  url: staticConfig.keycloakUrl,
2402
2425
  clientId: keycloakClientId ?? "oneof-next",
2403
2426
  ssoPageURI,
2404
- enabled: !envAccessToken
2427
+ enabled: !envTokenValid
2405
2428
  });
2406
- const _accessToken = envAccessToken ?? accessToken;
2407
- const unauthenticatedFetcher = useCallback7(() => Promise.resolve(null), []);
2408
- const slapiFetcher = useMemo7(() => {
2429
+ const _accessToken = envTokenValid ? envAccessToken : accessToken;
2430
+ const unauthenticatedFetcher = useCallback8(() => Promise.resolve(null), []);
2431
+ const slapiFetcher = useMemo9(() => {
2409
2432
  if (_accessToken) {
2410
2433
  return registerApi({
2411
2434
  accessToken: _accessToken,
@@ -2441,7 +2464,7 @@ var SpreePayInner = () => {
2441
2464
  ] });
2442
2465
  };
2443
2466
  var SpreePay = (props) => {
2444
- return /* @__PURE__ */ jsx20(ErrorBoundary, { children: /* @__PURE__ */ jsx20(StaticConfigProvider, { props, children: /* @__PURE__ */ jsx20(SpreePayInner, {}) }) });
2467
+ return /* @__PURE__ */ jsx20(ErrorBoundary, { className: props.className, children: /* @__PURE__ */ jsx20(StaticConfigProvider, { props, children: /* @__PURE__ */ jsx20(SpreePayInner, {}) }) });
2445
2468
  };
2446
2469
 
2447
2470
  // src/hooks/useCapture3DS.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superlogic/spree-pay",
3
- "version": "0.4.2",
3
+ "version": "0.4.6",
4
4
  "description": "Spree-pay React component and utilities",
5
5
  "private": false,
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "require": "./build/index.cjs",
19
19
  "default": "./build/index.js"
20
20
  },
21
- "./styles.css": "./build/index.css"
21
+ "./styles.css": "./build/index.css",
22
+ "./bridge.css": "./src/styles/bridge.css"
22
23
  },
23
24
  "files": [
24
25
  "build",
@@ -52,6 +53,7 @@
52
53
  "@tanstack/react-query": "^5.97.0",
53
54
  "class-variance-authority": "^0.7.0",
54
55
  "clsx": "^2.1.1",
56
+ "jwt-decode": "^4.0.0",
55
57
  "keycloak-js": "^26.2.3",
56
58
  "lucide-react": "^1.8.0",
57
59
  "swr": "^2.4.1",
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Spree-pay CSS variable bridge — live-tickets context only.
3
+ *
4
+ * Exposes legacy short-name CSS variables that spree-pay TSX components
5
+ * still reference, mapped to the current Figma token names. This file is
6
+ * imported by apps/live-tickets/src/theme/globals.css so the host app's
7
+ * tenant *.figma.css tokens are available under the old names.
8
+ *
9
+ * NOT used in standalone mode — the standalone build gets default values
10
+ * from packages/spree-pay/src/styles/globals.css instead.
11
+ */
12
+ :root {
13
+ /* text / icons */
14
+ --primary: var(--color-text-icons-primary-default);
15
+ --secondary: var(--color-text-icons-secondary-default);
16
+ --tertiary: var(--color-text-icons-tertiary-default);
17
+ --text-tertiary: var(--color-text-icons-tertiary-default); /* pre-existing alias bug */
18
+ --brand-primary: var(--color-text-icons-brand-default);
19
+ --accent: var(--color-text-icons-accent-default);
20
+ --inverse: var(--color-text-icons-inverse-default);
21
+ --disabled: var(--color-text-icons-primary-disabled);
22
+ --positive: var(--color-feedback-success);
23
+ --warning: var(--color-feedback-attention);
24
+ --negative: var(--color-feedback-error);
25
+
26
+ /* surface */
27
+ --s-default: var(--color-surface-layer-page);
28
+ --s-primary: var(--color-surface-container-subtle);
29
+ --s-primary-hover: var(--color-component-list-row-subtle-hover);
30
+ --s-secondary: var(--color-component-table-header);
31
+ --s-tertiary: var(--color-control-tertiary-bg-default);
32
+ --s-brand: var(--color-surface-container-brand);
33
+ --s-brand-hover: var(--color-control-primary-bg-hover);
34
+ --s-disabled: var(--color-component-bg-disabled);
35
+ --s-warning: var(--color-feedback-attention);
36
+
37
+ /* border */
38
+ --b-primary: var(--color-border-subtle);
39
+ --b-secondary: var(--color-border-default);
40
+ --b-tertiary: var(--color-component-divider-default);
41
+ --b-brand: var(--color-control-primary-border-default);
42
+ --b-inverse: var(--color-border-inverse);
43
+
44
+ /* overlay / component-specific */
45
+ --overlay: var(--color-surface-layer-backdrop);
46
+ --border-component-specific-card: var(--color-component-divider-subtle);
47
+ --surface-component-specific-card-default-card: var(--color-surface-layer-card);
48
+ --shadow-component-specific-card: var(--color-effect-shadow-card);
49
+
50
+ /* Crypto.com brand colors — same across all tenants */
51
+ --crypto-pay-bg: #00307d;
52
+ --crypto-pay-bg-hover: #002655;
53
+ }