@blocklet/payment-react 1.13.151 → 1.13.153
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/es/components/confirm.d.ts +5 -1
- package/es/components/confirm.js +7 -3
- package/es/history/invoice/list.d.ts +7 -1
- package/es/history/invoice/list.js +17 -7
- package/es/locales/en.js +13 -2
- package/es/locales/zh.js +14 -3
- package/es/payment/form/index.js +21 -2
- package/lib/components/confirm.d.ts +5 -1
- package/lib/components/confirm.js +7 -3
- package/lib/history/invoice/list.d.ts +7 -1
- package/lib/history/invoice/list.js +14 -7
- package/lib/locales/en.js +13 -2
- package/lib/locales/zh.js +14 -3
- package/lib/payment/form/index.js +20 -1
- package/package.json +3 -3
- package/src/components/confirm.tsx +8 -2
- package/src/history/invoice/list.tsx +14 -7
- package/src/locales/en.tsx +13 -1
- package/src/locales/zh.tsx +13 -2
- package/src/payment/form/index.tsx +22 -1
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { EventHandler } from 'react';
|
|
2
|
-
declare function ConfirmDialog({ onConfirm, onCancel, title, message, loading, }: {
|
|
2
|
+
declare function ConfirmDialog({ onConfirm, onCancel, title, message, confirm, cancel, loading, }: {
|
|
3
3
|
onConfirm: EventHandler<any>;
|
|
4
4
|
onCancel: EventHandler<any>;
|
|
5
5
|
title: string | React.ReactNode;
|
|
6
6
|
message: string | React.ReactNode;
|
|
7
|
+
confirm?: string | React.ReactNode;
|
|
8
|
+
cancel?: string | React.ReactNode;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
}): import("react").JSX.Element;
|
|
9
11
|
declare namespace ConfirmDialog {
|
|
10
12
|
var defaultProps: {
|
|
11
13
|
loading: boolean;
|
|
14
|
+
confirm: string;
|
|
15
|
+
cancel: string;
|
|
12
16
|
};
|
|
13
17
|
}
|
|
14
18
|
export default ConfirmDialog;
|
package/es/components/confirm.js
CHANGED
|
@@ -7,6 +7,8 @@ export default function ConfirmDialog({
|
|
|
7
7
|
onCancel,
|
|
8
8
|
title,
|
|
9
9
|
message,
|
|
10
|
+
confirm,
|
|
11
|
+
cancel,
|
|
10
12
|
loading
|
|
11
13
|
}) {
|
|
12
14
|
const { t } = useLocaleContext();
|
|
@@ -18,14 +20,16 @@ export default function ConfirmDialog({
|
|
|
18
20
|
onConfirm,
|
|
19
21
|
onCancel,
|
|
20
22
|
confirmButton: {
|
|
21
|
-
text: t("common.confirm"),
|
|
23
|
+
text: confirm || t("common.confirm"),
|
|
22
24
|
props: { color: "error", size: "small", variant: "contained", disabled: !!loading }
|
|
23
25
|
},
|
|
24
|
-
cancelButton: { text: t("common.cancel"), props: { color: "inherit", size: "small" } },
|
|
26
|
+
cancelButton: { text: cancel || t("common.cancel"), props: { color: "inherit", size: "small" } },
|
|
25
27
|
children: /* @__PURE__ */ jsx(Typography, { children: message })
|
|
26
28
|
}
|
|
27
29
|
);
|
|
28
30
|
}
|
|
29
31
|
ConfirmDialog.defaultProps = {
|
|
30
|
-
loading: false
|
|
32
|
+
loading: false,
|
|
33
|
+
confirm: "",
|
|
34
|
+
cancel: ""
|
|
31
35
|
};
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
type Props = {
|
|
3
3
|
customer_id?: string;
|
|
4
4
|
subscription_id?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
pageSize?: number;
|
|
7
|
+
target?: string;
|
|
5
8
|
};
|
|
6
|
-
declare function CustomerInvoiceList({ customer_id, subscription_id }: Props): import("react").JSX.Element;
|
|
9
|
+
declare function CustomerInvoiceList({ customer_id, subscription_id, status, pageSize, target }: Props): import("react").JSX.Element;
|
|
7
10
|
declare namespace CustomerInvoiceList {
|
|
8
11
|
var defaultProps: {
|
|
9
12
|
customer_id: string;
|
|
10
13
|
subscription_id: string;
|
|
14
|
+
status: string;
|
|
15
|
+
pageSize: number;
|
|
16
|
+
target: string;
|
|
11
17
|
};
|
|
12
18
|
}
|
|
13
19
|
export default CustomerInvoiceList;
|
|
@@ -27,13 +27,13 @@ const fetchData = (params = {}) => {
|
|
|
27
27
|
});
|
|
28
28
|
return api.get(`/api/invoices?${search.toString()}`).then((res) => res.data);
|
|
29
29
|
};
|
|
30
|
-
|
|
31
|
-
export default function CustomerInvoiceList({ customer_id, subscription_id }) {
|
|
30
|
+
export default function CustomerInvoiceList({ customer_id, subscription_id, status, pageSize, target }) {
|
|
32
31
|
const { t } = useLocaleContext();
|
|
32
|
+
const size = pageSize || 10;
|
|
33
33
|
const { data, loadMore, loadingMore, loading } = useInfiniteScroll(
|
|
34
34
|
(d) => {
|
|
35
|
-
const page = d ? Math.ceil(d.list.length /
|
|
36
|
-
return fetchData({ page, pageSize, status
|
|
35
|
+
const page = d ? Math.ceil(d.list.length / size) + 1 : 1;
|
|
36
|
+
return fetchData({ page, pageSize: size, status, customer_id, subscription_id });
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
reloadDeps: [customer_id]
|
|
@@ -65,7 +65,14 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }) {
|
|
|
65
65
|
},
|
|
66
66
|
flexWrap: "nowrap",
|
|
67
67
|
children: [
|
|
68
|
-
/* @__PURE__ */ jsx(Box, { flex: 3, children: /* @__PURE__ */ jsx(
|
|
68
|
+
/* @__PURE__ */ jsx(Box, { flex: 3, children: /* @__PURE__ */ jsx(
|
|
69
|
+
"a",
|
|
70
|
+
{
|
|
71
|
+
href: joinURL(window.location.origin, getPrefix(), `/customer/invoice/${invoice.id}`),
|
|
72
|
+
target,
|
|
73
|
+
children: /* @__PURE__ */ jsx(Typography, { component: "span", children: invoice.number })
|
|
74
|
+
}
|
|
75
|
+
) }),
|
|
69
76
|
/* @__PURE__ */ jsx(Box, { flex: 3, children: /* @__PURE__ */ jsx(Typography, { children: formatToDate(invoice.created_at) }) }),
|
|
70
77
|
/* @__PURE__ */ jsx(Box, { flex: 2, children: /* @__PURE__ */ jsxs(Typography, { textAlign: "right", children: [
|
|
71
78
|
fromUnitToToken(invoice.total, invoice.paymentCurrency.decimal),
|
|
@@ -81,11 +88,14 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }) {
|
|
|
81
88
|
] }, date)),
|
|
82
89
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
83
90
|
hasMore && /* @__PURE__ */ jsx(Button, { variant: "text", type: "button", color: "inherit", onClick: loadMore, disabled: loadingMore, children: loadingMore ? t("common.loadingMore", { resource: t("payment.customer.invoices") }) : t("common.loadMore", { resource: t("payment.customer.invoices") }) }),
|
|
84
|
-
!hasMore && data.count >
|
|
91
|
+
!hasMore && data.count > size && /* @__PURE__ */ jsx(Typography, { color: "text.secondary", children: t("common.noMore", { resource: t("payment.customer.invoices") }) })
|
|
85
92
|
] })
|
|
86
93
|
] });
|
|
87
94
|
}
|
|
88
95
|
CustomerInvoiceList.defaultProps = {
|
|
89
96
|
customer_id: "",
|
|
90
|
-
subscription_id: ""
|
|
97
|
+
subscription_id: "",
|
|
98
|
+
status: "open,paid,uncollectible",
|
|
99
|
+
pageSize: 10,
|
|
100
|
+
target: "self"
|
|
91
101
|
};
|
package/es/locales/en.js
CHANGED
|
@@ -148,7 +148,8 @@ export default flat({
|
|
|
148
148
|
customer: {
|
|
149
149
|
payments: "Payment History",
|
|
150
150
|
invoices: "Invoice History",
|
|
151
|
-
details: "
|
|
151
|
+
details: "Details",
|
|
152
|
+
summary: "Summary",
|
|
152
153
|
update: "Update Information",
|
|
153
154
|
empty: "Seems you do not have any subscriptions or payments here",
|
|
154
155
|
cancel: {
|
|
@@ -168,7 +169,14 @@ export default flat({
|
|
|
168
169
|
}
|
|
169
170
|
},
|
|
170
171
|
pastDue: {
|
|
171
|
-
button: "Pay"
|
|
172
|
+
button: "Pay",
|
|
173
|
+
invoices: "Past Due Invoices",
|
|
174
|
+
warning: "Past due invoices need to be paid immediately, otherwise you can not make new purchases anymore.",
|
|
175
|
+
alert: {
|
|
176
|
+
title: "You have unpaid invoices",
|
|
177
|
+
description: "Seems you have unpaid invoices from previous subscriptions, new purchases are not allowed unless you have paid all past due invoices.",
|
|
178
|
+
confirm: "Pay Now"
|
|
179
|
+
}
|
|
172
180
|
},
|
|
173
181
|
recover: {
|
|
174
182
|
button: "Renew",
|
|
@@ -207,6 +215,9 @@ export default flat({
|
|
|
207
215
|
payment: {
|
|
208
216
|
empty: "There are no payments here"
|
|
209
217
|
},
|
|
218
|
+
refund: {
|
|
219
|
+
empty: "There are no refunds here"
|
|
220
|
+
},
|
|
210
221
|
subscriptions: {
|
|
211
222
|
plan: "Plan",
|
|
212
223
|
nextInvoice: "Next Invoice",
|
package/es/locales/zh.js
CHANGED
|
@@ -148,7 +148,8 @@ export default flat({
|
|
|
148
148
|
customer: {
|
|
149
149
|
payments: "\u652F\u4ED8\u5386\u53F2",
|
|
150
150
|
invoices: "\u53D1\u7968\u5386\u53F2",
|
|
151
|
-
details: "\
|
|
151
|
+
details: "\u8D26\u6237\u8BE6\u60C5",
|
|
152
|
+
summary: "\u8BA1\u8D39\u6458\u8981",
|
|
152
153
|
update: "\u66F4\u65B0\u5BA2\u6237\u4FE1\u606F",
|
|
153
154
|
empty: "\u770B\u8D77\u6765\u60A8\u5728\u8FD9\u91CC\u6CA1\u6709\u4EFB\u4F55\u8BA2\u9605\u6216\u652F\u4ED8",
|
|
154
155
|
cancel: {
|
|
@@ -168,7 +169,14 @@ export default flat({
|
|
|
168
169
|
}
|
|
169
170
|
},
|
|
170
171
|
pastDue: {
|
|
171
|
-
button: "\u7EED\u8D39"
|
|
172
|
+
button: "\u7EED\u8D39",
|
|
173
|
+
invoices: "\u6B20\u8D39\u5E10\u5355",
|
|
174
|
+
warning: "\u8BF7\u5C3D\u5FEB\u652F\u4ED8\u6B20\u8D39\u8D26\u5355\uFF0C\u5426\u5219\u4F60\u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u670D\u52A1\u6216\u8D2D\u4E70\u65B0\u670D\u52A1",
|
|
175
|
+
alert: {
|
|
176
|
+
title: "\u4F60\u6709\u6B20\u8D39\u8D26\u5355",
|
|
177
|
+
description: "\u770B\u8D77\u6765\u4F60\u6709\u6B20\u8D39\u7684\u8D26\u5355\uFF0C\u5728\u4F60\u652F\u4ED8\u6240\u6709\u6B20\u8D39\u8D26\u5355\u4E4B\u524D\uFF0C\u65B0\u7684\u8D2D\u4E70\u6216\u8005\u8BA2\u9605\u5C06\u88AB\u7981\u6B62\uFF0C\u8BF7\u4E0D\u8981\u8C03\u76AE\u3002",
|
|
178
|
+
confirm: "\u53BB\u652F\u4ED8"
|
|
179
|
+
}
|
|
172
180
|
},
|
|
173
181
|
recover: {
|
|
174
182
|
button: "\u7EED\u8BA2",
|
|
@@ -205,7 +213,10 @@ export default flat({
|
|
|
205
213
|
empty: "\u6CA1\u6709\u4EFB\u4F55\u53D1\u7968"
|
|
206
214
|
},
|
|
207
215
|
payment: {
|
|
208
|
-
empty: "\u6CA1\u6709\
|
|
216
|
+
empty: "\u6CA1\u6709\u652F\u4ED8\u8BB0\u5F55"
|
|
217
|
+
},
|
|
218
|
+
refund: {
|
|
219
|
+
empty: "\u6CA1\u6709\u9000\u6B3E\u8BB0\u5F55"
|
|
209
220
|
},
|
|
210
221
|
subscriptions: {
|
|
211
222
|
plan: "\u8BA2\u9605",
|
package/es/payment/form/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { joinURL } from "ufo";
|
|
|
14
14
|
import { dispatch } from "use-bus";
|
|
15
15
|
import isEmail from "validator/es/lib/isEmail";
|
|
16
16
|
import api from "../../api.js";
|
|
17
|
+
import ConfirmDialog from "../../components/confirm.js";
|
|
17
18
|
import FormInput from "../../components/input.js";
|
|
18
19
|
import { usePaymentContext } from "../../contexts/payment.js";
|
|
19
20
|
import { formatError, getPrefix, getStatementDescriptor } from "../../util.js";
|
|
@@ -71,6 +72,7 @@ export default function PaymentForm({
|
|
|
71
72
|
paymentIntent,
|
|
72
73
|
stripeContext: void 0,
|
|
73
74
|
customer,
|
|
75
|
+
customerLimited: false,
|
|
74
76
|
stripePaying: false
|
|
75
77
|
});
|
|
76
78
|
const currencies = flatPaymentMethods(paymentMethods);
|
|
@@ -196,10 +198,17 @@ export default function PaymentForm({
|
|
|
196
198
|
}
|
|
197
199
|
}
|
|
198
200
|
} catch (err) {
|
|
201
|
+
let shouldToast = true;
|
|
199
202
|
if (err.response?.data?.code) {
|
|
200
203
|
dispatch(`error.${err.response?.data?.code}`);
|
|
204
|
+
if (err.response.data.code === "CUSTOMER_LIMITED") {
|
|
205
|
+
shouldToast = false;
|
|
206
|
+
setState({ customerLimited: true });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (shouldToast) {
|
|
210
|
+
Toast.error(formatError(err));
|
|
201
211
|
}
|
|
202
|
-
Toast.error(formatError(err));
|
|
203
212
|
} finally {
|
|
204
213
|
setState({ submitting: false });
|
|
205
214
|
}
|
|
@@ -353,6 +362,16 @@ export default function PaymentForm({
|
|
|
353
362
|
children: t("payment.checkout.confirm", { payee })
|
|
354
363
|
}
|
|
355
364
|
)
|
|
356
|
-
] }) })
|
|
365
|
+
] }) }),
|
|
366
|
+
state.customerLimited && /* @__PURE__ */ jsx(
|
|
367
|
+
ConfirmDialog,
|
|
368
|
+
{
|
|
369
|
+
onConfirm: () => window.open(joinURL(window.location.origin, getPrefix(), "/customer/invoice/past-due"), "_blank"),
|
|
370
|
+
onCancel: () => setState({ customerLimited: false }),
|
|
371
|
+
confirm: t("payment.customer.pastDue.alert.confirm"),
|
|
372
|
+
title: t("payment.customer.pastDue.alert.title"),
|
|
373
|
+
message: t("payment.customer.pastDue.alert.description")
|
|
374
|
+
}
|
|
375
|
+
)
|
|
357
376
|
] });
|
|
358
377
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import type { EventHandler } from 'react';
|
|
2
|
-
declare function ConfirmDialog({ onConfirm, onCancel, title, message, loading, }: {
|
|
2
|
+
declare function ConfirmDialog({ onConfirm, onCancel, title, message, confirm, cancel, loading, }: {
|
|
3
3
|
onConfirm: EventHandler<any>;
|
|
4
4
|
onCancel: EventHandler<any>;
|
|
5
5
|
title: string | React.ReactNode;
|
|
6
6
|
message: string | React.ReactNode;
|
|
7
|
+
confirm?: string | React.ReactNode;
|
|
8
|
+
cancel?: string | React.ReactNode;
|
|
7
9
|
loading?: boolean;
|
|
8
10
|
}): import("react").JSX.Element;
|
|
9
11
|
declare namespace ConfirmDialog {
|
|
10
12
|
var defaultProps: {
|
|
11
13
|
loading: boolean;
|
|
14
|
+
confirm: string;
|
|
15
|
+
cancel: string;
|
|
12
16
|
};
|
|
13
17
|
}
|
|
14
18
|
export default ConfirmDialog;
|
|
@@ -13,6 +13,8 @@ function ConfirmDialog({
|
|
|
13
13
|
onCancel,
|
|
14
14
|
title,
|
|
15
15
|
message,
|
|
16
|
+
confirm,
|
|
17
|
+
cancel,
|
|
16
18
|
loading
|
|
17
19
|
}) {
|
|
18
20
|
const {
|
|
@@ -24,7 +26,7 @@ function ConfirmDialog({
|
|
|
24
26
|
onConfirm,
|
|
25
27
|
onCancel,
|
|
26
28
|
confirmButton: {
|
|
27
|
-
text: t("common.confirm"),
|
|
29
|
+
text: confirm || t("common.confirm"),
|
|
28
30
|
props: {
|
|
29
31
|
color: "error",
|
|
30
32
|
size: "small",
|
|
@@ -33,7 +35,7 @@ function ConfirmDialog({
|
|
|
33
35
|
}
|
|
34
36
|
},
|
|
35
37
|
cancelButton: {
|
|
36
|
-
text: t("common.cancel"),
|
|
38
|
+
text: cancel || t("common.cancel"),
|
|
37
39
|
props: {
|
|
38
40
|
color: "inherit",
|
|
39
41
|
size: "small"
|
|
@@ -45,5 +47,7 @@ function ConfirmDialog({
|
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
ConfirmDialog.defaultProps = {
|
|
48
|
-
loading: false
|
|
50
|
+
loading: false,
|
|
51
|
+
confirm: "",
|
|
52
|
+
cancel: ""
|
|
49
53
|
};
|
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
type Props = {
|
|
3
3
|
customer_id?: string;
|
|
4
4
|
subscription_id?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
pageSize?: number;
|
|
7
|
+
target?: string;
|
|
5
8
|
};
|
|
6
|
-
declare function CustomerInvoiceList({ customer_id, subscription_id }: Props): import("react").JSX.Element;
|
|
9
|
+
declare function CustomerInvoiceList({ customer_id, subscription_id, status, pageSize, target }: Props): import("react").JSX.Element;
|
|
7
10
|
declare namespace CustomerInvoiceList {
|
|
8
11
|
var defaultProps: {
|
|
9
12
|
customer_id: string;
|
|
10
13
|
subscription_id: string;
|
|
14
|
+
status: string;
|
|
15
|
+
pageSize: number;
|
|
16
|
+
target: string;
|
|
11
17
|
};
|
|
12
18
|
}
|
|
13
19
|
export default CustomerInvoiceList;
|
|
@@ -34,25 +34,28 @@ const fetchData = (params = {}) => {
|
|
|
34
34
|
});
|
|
35
35
|
return _api.default.get(`/api/invoices?${search.toString()}`).then(res => res.data);
|
|
36
36
|
};
|
|
37
|
-
const pageSize = 10;
|
|
38
37
|
function CustomerInvoiceList({
|
|
39
38
|
customer_id,
|
|
40
|
-
subscription_id
|
|
39
|
+
subscription_id,
|
|
40
|
+
status,
|
|
41
|
+
pageSize,
|
|
42
|
+
target
|
|
41
43
|
}) {
|
|
42
44
|
const {
|
|
43
45
|
t
|
|
44
46
|
} = (0, _context.useLocaleContext)();
|
|
47
|
+
const size = pageSize || 10;
|
|
45
48
|
const {
|
|
46
49
|
data,
|
|
47
50
|
loadMore,
|
|
48
51
|
loadingMore,
|
|
49
52
|
loading
|
|
50
53
|
} = (0, _ahooks.useInfiniteScroll)(d => {
|
|
51
|
-
const page = d ? Math.ceil(d.list.length /
|
|
54
|
+
const page = d ? Math.ceil(d.list.length / size) + 1 : 1;
|
|
52
55
|
return fetchData({
|
|
53
56
|
page,
|
|
54
|
-
pageSize,
|
|
55
|
-
status
|
|
57
|
+
pageSize: size,
|
|
58
|
+
status,
|
|
56
59
|
customer_id,
|
|
57
60
|
subscription_id
|
|
58
61
|
});
|
|
@@ -103,6 +106,7 @@ function CustomerInvoiceList({
|
|
|
103
106
|
flex: 3,
|
|
104
107
|
children: /* @__PURE__ */(0, _jsxRuntime.jsx)("a", {
|
|
105
108
|
href: (0, _ufo.joinURL)(window.location.origin, (0, _util2.getPrefix)(), `/customer/invoice/${invoice.id}`),
|
|
109
|
+
target,
|
|
106
110
|
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
107
111
|
component: "span",
|
|
108
112
|
children: invoice.number
|
|
@@ -144,7 +148,7 @@ function CustomerInvoiceList({
|
|
|
144
148
|
}) : t("common.loadMore", {
|
|
145
149
|
resource: t("payment.customer.invoices")
|
|
146
150
|
})
|
|
147
|
-
}), !hasMore && data.count >
|
|
151
|
+
}), !hasMore && data.count > size && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
148
152
|
color: "text.secondary",
|
|
149
153
|
children: t("common.noMore", {
|
|
150
154
|
resource: t("payment.customer.invoices")
|
|
@@ -155,5 +159,8 @@ function CustomerInvoiceList({
|
|
|
155
159
|
}
|
|
156
160
|
CustomerInvoiceList.defaultProps = {
|
|
157
161
|
customer_id: "",
|
|
158
|
-
subscription_id: ""
|
|
162
|
+
subscription_id: "",
|
|
163
|
+
status: "open,paid,uncollectible",
|
|
164
|
+
pageSize: 10,
|
|
165
|
+
target: "self"
|
|
159
166
|
};
|
package/lib/locales/en.js
CHANGED
|
@@ -155,7 +155,8 @@ module.exports = (0, _flat.default)({
|
|
|
155
155
|
customer: {
|
|
156
156
|
payments: "Payment History",
|
|
157
157
|
invoices: "Invoice History",
|
|
158
|
-
details: "
|
|
158
|
+
details: "Details",
|
|
159
|
+
summary: "Summary",
|
|
159
160
|
update: "Update Information",
|
|
160
161
|
empty: "Seems you do not have any subscriptions or payments here",
|
|
161
162
|
cancel: {
|
|
@@ -175,7 +176,14 @@ module.exports = (0, _flat.default)({
|
|
|
175
176
|
}
|
|
176
177
|
},
|
|
177
178
|
pastDue: {
|
|
178
|
-
button: "Pay"
|
|
179
|
+
button: "Pay",
|
|
180
|
+
invoices: "Past Due Invoices",
|
|
181
|
+
warning: "Past due invoices need to be paid immediately, otherwise you can not make new purchases anymore.",
|
|
182
|
+
alert: {
|
|
183
|
+
title: "You have unpaid invoices",
|
|
184
|
+
description: "Seems you have unpaid invoices from previous subscriptions, new purchases are not allowed unless you have paid all past due invoices.",
|
|
185
|
+
confirm: "Pay Now"
|
|
186
|
+
}
|
|
179
187
|
},
|
|
180
188
|
recover: {
|
|
181
189
|
button: "Renew",
|
|
@@ -214,6 +222,9 @@ module.exports = (0, _flat.default)({
|
|
|
214
222
|
payment: {
|
|
215
223
|
empty: "There are no payments here"
|
|
216
224
|
},
|
|
225
|
+
refund: {
|
|
226
|
+
empty: "There are no refunds here"
|
|
227
|
+
},
|
|
217
228
|
subscriptions: {
|
|
218
229
|
plan: "Plan",
|
|
219
230
|
nextInvoice: "Next Invoice",
|
package/lib/locales/zh.js
CHANGED
|
@@ -155,7 +155,8 @@ module.exports = (0, _flat.default)({
|
|
|
155
155
|
customer: {
|
|
156
156
|
payments: "\u652F\u4ED8\u5386\u53F2",
|
|
157
157
|
invoices: "\u53D1\u7968\u5386\u53F2",
|
|
158
|
-
details: "\
|
|
158
|
+
details: "\u8D26\u6237\u8BE6\u60C5",
|
|
159
|
+
summary: "\u8BA1\u8D39\u6458\u8981",
|
|
159
160
|
update: "\u66F4\u65B0\u5BA2\u6237\u4FE1\u606F",
|
|
160
161
|
empty: "\u770B\u8D77\u6765\u60A8\u5728\u8FD9\u91CC\u6CA1\u6709\u4EFB\u4F55\u8BA2\u9605\u6216\u652F\u4ED8",
|
|
161
162
|
cancel: {
|
|
@@ -175,7 +176,14 @@ module.exports = (0, _flat.default)({
|
|
|
175
176
|
}
|
|
176
177
|
},
|
|
177
178
|
pastDue: {
|
|
178
|
-
button: "\u7EED\u8D39"
|
|
179
|
+
button: "\u7EED\u8D39",
|
|
180
|
+
invoices: "\u6B20\u8D39\u5E10\u5355",
|
|
181
|
+
warning: "\u8BF7\u5C3D\u5FEB\u652F\u4ED8\u6B20\u8D39\u8D26\u5355\uFF0C\u5426\u5219\u4F60\u5C06\u65E0\u6CD5\u7EE7\u7EED\u4F7F\u7528\u670D\u52A1\u6216\u8D2D\u4E70\u65B0\u670D\u52A1",
|
|
182
|
+
alert: {
|
|
183
|
+
title: "\u4F60\u6709\u6B20\u8D39\u8D26\u5355",
|
|
184
|
+
description: "\u770B\u8D77\u6765\u4F60\u6709\u6B20\u8D39\u7684\u8D26\u5355\uFF0C\u5728\u4F60\u652F\u4ED8\u6240\u6709\u6B20\u8D39\u8D26\u5355\u4E4B\u524D\uFF0C\u65B0\u7684\u8D2D\u4E70\u6216\u8005\u8BA2\u9605\u5C06\u88AB\u7981\u6B62\uFF0C\u8BF7\u4E0D\u8981\u8C03\u76AE\u3002",
|
|
185
|
+
confirm: "\u53BB\u652F\u4ED8"
|
|
186
|
+
}
|
|
179
187
|
},
|
|
180
188
|
recover: {
|
|
181
189
|
button: "\u7EED\u8BA2",
|
|
@@ -212,7 +220,10 @@ module.exports = (0, _flat.default)({
|
|
|
212
220
|
empty: "\u6CA1\u6709\u4EFB\u4F55\u53D1\u7968"
|
|
213
221
|
},
|
|
214
222
|
payment: {
|
|
215
|
-
empty: "\u6CA1\u6709\
|
|
223
|
+
empty: "\u6CA1\u6709\u652F\u4ED8\u8BB0\u5F55"
|
|
224
|
+
},
|
|
225
|
+
refund: {
|
|
226
|
+
empty: "\u6CA1\u6709\u9000\u6B3E\u8BB0\u5F55"
|
|
216
227
|
},
|
|
217
228
|
subscriptions: {
|
|
218
229
|
plan: "\u8BA2\u9605",
|
|
@@ -20,6 +20,7 @@ var _ufo = require("ufo");
|
|
|
20
20
|
var _useBus = require("use-bus");
|
|
21
21
|
var _isEmail = _interopRequireDefault(require("validator/es/lib/isEmail"));
|
|
22
22
|
var _api = _interopRequireDefault(require("../../api"));
|
|
23
|
+
var _confirm = _interopRequireDefault(require("../../components/confirm"));
|
|
23
24
|
var _input = _interopRequireDefault(require("../../components/input"));
|
|
24
25
|
var _payment = require("../../contexts/payment");
|
|
25
26
|
var _util = require("../../util");
|
|
@@ -90,6 +91,7 @@ function PaymentForm({
|
|
|
90
91
|
paymentIntent,
|
|
91
92
|
stripeContext: void 0,
|
|
92
93
|
customer,
|
|
94
|
+
customerLimited: false,
|
|
93
95
|
stripePaying: false
|
|
94
96
|
});
|
|
95
97
|
const currencies = flatPaymentMethods(paymentMethods);
|
|
@@ -243,10 +245,19 @@ function PaymentForm({
|
|
|
243
245
|
}
|
|
244
246
|
}
|
|
245
247
|
} catch (err) {
|
|
248
|
+
let shouldToast = true;
|
|
246
249
|
if (err.response?.data?.code) {
|
|
247
250
|
(0, _useBus.dispatch)(`error.${err.response?.data?.code}`);
|
|
251
|
+
if (err.response.data.code === "CUSTOMER_LIMITED") {
|
|
252
|
+
shouldToast = false;
|
|
253
|
+
setState({
|
|
254
|
+
customerLimited: true
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (shouldToast) {
|
|
259
|
+
_Toast.default.error((0, _util.formatError)(err));
|
|
248
260
|
}
|
|
249
|
-
_Toast.default.error((0, _util.formatError)(err));
|
|
250
261
|
} finally {
|
|
251
262
|
setState({
|
|
252
263
|
submitting: false
|
|
@@ -450,6 +461,14 @@ function PaymentForm({
|
|
|
450
461
|
})
|
|
451
462
|
})]
|
|
452
463
|
})
|
|
464
|
+
}), state.customerLimited && /* @__PURE__ */(0, _jsxRuntime.jsx)(_confirm.default, {
|
|
465
|
+
onConfirm: () => window.open((0, _ufo.joinURL)(window.location.origin, (0, _util.getPrefix)(), "/customer/invoice/past-due"), "_blank"),
|
|
466
|
+
onCancel: () => setState({
|
|
467
|
+
customerLimited: false
|
|
468
|
+
}),
|
|
469
|
+
confirm: t("payment.customer.pastDue.alert.confirm"),
|
|
470
|
+
title: t("payment.customer.pastDue.alert.title"),
|
|
471
|
+
message: t("payment.customer.pastDue.alert.description")
|
|
453
472
|
})]
|
|
454
473
|
});
|
|
455
474
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.153",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@babel/core": "^7.23.9",
|
|
90
90
|
"@babel/preset-env": "^7.23.9",
|
|
91
91
|
"@babel/preset-react": "^7.23.3",
|
|
92
|
-
"@blocklet/payment-types": "1.13.
|
|
92
|
+
"@blocklet/payment-types": "1.13.153",
|
|
93
93
|
"@storybook/addon-essentials": "^7.6.13",
|
|
94
94
|
"@storybook/addon-interactions": "^7.6.13",
|
|
95
95
|
"@storybook/addon-links": "^7.6.13",
|
|
@@ -118,5 +118,5 @@
|
|
|
118
118
|
"vite-plugin-babel": "^1.2.0",
|
|
119
119
|
"vite-plugin-node-polyfills": "^0.19.0"
|
|
120
120
|
},
|
|
121
|
-
"gitHead": "
|
|
121
|
+
"gitHead": "db16f61414e8f72da55dfa2faf9c17d79fcb6655"
|
|
122
122
|
}
|
|
@@ -8,12 +8,16 @@ export default function ConfirmDialog({
|
|
|
8
8
|
onCancel,
|
|
9
9
|
title,
|
|
10
10
|
message,
|
|
11
|
+
confirm,
|
|
12
|
+
cancel,
|
|
11
13
|
loading,
|
|
12
14
|
}: {
|
|
13
15
|
onConfirm: EventHandler<any>;
|
|
14
16
|
onCancel: EventHandler<any>;
|
|
15
17
|
title: string | React.ReactNode;
|
|
16
18
|
message: string | React.ReactNode;
|
|
19
|
+
confirm?: string | React.ReactNode;
|
|
20
|
+
cancel?: string | React.ReactNode;
|
|
17
21
|
loading?: boolean;
|
|
18
22
|
}) {
|
|
19
23
|
const { t } = useLocaleContext();
|
|
@@ -25,10 +29,10 @@ export default function ConfirmDialog({
|
|
|
25
29
|
onConfirm={onConfirm}
|
|
26
30
|
onCancel={onCancel}
|
|
27
31
|
confirmButton={{
|
|
28
|
-
text: t('common.confirm'),
|
|
32
|
+
text: confirm || t('common.confirm'),
|
|
29
33
|
props: { color: 'error', size: 'small', variant: 'contained', disabled: !!loading },
|
|
30
34
|
}}
|
|
31
|
-
cancelButton={{ text: t('common.cancel'), props: { color: 'inherit', size: 'small' } }}>
|
|
35
|
+
cancelButton={{ text: cancel || t('common.cancel'), props: { color: 'inherit', size: 'small' } }}>
|
|
32
36
|
<Typography>{message}</Typography>
|
|
33
37
|
</Confirm>
|
|
34
38
|
);
|
|
@@ -36,4 +40,6 @@ export default function ConfirmDialog({
|
|
|
36
40
|
|
|
37
41
|
ConfirmDialog.defaultProps = {
|
|
38
42
|
loading: false,
|
|
43
|
+
confirm: '',
|
|
44
|
+
cancel: '',
|
|
39
45
|
};
|
|
@@ -35,17 +35,19 @@ const fetchData = (params: Record<string, any> = {}): Promise<Paginated<TInvoice
|
|
|
35
35
|
type Props = {
|
|
36
36
|
customer_id?: string;
|
|
37
37
|
subscription_id?: string;
|
|
38
|
+
status?: string;
|
|
39
|
+
pageSize?: number;
|
|
40
|
+
target?: string;
|
|
38
41
|
};
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export default function CustomerInvoiceList({ customer_id, subscription_id }: Props) {
|
|
43
|
+
export default function CustomerInvoiceList({ customer_id, subscription_id, status, pageSize, target }: Props) {
|
|
43
44
|
const { t } = useLocaleContext();
|
|
45
|
+
const size = pageSize || 10;
|
|
44
46
|
|
|
45
47
|
const { data, loadMore, loadingMore, loading } = useInfiniteScroll<Paginated<TInvoiceExpanded>>(
|
|
46
48
|
(d) => {
|
|
47
|
-
const page = d ? Math.ceil(d.list.length /
|
|
48
|
-
return fetchData({ page, pageSize, status
|
|
49
|
+
const page = d ? Math.ceil(d.list.length / size) + 1 : 1;
|
|
50
|
+
return fetchData({ page, pageSize: size, status, customer_id, subscription_id });
|
|
49
51
|
},
|
|
50
52
|
{
|
|
51
53
|
reloadDeps: [customer_id],
|
|
@@ -84,7 +86,9 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }: Pr
|
|
|
84
86
|
}}
|
|
85
87
|
flexWrap="nowrap">
|
|
86
88
|
<Box flex={3}>
|
|
87
|
-
<a
|
|
89
|
+
<a
|
|
90
|
+
href={joinURL(window.location.origin, getPrefix(), `/customer/invoice/${invoice.id}`)}
|
|
91
|
+
target={target}>
|
|
88
92
|
<Typography component="span">{invoice.number}</Typography>
|
|
89
93
|
</a>
|
|
90
94
|
</Box>
|
|
@@ -115,7 +119,7 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }: Pr
|
|
|
115
119
|
: t('common.loadMore', { resource: t('payment.customer.invoices') })}
|
|
116
120
|
</Button>
|
|
117
121
|
)}
|
|
118
|
-
{!hasMore && data.count >
|
|
122
|
+
{!hasMore && data.count > size && (
|
|
119
123
|
<Typography color="text.secondary">
|
|
120
124
|
{t('common.noMore', { resource: t('payment.customer.invoices') })}
|
|
121
125
|
</Typography>
|
|
@@ -128,4 +132,7 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }: Pr
|
|
|
128
132
|
CustomerInvoiceList.defaultProps = {
|
|
129
133
|
customer_id: '',
|
|
130
134
|
subscription_id: '',
|
|
135
|
+
status: 'open,paid,uncollectible',
|
|
136
|
+
pageSize: 10,
|
|
137
|
+
target: 'self',
|
|
131
138
|
};
|
package/src/locales/en.tsx
CHANGED
|
@@ -152,7 +152,8 @@ export default flat({
|
|
|
152
152
|
customer: {
|
|
153
153
|
payments: 'Payment History',
|
|
154
154
|
invoices: 'Invoice History',
|
|
155
|
-
details: '
|
|
155
|
+
details: 'Details',
|
|
156
|
+
summary: 'Summary',
|
|
156
157
|
update: 'Update Information',
|
|
157
158
|
empty: 'Seems you do not have any subscriptions or payments here',
|
|
158
159
|
cancel: {
|
|
@@ -174,6 +175,14 @@ export default flat({
|
|
|
174
175
|
},
|
|
175
176
|
pastDue: {
|
|
176
177
|
button: 'Pay',
|
|
178
|
+
invoices: 'Past Due Invoices',
|
|
179
|
+
warning: 'Past due invoices need to be paid immediately, otherwise you can not make new purchases anymore.',
|
|
180
|
+
alert: {
|
|
181
|
+
title: 'You have unpaid invoices',
|
|
182
|
+
description:
|
|
183
|
+
'Seems you have unpaid invoices from previous subscriptions, new purchases are not allowed unless you have paid all past due invoices.',
|
|
184
|
+
confirm: 'Pay Now',
|
|
185
|
+
},
|
|
177
186
|
},
|
|
178
187
|
recover: {
|
|
179
188
|
button: 'Renew',
|
|
@@ -212,6 +221,9 @@ export default flat({
|
|
|
212
221
|
payment: {
|
|
213
222
|
empty: 'There are no payments here',
|
|
214
223
|
},
|
|
224
|
+
refund: {
|
|
225
|
+
empty: 'There are no refunds here',
|
|
226
|
+
},
|
|
215
227
|
subscriptions: {
|
|
216
228
|
plan: 'Plan',
|
|
217
229
|
nextInvoice: 'Next Invoice',
|
package/src/locales/zh.tsx
CHANGED
|
@@ -149,7 +149,8 @@ export default flat({
|
|
|
149
149
|
customer: {
|
|
150
150
|
payments: '支付历史',
|
|
151
151
|
invoices: '发票历史',
|
|
152
|
-
details: '
|
|
152
|
+
details: '账户详情',
|
|
153
|
+
summary: '计费摘要',
|
|
153
154
|
update: '更新客户信息',
|
|
154
155
|
empty: '看起来您在这里没有任何订阅或支付',
|
|
155
156
|
cancel: {
|
|
@@ -170,6 +171,13 @@ export default flat({
|
|
|
170
171
|
},
|
|
171
172
|
pastDue: {
|
|
172
173
|
button: '续费',
|
|
174
|
+
invoices: '欠费帐单',
|
|
175
|
+
warning: '请尽快支付欠费账单,否则你将无法继续使用服务或购买新服务',
|
|
176
|
+
alert: {
|
|
177
|
+
title: '你有欠费账单',
|
|
178
|
+
description: '看起来你有欠费的账单,在你支付所有欠费账单之前,新的购买或者订阅将被禁止,请不要调皮。',
|
|
179
|
+
confirm: '去支付',
|
|
180
|
+
},
|
|
173
181
|
},
|
|
174
182
|
recover: {
|
|
175
183
|
button: '续订',
|
|
@@ -206,7 +214,10 @@ export default flat({
|
|
|
206
214
|
empty: '没有任何发票',
|
|
207
215
|
},
|
|
208
216
|
payment: {
|
|
209
|
-
empty: '
|
|
217
|
+
empty: '没有支付记录',
|
|
218
|
+
},
|
|
219
|
+
refund: {
|
|
220
|
+
empty: '没有退款记录',
|
|
210
221
|
},
|
|
211
222
|
subscriptions: {
|
|
212
223
|
plan: '订阅',
|
|
@@ -16,6 +16,7 @@ import { dispatch } from 'use-bus';
|
|
|
16
16
|
import isEmail from 'validator/es/lib/isEmail';
|
|
17
17
|
|
|
18
18
|
import api from '../../api';
|
|
19
|
+
import ConfirmDialog from '../../components/confirm';
|
|
19
20
|
import FormInput from '../../components/input';
|
|
20
21
|
import { usePaymentContext } from '../../contexts/payment';
|
|
21
22
|
import { CheckoutCallbacks, CheckoutContext } from '../../types';
|
|
@@ -104,6 +105,7 @@ export default function PaymentForm({
|
|
|
104
105
|
status: string;
|
|
105
106
|
};
|
|
106
107
|
customer?: TCustomer;
|
|
108
|
+
customerLimited?: boolean;
|
|
107
109
|
stripePaying: boolean;
|
|
108
110
|
}>({
|
|
109
111
|
submitting: false,
|
|
@@ -112,6 +114,7 @@ export default function PaymentForm({
|
|
|
112
114
|
paymentIntent,
|
|
113
115
|
stripeContext: undefined,
|
|
114
116
|
customer,
|
|
117
|
+
customerLimited: false,
|
|
115
118
|
stripePaying: false,
|
|
116
119
|
});
|
|
117
120
|
|
|
@@ -254,10 +257,17 @@ export default function PaymentForm({
|
|
|
254
257
|
}
|
|
255
258
|
}
|
|
256
259
|
} catch (err: any) {
|
|
260
|
+
let shouldToast = true;
|
|
257
261
|
if (err.response?.data?.code) {
|
|
258
262
|
dispatch(`error.${err.response?.data?.code}`);
|
|
263
|
+
if (err.response.data.code === 'CUSTOMER_LIMITED') {
|
|
264
|
+
shouldToast = false;
|
|
265
|
+
setState({ customerLimited: true });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (shouldToast) {
|
|
269
|
+
Toast.error(formatError(err));
|
|
259
270
|
}
|
|
260
|
-
Toast.error(formatError(err));
|
|
261
271
|
} finally {
|
|
262
272
|
setState({ submitting: false });
|
|
263
273
|
}
|
|
@@ -415,6 +425,17 @@ export default function PaymentForm({
|
|
|
415
425
|
)}
|
|
416
426
|
</Stack>
|
|
417
427
|
</Fade>
|
|
428
|
+
{state.customerLimited && (
|
|
429
|
+
<ConfirmDialog
|
|
430
|
+
onConfirm={() =>
|
|
431
|
+
window.open(joinURL(window.location.origin, getPrefix(), '/customer/invoice/past-due'), '_blank')
|
|
432
|
+
}
|
|
433
|
+
onCancel={() => setState({ customerLimited: false })}
|
|
434
|
+
confirm={t('payment.customer.pastDue.alert.confirm')}
|
|
435
|
+
title={t('payment.customer.pastDue.alert.title')}
|
|
436
|
+
message={t('payment.customer.pastDue.alert.description')}
|
|
437
|
+
/>
|
|
438
|
+
)}
|
|
418
439
|
</>
|
|
419
440
|
);
|
|
420
441
|
}
|