@superlogic/spree-pay 0.4.14 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -8,39 +8,49 @@ import {
8
8
  getSplitAmount,
9
9
  getTransactionFee,
10
10
  useSlapiBalance
11
- } from "./chunk-UT65MGD2.js";
11
+ } from "./chunk-VBGTP4XP.js";
12
12
  import {
13
13
  Iframe3ds
14
- } from "./chunk-VZWGJKM3.js";
14
+ } from "./chunk-ABVIUWRK.js";
15
15
  import {
16
16
  InfoBanner,
17
17
  LogLevel,
18
+ LoginStatusProvider,
18
19
  PaymentError,
20
+ PaymentErrorCode,
21
+ PaymentStatus,
19
22
  PaymentType,
20
23
  PortalContainerProvider,
21
24
  SlapiPaymentService,
25
+ SpreePayHttpError,
22
26
  SpreePayProvider,
23
27
  StaticConfigProvider,
24
28
  cn,
25
29
  configureLogger,
30
+ isDeclineStatus,
26
31
  isNewCard,
32
+ isPaymentError,
33
+ isSuccessStatus,
27
34
  logger,
28
35
  registerApi,
36
+ settlePaymentResult,
37
+ toPaymentError,
38
+ useIsLoggedIn,
29
39
  useSpreePay,
30
40
  useSpreePayConfig,
31
41
  useSpreePayEnv,
32
42
  useSpreePayRegister,
33
43
  useSpreePaymentMethod,
34
44
  useStaticConfig
35
- } from "./chunk-XFJYLJZ4.js";
45
+ } from "./chunk-ECIGRDXS.js";
36
46
 
37
47
  // src/SpreePay.tsx
38
- import { useCallback as useCallback8, useEffect as useEffect7, useMemo as useMemo9, useState as useState12 } from "react";
48
+ import { useCallback as useCallback8, useEffect as useEffect8, useMemo as useMemo9, useState as useState12 } from "react";
39
49
  import NiceModal4 from "@ebay/nice-modal-react";
40
50
  import { SWRConfig } from "swr";
41
51
 
42
52
  // src/SpreePayContent.tsx
43
- import { Suspense, lazy } from "react";
53
+ import { Suspense, lazy, useEffect as useEffect6 } from "react";
44
54
 
45
55
  // src/components/CreditCardTab/CreditCardTab.tsx
46
56
  import { useCallback as useCallback6, useEffect as useEffect5, useState as useState10 } from "react";
@@ -61,12 +71,8 @@ var useCardPayment = () => {
61
71
  });
62
72
  throw error;
63
73
  }
64
- const { hash, capture, metadata } = params;
65
- cardPaymentLogger.info("Starting card payment", {
66
- hash,
67
- capture,
68
- hasMetadata: Boolean(metadata)
69
- });
74
+ const { hash, capture } = params;
75
+ cardPaymentLogger.info("Starting card payment", { hash, capture });
70
76
  const card = selectedPaymentMethod.method;
71
77
  let cardId;
