@doujins/payments-ui 0.1.5 → 0.1.7

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/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { SolflareWalletAdapter } from '@solana/wallet-adapter-solflare';
11
11
  import { TrustWalletAdapter } from '@solana/wallet-adapter-trust';
12
12
  import { CoinbaseWalletAdapter } from '@solana/wallet-adapter-coinbase';
13
13
  import * as DialogPrimitive from '@radix-ui/react-dialog';
14
- import { X, ChevronDown, ChevronUp, Check, User, MapPin, Loader2, CreditCard, WalletCards, Trash2, ArrowLeft, CheckCircle, AlertCircle, Wallet, Ban, TriangleAlert, Shield, UserRound, Calendar, KeyRound, Sparkles, XCircle, RotateCcw, RefreshCw } from 'lucide-react';
14
+ import { X, ChevronDown, ChevronUp, Check, Loader2, CheckCircle, AlertCircle, Wallet, Ban, TriangleAlert, WalletCards, CreditCard, Trash2, Shield, UserRound, Calendar, KeyRound, Sparkles, XCircle, RotateCcw, RefreshCw } from 'lucide-react';
15
15
  import { clsx } from 'clsx';
16
16
  import { twMerge } from 'tailwind-merge';
17
17
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -88,14 +88,15 @@ var createClient = (config) => {
88
88
  }
89
89
  };
90
90
  const buildUrl = (path, query) => {
91
- path = path.replace(/^\/+|\/+$/g, "");
92
- const baseUrl = config.baseUrl.replace(/^\/+|\/+$/g, "");
93
- const url = new URL(`${baseUrl}${path.endsWith("v1") ? "/" : "/v1/"}${path}`);
91
+ const sanitizedPath = path.replace(/^\/+/, "");
92
+ const baseUrl = config.baseUrl.trim().replace(/\/+$/, "");
93
+ const versionedBaseUrl = baseUrl.endsWith("/v1") ? baseUrl : `${baseUrl}/v1`;
94
+ const url = new URL(sanitizedPath, `${versionedBaseUrl.replace(/\/+$/, "")}/`);
94
95
  if (query) {
95
- Object.entries(query).forEach(([key, value]) => {
96
- if (value === void 0 || value === null) return;
96
+ for (const [key, value] of Object.entries(query)) {
97
+ if (value === void 0 || value === null) continue;
97
98
  url.searchParams.append(key, String(value));
98
- });
99
+ }
99
100
  }
100
101
  return url.toString();
101
102
  };
@@ -691,12 +692,9 @@ var CardDetailsForm = ({
691
692
  noValidate: true,
692
693
  children: [
693
694
  errorMessage && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-500/40 bg-red-500/10 px-4 py-2 text-sm text-red-400", children: errorMessage }),
694
- /* @__PURE__ */ jsxs("div", { className: "grid gap-5 md:grid-cols-2", children: [
695
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
696
- /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-first", className: "flex items-center gap-2 text-white/70", children: [
697
- /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
698
- " First name"
699
- ] }),
695
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 md:flex-row", children: [
696
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
697
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-first", children: "First name" }),
700
698
  /* @__PURE__ */ jsx(
701
699
  Input,
702
700
  {
@@ -707,11 +705,8 @@ var CardDetailsForm = ({
707
705
  }
708
706
  )
709
707
  ] }),
710
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
711
- /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-last", className: "flex items-center gap-2 text-white/70", children: [
712
- /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }),
713
- " Last name"
714
- ] }),
708
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
709
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-last", children: "Last name" }),
715
710
  /* @__PURE__ */ jsx(
716
711
  Input,
717
712
  {
@@ -775,10 +770,7 @@ var CardDetailsForm = ({
775
770
  ] }),
776
771
  /* @__PURE__ */ jsxs("div", { className: "grid gap-5 md:grid-cols-2", children: [
777
772
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
778
- /* @__PURE__ */ jsxs(Label, { htmlFor: "payments-postal", className: "flex items-center gap-2 text-white/70", children: [
779
- /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
780
- " Postal code"
781
- ] }),
773
+ /* @__PURE__ */ jsx(Label, { htmlFor: "payments-postal", children: "Postal code" }),
782
774
  /* @__PURE__ */ jsx(
783
775
  Input,
784
776
  {
@@ -820,17 +812,10 @@ var CardDetailsForm = ({
820
812
  children: submitting || isTokenizing ? /* @__PURE__ */ jsxs(Fragment, { children: [
821
813
  /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
822
814
  " Processing\u2026"
823
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
824
- /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
825
- " ",
826
- submitLabel
827
- ] })
815
+ ] }) : submitLabel
828
816
  }
829
817
  ),
830
- /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-xs text-white/50", children: [
831
- /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
832
- " Your payment information is encrypted and processed securely."
833
- ] })
818
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-white/60", children: "Your payment information is encrypted and processed securely." })
834
819
  ]
835
820
  }
836
821
  );
