@doujins/payments-ui 0.1.16 → 0.1.17-alpha
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.cjs +823 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +306 -68
- package/dist/index.d.ts +306 -68
- package/dist/index.js +821 -131
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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 { ChevronDown, ChevronUp, Check, Pencil, Loader2, CheckCircle, AlertCircle, Wallet, Ban, TriangleAlert, CreditCard, Trash2, Shield, UserRound, Calendar, KeyRound, XIcon, XCircle, RotateCcw
|
|
14
|
+
import { ChevronDown, ChevronUp, Check, Pencil, Loader2, CheckCircle, AlertCircle, Wallet, Ban, TriangleAlert, CreditCard, Trash2, WalletCards, RefreshCw, Shield, UserRound, Calendar, KeyRound, XIcon, XCircle, RotateCcw } from 'lucide-react';
|
|
15
15
|
import clsx2, { clsx } from 'clsx';
|
|
16
16
|
import { twMerge } from 'tailwind-merge';
|
|
17
17
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -248,6 +248,7 @@ var createClient = (config) => {
|
|
|
248
248
|
return normalizeList(result);
|
|
249
249
|
},
|
|
250
250
|
createPaymentMethod(payload) {
|
|
251
|
+
console.log("Creating payment method with payload:", payload);
|
|
251
252
|
return request("POST", "/me/payment-methods", {
|
|
252
253
|
body: payload
|
|
253
254
|
});
|
|
@@ -265,10 +266,10 @@ var createClient = (config) => {
|
|
|
265
266
|
},
|
|
266
267
|
checkout(payload, idempotencyKey) {
|
|
267
268
|
const key = idempotencyKey ?? crypto.randomUUID();
|
|
268
|
-
return request("POST", "/
|
|
269
|
+
return request("POST", "/checkout", {
|
|
269
270
|
body: payload,
|
|
270
271
|
headers: {
|
|
271
|
-
"Idempotency-Key": key
|
|
272
|
+
"X-Idempotency-Key": key
|
|
272
273
|
}
|
|
273
274
|
});
|
|
274
275
|
},
|
|
@@ -277,6 +278,36 @@ var createClient = (config) => {
|
|
|
277
278
|
body: feedback ? { feedback } : void 0
|
|
278
279
|
});
|
|
279
280
|
},
|
|
281
|
+
async listSubscriptions(params) {
|
|
282
|
+
const result = await request(
|
|
283
|
+
"GET",
|
|
284
|
+
"/me/subscriptions",
|
|
285
|
+
{
|
|
286
|
+
query: {
|
|
287
|
+
status: params?.status,
|
|
288
|
+
limit: params?.limit,
|
|
289
|
+
offset: params?.offset
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
);
|
|
293
|
+
return normalizeList(result);
|
|
294
|
+
},
|
|
295
|
+
updateSubscriptionPaymentMethod(payload) {
|
|
296
|
+
return request("PUT", "/me/subscriptions/payment-method", {
|
|
297
|
+
body: {
|
|
298
|
+
subscription_id: payload.subscription_id,
|
|
299
|
+
payment_method_id: payload.payment_method_id
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
},
|
|
303
|
+
resumeSubscription() {
|
|
304
|
+
return request("POST", "/me/subscriptions/resume");
|
|
305
|
+
},
|
|
306
|
+
changeSubscription(payload) {
|
|
307
|
+
return request("POST", "/me/subscriptions/change", {
|
|
308
|
+
body: payload
|
|
309
|
+
});
|
|
310
|
+
},
|
|
280
311
|
async getPaymentHistory(params) {
|
|
281
312
|
const result = await request("GET", "/me/payments", {
|
|
282
313
|
query: {
|
|
@@ -422,6 +453,19 @@ function DialogHeader({ className, ...props }) {
|
|
|
422
453
|
}
|
|
423
454
|
);
|
|
424
455
|
}
|
|
456
|
+
function DialogFooter({ className, ...props }) {
|
|
457
|
+
return /* @__PURE__ */ jsx(
|
|
458
|
+
"div",
|
|
459
|
+
{
|
|
460
|
+
"data-slot": "dialog-footer",
|
|
461
|
+
className: cn(
|
|
462
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
463
|
+
className
|
|
464
|
+
),
|
|
465
|
+
...props
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
}
|
|
425
469
|
function DialogTitle({
|
|
426
470
|
className,
|
|
427
471
|
...props
|
|
@@ -676,6 +720,28 @@ var defaultBillingDetails = {
|
|
|
676
720
|
email: "",
|
|
677
721
|
provider: "mobius"
|
|
678
722
|
};
|
|
723
|
+
var defaultCardDetailsFormTranslations = {
|
|
724
|
+
firstName: "First name",
|
|
725
|
+
lastName: "Last name",
|
|
726
|
+
email: "Email",
|
|
727
|
+
address: "Address",
|
|
728
|
+
city: "City",
|
|
729
|
+
state: "State / Region",
|
|
730
|
+
postalCode: "Postal code",
|
|
731
|
+
country: "Country",
|
|
732
|
+
cardNumber: "Card number",
|
|
733
|
+
expiry: "Expiry",
|
|
734
|
+
cvv: "CVV",
|
|
735
|
+
submit: "Submit",
|
|
736
|
+
processing: "Processing\u2026",
|
|
737
|
+
errorRequiredFields: "Please complete all required billing fields.",
|
|
738
|
+
errorTokenization: "Payment tokenization failed. Please try again.",
|
|
739
|
+
errorFormNotReady: "Payment form is not ready. Please try again later.",
|
|
740
|
+
infoSecure: "Your payment information is encrypted and processed securely.",
|
|
741
|
+
cancel: "Cancel",
|
|
742
|
+
editEmail: "Edit email",
|
|
743
|
+
selectCountry: "Select a country"
|
|
744
|
+
};
|
|
679
745
|
var buildSelector = (prefix, field) => `#${prefix}-${field}`;
|
|
680
746
|
var CardDetailsForm = ({
|
|
681
747
|
visible,
|
|
@@ -687,8 +753,10 @@ var CardDetailsForm = ({
|
|
|
687
753
|
collectPrefix = "card-form",
|
|
688
754
|
className,
|
|
689
755
|
onBillingChange,
|
|
690
|
-
submitDisabled = false
|
|
756
|
+
submitDisabled = false,
|
|
757
|
+
translations
|
|
691
758
|
}) => {
|
|
759
|
+
const t = { ...defaultCardDetailsFormTranslations, ...translations };
|
|
692
760
|
const { config } = usePaymentContext();
|
|
693
761
|
const defaultValuesKey = useMemo(() => JSON.stringify(defaultValues ?? {}), [defaultValues]);
|
|
694
762
|
const mergedDefaults = useMemo(
|
|
@@ -729,8 +797,11 @@ var CardDetailsForm = ({
|
|
|
729
797
|
if (!visible) {
|
|
730
798
|
setLocalError(null);
|
|
731
799
|
setIsTokenizing(false);
|
|
800
|
+
if (typeof window !== "undefined" && window.__doujinsCollectConfigured && collectPrefix) {
|
|
801
|
+
window.__doujinsCollectConfigured[collectPrefix] = false;
|
|
802
|
+
}
|
|
732
803
|
}
|
|
733
|
-
}, [visible]);
|
|
804
|
+
}, [visible, collectPrefix]);
|
|
734
805
|
useEffect(() => {
|
|
735
806
|
if (!visible) return;
|
|
736
807
|
setFirstName(mergedDefaults.firstName);
|
|
@@ -792,6 +863,8 @@ var CardDetailsForm = ({
|
|
|
792
863
|
setLocalError("Payment tokenization failed. Please try again.");
|
|
793
864
|
return;
|
|
794
865
|
}
|
|
866
|
+
let rawExp = response.card?.exp;
|
|
867
|
+
let formattedExp = rawExp && rawExp.length === 4 ? `${rawExp.slice(0, 2)}/${rawExp.slice(2)}` : rawExp;
|
|
795
868
|
const billing = {
|
|
796
869
|
firstName,
|
|
797
870
|
lastName,
|
|
@@ -801,7 +874,10 @@ var CardDetailsForm = ({
|
|
|
801
874
|
postalCode,
|
|
802
875
|
country,
|
|
803
876
|
email,
|
|
804
|
-
provider: mergedDefaults.provider ?? "mobius"
|
|
877
|
+
provider: mergedDefaults.provider ?? "mobius",
|
|
878
|
+
last_four: response.card?.number,
|
|
879
|
+
card_type: response.card?.type,
|
|
880
|
+
expiry_date: formattedExp
|
|
805
881
|
};
|
|
806
882
|
onTokenize(response.token, billing);
|
|
807
883
|
};
|
|
@@ -842,7 +918,7 @@ var CardDetailsForm = ({
|
|
|
842
918
|
]);
|
|
843
919
|
const validate = () => {
|
|
844
920
|
if (!firstName.trim() || !lastName.trim() || !address1.trim() || !city.trim() || !postalCode.trim() || !country.trim() || !email.trim()) {
|
|
845
|
-
setLocalError(
|
|
921
|
+
setLocalError(t.errorRequiredFields);
|
|
846
922
|
return false;
|
|
847
923
|
}
|
|
848
924
|
setLocalError(null);
|
|
@@ -852,7 +928,7 @@ var CardDetailsForm = ({
|
|
|
852
928
|
event.preventDefault();
|
|
853
929
|
if (!validate()) return;
|
|
854
930
|
if (!window.CollectJS) {
|
|
855
|
-
setLocalError(
|
|
931
|
+
setLocalError(t.errorFormNotReady);
|
|
856
932
|
return;
|
|
857
933
|
}
|
|
858
934
|
setIsTokenizing(true);
|
|
@@ -872,7 +948,7 @@ var CardDetailsForm = ({
|
|
|
872
948
|
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 }),
|
|
873
949
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:flex-row", children: [
|
|
874
950
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
875
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "firstName", children:
|
|
951
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "firstName", children: t.firstName }),
|
|
876
952
|
/* @__PURE__ */ jsx(
|
|
877
953
|
Input,
|
|
878
954
|
{
|
|
@@ -884,7 +960,7 @@ var CardDetailsForm = ({
|
|
|
884
960
|
)
|
|
885
961
|
] }),
|
|
886
962
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
887
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "lastName", children:
|
|
963
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "lastName", children: t.lastName }),
|
|
888
964
|
/* @__PURE__ */ jsx(
|
|
889
965
|
Input,
|
|
890
966
|
{
|
|
@@ -897,7 +973,7 @@ var CardDetailsForm = ({
|
|
|
897
973
|
] })
|
|
898
974
|
] }),
|
|
899
975
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
900
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "email", children:
|
|
976
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "email", children: t.email }),
|
|
901
977
|
showEmailInput ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
902
978
|
/* @__PURE__ */ jsx(
|
|
903
979
|
Input,
|
|
@@ -921,7 +997,7 @@ var CardDetailsForm = ({
|
|
|
921
997
|
setEmail(mergedDefaults.email ?? "");
|
|
922
998
|
},
|
|
923
999
|
className: "px-3 text-xs text-muted-foreground hover:text-foreground",
|
|
924
|
-
children:
|
|
1000
|
+
children: t.cancel
|
|
925
1001
|
}
|
|
926
1002
|
)
|
|
927
1003
|
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between h-9 w-full rounded-md border border-white/30 bg-transparent px-3 text-sm text-foreground", children: [
|
|
@@ -932,14 +1008,14 @@ var CardDetailsForm = ({
|
|
|
932
1008
|
type: "button",
|
|
933
1009
|
onClick: () => setIsEditingEmail(true),
|
|
934
1010
|
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
935
|
-
"aria-label":
|
|
1011
|
+
"aria-label": t.editEmail,
|
|
936
1012
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
|
|
937
1013
|
}
|
|
938
1014
|
)
|
|
939
1015
|
] })
|
|
940
1016
|
] }),
|
|
941
1017
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
942
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "address1", children:
|
|
1018
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "address1", children: t.address }),
|
|
943
1019
|
/* @__PURE__ */ jsx(
|
|
944
1020
|
Input,
|
|
945
1021
|
{
|
|
@@ -952,7 +1028,7 @@ var CardDetailsForm = ({
|
|
|
952
1028
|
] }),
|
|
953
1029
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-2 md:grid-cols-2", children: [
|
|
954
1030
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
955
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "city", children:
|
|
1031
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "city", children: t.city }),
|
|
956
1032
|
/* @__PURE__ */ jsx(
|
|
957
1033
|
Input,
|
|
958
1034
|
{
|
|
@@ -964,7 +1040,7 @@ var CardDetailsForm = ({
|
|
|
964
1040
|
)
|
|
965
1041
|
] }),
|
|
966
1042
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
967
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "state", children:
|
|
1043
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "state", children: t.state }),
|
|
968
1044
|
/* @__PURE__ */ jsx(
|
|
969
1045
|
Input,
|
|
970
1046
|
{
|
|
@@ -977,7 +1053,7 @@ var CardDetailsForm = ({
|
|
|
977
1053
|
] }),
|
|
978
1054
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-2 md:grid-cols-2", children: [
|
|
979
1055
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
980
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "postal", children:
|
|
1056
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "postal", children: t.postalCode }),
|
|
981
1057
|
/* @__PURE__ */ jsx(
|
|
982
1058
|
Input,
|
|
983
1059
|
{
|
|
@@ -989,24 +1065,24 @@ var CardDetailsForm = ({
|
|
|
989
1065
|
)
|
|
990
1066
|
] }),
|
|
991
1067
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
992
|
-
/* @__PURE__ */ jsx(Label, { children:
|
|
1068
|
+
/* @__PURE__ */ jsx(Label, { children: t.country }),
|
|
993
1069
|
/* @__PURE__ */ jsxs(Select, { value: country, onValueChange: setCountry, children: [
|
|
994
|
-
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder:
|
|
1070
|
+
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t.selectCountry }) }),
|
|
995
1071
|
/* @__PURE__ */ jsx(SelectContent, { children: countries.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.code, children: option.name }, option.code)) })
|
|
996
1072
|
] })
|
|
997
1073
|
] })
|
|
998
1074
|
] }),
|
|
999
1075
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1000
|
-
/* @__PURE__ */ jsx(Label, { children:
|
|
1076
|
+
/* @__PURE__ */ jsx(Label, { children: t.cardNumber }),
|
|
1001
1077
|
/* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccnumber").slice(1), className: collectFieldClass })
|
|
1002
1078
|
] }),
|
|
1003
1079
|
/* @__PURE__ */ jsxs("div", { className: "grid gap-2 md:grid-cols-2", children: [
|
|
1004
1080
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1005
|
-
/* @__PURE__ */ jsx(Label, { children:
|
|
1081
|
+
/* @__PURE__ */ jsx(Label, { children: t.expiry }),
|
|
1006
1082
|
/* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "ccexp").slice(1), className: collectFieldClass })
|
|
1007
1083
|
] }),
|
|
1008
1084
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
1009
|
-
/* @__PURE__ */ jsx(Label, { children:
|
|
1085
|
+
/* @__PURE__ */ jsx(Label, { children: t.cvv }),
|
|
1010
1086
|
/* @__PURE__ */ jsx("div", { id: buildSelector(collectPrefix, "cvv").slice(1), className: collectFieldClass })
|
|
1011
1087
|
] })
|
|
1012
1088
|
] }),
|
|
@@ -1018,11 +1094,12 @@ var CardDetailsForm = ({
|
|
|
1018
1094
|
disabled: submitting || submitDisabled || isTokenizing,
|
|
1019
1095
|
children: submitting || isTokenizing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1020
1096
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
1021
|
-
"
|
|
1022
|
-
|
|
1097
|
+
" ",
|
|
1098
|
+
t.processing
|
|
1099
|
+
] }) : submitLabel || t.submit
|
|
1023
1100
|
}
|
|
1024
1101
|
),
|
|
1025
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-white/60", children:
|
|
1102
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-white/60", children: t.infoSecure })
|
|
1026
1103
|
]
|
|
1027
1104
|
}
|
|
1028
1105
|
);
|
|
@@ -1059,7 +1136,9 @@ var usePaymentMethods = () => {
|
|
|
1059
1136
|
zip: billing.postalCode,
|
|
1060
1137
|
country: billing.country,
|
|
1061
1138
|
email: billing.email,
|
|
1062
|
-
provider: billing.provider
|
|
1139
|
+
provider: billing.provider,
|
|
1140
|
+
last_four: billing.last_four,
|
|
1141
|
+
card_type: billing.card_type
|
|
1063
1142
|
};
|
|
1064
1143
|
return client.createPaymentMethod(payload);
|
|
1065
1144
|
},
|
|
@@ -1128,21 +1207,34 @@ var ScrollBar = React4.forwardRef(({ className, orientation = "vertical", ...pro
|
|
|
1128
1207
|
}
|
|
1129
1208
|
));
|
|
1130
1209
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
1210
|
+
var defaultTranslations = {
|
|
1211
|
+
loadingCards: "Loading cards...",
|
|
1212
|
+
noSavedMethods: "No saved payment methods yet.",
|
|
1213
|
+
selectedLabel: "Selected",
|
|
1214
|
+
useCardLabel: "Use card"
|
|
1215
|
+
};
|
|
1131
1216
|
var formatCardLabel = (method) => {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1217
|
+
if (method.card) {
|
|
1218
|
+
const brand = method.card.brand ? method.card.brand.toUpperCase() : "CARD";
|
|
1219
|
+
const lastFour = method.card.last4 ? `\u2022\u2022\u2022\u2022 ${method.card.last4}` : "";
|
|
1220
|
+
const exp = method.card.exp_month && method.card.exp_year ? ` \u2022 ${String(method.card.exp_month).padStart(2, "0")}/${String(method.card.exp_year).slice(-2)}` : "";
|
|
1221
|
+
return `${brand} ${lastFour}${exp}`.trim();
|
|
1222
|
+
}
|
|
1223
|
+
return "CARD";
|
|
1135
1224
|
};
|
|
1136
1225
|
var StoredPaymentMethods = ({
|
|
1137
1226
|
selectedMethodId,
|
|
1138
|
-
onMethodSelect
|
|
1227
|
+
onMethodSelect,
|
|
1228
|
+
translations
|
|
1139
1229
|
}) => {
|
|
1140
1230
|
const { listQuery } = usePaymentMethods();
|
|
1141
1231
|
const payments = useMemo(() => listQuery.data?.data ?? [], [listQuery.data]);
|
|
1232
|
+
const t = { ...defaultTranslations, ...translations };
|
|
1142
1233
|
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: listQuery.isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-4 text-sm text-muted-foreground", children: [
|
|
1143
1234
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
1144
|
-
"
|
|
1145
|
-
|
|
1235
|
+
" ",
|
|
1236
|
+
t.loadingCards
|
|
1237
|
+
] }) : payments.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-sm text-muted-foreground", children: t.noSavedMethods }) : /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[320px] pr-2", children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: payments.map((method) => {
|
|
1146
1238
|
const isSelected = selectedMethodId === method.id;
|
|
1147
1239
|
return /* @__PURE__ */ jsxs(
|
|
1148
1240
|
"div",
|
|
@@ -1165,7 +1257,7 @@ var StoredPaymentMethods = ({
|
|
|
1165
1257
|
disabled: isSelected,
|
|
1166
1258
|
onClick: () => onMethodSelect(method),
|
|
1167
1259
|
className: clsx2("px-3", { "bg-muted/90": !isSelected, "bg-inherit": isSelected }),
|
|
1168
|
-
children: isSelected ?
|
|
1260
|
+
children: isSelected ? t.selectedLabel : t.useCardLabel
|
|
1169
1261
|
}
|
|
1170
1262
|
)
|
|
1171
1263
|
] })
|
|
@@ -1175,6 +1267,26 @@ var StoredPaymentMethods = ({
|
|
|
1175
1267
|
);
|
|
1176
1268
|
}) }) }) });
|
|
1177
1269
|
};
|
|
1270
|
+
|
|
1271
|
+
// src/utils/errorMessages.ts
|
|
1272
|
+
var resolveErrorMessageByCode = (error, translationErrors, fallbackMessage) => {
|
|
1273
|
+
const errors = translationErrors ?? {};
|
|
1274
|
+
const defaultMessage = fallbackMessage ?? (error instanceof Error ? error.message : typeof error === "string" ? error : "An unexpected error occurred");
|
|
1275
|
+
if (error instanceof ClientApiError) {
|
|
1276
|
+
const payload = error.body;
|
|
1277
|
+
const code = payload?.code ?? payload?.error?.code;
|
|
1278
|
+
if (code && errors[code]) return errors[code];
|
|
1279
|
+
if (typeof payload?.error?.message === "string") return payload.error.message;
|
|
1280
|
+
return error.message;
|
|
1281
|
+
}
|
|
1282
|
+
if (typeof error === "object" && error !== null && "code" in error) {
|
|
1283
|
+
const code = error.code;
|
|
1284
|
+
if (typeof code === "string" && errors[code]) return errors[code];
|
|
1285
|
+
}
|
|
1286
|
+
if (error instanceof Error) return error.message;
|
|
1287
|
+
if (typeof error === "string") return error;
|
|
1288
|
+
return defaultMessage;
|
|
1289
|
+
};
|
|
1178
1290
|
function Tabs({
|
|
1179
1291
|
className,
|
|
1180
1292
|
...props
|
|
@@ -1970,20 +2082,45 @@ var SolanaPaymentView = ({
|
|
|
1970
2082
|
renderBody()
|
|
1971
2083
|
] });
|
|
1972
2084
|
};
|
|
2085
|
+
var defaultPaymentExperienceTranslations = {
|
|
2086
|
+
...defaultCardDetailsFormTranslations,
|
|
2087
|
+
useSavedCardTab: "Use saved card",
|
|
2088
|
+
addNewCardTab: "Add new card",
|
|
2089
|
+
savedUnavailable: "Saved payment methods are unavailable right now. Add a new card to get started.",
|
|
2090
|
+
payWithSavedCard: "Pay with selected card",
|
|
2091
|
+
processingSavedCard: "Processing...",
|
|
2092
|
+
savedErrorFallback: "Unable to complete payment with saved card",
|
|
2093
|
+
newCardUnavailable: "Select a subscription plan to add a new card.",
|
|
2094
|
+
payNow: "Pay now",
|
|
2095
|
+
storedLoadingCards: "Loading cards...",
|
|
2096
|
+
storedNoSavedMethods: "No saved payment methods yet.",
|
|
2097
|
+
storedSelectedLabel: "Selected",
|
|
2098
|
+
storedUseCardLabel: "Use card",
|
|
2099
|
+
payWithCcbill: "Pay with CCBill",
|
|
2100
|
+
processingCcbill: "Redirecting...",
|
|
2101
|
+
errors: {}
|
|
2102
|
+
};
|
|
1973
2103
|
var PaymentExperience = ({
|
|
1974
2104
|
priceId,
|
|
1975
2105
|
usdAmount,
|
|
1976
2106
|
onNewCardPayment,
|
|
1977
2107
|
onSavedMethodPayment,
|
|
2108
|
+
onCcbillPayment,
|
|
1978
2109
|
enableNewCard = true,
|
|
1979
2110
|
enableStoredMethods = true,
|
|
1980
2111
|
enableSolanaPay = true,
|
|
1981
2112
|
onSolanaSuccess,
|
|
1982
2113
|
onSolanaError,
|
|
1983
|
-
initialMode = "cards"
|
|
2114
|
+
initialMode = "cards",
|
|
2115
|
+
translations
|
|
1984
2116
|
}) => {
|
|
2117
|
+
const t = {
|
|
2118
|
+
...defaultPaymentExperienceTranslations,
|
|
2119
|
+
...translations
|
|
2120
|
+
};
|
|
1985
2121
|
const showNewCard = enableNewCard && Boolean(onNewCardPayment);
|
|
1986
2122
|
const showStored = enableStoredMethods && Boolean(onSavedMethodPayment);
|
|
2123
|
+
const showCcbill = showNewCard && Boolean(onCcbillPayment);
|
|
1987
2124
|
const defaultTab = showStored ? "saved" : "new";
|
|
1988
2125
|
const [activeTab, setActiveTab] = useState(defaultTab);
|
|
1989
2126
|
const [mode, setMode] = useState(
|
|
@@ -1994,6 +2131,9 @@ var PaymentExperience = ({
|
|
|
1994
2131
|
const [savedError, setSavedError] = useState(null);
|
|
1995
2132
|
const [newCardStatus, setNewCardStatus] = useState("idle");
|
|
1996
2133
|
const [newCardError, setNewCardError] = useState(null);
|
|
2134
|
+
const [billingDetails, setBillingDetails] = useState(null);
|
|
2135
|
+
const [ccbillStatus, setCcbillStatus] = useState("idle");
|
|
2136
|
+
const [ccbillError, setCcbillError] = useState(null);
|
|
1997
2137
|
const { notifyStatus, notifyError } = usePaymentNotifications();
|
|
1998
2138
|
useEffect(() => {
|
|
1999
2139
|
setActiveTab(showStored ? "saved" : "new");
|
|
@@ -2009,6 +2149,24 @@ var PaymentExperience = ({
|
|
|
2009
2149
|
setMode("cards");
|
|
2010
2150
|
}
|
|
2011
2151
|
}, [enableSolanaPay, initialMode]);
|
|
2152
|
+
useEffect(() => {
|
|
2153
|
+
if (!showNewCard) {
|
|
2154
|
+
setBillingDetails(null);
|
|
2155
|
+
setCcbillStatus("idle");
|
|
2156
|
+
setCcbillError(null);
|
|
2157
|
+
}
|
|
2158
|
+
}, [showNewCard]);
|
|
2159
|
+
const handleBillingChange = useCallback((billing) => {
|
|
2160
|
+
setBillingDetails(billing);
|
|
2161
|
+
setCcbillError(null);
|
|
2162
|
+
setCcbillStatus("idle");
|
|
2163
|
+
}, []);
|
|
2164
|
+
const isBillingComplete = useCallback((billing) => {
|
|
2165
|
+
if (!billing) return false;
|
|
2166
|
+
return Boolean(
|
|
2167
|
+
billing.firstName.trim() && billing.lastName.trim() && billing.address1.trim() && billing.city.trim() && billing.postalCode.trim() && billing.country.trim() && billing.email.trim()
|
|
2168
|
+
);
|
|
2169
|
+
}, []);
|
|
2012
2170
|
const handleMethodSelect = useCallback((method) => {
|
|
2013
2171
|
setSelectedMethodId(method.id);
|
|
2014
2172
|
setSavedStatus("idle");
|
|
@@ -2027,13 +2185,17 @@ var PaymentExperience = ({
|
|
|
2027
2185
|
setSavedStatus("success");
|
|
2028
2186
|
notifyStatus("success", { source: "saved-payment" });
|
|
2029
2187
|
} catch (error) {
|
|
2030
|
-
const message =
|
|
2188
|
+
const message = resolveErrorMessageByCode(
|
|
2189
|
+
error,
|
|
2190
|
+
t.errors,
|
|
2191
|
+
t.savedErrorFallback
|
|
2192
|
+
);
|
|
2031
2193
|
setSavedStatus("error");
|
|
2032
2194
|
setSavedError(message);
|
|
2033
2195
|
notifyStatus("error", { source: "saved-payment" });
|
|
2034
2196
|
notifyError(message);
|
|
2035
2197
|
}
|
|
2036
|
-
}, [notifyError, notifyStatus, onSavedMethodPayment, selectedMethodId, usdAmount]);
|
|
2198
|
+
}, [notifyError, notifyStatus, onSavedMethodPayment, selectedMethodId, t, usdAmount]);
|
|
2037
2199
|
const handleNewCardTokenize = useCallback(
|
|
2038
2200
|
async (token, billing) => {
|
|
2039
2201
|
if (!onNewCardPayment) return;
|
|
@@ -2045,15 +2207,56 @@ var PaymentExperience = ({
|
|
|
2045
2207
|
setNewCardStatus("success");
|
|
2046
2208
|
notifyStatus("success", { source: "new-card" });
|
|
2047
2209
|
} catch (error) {
|
|
2048
|
-
const message =
|
|
2210
|
+
const message = resolveErrorMessageByCode(
|
|
2211
|
+
error,
|
|
2212
|
+
t.errors,
|
|
2213
|
+
"Unable to complete payment"
|
|
2214
|
+
);
|
|
2049
2215
|
setNewCardStatus("error");
|
|
2050
2216
|
setNewCardError(message);
|
|
2051
2217
|
notifyStatus("error", { source: "new-card" });
|
|
2052
2218
|
notifyError(message);
|
|
2053
2219
|
}
|
|
2054
2220
|
},
|
|
2055
|
-
[notifyError, notifyStatus, onNewCardPayment]
|
|
2221
|
+
[notifyError, notifyStatus, onNewCardPayment, t]
|
|
2056
2222
|
);
|
|
2223
|
+
const handleCcbillPayment = useCallback(async () => {
|
|
2224
|
+
if (!onCcbillPayment) return;
|
|
2225
|
+
if (!billingDetails || !isBillingComplete(billingDetails)) {
|
|
2226
|
+
const message = t.errorRequiredFields;
|
|
2227
|
+
setActiveTab("new");
|
|
2228
|
+
setCcbillStatus("error");
|
|
2229
|
+
setCcbillError(message);
|
|
2230
|
+
notifyStatus("error", { source: "ccbill" });
|
|
2231
|
+
notifyError(message);
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
try {
|
|
2235
|
+
setCcbillStatus("processing");
|
|
2236
|
+
setCcbillError(null);
|
|
2237
|
+
notifyStatus("processing", { source: "ccbill" });
|
|
2238
|
+
await onCcbillPayment({ billing: billingDetails });
|
|
2239
|
+
setCcbillStatus("success");
|
|
2240
|
+
notifyStatus("success", { source: "ccbill" });
|
|
2241
|
+
} catch (error) {
|
|
2242
|
+
const message = resolveErrorMessageByCode(
|
|
2243
|
+
error,
|
|
2244
|
+
t.errors,
|
|
2245
|
+
"Unable to start CCBill checkout"
|
|
2246
|
+
);
|
|
2247
|
+
setCcbillStatus("error");
|
|
2248
|
+
setCcbillError(message);
|
|
2249
|
+
notifyStatus("error", { source: "ccbill" });
|
|
2250
|
+
notifyError(message);
|
|
2251
|
+
}
|
|
2252
|
+
}, [
|
|
2253
|
+
billingDetails,
|
|
2254
|
+
isBillingComplete,
|
|
2255
|
+
notifyError,
|
|
2256
|
+
notifyStatus,
|
|
2257
|
+
onCcbillPayment,
|
|
2258
|
+
t
|
|
2259
|
+
]);
|
|
2057
2260
|
useCallback(() => {
|
|
2058
2261
|
if (!enableSolanaPay) return;
|
|
2059
2262
|
setMode("solana");
|
|
@@ -2076,14 +2279,20 @@ var PaymentExperience = ({
|
|
|
2076
2279
|
);
|
|
2077
2280
|
const renderSavedTab = () => {
|
|
2078
2281
|
if (!showStored) {
|
|
2079
|
-
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children:
|
|
2282
|
+
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t.savedUnavailable });
|
|
2080
2283
|
}
|
|
2081
2284
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
2082
2285
|
/* @__PURE__ */ jsx(
|
|
2083
2286
|
StoredPaymentMethods,
|
|
2084
2287
|
{
|
|
2085
2288
|
selectedMethodId,
|
|
2086
|
-
onMethodSelect: handleMethodSelect
|
|
2289
|
+
onMethodSelect: handleMethodSelect,
|
|
2290
|
+
translations: {
|
|
2291
|
+
loadingCards: t.storedLoadingCards,
|
|
2292
|
+
noSavedMethods: t.storedNoSavedMethods,
|
|
2293
|
+
selectedLabel: t.storedSelectedLabel,
|
|
2294
|
+
useCardLabel: t.storedUseCardLabel
|
|
2295
|
+
}
|
|
2087
2296
|
}
|
|
2088
2297
|
),
|
|
2089
2298
|
/* @__PURE__ */ jsx(
|
|
@@ -2092,7 +2301,7 @@ var PaymentExperience = ({
|
|
|
2092
2301
|
className: "w-full",
|
|
2093
2302
|
disabled: !selectedMethodId || savedStatus === "processing",
|
|
2094
2303
|
onClick: handleSavedPayment,
|
|
2095
|
-
children: savedStatus === "processing" ?
|
|
2304
|
+
children: savedStatus === "processing" ? t.processingSavedCard : t.payWithSavedCard
|
|
2096
2305
|
}
|
|
2097
2306
|
),
|
|
2098
2307
|
savedError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: savedError })
|
|
@@ -2100,29 +2309,50 @@ var PaymentExperience = ({
|
|
|
2100
2309
|
};
|
|
2101
2310
|
const renderNewTab = () => {
|
|
2102
2311
|
if (!showNewCard) {
|
|
2103
|
-
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children:
|
|
2312
|
+
return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t.newCardUnavailable });
|
|
2104
2313
|
}
|
|
2105
2314
|
return /* @__PURE__ */ jsx(
|
|
2106
2315
|
CardDetailsForm,
|
|
2107
2316
|
{
|
|
2108
2317
|
visible: true,
|
|
2109
|
-
submitLabel:
|
|
2318
|
+
submitLabel: t.payNow,
|
|
2110
2319
|
externalError: newCardError,
|
|
2111
2320
|
onTokenize: handleNewCardTokenize,
|
|
2112
|
-
submitting: newCardStatus === "processing"
|
|
2321
|
+
submitting: newCardStatus === "processing",
|
|
2322
|
+
onBillingChange: handleBillingChange,
|
|
2323
|
+
translations: t
|
|
2113
2324
|
}
|
|
2114
2325
|
);
|
|
2115
2326
|
};
|
|
2116
2327
|
const renderCardExperience = () => /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, children: [
|
|
2117
2328
|
/* @__PURE__ */ jsxs(TabsList, { className: "w-full rounded-md mb-4", children: [
|
|
2118
|
-
/* @__PURE__ */ jsx(TabsTrigger, { className: "cursor-pointer", value: "saved", children:
|
|
2119
|
-
/* @__PURE__ */ jsx(TabsTrigger, { className: "cursor-pointer", value: "new", children:
|
|
2329
|
+
/* @__PURE__ */ jsx(TabsTrigger, { className: "cursor-pointer", value: "saved", children: t.useSavedCardTab }),
|
|
2330
|
+
/* @__PURE__ */ jsx(TabsTrigger, { className: "cursor-pointer", value: "new", children: t.addNewCardTab })
|
|
2120
2331
|
] }),
|
|
2121
2332
|
/* @__PURE__ */ jsx(TabsContent, { value: "saved", children: renderSavedTab() }),
|
|
2122
2333
|
/* @__PURE__ */ jsx(TabsContent, { value: "new", children: renderNewTab() })
|
|
2123
2334
|
] });
|
|
2335
|
+
const renderCcbillAction = () => {
|
|
2336
|
+
if (!showCcbill) return null;
|
|
2337
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2 border-t border-white/10 pt-4", children: [
|
|
2338
|
+
/* @__PURE__ */ jsx(
|
|
2339
|
+
Button,
|
|
2340
|
+
{
|
|
2341
|
+
className: "w-full",
|
|
2342
|
+
variant: "outline",
|
|
2343
|
+
disabled: ccbillStatus === "processing",
|
|
2344
|
+
onClick: handleCcbillPayment,
|
|
2345
|
+
children: ccbillStatus === "processing" ? t.processingCcbill : t.payWithCcbill
|
|
2346
|
+
}
|
|
2347
|
+
),
|
|
2348
|
+
ccbillError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: ccbillError })
|
|
2349
|
+
] });
|
|
2350
|
+
};
|
|
2124
2351
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6 pt-4", children: [
|
|
2125
|
-
mode === "cards" &&
|
|
2352
|
+
mode === "cards" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2353
|
+
renderCardExperience(),
|
|
2354
|
+
renderCcbillAction()
|
|
2355
|
+
] }),
|
|
2126
2356
|
mode === "solana" && enableSolanaPay && /* @__PURE__ */ jsx(
|
|
2127
2357
|
SolanaPaymentView,
|
|
2128
2358
|
{
|
|
@@ -2174,17 +2404,17 @@ var useSubscriptionActions = () => {
|
|
|
2174
2404
|
const subscribeWithCard = useCallback(
|
|
2175
2405
|
async ({
|
|
2176
2406
|
priceId,
|
|
2177
|
-
processor = "
|
|
2407
|
+
processor = "mobius",
|
|
2178
2408
|
provider,
|
|
2179
2409
|
paymentToken,
|
|
2180
2410
|
billing,
|
|
2181
2411
|
idempotencyKey
|
|
2182
2412
|
}) => {
|
|
2183
|
-
|
|
2184
|
-
|
|
2413
|
+
if (processor !== "ccbill" && !paymentToken) {
|
|
2414
|
+
throw new Error("payments-ui: payment token is required for card checkout");
|
|
2415
|
+
}
|
|
2416
|
+
const payment = {
|
|
2185
2417
|
processor,
|
|
2186
|
-
provider,
|
|
2187
|
-
payment_token: paymentToken,
|
|
2188
2418
|
email: billing.email,
|
|
2189
2419
|
first_name: billing.firstName,
|
|
2190
2420
|
last_name: billing.lastName,
|
|
@@ -2194,6 +2424,17 @@ var useSubscriptionActions = () => {
|
|
|
2194
2424
|
zip: billing.postalCode,
|
|
2195
2425
|
country: billing.country
|
|
2196
2426
|
};
|
|
2427
|
+
if (paymentToken) {
|
|
2428
|
+
payment.payment_token = paymentToken;
|
|
2429
|
+
payment.last_four = billing.last_four;
|
|
2430
|
+
payment.card_type = billing.card_type;
|
|
2431
|
+
payment.expiry_date = billing.expiry_date;
|
|
2432
|
+
}
|
|
2433
|
+
const payload = {
|
|
2434
|
+
price_id: ensurePrice(priceId),
|
|
2435
|
+
provider,
|
|
2436
|
+
payment
|
|
2437
|
+
};
|
|
2197
2438
|
return client.checkout(payload, idempotencyKey);
|
|
2198
2439
|
},
|
|
2199
2440
|
[client]
|
|
@@ -2201,7 +2442,7 @@ var useSubscriptionActions = () => {
|
|
|
2201
2442
|
const subscribeWithSavedMethod = useCallback(
|
|
2202
2443
|
async ({
|
|
2203
2444
|
priceId,
|
|
2204
|
-
processor = "
|
|
2445
|
+
processor = "mobius",
|
|
2205
2446
|
provider,
|
|
2206
2447
|
paymentMethodId,
|
|
2207
2448
|
email,
|
|
@@ -2209,10 +2450,12 @@ var useSubscriptionActions = () => {
|
|
|
2209
2450
|
}) => {
|
|
2210
2451
|
const payload = {
|
|
2211
2452
|
price_id: ensurePrice(priceId),
|
|
2212
|
-
processor,
|
|
2213
2453
|
provider,
|
|
2214
|
-
|
|
2215
|
-
|
|
2454
|
+
payment: {
|
|
2455
|
+
processor,
|
|
2456
|
+
payment_method_id: paymentMethodId,
|
|
2457
|
+
email
|
|
2458
|
+
}
|
|
2216
2459
|
};
|
|
2217
2460
|
return client.checkout(payload, idempotencyKey);
|
|
2218
2461
|
},
|
|
@@ -2231,12 +2474,14 @@ var useSubscriptionActions = () => {
|
|
|
2231
2474
|
}) => {
|
|
2232
2475
|
const payload = {
|
|
2233
2476
|
price_id: ensurePrice(priceId),
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2477
|
+
payment: {
|
|
2478
|
+
processor,
|
|
2479
|
+
email,
|
|
2480
|
+
first_name: firstName,
|
|
2481
|
+
last_name: lastName,
|
|
2482
|
+
zip: zipCode,
|
|
2483
|
+
country
|
|
2484
|
+
}
|
|
2240
2485
|
};
|
|
2241
2486
|
return client.checkout(payload, idempotencyKey);
|
|
2242
2487
|
},
|
|
@@ -2248,6 +2493,11 @@ var useSubscriptionActions = () => {
|
|
|
2248
2493
|
subscribeWithCCBill
|
|
2249
2494
|
};
|
|
2250
2495
|
};
|
|
2496
|
+
var defaultTranslations2 = {
|
|
2497
|
+
...defaultPaymentExperienceTranslations,
|
|
2498
|
+
title: "Checkout",
|
|
2499
|
+
selectPlanMessage: "Select a subscription plan to continue."
|
|
2500
|
+
};
|
|
2251
2501
|
var SubscriptionCheckoutModal = ({
|
|
2252
2502
|
open,
|
|
2253
2503
|
onOpenChange,
|
|
@@ -2262,11 +2512,16 @@ var SubscriptionCheckoutModal = ({
|
|
|
2262
2512
|
enableSolanaPay = true,
|
|
2263
2513
|
onSolanaSuccess,
|
|
2264
2514
|
onSolanaError,
|
|
2265
|
-
initialMode = "cards"
|
|
2515
|
+
initialMode = "cards",
|
|
2516
|
+
translations
|
|
2266
2517
|
}) => {
|
|
2267
2518
|
const [showSuccess, setShowSuccess] = useState(false);
|
|
2268
2519
|
const [idempotencyKey, setIdempotencyKey] = useState(() => crypto.randomUUID());
|
|
2269
2520
|
const { subscribeWithCard, subscribeWithSavedMethod } = useSubscriptionActions();
|
|
2521
|
+
const t = {
|
|
2522
|
+
...defaultTranslations2,
|
|
2523
|
+
...translations
|
|
2524
|
+
};
|
|
2270
2525
|
useEffect(() => {
|
|
2271
2526
|
if (open) {
|
|
2272
2527
|
setIdempotencyKey(crypto.randomUUID());
|
|
@@ -2290,13 +2545,31 @@ var SubscriptionCheckoutModal = ({
|
|
|
2290
2545
|
console.debug("[payments-ui] subscription success", result);
|
|
2291
2546
|
}
|
|
2292
2547
|
};
|
|
2293
|
-
const
|
|
2294
|
-
if (status === "blocked") {
|
|
2295
|
-
throw new Error(message || "This subscription cannot be completed right now.");
|
|
2548
|
+
const handleCheckoutResponse = (response) => {
|
|
2549
|
+
if (response.status === "blocked") {
|
|
2550
|
+
throw new Error(response.message || "This subscription cannot be completed right now.");
|
|
2551
|
+
}
|
|
2552
|
+
const nextAction = response.next_action;
|
|
2553
|
+
if (nextAction?.type === "redirect_to_url") {
|
|
2554
|
+
const redirectUrl = nextAction.redirect_to_url?.url || response.payment?.redirect_url;
|
|
2555
|
+
if (!redirectUrl) {
|
|
2556
|
+
throw new Error(response.message || "Checkout requires a redirect URL.");
|
|
2557
|
+
}
|
|
2558
|
+
if (typeof window !== "undefined") {
|
|
2559
|
+
window.location.assign(redirectUrl);
|
|
2560
|
+
}
|
|
2561
|
+
return;
|
|
2562
|
+
}
|
|
2563
|
+
if (response.payment?.redirect_url) {
|
|
2564
|
+
if (typeof window !== "undefined") {
|
|
2565
|
+
window.location.assign(response.payment.redirect_url);
|
|
2566
|
+
}
|
|
2567
|
+
return;
|
|
2296
2568
|
}
|
|
2297
|
-
if (
|
|
2298
|
-
throw new Error(message || "
|
|
2569
|
+
if (nextAction && nextAction.type !== "none") {
|
|
2570
|
+
throw new Error(response.message || "Unsupported checkout action.");
|
|
2299
2571
|
}
|
|
2572
|
+
notifySuccess();
|
|
2300
2573
|
};
|
|
2301
2574
|
const handleNewCardPayment = async ({ token, billing }) => {
|
|
2302
2575
|
const response = await subscribeWithCard({
|
|
@@ -2306,8 +2579,7 @@ var SubscriptionCheckoutModal = ({
|
|
|
2306
2579
|
paymentToken: token,
|
|
2307
2580
|
priceId: ensurePrice()
|
|
2308
2581
|
});
|
|
2309
|
-
|
|
2310
|
-
notifySuccess();
|
|
2582
|
+
handleCheckoutResponse(response);
|
|
2311
2583
|
};
|
|
2312
2584
|
const handleSavedMethodPayment = async ({ paymentMethodId }) => {
|
|
2313
2585
|
const response = await subscribeWithSavedMethod({
|
|
@@ -2317,8 +2589,16 @@ var SubscriptionCheckoutModal = ({
|
|
|
2317
2589
|
email: userEmail ?? "",
|
|
2318
2590
|
idempotencyKey
|
|
2319
2591
|
});
|
|
2320
|
-
|
|
2321
|
-
|
|
2592
|
+
handleCheckoutResponse(response);
|
|
2593
|
+
};
|
|
2594
|
+
const handleCcbillPayment = async ({ billing }) => {
|
|
2595
|
+
const response = await subscribeWithCard({
|
|
2596
|
+
billing,
|
|
2597
|
+
idempotencyKey,
|
|
2598
|
+
processor: "ccbill",
|
|
2599
|
+
priceId: ensurePrice()
|
|
2600
|
+
});
|
|
2601
|
+
handleCheckoutResponse(response);
|
|
2322
2602
|
};
|
|
2323
2603
|
const solanaSuccess = (result) => {
|
|
2324
2604
|
notifySuccess(result);
|
|
@@ -2334,11 +2614,11 @@ var SubscriptionCheckoutModal = ({
|
|
|
2334
2614
|
{
|
|
2335
2615
|
className: "z-[100] max-w-xl max-h-[90vh] overflow-y-auto border border-white/20 p-6 backdrop-blur-xl bg-background-regular rounded-md [&::-webkit-scrollbar]:hidden",
|
|
2336
2616
|
children: [
|
|
2337
|
-
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { className: "flex items-center gap-2 text-foreground", children:
|
|
2617
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { className: "flex items-center gap-2 text-foreground", children: t.title }) }),
|
|
2338
2618
|
/* @__PURE__ */ jsx("div", { className: "space-y-4", children: !priceId ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-center px-3 py-2 text-sm text-destructive", children: [
|
|
2339
2619
|
/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
|
|
2340
2620
|
" ",
|
|
2341
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
2621
|
+
/* @__PURE__ */ jsx("span", { children: t.selectPlanMessage })
|
|
2342
2622
|
] }) : /* @__PURE__ */ jsx(
|
|
2343
2623
|
PaymentExperience,
|
|
2344
2624
|
{
|
|
@@ -2351,7 +2631,9 @@ var SubscriptionCheckoutModal = ({
|
|
|
2351
2631
|
enableStoredMethods: Boolean(priceId),
|
|
2352
2632
|
enableSolanaPay: enableSolanaPay && Boolean(priceId),
|
|
2353
2633
|
onNewCardPayment: priceId ? handleNewCardPayment : void 0,
|
|
2354
|
-
onSavedMethodPayment: priceId ? handleSavedMethodPayment : void 0
|
|
2634
|
+
onSavedMethodPayment: priceId ? handleSavedMethodPayment : void 0,
|
|
2635
|
+
onCcbillPayment: priceId ? handleCcbillPayment : void 0,
|
|
2636
|
+
translations: t
|
|
2355
2637
|
}
|
|
2356
2638
|
) })
|
|
2357
2639
|
]
|
|
@@ -2361,7 +2643,9 @@ var SubscriptionCheckoutModal = ({
|
|
|
2361
2643
|
SubscriptionSuccessDialog,
|
|
2362
2644
|
{
|
|
2363
2645
|
open: showSuccess,
|
|
2364
|
-
onClose: () =>
|
|
2646
|
+
onClose: () => {
|
|
2647
|
+
setShowSuccess(false);
|
|
2648
|
+
},
|
|
2365
2649
|
planName,
|
|
2366
2650
|
amountLabel: amountLabel ?? `$${usdAmount.toFixed(2)}`,
|
|
2367
2651
|
billingPeriodLabel
|
|
@@ -2786,7 +3070,7 @@ var notifyDefault = (payload) => {
|
|
|
2786
3070
|
const level = payload.status === "destructive" ? "error" : "info";
|
|
2787
3071
|
console[level === "error" ? "error" : "log"]("[payments-ui] cancellation", payload);
|
|
2788
3072
|
};
|
|
2789
|
-
var
|
|
3073
|
+
var defaultTranslations3 = {
|
|
2790
3074
|
buttonLabel: "Cancel Membership",
|
|
2791
3075
|
title: "Confirm Membership Cancellation",
|
|
2792
3076
|
description: "You are about to cancel your membership. Please review the consequences:",
|
|
@@ -2808,23 +3092,33 @@ var CancelMembershipDialog = ({
|
|
|
2808
3092
|
minReasonLength = 15,
|
|
2809
3093
|
onCancelled,
|
|
2810
3094
|
onNotify,
|
|
2811
|
-
translations: customTranslations
|
|
3095
|
+
translations: customTranslations,
|
|
3096
|
+
open,
|
|
3097
|
+
onOpenChange
|
|
2812
3098
|
}) => {
|
|
2813
3099
|
const { client } = usePaymentContext();
|
|
2814
3100
|
const notify = onNotify ?? notifyDefault;
|
|
2815
|
-
const t = { ...
|
|
3101
|
+
const t = { ...defaultTranslations3, ...customTranslations };
|
|
2816
3102
|
const [cancelReason, setCancelReason] = useState("");
|
|
2817
|
-
const [
|
|
3103
|
+
const [internalOpen, setInternalOpen] = useState(false);
|
|
2818
3104
|
const [isReasonValid, setIsReasonValid] = useState(false);
|
|
2819
3105
|
const [hasInteracted, setHasInteracted] = useState(false);
|
|
2820
3106
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
3107
|
+
const isControlled = typeof open === "boolean";
|
|
3108
|
+
const isOpen = isControlled ? open : internalOpen;
|
|
3109
|
+
const setOpen = (next) => {
|
|
3110
|
+
if (!isControlled) {
|
|
3111
|
+
setInternalOpen(next);
|
|
3112
|
+
}
|
|
3113
|
+
onOpenChange?.(next);
|
|
3114
|
+
};
|
|
2821
3115
|
useEffect(() => {
|
|
2822
3116
|
const trimmed = cancelReason.trim();
|
|
2823
3117
|
setIsReasonValid(trimmed.length >= minReasonLength);
|
|
2824
3118
|
}, [cancelReason, minReasonLength]);
|
|
2825
|
-
const handleOpenChange = (
|
|
2826
|
-
|
|
2827
|
-
if (!
|
|
3119
|
+
const handleOpenChange = (open2) => {
|
|
3120
|
+
setOpen(open2);
|
|
3121
|
+
if (!open2) {
|
|
2828
3122
|
setCancelReason("");
|
|
2829
3123
|
setIsReasonValid(false);
|
|
2830
3124
|
setHasInteracted(false);
|
|
@@ -2861,7 +3155,7 @@ var CancelMembershipDialog = ({
|
|
|
2861
3155
|
};
|
|
2862
3156
|
const showError = hasInteracted && !isReasonValid;
|
|
2863
3157
|
return /* @__PURE__ */ jsxs(AlertDialog, { open: isOpen, onOpenChange: handleOpenChange, children: [
|
|
2864
|
-
/* @__PURE__ */ jsx(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, {
|
|
3158
|
+
/* @__PURE__ */ jsx(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { className: "bg-destructive text-destructive-foreground border-destructive/50 hover:bg-destructive/90", children: [
|
|
2865
3159
|
/* @__PURE__ */ jsx(Ban, { className: "mr-2 h-4 w-4" }),
|
|
2866
3160
|
" ",
|
|
2867
3161
|
t.buttonLabel
|
|
@@ -2928,7 +3222,7 @@ var notifyDefault2 = (payload) => {
|
|
|
2928
3222
|
const level = payload.status === "destructive" ? "error" : "info";
|
|
2929
3223
|
console[level === "error" ? "error" : "log"]("[payments-ui] billing", payload);
|
|
2930
3224
|
};
|
|
2931
|
-
var
|
|
3225
|
+
var defaultTranslations4 = {
|
|
2932
3226
|
title: "Transaction History",
|
|
2933
3227
|
description: "Record of billing history",
|
|
2934
3228
|
reviewActivity: "Review your account activity below",
|
|
@@ -2950,7 +3244,7 @@ var BillingHistory = ({
|
|
|
2950
3244
|
}) => {
|
|
2951
3245
|
const { client } = usePaymentContext();
|
|
2952
3246
|
const notify = onNotify ?? notifyDefault2;
|
|
2953
|
-
const t = { ...
|
|
3247
|
+
const t = { ...defaultTranslations4, ...customTranslations };
|
|
2954
3248
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
2955
3249
|
const observerRef = useRef(null);
|
|
2956
3250
|
const loadMoreRef = useRef(null);
|
|
@@ -3059,15 +3353,21 @@ var BillingHistory = ({
|
|
|
3059
3353
|
] }) });
|
|
3060
3354
|
};
|
|
3061
3355
|
var formatCardLabel2 = (method) => {
|
|
3062
|
-
|
|
3063
|
-
|
|
3356
|
+
if (method.card) {
|
|
3357
|
+
const brand2 = method.card.brand ? method.card.brand.toUpperCase() : "CARD";
|
|
3358
|
+
const lastFour2 = method.card.last4 ? `\u2022\u2022\u2022\u2022 ${method.card.last4}` : "";
|
|
3359
|
+
const exp = method.card.exp_month && method.card.exp_year ? ` \u2022 ${String(method.card.exp_month).padStart(2, "0")}/${String(method.card.exp_year).slice(-2)}` : "";
|
|
3360
|
+
return `${brand2} ${lastFour2}${exp}`.trim();
|
|
3361
|
+
}
|
|
3362
|
+
const brand = "CARD";
|
|
3363
|
+
const lastFour = "";
|
|
3064
3364
|
return `${brand} ${lastFour}`.trim();
|
|
3065
3365
|
};
|
|
3066
3366
|
var notifyDefault3 = (payload) => {
|
|
3067
3367
|
const level = payload.status === "destructive" ? "error" : "info";
|
|
3068
3368
|
console[level === "error" ? "error" : "log"]("[payments-ui] notification", payload);
|
|
3069
3369
|
};
|
|
3070
|
-
var
|
|
3370
|
+
var defaultTranslations5 = {
|
|
3071
3371
|
title: "Payment Methods",
|
|
3072
3372
|
description: "Manage your saved billing cards",
|
|
3073
3373
|
addCard: "Add card",
|
|
@@ -3088,7 +3388,11 @@ var defaultTranslations3 = {
|
|
|
3088
3388
|
cardUpdated: "Card updated",
|
|
3089
3389
|
unableToRemoveCard: "Unable to remove card",
|
|
3090
3390
|
defaultPaymentMethodUpdated: "Default payment method updated",
|
|
3091
|
-
unableToSetDefault: "Unable to set default payment method"
|
|
3391
|
+
unableToSetDefault: "Unable to set default payment method",
|
|
3392
|
+
errors: {},
|
|
3393
|
+
activeSubscriptions: "Active subscriptions",
|
|
3394
|
+
showSubscriptions: "Show",
|
|
3395
|
+
hideSubscriptions: "Hide"
|
|
3092
3396
|
};
|
|
3093
3397
|
var PaymentMethodsSection = ({
|
|
3094
3398
|
isAuthenticated = true,
|
|
@@ -3099,8 +3403,7 @@ var PaymentMethodsSection = ({
|
|
|
3099
3403
|
onNotify,
|
|
3100
3404
|
translations: customTranslations
|
|
3101
3405
|
}) => {
|
|
3102
|
-
const { client } = usePaymentContext();
|
|
3103
|
-
const queryClient = useQueryClient();
|
|
3406
|
+
const { client, queryClient } = usePaymentContext();
|
|
3104
3407
|
const paymentMethods = {
|
|
3105
3408
|
list: (params) => client.listPaymentMethods({ limit: params.pageSize }),
|
|
3106
3409
|
create: (payload) => client.createPaymentMethod(payload),
|
|
@@ -3110,13 +3413,15 @@ var PaymentMethodsSection = ({
|
|
|
3110
3413
|
};
|
|
3111
3414
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
3112
3415
|
const [deletingId, setDeletingId] = useState(null);
|
|
3416
|
+
const [createErrorMessage, setCreateErrorMessage] = useState(null);
|
|
3417
|
+
const [expandedSubscriptions, setExpandedSubscriptions] = useState({});
|
|
3113
3418
|
const notify = onNotify ?? notifyDefault3;
|
|
3114
|
-
const t = { ...
|
|
3419
|
+
const t = { ...defaultTranslations5, ...customTranslations };
|
|
3115
3420
|
const queryKey = ["payments-ui", "payment-methods"];
|
|
3116
3421
|
const paymentQuery = useQuery({
|
|
3117
3422
|
queryKey,
|
|
3118
3423
|
queryFn: () => paymentMethods.list({ pageSize: 50 }),
|
|
3119
|
-
enabled: isAuthenticated,
|
|
3424
|
+
enabled: isAuthenticated && !!client,
|
|
3120
3425
|
staleTime: 3e4
|
|
3121
3426
|
});
|
|
3122
3427
|
const createMutation = useMutation({
|
|
@@ -3125,11 +3430,14 @@ var PaymentMethodsSection = ({
|
|
|
3125
3430
|
notify({ title: t.cardAddedSuccess, status: "success" });
|
|
3126
3431
|
setIsModalOpen(false);
|
|
3127
3432
|
void queryClient.invalidateQueries({ queryKey });
|
|
3433
|
+
setCreateErrorMessage(null);
|
|
3128
3434
|
},
|
|
3129
3435
|
onError: (error) => {
|
|
3436
|
+
const message = resolveErrorMessageByCode(error, t.errors, error.message);
|
|
3437
|
+
setCreateErrorMessage(message);
|
|
3130
3438
|
notify({
|
|
3131
3439
|
title: t.unableToAddCard,
|
|
3132
|
-
description:
|
|
3440
|
+
description: message,
|
|
3133
3441
|
status: "destructive"
|
|
3134
3442
|
});
|
|
3135
3443
|
}
|
|
@@ -3140,6 +3448,9 @@ var PaymentMethodsSection = ({
|
|
|
3140
3448
|
onSuccess: () => {
|
|
3141
3449
|
notify({ title: t.cardRemoved, status: "success" });
|
|
3142
3450
|
void queryClient.invalidateQueries({ queryKey });
|
|
3451
|
+
if (paymentQuery.refetch) {
|
|
3452
|
+
paymentQuery.refetch();
|
|
3453
|
+
}
|
|
3143
3454
|
},
|
|
3144
3455
|
onError: (error) => {
|
|
3145
3456
|
notify({
|
|
@@ -3150,7 +3461,7 @@ var PaymentMethodsSection = ({
|
|
|
3150
3461
|
},
|
|
3151
3462
|
onSettled: () => setDeletingId(null)
|
|
3152
3463
|
});
|
|
3153
|
-
|
|
3464
|
+
useMutation({
|
|
3154
3465
|
mutationFn: (id) => paymentMethods.activate(id),
|
|
3155
3466
|
onSuccess: () => {
|
|
3156
3467
|
notify({ title: t.defaultPaymentMethodUpdated, status: "success" });
|
|
@@ -3167,8 +3478,14 @@ var PaymentMethodsSection = ({
|
|
|
3167
3478
|
useEffect(() => {
|
|
3168
3479
|
if (!isModalOpen) {
|
|
3169
3480
|
createMutation.reset();
|
|
3481
|
+
setCreateErrorMessage(null);
|
|
3482
|
+
}
|
|
3483
|
+
}, [isModalOpen]);
|
|
3484
|
+
useEffect(() => {
|
|
3485
|
+
if (!isModalOpen && paymentQuery.refetch) {
|
|
3486
|
+
paymentQuery.refetch();
|
|
3170
3487
|
}
|
|
3171
|
-
}, [
|
|
3488
|
+
}, [isModalOpen]);
|
|
3172
3489
|
const payments = useMemo(() => paymentQuery.data?.data ?? [], [paymentQuery.data]);
|
|
3173
3490
|
const loading = paymentQuery.isLoading || paymentQuery.isFetching;
|
|
3174
3491
|
const buildPayload = (token, billing) => ({
|
|
@@ -3182,9 +3499,13 @@ var PaymentMethodsSection = ({
|
|
|
3182
3499
|
zip: billing.postalCode,
|
|
3183
3500
|
country: billing.country,
|
|
3184
3501
|
email: billing.email,
|
|
3185
|
-
provider: billing.provider
|
|
3502
|
+
provider: billing.provider,
|
|
3503
|
+
last_four: billing.last_four,
|
|
3504
|
+
card_type: billing.card_type,
|
|
3505
|
+
expiry_date: billing.expiry_date
|
|
3186
3506
|
});
|
|
3187
3507
|
const handleCardTokenize = (token, billing) => {
|
|
3508
|
+
setCreateErrorMessage(null);
|
|
3188
3509
|
createMutation.mutate(buildPayload(token, billing));
|
|
3189
3510
|
};
|
|
3190
3511
|
return /* @__PURE__ */ jsxs(Card, { className: "border-0 bg-black/30 shadow-2xl backdrop-blur-xl", children: [
|
|
@@ -3203,32 +3524,19 @@ var PaymentMethodsSection = ({
|
|
|
3203
3524
|
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" }),
|
|
3204
3525
|
" ",
|
|
3205
3526
|
t.loadingCards
|
|
3206
|
-
] }) : 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) =>
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3527
|
+
] }) : 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) => {
|
|
3528
|
+
(method.subscriptions?.length ?? 0) > 0;
|
|
3529
|
+
expandedSubscriptions[method.id] ?? false;
|
|
3530
|
+
return /* @__PURE__ */ jsxs(
|
|
3531
|
+
"div",
|
|
3532
|
+
{
|
|
3533
|
+
className: "rounded-lg border bg-white/5 p-4 shadow-sm",
|
|
3534
|
+
children: [
|
|
3535
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
3536
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-between", children: /* @__PURE__ */ jsx("div", { className: "text-base font-medium text-white", children: formatCardLabel2(method) }) }),
|
|
3537
|
+
/* @__PURE__ */ jsx("div", { children: method.failure_reason && /* @__PURE__ */ jsx(Badge, { variant: "destructive", children: method.failure_reason }) })
|
|
3215
3538
|
] }),
|
|
3216
|
-
/* @__PURE__ */ jsx("div", {
|
|
3217
|
-
] }),
|
|
3218
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap gap-2", children: [
|
|
3219
|
-
/* @__PURE__ */ jsxs(
|
|
3220
|
-
Button,
|
|
3221
|
-
{
|
|
3222
|
-
variant: "outline",
|
|
3223
|
-
disabled: method.is_active || activateMutation.isPending,
|
|
3224
|
-
onClick: () => activateMutation.mutate(method.id),
|
|
3225
|
-
children: [
|
|
3226
|
-
activateMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3227
|
-
method.is_active ? t.defaultMethod : t.makeDefault
|
|
3228
|
-
]
|
|
3229
|
-
}
|
|
3230
|
-
),
|
|
3231
|
-
/* @__PURE__ */ jsxs(
|
|
3539
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: /* @__PURE__ */ jsxs(
|
|
3232
3540
|
Button,
|
|
3233
3541
|
{
|
|
3234
3542
|
variant: "ghost",
|
|
@@ -3240,12 +3548,12 @@ var PaymentMethodsSection = ({
|
|
|
3240
3548
|
t.remove
|
|
3241
3549
|
]
|
|
3242
3550
|
}
|
|
3243
|
-
)
|
|
3244
|
-
]
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
)
|
|
3551
|
+
) })
|
|
3552
|
+
]
|
|
3553
|
+
},
|
|
3554
|
+
method.id
|
|
3555
|
+
);
|
|
3556
|
+
}) }) }),
|
|
3249
3557
|
/* @__PURE__ */ jsx(Dialog, { open: isModalOpen, onOpenChange: setIsModalOpen, children: /* @__PURE__ */ jsxs(
|
|
3250
3558
|
DialogContent,
|
|
3251
3559
|
{
|
|
@@ -3263,12 +3571,13 @@ var PaymentMethodsSection = ({
|
|
|
3263
3571
|
collectPrefix,
|
|
3264
3572
|
onTokenize: handleCardTokenize,
|
|
3265
3573
|
submitting: createMutation.isPending,
|
|
3574
|
+
translations: t,
|
|
3266
3575
|
defaultValues: {
|
|
3267
3576
|
provider,
|
|
3268
3577
|
email: userEmail ?? "",
|
|
3269
3578
|
country: defaultCountry
|
|
3270
3579
|
},
|
|
3271
|
-
externalError:
|
|
3580
|
+
externalError: createErrorMessage
|
|
3272
3581
|
}
|
|
3273
3582
|
)
|
|
3274
3583
|
]
|
|
@@ -3276,6 +3585,387 @@ var PaymentMethodsSection = ({
|
|
|
3276
3585
|
) })
|
|
3277
3586
|
] });
|
|
3278
3587
|
};
|
|
3588
|
+
var notifyDefault4 = (payload) => {
|
|
3589
|
+
const level = payload.status === "destructive" ? "error" : "info";
|
|
3590
|
+
console[level === "error" ? "error" : "log"]("[payments-ui] notification", payload);
|
|
3591
|
+
};
|
|
3592
|
+
var defaultTranslations6 = {
|
|
3593
|
+
title: "Subscriptions",
|
|
3594
|
+
description: "Manage your active and recent subscriptions.",
|
|
3595
|
+
loading: "Loading subscriptions...",
|
|
3596
|
+
noSubscriptions: "No subscriptions found.",
|
|
3597
|
+
status: "Status",
|
|
3598
|
+
active: "Active",
|
|
3599
|
+
cancelled: "Cancelled",
|
|
3600
|
+
pastDue: "Past due",
|
|
3601
|
+
pending: "Pending",
|
|
3602
|
+
paymentMethodLabel: "Payment method",
|
|
3603
|
+
changePaymentMethod: "Change payment method",
|
|
3604
|
+
paymentMethodUpdated: "Payment method updated",
|
|
3605
|
+
paymentMethodUpdateFailed: "Unable to update payment method",
|
|
3606
|
+
resume: "Resume subscription",
|
|
3607
|
+
changePlan: "Change plan",
|
|
3608
|
+
changePlanPlaceholder: "Enter a new price ID",
|
|
3609
|
+
planChanged: "Subscription updated",
|
|
3610
|
+
planChangeFailed: "Unable to update subscription",
|
|
3611
|
+
planChangeUnavailable: "Plan changes are unavailable for this subscription.",
|
|
3612
|
+
resumeSuccess: "Resume requested",
|
|
3613
|
+
resumeFailed: "Unable to resume subscription",
|
|
3614
|
+
update: "Update",
|
|
3615
|
+
product: "Product",
|
|
3616
|
+
price: "Price",
|
|
3617
|
+
currentPeriod: "Current period",
|
|
3618
|
+
refresh: "Refresh",
|
|
3619
|
+
manage: "Manage",
|
|
3620
|
+
close: "Close",
|
|
3621
|
+
paymentMethodTab: "Payment method",
|
|
3622
|
+
changePlanTab: "Change plan",
|
|
3623
|
+
statusTab: "Details",
|
|
3624
|
+
cancelTab: "Cancel/Resume"
|
|
3625
|
+
};
|
|
3626
|
+
var formatCardLabel3 = (method) => {
|
|
3627
|
+
if (method.card) {
|
|
3628
|
+
const brand2 = method.card.brand ? method.card.brand.toUpperCase() : "CARD";
|
|
3629
|
+
const lastFour2 = method.card.last4 ? `\u2022\u2022\u2022\u2022 ${method.card.last4}` : "";
|
|
3630
|
+
const exp = method.card.exp_month && method.card.exp_year ? ` \u2022 ${String(method.card.exp_month).padStart(2, "0")}/${String(method.card.exp_year).slice(-2)}` : "";
|
|
3631
|
+
return `${brand2} ${lastFour2}${exp}`.trim();
|
|
3632
|
+
}
|
|
3633
|
+
const brand = "CARD";
|
|
3634
|
+
const lastFour = "";
|
|
3635
|
+
return `${brand} ${lastFour}`.trim();
|
|
3636
|
+
};
|
|
3637
|
+
var SubscriptionsSection = ({
|
|
3638
|
+
isAuthenticated = true,
|
|
3639
|
+
translations: customTranslations,
|
|
3640
|
+
onNotify,
|
|
3641
|
+
statusFilter,
|
|
3642
|
+
cancelDialogTranslations,
|
|
3643
|
+
onCancelled
|
|
3644
|
+
}) => {
|
|
3645
|
+
const { client, queryClient } = usePaymentContext();
|
|
3646
|
+
const notify = onNotify ?? notifyDefault4;
|
|
3647
|
+
const t = { ...defaultTranslations6, ...customTranslations };
|
|
3648
|
+
const cancelTranslations = cancelDialogTranslations ?? defaultTranslations3;
|
|
3649
|
+
const [paymentSelections, setPaymentSelections] = useState({});
|
|
3650
|
+
const [priceInputs, setPriceInputs] = useState({});
|
|
3651
|
+
const [activeSubId, setActiveSubId] = useState(null);
|
|
3652
|
+
const [cancelDialogOpen, setCancelDialogOpen] = useState(false);
|
|
3653
|
+
const [sectionsOpen, setSectionsOpen] = useState({
|
|
3654
|
+
status: true,
|
|
3655
|
+
payment: false,
|
|
3656
|
+
plan: false,
|
|
3657
|
+
cancel: false
|
|
3658
|
+
});
|
|
3659
|
+
const normalizedStatusFilter = statusFilter ?? "all";
|
|
3660
|
+
const subscriptionsQueryKey = ["payments-ui", "subscriptions", normalizedStatusFilter];
|
|
3661
|
+
const paymentMethodsQueryKey = ["payments-ui", "payment-methods"];
|
|
3662
|
+
const subscriptionsQuery = useQuery({
|
|
3663
|
+
queryKey: subscriptionsQueryKey,
|
|
3664
|
+
queryFn: () => client.listSubscriptions({
|
|
3665
|
+
status: normalizedStatusFilter,
|
|
3666
|
+
limit: 50
|
|
3667
|
+
}),
|
|
3668
|
+
enabled: isAuthenticated && !!client,
|
|
3669
|
+
staleTime: 3e4
|
|
3670
|
+
});
|
|
3671
|
+
const paymentMethodsQuery = useQuery({
|
|
3672
|
+
queryKey: paymentMethodsQueryKey,
|
|
3673
|
+
queryFn: () => client.listPaymentMethods({ limit: 50 }),
|
|
3674
|
+
enabled: isAuthenticated && !!client,
|
|
3675
|
+
staleTime: 3e4
|
|
3676
|
+
});
|
|
3677
|
+
const subscriptions = useMemo(() => subscriptionsQuery.data?.data ?? [], [subscriptionsQuery.data]);
|
|
3678
|
+
const paymentMethods = useMemo(() => paymentMethodsQuery.data?.data ?? [], [paymentMethodsQuery.data]);
|
|
3679
|
+
const activeSubscription = useMemo(
|
|
3680
|
+
() => subscriptions.find((sub) => sub.id === activeSubId),
|
|
3681
|
+
[subscriptions, activeSubId]
|
|
3682
|
+
);
|
|
3683
|
+
useEffect(() => {
|
|
3684
|
+
setPaymentSelections((prev) => {
|
|
3685
|
+
const next = {};
|
|
3686
|
+
subscriptions.forEach((sub) => {
|
|
3687
|
+
next[sub.id] = prev[sub.id] ?? "";
|
|
3688
|
+
});
|
|
3689
|
+
return next;
|
|
3690
|
+
});
|
|
3691
|
+
}, [subscriptions]);
|
|
3692
|
+
useEffect(() => {
|
|
3693
|
+
setCancelDialogOpen(false);
|
|
3694
|
+
}, [activeSubId]);
|
|
3695
|
+
const updatePaymentMethodMutation = useMutation({
|
|
3696
|
+
mutationFn: (payload) => client.updateSubscriptionPaymentMethod({
|
|
3697
|
+
subscription_id: payload.subscriptionId,
|
|
3698
|
+
payment_method_id: payload.paymentMethodId
|
|
3699
|
+
}),
|
|
3700
|
+
onSuccess: () => {
|
|
3701
|
+
notify({ title: t.paymentMethodUpdated, status: "success" });
|
|
3702
|
+
void queryClient.invalidateQueries({ queryKey: subscriptionsQueryKey });
|
|
3703
|
+
},
|
|
3704
|
+
onError: (error) => {
|
|
3705
|
+
notify({
|
|
3706
|
+
title: t.paymentMethodUpdateFailed,
|
|
3707
|
+
description: resolveErrorMessageByCode(error, {}, error.message),
|
|
3708
|
+
status: "destructive"
|
|
3709
|
+
});
|
|
3710
|
+
}
|
|
3711
|
+
});
|
|
3712
|
+
const resumeSubscriptionMutation = useMutation({
|
|
3713
|
+
mutationFn: () => client.resumeSubscription(),
|
|
3714
|
+
onSuccess: () => {
|
|
3715
|
+
notify({ title: t.resumeSuccess, status: "success" });
|
|
3716
|
+
void queryClient.invalidateQueries({ queryKey: subscriptionsQueryKey });
|
|
3717
|
+
},
|
|
3718
|
+
onError: (error) => {
|
|
3719
|
+
notify({
|
|
3720
|
+
title: t.resumeFailed,
|
|
3721
|
+
description: resolveErrorMessageByCode(error, {}, error.message),
|
|
3722
|
+
status: "destructive"
|
|
3723
|
+
});
|
|
3724
|
+
}
|
|
3725
|
+
});
|
|
3726
|
+
useMutation({
|
|
3727
|
+
mutationFn: (payload) => client.changeSubscription({ price_id: payload.priceId }),
|
|
3728
|
+
onSuccess: () => {
|
|
3729
|
+
notify({ title: t.planChanged, status: "success" });
|
|
3730
|
+
void queryClient.invalidateQueries({ queryKey: subscriptionsQueryKey });
|
|
3731
|
+
},
|
|
3732
|
+
onError: (error) => {
|
|
3733
|
+
notify({
|
|
3734
|
+
title: t.planChangeFailed,
|
|
3735
|
+
description: resolveErrorMessageByCode(error, {}, error.message),
|
|
3736
|
+
status: "destructive"
|
|
3737
|
+
});
|
|
3738
|
+
}
|
|
3739
|
+
});
|
|
3740
|
+
const isLoading = subscriptionsQuery.isLoading || subscriptionsQuery.isFetching;
|
|
3741
|
+
const isError = subscriptionsQuery.isError;
|
|
3742
|
+
const errorMessage = subscriptionsQuery.error instanceof Error ? subscriptionsQuery.error.message : void 0;
|
|
3743
|
+
useEffect(() => {
|
|
3744
|
+
if (subscriptionsQuery.refetch) {
|
|
3745
|
+
void subscriptionsQuery.refetch();
|
|
3746
|
+
}
|
|
3747
|
+
}, []);
|
|
3748
|
+
const formatPrice = (sub) => {
|
|
3749
|
+
const price = sub.price;
|
|
3750
|
+
if (!price) return t.price;
|
|
3751
|
+
const amount = (price.amount / 100).toFixed(2);
|
|
3752
|
+
const currency = price.currency ? price.currency?.toUpperCase() : "";
|
|
3753
|
+
return `${price.display_name ?? t.price} \u2014 ${currency} ${amount}`;
|
|
3754
|
+
};
|
|
3755
|
+
const renderStatusBadge = (status) => {
|
|
3756
|
+
const normalized = status.toLowerCase();
|
|
3757
|
+
const label = normalized === "active" ? t.active : normalized === "past_due" ? t.pastDue : normalized === "pending" ? t.pending : t.cancelled;
|
|
3758
|
+
const variant = normalized === "active" ? "default" : normalized === "past_due" ? "destructive" : normalized === "pending" ? "outline" : "secondary";
|
|
3759
|
+
return /* @__PURE__ */ jsx(Badge, { variant, children: label });
|
|
3760
|
+
};
|
|
3761
|
+
const handleUpdatePaymentMethod = (subscriptionId) => {
|
|
3762
|
+
const paymentMethodId = paymentSelections[subscriptionId];
|
|
3763
|
+
const currentPaymentMethodId = "pm_" + subscriptions.find((s) => s.id === subscriptionId)?.payment_method_id;
|
|
3764
|
+
if (!paymentMethodId) return;
|
|
3765
|
+
if (currentPaymentMethodId && paymentMethodId === currentPaymentMethodId) {
|
|
3766
|
+
notify({
|
|
3767
|
+
title: t.paymentMethodUpdateFailed,
|
|
3768
|
+
description: t.paymentMethodUpdateFailed,
|
|
3769
|
+
status: "destructive"
|
|
3770
|
+
});
|
|
3771
|
+
return;
|
|
3772
|
+
}
|
|
3773
|
+
updatePaymentMethodMutation.mutate({ subscriptionId, paymentMethodId });
|
|
3774
|
+
};
|
|
3775
|
+
const toggleSection = (key) => {
|
|
3776
|
+
setSectionsOpen((prev) => ({
|
|
3777
|
+
...prev,
|
|
3778
|
+
[key]: !prev[key]
|
|
3779
|
+
}));
|
|
3780
|
+
};
|
|
3781
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3782
|
+
/* @__PURE__ */ jsxs(Card, { className: "border-0 bg-black/30 shadow-2xl backdrop-blur-xl", children: [
|
|
3783
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between", children: [
|
|
3784
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3785
|
+
/* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
|
|
3786
|
+
/* @__PURE__ */ jsx(WalletCards, { className: "h-5 w-5" }),
|
|
3787
|
+
t.title
|
|
3788
|
+
] }),
|
|
3789
|
+
/* @__PURE__ */ jsx(CardDescription, { children: t.description })
|
|
3790
|
+
] }),
|
|
3791
|
+
/* @__PURE__ */ jsxs(
|
|
3792
|
+
Button,
|
|
3793
|
+
{
|
|
3794
|
+
variant: "ghost",
|
|
3795
|
+
size: "sm",
|
|
3796
|
+
onClick: () => subscriptionsQuery.refetch?.(),
|
|
3797
|
+
disabled: subscriptionsQuery.isFetching,
|
|
3798
|
+
children: [
|
|
3799
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
3800
|
+
" ",
|
|
3801
|
+
subscriptionsQuery.isFetching ? t.loading : t.refresh
|
|
3802
|
+
]
|
|
3803
|
+
}
|
|
3804
|
+
)
|
|
3805
|
+
] }),
|
|
3806
|
+
/* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-10 text-white/60", children: [
|
|
3807
|
+
/* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-5 w-5 animate-spin" }),
|
|
3808
|
+
" ",
|
|
3809
|
+
t.loading
|
|
3810
|
+
] }) : isError ? /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-500/30 bg-red-500/10 p-4 text-sm text-red-100", children: errorMessage ?? "Unable to load subscriptions." }) : subscriptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-6 text-sm text-center", children: t.noSubscriptions }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: subscriptions.map((subscription) => {
|
|
3811
|
+
return /* @__PURE__ */ jsx(
|
|
3812
|
+
"div",
|
|
3813
|
+
{
|
|
3814
|
+
className: "rounded-lg border bg-white/5 p-4 shadow-sm",
|
|
3815
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
3816
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3817
|
+
/* @__PURE__ */ jsx("div", { className: "text-base font-semibold text-white", children: subscription.product?.display_name ?? t.product }),
|
|
3818
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-white/80", children: formatPrice(subscription) })
|
|
3819
|
+
] }),
|
|
3820
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3821
|
+
renderStatusBadge(subscription.status),
|
|
3822
|
+
/* @__PURE__ */ jsx(
|
|
3823
|
+
Button,
|
|
3824
|
+
{
|
|
3825
|
+
variant: "default",
|
|
3826
|
+
size: "sm",
|
|
3827
|
+
className: "rounded-full bg-foreground/10 text-muted-foreground hover:bg-foreground/20 hover:text-foreground",
|
|
3828
|
+
onClick: () => setActiveSubId(subscription.id),
|
|
3829
|
+
children: t.update
|
|
3830
|
+
}
|
|
3831
|
+
)
|
|
3832
|
+
] })
|
|
3833
|
+
] })
|
|
3834
|
+
},
|
|
3835
|
+
subscription.id
|
|
3836
|
+
);
|
|
3837
|
+
}) }) })
|
|
3838
|
+
] }),
|
|
3839
|
+
/* @__PURE__ */ jsx(Dialog, { open: !!activeSubscription, onOpenChange: (open) => setActiveSubId(open ? activeSubId : null), children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-2xl min-h-[300px] border border-white/20 bg-background-regular p-6 text-foreground", children: [
|
|
3840
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
3841
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "flex items-center gap-2", children: activeSubscription?.product?.display_name ?? t.product }),
|
|
3842
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "text-white/70", children: activeSubscription ? formatPrice(activeSubscription) : null })
|
|
3843
|
+
] }),
|
|
3844
|
+
activeSubscription && /* @__PURE__ */ jsxs("div", { className: "mt-4 space-y-3", children: [
|
|
3845
|
+
/* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-lg border border-white/15 bg-white/5", children: [
|
|
3846
|
+
/* @__PURE__ */ jsxs(
|
|
3847
|
+
"button",
|
|
3848
|
+
{
|
|
3849
|
+
type: "button",
|
|
3850
|
+
className: "flex w-full items-center justify-between px-4 py-3 text-left text-white hover:bg-white/10",
|
|
3851
|
+
onClick: () => toggleSection("status"),
|
|
3852
|
+
children: [
|
|
3853
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: t.statusTab }),
|
|
3854
|
+
/* @__PURE__ */ jsx(
|
|
3855
|
+
ChevronDown,
|
|
3856
|
+
{
|
|
3857
|
+
className: `h-4 w-4 transition-transform ${sectionsOpen.status ? "rotate-180" : ""}`
|
|
3858
|
+
}
|
|
3859
|
+
)
|
|
3860
|
+
]
|
|
3861
|
+
}
|
|
3862
|
+
),
|
|
3863
|
+
sectionsOpen.status ? /* @__PURE__ */ jsxs("div", { className: "space-y-3 border-t border-white/10 px-4 py-3", children: [
|
|
3864
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3", children: [
|
|
3865
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-white/80", children: t.status }),
|
|
3866
|
+
renderStatusBadge(activeSubscription.status)
|
|
3867
|
+
] }),
|
|
3868
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-white/60", children: [
|
|
3869
|
+
t.currentPeriod,
|
|
3870
|
+
": ",
|
|
3871
|
+
activeSubscription.started_at ? new Date(activeSubscription.started_at).toLocaleDateString() : "\u2014",
|
|
3872
|
+
" \u2192",
|
|
3873
|
+
" ",
|
|
3874
|
+
activeSubscription.current_period_ends_at ?? "\u2014"
|
|
3875
|
+
] }),
|
|
3876
|
+
activeSubscription.status.toLowerCase() === "cancelled" ? /* @__PURE__ */ jsxs(
|
|
3877
|
+
Button,
|
|
3878
|
+
{
|
|
3879
|
+
variant: "secondary",
|
|
3880
|
+
onClick: () => resumeSubscriptionMutation.mutate(),
|
|
3881
|
+
disabled: resumeSubscriptionMutation.isPending,
|
|
3882
|
+
className: "rounded-full px-4",
|
|
3883
|
+
children: [
|
|
3884
|
+
resumeSubscriptionMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3885
|
+
t.resume
|
|
3886
|
+
]
|
|
3887
|
+
}
|
|
3888
|
+
) : null
|
|
3889
|
+
] }) : null
|
|
3890
|
+
] }),
|
|
3891
|
+
/* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-lg border border-white/15 bg-white/5", children: [
|
|
3892
|
+
/* @__PURE__ */ jsxs(
|
|
3893
|
+
"button",
|
|
3894
|
+
{
|
|
3895
|
+
type: "button",
|
|
3896
|
+
className: "flex w-full items-center justify-between px-4 py-3 text-left text-white hover:bg-white/10",
|
|
3897
|
+
onClick: () => toggleSection("payment"),
|
|
3898
|
+
children: [
|
|
3899
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: t.paymentMethodTab }),
|
|
3900
|
+
/* @__PURE__ */ jsx(
|
|
3901
|
+
ChevronDown,
|
|
3902
|
+
{
|
|
3903
|
+
className: `h-4 w-4 transition-transform ${sectionsOpen.payment ? "rotate-180" : ""}`
|
|
3904
|
+
}
|
|
3905
|
+
)
|
|
3906
|
+
]
|
|
3907
|
+
}
|
|
3908
|
+
),
|
|
3909
|
+
sectionsOpen.payment ? /* @__PURE__ */ jsxs("div", { className: "space-y-2 border-t border-white/10 px-4 py-3", children: [
|
|
3910
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs uppercase tracking-wide text-white/60", children: t.paymentMethodLabel }),
|
|
3911
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:gap-2", children: [
|
|
3912
|
+
/* @__PURE__ */ jsxs(
|
|
3913
|
+
Select,
|
|
3914
|
+
{
|
|
3915
|
+
value: paymentSelections[activeSubscription.id] || "pm_" + activeSubscription.payment_method_id || "",
|
|
3916
|
+
onValueChange: (value) => setPaymentSelections((prev) => ({ ...prev, [activeSubscription.id]: value })),
|
|
3917
|
+
disabled: paymentMethodsQuery.isLoading || paymentMethods.length === 0,
|
|
3918
|
+
children: [
|
|
3919
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-full md:w-64 text-white", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: paymentMethodsQuery.isLoading ? t.loading : "" }) }),
|
|
3920
|
+
/* @__PURE__ */ jsx(SelectContent, { children: paymentMethods.filter((method) => method.id !== activeSubscription.payment_method_id).map((method) => /* @__PURE__ */ jsx(SelectItem, { value: method.id, children: formatCardLabel3(method) }, method.id)) })
|
|
3921
|
+
]
|
|
3922
|
+
}
|
|
3923
|
+
),
|
|
3924
|
+
/* @__PURE__ */ jsxs(
|
|
3925
|
+
Button,
|
|
3926
|
+
{
|
|
3927
|
+
size: "sm",
|
|
3928
|
+
onClick: () => handleUpdatePaymentMethod(activeSubscription.id),
|
|
3929
|
+
disabled: updatePaymentMethodMutation.isPending || !paymentSelections[activeSubscription.id] || paymentSelections[activeSubscription.id] === activeSubscription.payment_method_id,
|
|
3930
|
+
className: "border-0 bg-green-bg text-white hover:bg-green-bg/80 disabled:opacity-50",
|
|
3931
|
+
children: [
|
|
3932
|
+
updatePaymentMethodMutation.isPending ? /* @__PURE__ */ jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null,
|
|
3933
|
+
t.update
|
|
3934
|
+
]
|
|
3935
|
+
}
|
|
3936
|
+
)
|
|
3937
|
+
] })
|
|
3938
|
+
] }) : null
|
|
3939
|
+
] })
|
|
3940
|
+
] }),
|
|
3941
|
+
/* @__PURE__ */ jsxs(DialogFooter, { className: "flex flex-wrap gap-2", children: [
|
|
3942
|
+
/* @__PURE__ */ jsx(
|
|
3943
|
+
CancelMembershipDialog,
|
|
3944
|
+
{
|
|
3945
|
+
translations: cancelTranslations,
|
|
3946
|
+
onNotify,
|
|
3947
|
+
open: cancelDialogOpen,
|
|
3948
|
+
onOpenChange: (openState) => setCancelDialogOpen(openState),
|
|
3949
|
+
onCancelled: () => {
|
|
3950
|
+
void queryClient.invalidateQueries({ queryKey: subscriptionsQueryKey });
|
|
3951
|
+
onCancelled?.();
|
|
3952
|
+
setActiveSubId(null);
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
),
|
|
3956
|
+
/* @__PURE__ */ jsx(
|
|
3957
|
+
Button,
|
|
3958
|
+
{
|
|
3959
|
+
variant: "secondary",
|
|
3960
|
+
onClick: () => setActiveSubId(null),
|
|
3961
|
+
className: "border-white/20 bg-transparent text-foreground hover:bg-foreground/10 hover:text-foreground",
|
|
3962
|
+
children: t.close
|
|
3963
|
+
}
|
|
3964
|
+
)
|
|
3965
|
+
] })
|
|
3966
|
+
] }) })
|
|
3967
|
+
] });
|
|
3968
|
+
};
|
|
3279
3969
|
var Checkbox = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
3280
3970
|
CheckboxPrimitive.Root,
|
|
3281
3971
|
{
|
|
@@ -3791,6 +4481,6 @@ var usePaymentStatus = (options = {}) => {
|
|
|
3791
4481
|
};
|
|
3792
4482
|
};
|
|
3793
4483
|
|
|
3794
|
-
export { BillingHistory, CancelMembershipDialog, CardDetailsForm, ClientApiError, PaymentContext, PaymentExperience, PaymentMethodsSection, PaymentProvider, PaymentsDialogProvider, SolanaPaymentSelector, SolanaPaymentView, StoredPaymentMethods, SubscriptionCheckoutModal, SubscriptionSuccessDialog, WalletDialog, WalletModal, createClient, usePaymentContext, usePaymentDialogs, usePaymentMethods, usePaymentNotifications, usePaymentStatus, useSolanaQrPayment, useSubscriptionActions, useSupportedTokens, useTokenBalance };
|
|
4484
|
+
export { BillingHistory, CancelMembershipDialog, CardDetailsForm, ClientApiError, PaymentContext, PaymentExperience, PaymentMethodsSection, PaymentProvider, PaymentsDialogProvider, SolanaPaymentSelector, SolanaPaymentView, StoredPaymentMethods, SubscriptionCheckoutModal, SubscriptionSuccessDialog, SubscriptionsSection, WalletDialog, WalletModal, createClient, defaultCardDetailsFormTranslations, defaultPaymentExperienceTranslations, defaultTranslations3 as defaultTranslations, usePaymentContext, usePaymentDialogs, usePaymentMethods, usePaymentNotifications, usePaymentStatus, useSolanaQrPayment, useSubscriptionActions, useSupportedTokens, useTokenBalance };
|
|
3795
4485
|
//# sourceMappingURL=index.js.map
|
|
3796
4486
|
//# sourceMappingURL=index.js.map
|