72
78
  if ("token" in card) {
@@ -97,7 +103,6 @@ var useCardPayment = () => {
97
103
  const { data: paymentResData } = await SlapiPaymentService.createPayment({
98
104
  hash,
99
105
  capture,
100
- metadata,
101
106
  type: "CREDIT_CARD" /* CREDIT_CARD */,
102
107
  card: {
103
108
  cardId,
@@ -260,10 +265,13 @@ async function longPollPoints(paymentId) {
260
265
  let retries = 0;
261
266
  while (retries < MAX_RETRIES) {
262
267
  const { detail } = await SlapiPaymentService.getStatus(paymentId);
263
- if (detail.status === "FAILED" /* FAILED */) {
264
- throw new Error("Something went wrong with the payment");
268
+ if (isDeclineStatus(detail.status)) {
269
+ throw new PaymentError("Something went wrong with the points payment.", detail.status, {
270
+ code: "PAYMENT_ERROR" /* PAYMENT_ERROR */,
271
+ backendCode: detail.errorCode ?? void 0
272
+ });
265
273
  }
266
- if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(detail.status)) {
274
+ if (isSuccessStatus(detail.status)) {
267
275
  return detail.status;
268
276
  }
269
277
  await new Promise((res) => setTimeout(res, REFRESH_INTERVAL));
@@ -276,13 +284,21 @@ async function longPollCardStatus(paymentId) {
276
284
  let shown3ds = false;
277
285
  while (retries < MAX_RETRIES) {
278
286
  const { detail } = await SlapiPaymentService.getStatus(paymentId);
279
- if (detail.status === "FAILED" /* FAILED */) {
280
- throw new Error(`Something went wrong with the ${detail.validationType} payment`);
287
+ if (isDeclineStatus(detail.status)) {
288
+ const isPointsLeg = detail.validationType === "POINTS";
289
+ throw new PaymentError(
290
+ isPointsLeg ? "Something went wrong with the points payment." : "Your card payment could not be completed.",
291
+ detail.status,
292
+ {
293
+ code: isPointsLeg ? "PAYMENT_ERROR" /* PAYMENT_ERROR */ : "CARD_ERROR" /* CARD_ERROR */,
294
+ backendCode: detail.errorCode ?? void 0
295
+ }
296
+ );
281
297
  }
282
298
  if (
283
299
  // Process to points payment
284
300
  detail.validationType === "POINTS" || // early card payment completion
285
- ["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(detail.status)
301
+ isSuccessStatus(detail.status)
286
302
  ) {
287
303
  return detail.status;
288
304
  }
@@ -312,7 +328,7 @@ var usePointsPayment = (mode = "web2") => {
312
328
  });
313
329
  throw error;
314
330
  }
315
- const { hash, capture, metadata } = params;
331
+ const { hash, capture } = params;
316
332
  pointsPaymentLogger.info("Starting points payment", {
317
333
  hash,
318
334
  capture,
@@ -327,7 +343,6 @@ var usePointsPayment = (mode = "web2") => {
327
343
  hash,
328
344
  // capture should be always true for web2 points payments
329
345
  capture: mode === "web2" ? true : capture,
330
- metadata,
331
346
  type: "POINTS" /* POINTS */
332
347
  });
333
348
  pointsPaymentLogger.info("Points payment created", {
@@ -420,7 +435,7 @@ var useSplitCardPayments = (mode = "web2") => {
420
435
  if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method || !params.points) {
421
436
  throw new Error("Unsupported payment method");
422
437
  }
423
- const { hash, capture, metadata, points } = params;
438
+ const { hash, capture, points } = params;
424
439
  splitPaymentLogger.info("Starting split card+points payment", { hash, mode, points, capture });
425
440
  const card = selectedPaymentMethod.method;
426
441
  let cardId;
@@ -448,7 +463,6 @@ var useSplitCardPayments = (mode = "web2") => {
448
463
  const { data: paymentResData } = await SlapiPaymentService.createPayment({
449
464
  hash,
450
465
  capture,
451
- metadata,
452
466
  type: "SPLIT" /* CREDIT_CARD_SPLIT */,
453
467
  card: {
454
468
  cardId,
@@ -663,15 +677,15 @@ import { Slot } from "@radix-ui/react-slot";
663
677
  import { cva } from "class-variance-authority";
664
678
  import { jsx as jsx2 } from "react/jsx-runtime";
665
679
  var buttonVariants = cva(
666
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
680
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-(--b-tertiary) focus-visible:ring-(--b-tertiary)/50 focus-visible:ring-[3px] aria-invalid:ring-(--negative)/20 dark:aria-invalid:ring-(--negative)/40 aria-invalid:border-(--negative)",
667
681
  {
668
682
  variants: {
669
683
  variant: {
670
684
  default: "bg-(--primary) text-(--inverse) shadow-xs hover:bg-(--primary)/90 ",
671
- destructive: "bg-destructive text-(--inverse) shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
672
- outline: "border bg-background shadow-xs hover:bg-(--accent) hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
673
- secondary: "bg-(--secondary) text-secondary-foreground shadow-xs hover:bg-(--secondary)/80",
674
- ghost: "hover:bg-(--accent) hover:text-accent-foreground dark:hover:bg-(--accent)/50",
685
+ destructive: "bg-(--negative) text-(--inverse) shadow-xs hover:bg-(--negative)/90 focus-visible:ring-(--negative)/20 dark:focus-visible:ring-(--negative)/40 dark:bg-(--negative)/60",
686
+ outline: "border bg-(--s-default) shadow-xs hover:bg-(--accent) hover:text-(--brand-primary) dark:bg-(--s-primary)/30 dark:border-(--b-tertiary) dark:hover:bg-(--s-primary)/50",
687
+ secondary: "bg-(--secondary) text-(--inverse) shadow-xs hover:bg-(--secondary)/80",
688
+ ghost: "hover:bg-(--accent) hover:text-(--brand-primary) dark:hover:bg-(--accent)/50",
675
689
  link: "text-(--brand-primary) underline-offset-4 hover:underline"
676
690
  },
677
691
  size: {
@@ -709,7 +723,7 @@ function Checkbox({ className, ...props }) {
709
723
  {
710
724
  "data-slot": "checkbox",
711
725
  className: cn(
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)",
726
+ "peer size-4 shrink-0 rounded-sm border border-(--b-tertiary) shadow-xs transition-shadow outline-none focus-visible:border-(--b-tertiary) focus-visible:ring-[3px] focus-visible:ring-(--b-tertiary)/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-(--negative) aria-invalid:ring-(--negative)/20 data-[state=checked]:border-(--s-brand) data-[state=checked]:bg-(--s-brand) data-[state=checked]:text-(--inverse) dark:bg-(--s-primary)/30 dark:aria-invalid:ring-(--negative)/40",
713
727
  className
714
728
  ),
715
729
  ...props,
@@ -729,9 +743,9 @@ function Checkbox({ className, ...props }) {
729
743
  import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
730
744
  var cardFormLogger = logger.child("card-form");
731
745
  var stripeElementClasses = {
732
- base: "w-full rounded-[12px] bg-(--s-primary) px-5 py-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",
733
- invalid: "focus-visible:ring-destructive",
734
- focus: "border-ring ring-ring/50 ring-2"
746
+ base: "w-full rounded-[12px] bg-(--s-primary) px-5 py-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-(--b-tertiary) focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",
747
+ invalid: "focus-visible:ring-(--negative)",
748
+ focus: "border-(--b-tertiary) ring-(--b-tertiary)/50 ring-2"
735
749
  };
736
750
  var CreditCardForm = ({ cancel, saveCard }) => {
737
751
  const [cardError, setCardError] = useState2(void 0);
@@ -833,7 +847,7 @@ var CreditCardForm = ({ cancel, saveCard }) => {
833
847
  }
834
848
  )
835
849
  ] }),
836
- cardError && /* @__PURE__ */ jsx4("p", { className: "text-destructive mt-1 text-sm", children: cardError })
850
+ cardError && /* @__PURE__ */ jsx4("p", { className: "mt-1 text-sm text-(--negative)", children: cardError })
837
851
  ] }),
838
852
  /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
839
853
  /* @__PURE__ */ jsx4(Checkbox, { checked: shouldSaveCard, onCheckedChange: (v) => setShouldSaveCard(v === true), id: "saveCard" }),
@@ -871,6 +885,7 @@ var StripeWrapper = ({ onCancel, saveNewCard, publicKey }) => {
871
885
  };
872
886
  var CreditCard = ({ newCards, setNewCards }) => {
873
887
  const [showForm, setShowForm] = useState3(false);
888
+ const isLoggedIn = useIsLoggedIn();
874
889
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
875
890
  const { spreePayConfig } = useSpreePayConfig();
876
891
  const setCard = (card) => {
@@ -920,13 +935,13 @@ var CreditCard = ({ newCards, setNewCards }) => {
920
935
  "button",
921
936
  {
922
937
  onClick: handleAddNewCard,
923
- disabled: !spreePayConfig?.stripePublicKey,
938
+ disabled: !isLoggedIn || !spreePayConfig?.stripePublicKey,
924
939
  className: "text-md text-(--brand-primary) hover:underline disabled:cursor-not-allowed disabled:no-underline disabled:opacity-50",
925
940
  children: "Add new card"
926
941
  }
927
942
  )
928
943
  ] }),
929
- spreePayConfig?.stripePublicKey && showForm && /* @__PURE__ */ jsx5(StripeWrapper, { onCancel: handleCancel, saveNewCard, publicKey: spreePayConfig.stripePublicKey })
944
+ isLoggedIn && spreePayConfig?.stripePublicKey && showForm && /* @__PURE__ */ jsx5(StripeWrapper, { onCancel: handleCancel, saveNewCard, publicKey: spreePayConfig.stripePublicKey })
930
945
  ] });
931
946
  };
932
947
 
@@ -949,9 +964,9 @@ function Input({ className, type, ...props }) {
949
964
  type,
950
965
  "data-slot": "input",
951
966
  className: cn(
952
- "file:text-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-(--brand-primary) shadow-xs transition-[color,box-shadow] outline-none selection:bg-(--primary) selection:text-(--inverse) 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",
953
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
954
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
967
+ "flex h-9 w-full min-w-0 rounded-md border border-(--b-tertiary) bg-transparent px-3 py-1 text-base text-(--brand-primary) shadow-xs transition-[color,box-shadow] outline-none selection:bg-(--primary) selection:text-(--inverse) file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-(--primary) placeholder:text-(--tertiary) disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-(--s-primary)/30",
968
+ "focus-visible:border-(--b-tertiary) focus-visible:ring-[3px] focus-visible:ring-(--b-tertiary)/50",
969
+ "aria-invalid:border-(--negative) aria-invalid:ring-(--negative)/20 dark:aria-invalid:ring-(--negative)/40",
955
970
  className
956
971
  ),
957
972
  ...props
@@ -1907,7 +1922,7 @@ function Slider2(props) {
1907
1922
  Thumb,
1908
1923
  {
1909
1924
  "data-slot": "slider-thumb",
1910
- className: "ring-ring/50 block size-5 shrink-0 rounded-full border border-(--b-inverse) bg-(--primary) shadow-(--primary)/20 shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
1925
+ className: "block size-5 shrink-0 rounded-full border border-(--b-inverse) bg-(--primary) shadow-(--primary)/20 shadow-sm ring-(--b-tertiary)/50 transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
1911
1926
  },
1912
1927
  index
1913
1928
  ))
@@ -2089,6 +2104,7 @@ var SplitBlock = (props) => {
2089
2104
  // src/components/CreditCardTab/Points/Points.tsx
2090
2105
  import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
2091
2106
  var Points = () => {
2107
+ const isLoggedIn = useIsLoggedIn();
2092
2108
  const [usePoints, setUsePoints] = useState9(false);
2093
2109
  const [selectedPointsType, setSelectedPointsType] = useState9(null);
2094
2110
  const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
@@ -2108,7 +2124,7 @@ var Points = () => {
2108
2124
  value: usePoints,
2109
2125
  onChange: handleTogglePoints,
2110
2126
  message: spreePayConfig?.creditCard.pointsInfoMessage,
2111
- disabled: !spreePayConfig?.creditCard.enabled || !spreePayConfig?.creditCard.points || appProps.disabledPoints
2127
+ disabled: !isLoggedIn || !spreePayConfig?.creditCard.enabled || !spreePayConfig?.creditCard.points || appProps.disabledPoints
2112
2128
  }
2113
2129
  ),
2114
2130
  usePoints && /* @__PURE__ */ jsx15(
@@ -2124,7 +2140,7 @@ var Points = () => {
2124
2140
 
2125
2141
  // src/components/CreditCardTab/CreditCardTab.tsx
2126
2142
  import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
2127
- var CreditCardTab = ({ isLoggedIn }) => {
2143
+ var CreditCardTab = () => {
2128
2144
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
2129
2145
  const { useWeb3Points } = useSpreePayEnv();
2130
2146
  const { appProps } = useStaticConfig();
@@ -2139,23 +2155,23 @@ var CreditCardTab = ({ isLoggedIn }) => {
2139
2155
  const { pointsPayment } = usePointsPayment(isWeb3Enabled ? "web3" : "web2");
2140
2156
  const handlePay = useCallback6(
2141
2157
  async (data) => {
2158
+ const pointsAmount = selectedPaymentMethod.pointsAmount ?? 0;
2159
+ const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, spreePayConfig?.pointsConversionRatio);
2160
+ const isPurePoints = !usdAmount && pointsAmount > 0;
2161
+ const failureMessage = isPurePoints ? "Points payment failed" : "Card payment failed";
2162
+ const failureCode = isPurePoints ? "PAYMENT_ERROR" /* PAYMENT_ERROR */ : "CARD_ERROR" /* CARD_ERROR */;
2142
2163
  try {
2143
- let res = null;
2144
- const pointsAmount = selectedPaymentMethod.pointsAmount ?? 0;
2145
- const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, spreePayConfig?.pointsConversionRatio);
2164
+ let res;
2146
2165
  if (usdAmount && pointsAmount) {
2147
2166
  res = await splitPayment({ ...data, points: pointsAmount });
2148
- } else if (!usdAmount && pointsAmount) {
2167
+ } else if (isPurePoints) {
2149
2168
  res = await pointsPayment({ ...data, points: pointsAmount });
2150
2169
  } else {
2151
2170
  res = await cardPayment(data);
2152
2171
  }
2153
- if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
2154
- return Promise.resolve(res);
2155
- }
2156
- return Promise.reject(new PaymentError("Card payment failed", res.status));
2157
- } catch (_) {
2158
- return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
2172
+ return settlePaymentResult(res, failureMessage, failureCode);
2173
+ } catch (e) {
2174
+ return Promise.reject(toPaymentError(e, failureMessage, failureCode));
2159
2175
  } finally {
2160
2176
  mutateBalance();
2161
2177
  if (selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && selectedPaymentMethod.method && isNewCard(selectedPaymentMethod.method)) {
@@ -2192,7 +2208,7 @@ var CreditCardTab = ({ isLoggedIn }) => {
2192
2208
  return /* @__PURE__ */ jsxs9("div", { children: [
2193
2209
  /* @__PURE__ */ jsx16("div", { className: "border-b border-b-(--border-component-specific-card) px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx16(CreditCard, { newCards, setNewCards }) }),
2194
2210
  !spreePayConfig?.creditCard.hidePoints && /* @__PURE__ */ jsx16("div", { className: "flex flex-col gap-4 border-b border-b-(--border-component-specific-card) px-5 pt-5 pb-5 md:px-7 md:pt-6 md:pb-7", children: /* @__PURE__ */ jsx16(Points, {}) }),
2195
- /* @__PURE__ */ jsx16(CheckoutButton, { isLoggedIn })
2211
+ /* @__PURE__ */ jsx16(CheckoutButton, {})
2196
2212
  ] });
2197
2213
  };
2198
2214
 
@@ -2268,24 +2284,30 @@ var TabButtons = (props) => {
2268
2284
 
2269
2285
  // src/SpreePayContent.tsx
2270
2286
  import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
2271
- var CryptoTab = lazy(() => import("./CryptoTab-4IC63YD5.js").then((module) => ({ default: module.CryptoTab })));
2287
+ var CryptoTab = lazy(() => import("./CryptoTab-XJZHGZ5E.js").then((module) => ({ default: module.CryptoTab })));
2272
2288
  var CryptoComTab = lazy(
2273
- () => import("./CryptoComTab-NMS7BP25.js").then((module) => ({ default: module.CryptoComTab }))
2289
+ () => import("./CryptoComTab-EKWP4XOV.js").then((module) => ({ default: module.CryptoComTab }))
2274
2290
  );
2275
2291
  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: [
2276
2292
  /* @__PURE__ */ jsx18("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-(--border-component-specific-card) border-t-(--brand-primary)" }),
2277
2293
  /* @__PURE__ */ jsx18("p", { className: "text-sm text-(--text-tertiary)", children: "Loading payment method..." })
2278
2294
  ] }) });
2279
- var SpreePayContent = ({ isLoggedIn }) => {
2295
+ var SpreePayContent = () => {
2296
+ const isLoggedIn = useIsLoggedIn();
2280
2297
  const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
2298
+ useEffect6(() => {
2299
+ if (!isLoggedIn) {
2300
+ setSelectedPaymentMethod({ type: "CREDIT_CARD" /* CREDIT_CARD */, method: null });
2301
+ }
2302
+ }, [isLoggedIn, setSelectedPaymentMethod]);
2281
2303
  return /* @__PURE__ */ jsxs11("div", { className: "w-full overflow-hidden rounded-3xl border border-(--border-component-specific-card) bg-(--surface-component-specific-card-default-card) shadow-[0_6.25px_25px_0_var(--shadow-component-specific-card)]", children: [
2282
2304
  /* @__PURE__ */ jsxs11("div", { className: "flex w-full flex-col gap-2 border-b border-b-(--border-component-specific-card) pt-5 pb-3 md:pt-6 md:pb-5", children: [
2283
2305
  /* @__PURE__ */ jsx18("h2", { className: "px-5 text-[28px] leading-8 font-medium text-(--brand-primary) md:px-7", children: "Choose a payment method" }),
2284
2306
  /* @__PURE__ */ jsx18(TabButtons, { value: selectedPaymentMethod.type, onChange: setSelectedPaymentMethod })
2285
2307
  ] }),
2286
- selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ jsx18(CreditCardTab, { isLoggedIn }),
2308
+ selectedPaymentMethod.type === "CREDIT_CARD" /* CREDIT_CARD */ && /* @__PURE__ */ jsx18(CreditCardTab, {}),
2287
2309
  /* @__PURE__ */ jsxs11(Suspense, { fallback: /* @__PURE__ */ jsx18(TabLoadingFallback, {}), children: [
2288
- selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ jsx18(CryptoTab, { isLoggedIn }),
2310
+ selectedPaymentMethod.type === "CRYPTO" /* CRYPTO */ && /* @__PURE__ */ jsx18(CryptoTab, {}),
2289
2311
  selectedPaymentMethod.type === "CDC" /* CDC */ && /* @__PURE__ */ jsx18(CryptoComTab, {})
2290
2312
  ] })
2291
2313
  ] });
@@ -2340,7 +2362,7 @@ var ErrorBoundary = class extends Component {
2340
2362
  };
2341
2363
 
2342
2364
  // src/hooks/useKeycloakSSO.ts
2343
- import { useCallback as useCallback7, useEffect as useEffect6, useRef as useRef6, useState as useState11 } from "react";
2365
+ import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef6, useState as useState11 } from "react";
2344
2366
  import Keycloak from "keycloak-js";
2345
2367
  var refreshAheadSeconds = 60;
2346
2368
  var keycloakLogger = logger.child("keycloak");
@@ -2378,10 +2400,10 @@ function useKeycloakSSO(config) {
2378
2400
  });
2379
2401
  }, delayMs);
2380
2402
  }, []);
2381
- useEffect6(() => {
2403
+ useEffect7(() => {
2382
2404
  scheduleRefreshRef.current = scheduleRefresh;
2383
2405
  }, [scheduleRefresh]);
2384
- useEffect6(() => {
2406
+ useEffect7(() => {
2385
2407
  if (initRef.current || !enabled) return;
2386
2408
  initRef.current = true;
2387
2409
  const kc = new Keycloak({ url, realm, clientId });
@@ -2427,6 +2449,7 @@ var isTokenExpired = (token) => {
2427
2449
 
2428
2450
  // src/SpreePay.tsx
2429
2451
  import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
2452
+ var unauthenticatedFetcher = () => Promise.resolve(null);
2430
2453
  var SpreePayInner = () => {
2431
2454
  const [portalEl, setPortalEl] = useState12(null);
2432
2455
  const rootRef = useCallback8((node) => {
@@ -2435,7 +2458,7 @@ var SpreePayInner = () => {
2435
2458
  setPortalEl(el ?? null);
2436
2459
  }, []);
2437
2460
  const { environment, tenantId, keycloakClientId, accessToken: envAccessToken, ssoPageURI } = useSpreePayEnv();
2438
- useEffect7(() => {
2461
+ useEffect8(() => {
2439
2462
  configureLogger({ environment });
2440
2463
  logger.logVersion();
2441
2464
  }, [environment]);
@@ -2449,7 +2472,6 @@ var SpreePayInner = () => {
2449
2472
  enabled: !envTokenValid
2450
2473
  });
2451
2474
  const _accessToken = envTokenValid ? envAccessToken : accessToken;
2452
- const unauthenticatedFetcher = useCallback8(() => Promise.resolve(null), []);
2453
2475
  const slapiFetcher = useMemo9(() => {
2454
2476
  if (_accessToken) {
2455
2477
  return registerApi({
@@ -2459,7 +2481,7 @@ var SpreePayInner = () => {
2459
2481
  });
2460
2482
  }
2461
2483
  return unauthenticatedFetcher;
2462
- }, [_accessToken, staticConfig, tenantId, unauthenticatedFetcher]);
2484
+ }, [_accessToken, staticConfig, tenantId]);
2463
2485
  const getContent = () => {
2464
2486
  if (isChecking) {
2465
2487
  return /* @__PURE__ */ jsxs13("div", { className: "flex w-full flex-col", children: [
@@ -2476,7 +2498,7 @@ var SpreePayInner = () => {
2476
2498
  revalidateOnFocus: false,
2477
2499
  revalidateIfStale: false
2478
2500
  },
2479
- children: /* @__PURE__ */ jsx20(PortalContainerProvider, { container: portalEl, children: /* @__PURE__ */ jsx20(NiceModal4.Provider, { children: /* @__PURE__ */ jsx20(SpreePayContent, { isLoggedIn: Boolean(_accessToken) }) }) })
2501
+ children: /* @__PURE__ */ jsx20(PortalContainerProvider, { container: portalEl, children: /* @__PURE__ */ jsx20(NiceModal4.Provider, { children: /* @__PURE__ */ jsx20(LoginStatusProvider, { isLoggedIn: Boolean(_accessToken), children: /* @__PURE__ */ jsx20(SpreePayContent, {}) }) }) })
2480
2502
  }
2481
2503
  );
2482
2504
  };
@@ -2490,20 +2512,25 @@ var SpreePay = (props) => {
2490
2512
  };
2491
2513
 
2492
2514
  // src/hooks/useCapture3DS.ts
2493
- import { useEffect as useEffect8 } from "react";
2494
- var useCapture3DS = (searchParams) => {
2495
- useEffect8(() => {
2496
- if (typeof window !== "undefined" && window.parent && searchParams?.paymentIntent) {
2497
- window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
2515
+ import { useEffect as useEffect9 } from "react";
2516
+ var useCapture3DS = ({ paymentIntent }) => {
2517
+ useEffect9(() => {
2518
+ if (typeof window !== "undefined" && window.parent && paymentIntent) {
2519
+ window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent });
2498
2520
  }
2499
- }, [searchParams]);
2521
+ }, [paymentIntent]);
2500
2522
  };
2501
2523
  export {
2502
2524
  LogLevel,
2525
+ PaymentError,
2526
+ PaymentErrorCode,
2527
+ PaymentStatus,
2503
2528
  PaymentType,
2504
2529
  SpreePay,
2530
+ SpreePayHttpError,
2505
2531
  SpreePayProvider,
2506
2532
  configureLogger,
2533
+ isPaymentError,
2507
2534
  logger,
2508
2535
  useCapture3DS,
2509
2536
  useSpreePay
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superlogic/spree-pay",
3
- "version": "0.4.14",
3
+ "version": "0.5.2",
4
4
  "description": "Spree-pay React component and utilities",
5
5
  "private": false,
6
6
  "type": "module",
@@ -30,6 +30,8 @@
30
30
  "dev": "tsup --watch",
31
31
  "lint": "eslint . --max-warnings 0",
32
32
  "check-ts": "tsc --noEmit",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
33
35
  "publish": "npm run build"
34
36
  },
35
37
  "publishConfig": {
@@ -71,7 +73,8 @@
71
73
  "tailwindcss": "^4.3.0",
72
74
  "tsup": "^8.5.1",
73
75
  "tw-animate-css": "^1.4.0",
74
- "typescript": "^6.0.3"
76
+ "typescript": "^6.0.3",
77
+ "vitest": "^4.1.6"
75
78
  },
76
79
  "tsup": {
77
80
  "entry": [