@@ -944,9 +929,7 @@ var formatCardLabel = (method) => {
944
929
  var StoredPaymentMethods = ({
945
930
  selectedMethodId,
946
931
  onMethodSelect,
947
- showAddButton = true,
948
- heading = "Payment Methods",
949
- description = "Manage your saved cards"
932
+ showAddButton = true
950
933
  }) => {
951
934
  const { listQuery, createMutation, deleteMutation } = usePaymentMethods();
952
935
  const [isModalOpen, setIsModalOpen] = useState(false);
@@ -965,31 +948,18 @@ var StoredPaymentMethods = ({
965
948
  );
966
949
  };
967
950
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
968
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
969
- /* @__PURE__ */ jsxs("div", { children: [
970
- /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [
971
- /* @__PURE__ */ jsx(WalletCards, { className: "h-4 w-4" }),
972
- " ",
973
- heading
974
- ] }),
975
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: description })
976
- ] }),
977
- showAddButton && /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", onClick: () => setIsModalOpen(true), children: [
978
- /* @__PURE__ */ jsx(CreditCard, { className: "mr-2 h-4 w-4" }),
979
- " Add card"
980
- ] })
981
- ] }),
982
- listQuery.isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center rounded-lg border border-dashed border-border/60 bg-muted/10 py-8 text-sm text-muted-foreground", children: [
951
+ /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between gap-4", children: showAddButton && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: () => setIsModalOpen(true), children: "Add card" }) }),
952
+ listQuery.isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-4 text-sm text-muted-foreground", children: [
983
953
  /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
984
- " Loading cards\u2026"
985
- ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed border-border/60 bg-muted/10 px-4 py-6 text-sm text-muted-foreground", children: "No saved payment methods yet." }) : /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[320px] pr-2", children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => {
954
+ " Loading cards..."
955
+ ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-sm text-muted-foreground", children: "No saved payment methods yet." }) : /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[320px] pr-2", children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => {
986
956
  const isSelected = selectedMethodId === method.id;
987
957
  return /* @__PURE__ */ jsxs(
988
958
  "div",
989
959
  {
990
960
  className: cn(
991
- "flex flex-col gap-3 rounded-lg border px-4 py-3 transition-colors md:flex-row md:items-center md:justify-between",
992
- isSelected ? "border-primary/60 bg-primary/5" : "border-border/60 bg-background"
961
+ "flex flex-col gap-3 rounded-md px-4 py-3 transition-colors md:flex-row md:items-center md:justify-between",
962
+ isSelected ? "ring-1 ring-primary/70 bg-primary/5" : "ring-1 ring-border/40 bg-transparent"
993
963
  ),
994
964
  children: [
995
965
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
@@ -1016,7 +986,8 @@ var StoredPaymentMethods = ({
1016
986
  Button,
1017
987
  {
1018
988
  size: "sm",
1019
- variant: isSelected ? "default" : "outline",
989
+ variant: "ghost",
990
+ className: "px-3",
1020
991
  onClick: () => onMethodSelect(method),
1021
992
  children: isSelected ? "Selected" : "Use card"
1022
993
  }
@@ -1024,12 +995,12 @@ var StoredPaymentMethods = ({
1024
995
  /* @__PURE__ */ jsx(
1025
996
  Button,
1026
997
  {
1027
- size: "icon",
1028
- variant: "outline",
1029
- className: "text-destructive",
998
+ size: "sm",
999
+ variant: "ghost",
1000
+ className: "px-3 text-destructive",
1030
1001
  onClick: () => handleDelete(method),
1031
1002
  disabled: deletingId === method.id && deleteMutation.isPending,
1032
- children: deletingId === method.id && deleteMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4" })
1003
+ children: deletingId === method.id && deleteMutation.isPending ? "Removing\u2026" : "Remove"
1033
1004
  }
1034
1005
  )
1035
1006
  ] })
@@ -1768,7 +1739,7 @@ var SolanaPaymentView = ({
1768
1739
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1769
1740
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Select token" }),
1770
1741
  /* @__PURE__ */ jsxs(Select, { value: selectedToken?.symbol ?? "", onValueChange: handleTokenChange, children: [
1771
- /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select token" }) }),
1742
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "border border-border/60 bg-transparent", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select token" }) }),
1772
1743
  /* @__PURE__ */ jsx(SelectContent, { className: "max-h-64", children: tokens.map((token) => /* @__PURE__ */ jsxs(SelectItem, { value: token.symbol, children: [
1773
1744
  token.name,
1774
1745
  " (",
@@ -1795,7 +1766,7 @@ var SolanaPaymentView = ({
1795
1766
  /* @__PURE__ */ jsx("p", { className: "text-2xl font-semibold text-foreground", children: "Pay with Solana" }),
1796
1767
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Choose a supported token and send the payment via Solana Pay QR code." })
1797
1768
  ] }),
1798
- onClose && /* @__PURE__ */ jsxs(
1769
+ onClose && /* @__PURE__ */ jsx(
1799
1770
  Button,
1800
1771
  {
1801
1772
  type: "button",
@@ -1803,11 +1774,8 @@ var SolanaPaymentView = ({
1803
1774
  variant: "ghost",
1804
1775
  onClick: handleClose,
1805
1776
  disabled: paymentState === "processing" || paymentState === "confirming",
1806
- className: "h-8 px-2 text-sm",
1807
- children: [
1808
- /* @__PURE__ */ jsx(ArrowLeft, { className: "mr-2 h-4 w-4" }),
1809
- " Back"
1810
- ]
1777
+ className: "h-8 px-3 text-sm",
1778
+ children: "Back"
1811
1779
  }
1812
1780
  )
1813
1781
  ] }),
@@ -1926,11 +1894,9 @@ var PaymentExperience = ({
1926
1894
  /* @__PURE__ */ jsx(
1927
1895
  StoredPaymentMethods,
1928
1896
  {
1929
- heading: "Saved cards",
1897
+ showAddButton: false,
1930
1898
  selectedMethodId,
1931
- onMethodSelect: handleMethodSelect,
1932
- description: "Select one of your stored payment methods.",
1933
- showAddButton: false
1899
+ onMethodSelect: handleMethodSelect
1934
1900
  }
1935
1901
  ),
1936
1902
  /* @__PURE__ */ jsx(
@@ -1939,7 +1905,7 @@ var PaymentExperience = ({
1939
1905
  className: "w-full",
1940
1906
  disabled: !selectedMethodId || savedStatus === "processing",
1941
1907
  onClick: handleSavedPayment,
1942
- children: savedStatus === "processing" ? "Processing\u2026" : "Pay with selected card"
1908
+ children: savedStatus === "processing" ? "Processing..." : "Pay with selected card"
1943
1909
  }
1944
1910
  ),
1945
1911
  savedError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: savedError })
@@ -1972,8 +1938,8 @@ var PaymentExperience = ({
1972
1938
  /* @__PURE__ */ jsx(TabsTrigger, { value: "saved", disabled: !showStored, children: "Use saved card" }),
1973
1939
  /* @__PURE__ */ jsx(TabsTrigger, { value: "new", disabled: !showNewCard, children: "Add new card" })
1974
1940
  ] }),
1975
- /* @__PURE__ */ jsx(TabsContent, { value: "saved", className: "space-y-4", children: renderSavedTab() }),
1976
- /* @__PURE__ */ jsx(TabsContent, { value: "new", className: "space-y-4", children: renderNewTab() })
1941
+ /* @__PURE__ */ jsx(TabsContent, { value: "saved", children: renderSavedTab() }),
1942
+ /* @__PURE__ */ jsx(TabsContent, { value: "new", children: renderNewTab() })
1977
1943
  ]
1978
1944
  }
1979
1945
  ),
@@ -2161,11 +2127,11 @@ var SubscriptionCheckoutModal = ({
2161
2127
  };
2162
2128
  const handleNewCardPayment = async ({ token, billing }) => {
2163
2129
  const response = await subscribeWithCard({
2164
- priceId: ensurePrice(),
2130
+ billing,
2165
2131
  provider,
2132
+ idempotencyKey,
2166
2133
  paymentToken: token,
2167
- billing,
2168
- idempotencyKey
2134
+ priceId: ensurePrice()
2169
2135
  });
2170
2136
  assertCheckoutSuccess(response.status, response.message);
2171
2137
  notifySuccess();
@@ -2204,14 +2170,14 @@ var SubscriptionCheckoutModal = ({
2204
2170
  {
2205
2171
  usdAmount,
2206
2172
  priceId: priceId ?? "",
2207
- onSolanaSuccess: solanaSuccess,
2173
+ initialMode,
2208
2174
  onSolanaError: solanaError,
2175
+ onSolanaSuccess: solanaSuccess,
2209
2176
  enableNewCard: Boolean(priceId),
2210
2177
  enableStoredMethods: Boolean(priceId),
2211
2178
  enableSolanaPay: enableSolanaPay && Boolean(priceId),
2212
2179
  onNewCardPayment: priceId ? handleNewCardPayment : void 0,
2213
- onSavedMethodPayment: priceId ? handleSavedMethodPayment : void 0,
2214
- initialMode
2180
+ onSavedMethodPayment: priceId ? handleSavedMethodPayment : void 0
2215
2181
  }
2216
2182
  )
2217
2183
  ] })
@@ -3125,7 +3091,7 @@ var PaymentMethodsSection = ({
3125
3091
  /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" }),
3126
3092
  " ",
3127
3093
  t.loadingCards
3128
- ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed border-white/20 bg-white/5 p-6 text-sm text-white/60", children: t.noPaymentMethods }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => /* @__PURE__ */ jsxs(
3094
+ ] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-6 text-sm text-center", children: t.noPaymentMethods }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => /* @__PURE__ */ jsxs(
3129
3095
  "div",
3130
3096
  {
3131
3097
  className: "rounded-lg border border-white/10 bg-white/5 p-4 shadow-sm",