payment-kit 1.13.239 → 1.13.241
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/api/src/crons/base.ts +8 -5
- package/api/src/crons/subscription-will-canceled.ts +5 -1
- package/api/src/crons/subscription-will-renew.ts +0 -1
- package/api/src/index.ts +3 -0
- package/api/src/libs/env.ts +1 -0
- package/api/src/libs/invoice.ts +6 -5
- package/api/src/libs/notification/template/one-time-payment-succeeded.ts +10 -4
- package/api/src/libs/notification/template/subscription-canceled.ts +10 -6
- package/api/src/libs/notification/template/subscription-refund-succeeded.ts +9 -3
- package/api/src/libs/notification/template/subscription-renew-failed.ts +13 -6
- package/api/src/libs/notification/template/subscription-renewed.ts +11 -4
- package/api/src/libs/notification/template/subscription-succeeded.ts +10 -4
- package/api/src/libs/notification/template/subscription-trial-start.ts +2 -2
- package/api/src/libs/notification/template/subscription-trial-will-end.ts +1 -1
- package/api/src/libs/notification/template/subscription-upgraded.ts +10 -4
- package/api/src/libs/notification/template/subscription-will-canceled.ts +2 -2
- package/api/src/libs/notification/template/subscription-will-renew.ts +23 -2
- package/api/src/libs/payment.ts +7 -6
- package/api/src/libs/subscription.ts +5 -5
- package/api/src/libs/util.ts +13 -6
- package/api/src/libs/ws.ts +25 -0
- package/api/src/locales/en.ts +26 -29
- package/api/src/locales/zh.ts +24 -24
- package/api/src/queues/notification.ts +9 -0
- package/api/src/queues/payment.ts +2 -2
- package/api/src/queues/usage-record.ts +11 -2
- package/api/src/routes/usage-records.ts +8 -1
- package/api/src/store/models/subscription.ts +2 -0
- package/blocklet.yml +1 -1
- package/package.json +35 -35
- package/src/components/invoice/table.tsx +103 -62
- package/src/components/subscription/items/usage-records.tsx +64 -13
- package/src/components/subscription/portal/list.tsx +4 -3
- package/src/pages/customer/index.tsx +24 -3
- package/src/pages/customer/invoice/detail.tsx +28 -31
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
2
|
import { formatAmount, formatToDate, getPriceUintAmountByCurrency } from '@blocklet/payment-react';
|
|
3
|
-
import type { TInvoiceExpanded } from '@blocklet/payment-types';
|
|
3
|
+
import type { TInvoiceExpanded, TInvoiceItem } from '@blocklet/payment-types';
|
|
4
4
|
import { InfoOutlined } from '@mui/icons-material';
|
|
5
|
-
import { Stack, Table, TableBody, TableCell, TableHead, TableRow, Tooltip, Typography } from '@mui/material';
|
|
5
|
+
import { Box, Stack, Table, TableBody, TableCell, TableHead, TableRow, Tooltip, Typography } from '@mui/material';
|
|
6
6
|
import { styled } from '@mui/system';
|
|
7
7
|
import { toBN } from '@ocap/util';
|
|
8
|
+
import { useSetState } from 'ahooks';
|
|
8
9
|
|
|
9
10
|
import LineItemActions from '../subscription/items/actions';
|
|
11
|
+
import { UsageRecordDialog } from '../subscription/items/usage-records';
|
|
10
12
|
|
|
11
13
|
type Props = {
|
|
12
14
|
invoice: TInvoiceExpanded;
|
|
@@ -20,6 +22,7 @@ type InvoiceDetailItem = {
|
|
|
20
22
|
rawQuantity: number;
|
|
21
23
|
price: string;
|
|
22
24
|
amount: string;
|
|
25
|
+
raw: TInvoiceItem;
|
|
23
26
|
};
|
|
24
27
|
|
|
25
28
|
type InvoiceSummaryItem = {
|
|
@@ -61,6 +64,7 @@ export function getInvoiceRows(invoice: TInvoiceExpanded) {
|
|
|
61
64
|
? formatAmount(getPriceUintAmountByCurrency(line.price, invoice.paymentCurrency) || line.amount, invoice.paymentCurrency.decimal) // prettier-ignore
|
|
62
65
|
: '',
|
|
63
66
|
amount: formatAmount(line.amount, invoice.paymentCurrency.decimal),
|
|
67
|
+
raw: line,
|
|
64
68
|
}));
|
|
65
69
|
|
|
66
70
|
const summary: InvoiceSummaryItem[] = [
|
|
@@ -106,75 +110,112 @@ export function getInvoiceRows(invoice: TInvoiceExpanded) {
|
|
|
106
110
|
export default function InvoiceTable({ invoice, simple }: Props) {
|
|
107
111
|
const { t } = useLocaleContext();
|
|
108
112
|
const { detail, summary } = getInvoiceRows(invoice);
|
|
113
|
+
const [state, setState] = useSetState({
|
|
114
|
+
subscriptionId: '',
|
|
115
|
+
subscriptionItemId: '',
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const onOpenUsageRecords = (line: InvoiceDetailItem) => {
|
|
119
|
+
if (line.rawQuantity && line.raw.subscription_id && line.raw.subscription_item_id) {
|
|
120
|
+
setState({
|
|
121
|
+
subscriptionId: line.raw.subscription_id,
|
|
122
|
+
subscriptionItemId: line.raw.subscription_item_id,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const onCloseUsageRecords = () => {
|
|
128
|
+
setState({
|
|
129
|
+
subscriptionId: '',
|
|
130
|
+
subscriptionItemId: '',
|
|
131
|
+
});
|
|
132
|
+
};
|
|
109
133
|
|
|
110
134
|
return (
|
|
111
|
-
<
|
|
112
|
-
<
|
|
113
|
-
<
|
|
114
|
-
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal' }}>Description</TableCell>
|
|
115
|
-
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 80 }} align="right">
|
|
116
|
-
{t('common.quantity')}
|
|
117
|
-
</TableCell>
|
|
118
|
-
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 120 }} align="right">
|
|
119
|
-
{t('payment.customer.invoice.unitPrice')}
|
|
120
|
-
</TableCell>
|
|
121
|
-
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 110 }} align="right">
|
|
122
|
-
{t('common.amount')}
|
|
123
|
-
</TableCell>
|
|
124
|
-
{!simple && (
|
|
125
|
-
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 50 }} align="right">
|
|
126
|
-
|
|
127
|
-
</TableCell>
|
|
128
|
-
)}
|
|
129
|
-
</TableRow>
|
|
130
|
-
{invoice.period_end > 0 && invoice.period_start > 0 && (
|
|
135
|
+
<Box>
|
|
136
|
+
<StyledTable>
|
|
137
|
+
<TableHead>
|
|
131
138
|
<TableRow sx={{ borderBottom: '1px solid #eee' }}>
|
|
132
|
-
<TableCell
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
</Typography>
|
|
139
|
+
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal' }}>Description</TableCell>
|
|
140
|
+
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 80 }} align="right">
|
|
141
|
+
{t('common.quantity')}
|
|
136
142
|
</TableCell>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<TableRow key={line.id} sx={{ borderBottom: '1px solid #eee' }}>
|
|
143
|
-
<TableCell sx={{ fontWeight: 600 }}>{line.product}</TableCell>
|
|
144
|
-
<TableCell align="right">
|
|
145
|
-
<Stack direction="row" spacing={0.5} alignItems="center" justifyContent="flex-end">
|
|
146
|
-
<Typography>{line.quantity}</Typography>
|
|
147
|
-
{!!line.rawQuantity && (
|
|
148
|
-
<Tooltip
|
|
149
|
-
title={t('payment.customer.invoice.rawQuantity', { quantity: line.rawQuantity })}
|
|
150
|
-
placement="top">
|
|
151
|
-
<InfoOutlined fontSize="small" sx={{ color: 'text.secondary', cursor: 'pointer' }} />
|
|
152
|
-
</Tooltip>
|
|
153
|
-
)}
|
|
154
|
-
</Stack>
|
|
143
|
+
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 120 }} align="right">
|
|
144
|
+
{t('payment.customer.invoice.unitPrice')}
|
|
145
|
+
</TableCell>
|
|
146
|
+
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 110 }} align="right">
|
|
147
|
+
{t('common.amount')}
|
|
155
148
|
</TableCell>
|
|
156
|
-
<TableCell align="right">{line.price}</TableCell>
|
|
157
|
-
<TableCell align="right">{line.amount}</TableCell>
|
|
158
149
|
{!simple && (
|
|
159
|
-
<TableCell align="right">
|
|
160
|
-
|
|
150
|
+
<TableCell sx={{ textTransform: 'none', fontWeight: 'normal', width: 50 }} align="right">
|
|
151
|
+
|
|
161
152
|
</TableCell>
|
|
162
153
|
)}
|
|
163
154
|
</TableRow>
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
155
|
+
{invoice.period_end > 0 && invoice.period_start > 0 && (
|
|
156
|
+
<TableRow sx={{ borderBottom: '1px solid #eee' }}>
|
|
157
|
+
<TableCell align="left" colSpan={simple ? 4 : 5}>
|
|
158
|
+
<Typography component="span" variant="body1" color="text.secondary">
|
|
159
|
+
{formatToDate(invoice.period_start * 1000)} - {formatToDate(invoice.period_end * 1000)}
|
|
160
|
+
</Typography>
|
|
161
|
+
</TableCell>
|
|
162
|
+
</TableRow>
|
|
163
|
+
)}
|
|
164
|
+
</TableHead>
|
|
165
|
+
<TableBody>
|
|
166
|
+
{detail.map((line) => (
|
|
167
|
+
<TableRow key={line.id} sx={{ borderBottom: '1px solid #eee' }}>
|
|
168
|
+
<TableCell sx={{ fontWeight: 600 }}>{line.product}</TableCell>
|
|
169
|
+
<TableCell align="right">
|
|
170
|
+
<Stack
|
|
171
|
+
direction="row"
|
|
172
|
+
spacing={0.5}
|
|
173
|
+
alignItems="center"
|
|
174
|
+
justifyContent="flex-end"
|
|
175
|
+
sx={{ cursor: 'pointer' }}
|
|
176
|
+
onClick={() => onOpenUsageRecords(line)}>
|
|
177
|
+
<Typography component="span">{line.quantity}</Typography>
|
|
178
|
+
{!!line.rawQuantity && (
|
|
179
|
+
<Tooltip
|
|
180
|
+
title={t('payment.customer.invoice.rawQuantity', { quantity: line.rawQuantity })}
|
|
181
|
+
placement="top">
|
|
182
|
+
<InfoOutlined fontSize="small" sx={{ color: 'text.secondary', cursor: 'pointer' }} />
|
|
183
|
+
</Tooltip>
|
|
184
|
+
)}
|
|
185
|
+
</Stack>
|
|
186
|
+
</TableCell>
|
|
187
|
+
<TableCell align="right">{line.price}</TableCell>
|
|
188
|
+
<TableCell align="right">{line.amount}</TableCell>
|
|
189
|
+
{!simple && (
|
|
190
|
+
<TableCell align="right">
|
|
191
|
+
<LineItemActions data={line as any} />
|
|
192
|
+
</TableCell>
|
|
193
|
+
)}
|
|
194
|
+
</TableRow>
|
|
195
|
+
))}
|
|
196
|
+
{summary.map((line) => (
|
|
197
|
+
<TableRow key={line.key}>
|
|
198
|
+
<TableCell colSpan={3} align="right" sx={{ fontWeight: 600, color: line.color }}>
|
|
199
|
+
{t(line.key)}
|
|
200
|
+
</TableCell>
|
|
201
|
+
<TableCell align="right" sx={{ fontWeight: 600 }}>
|
|
202
|
+
{line.value}
|
|
203
|
+
</TableCell>
|
|
204
|
+
<TableCell> </TableCell>
|
|
205
|
+
</TableRow>
|
|
206
|
+
))}
|
|
207
|
+
</TableBody>
|
|
208
|
+
</StyledTable>
|
|
209
|
+
{state.subscriptionId && state.subscriptionItemId && (
|
|
210
|
+
<UsageRecordDialog
|
|
211
|
+
subscriptionId={state.subscriptionId}
|
|
212
|
+
id={state.subscriptionItemId}
|
|
213
|
+
onConfirm={onCloseUsageRecords}
|
|
214
|
+
start={invoice.period_start}
|
|
215
|
+
end={invoice.period_end}
|
|
216
|
+
/>
|
|
217
|
+
)}
|
|
218
|
+
</Box>
|
|
178
219
|
);
|
|
179
220
|
}
|
|
180
221
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
1
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
3
|
import { ConfirmDialog, api } from '@blocklet/payment-react';
|
|
3
4
|
import type { TUsageRecord } from '@blocklet/payment-types';
|
|
@@ -5,12 +6,26 @@ import { Alert, Box, Button, CircularProgress } from '@mui/material';
|
|
|
5
6
|
import { useRequest } from 'ahooks';
|
|
6
7
|
import { useState } from 'react';
|
|
7
8
|
import { Bar, BarChart, Rectangle, Tooltip, XAxis, YAxis } from 'recharts';
|
|
9
|
+
import { withQuery } from 'ufo';
|
|
8
10
|
|
|
9
11
|
import { stringToColor } from '../../../libs/util';
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
// FIXME: pagination here
|
|
14
|
+
const fetchData = (
|
|
15
|
+
subscriptionId: string,
|
|
16
|
+
id: string,
|
|
17
|
+
start: number = 0,
|
|
18
|
+
end: number = 0
|
|
19
|
+
): Promise<{ list: TUsageRecord[]; count: number }> => {
|
|
12
20
|
return api
|
|
13
|
-
.get(
|
|
21
|
+
.get(
|
|
22
|
+
withQuery(`/api/subscriptions/${subscriptionId}/usage-records`, {
|
|
23
|
+
subscription_item_id: id,
|
|
24
|
+
pageSize: 100,
|
|
25
|
+
start,
|
|
26
|
+
end,
|
|
27
|
+
})
|
|
28
|
+
)
|
|
14
29
|
.then((res) => res.data);
|
|
15
30
|
};
|
|
16
31
|
|
|
@@ -19,10 +34,22 @@ const colors = {
|
|
|
19
34
|
active: stringToColor('active'),
|
|
20
35
|
};
|
|
21
36
|
|
|
22
|
-
export function UsageRecordDialog(
|
|
37
|
+
export function UsageRecordDialog({
|
|
38
|
+
subscriptionId,
|
|
39
|
+
id,
|
|
40
|
+
onConfirm,
|
|
41
|
+
start = 0,
|
|
42
|
+
end = 0,
|
|
43
|
+
}: {
|
|
44
|
+
subscriptionId: string;
|
|
45
|
+
id: string;
|
|
46
|
+
onConfirm: any;
|
|
47
|
+
start?: number;
|
|
48
|
+
end?: number;
|
|
49
|
+
}) {
|
|
23
50
|
const { t } = useLocaleContext();
|
|
24
|
-
const { loading, error, data } = useRequest(() => fetchData(
|
|
25
|
-
refreshDeps: [
|
|
51
|
+
const { loading, error, data } = useRequest(() => fetchData(subscriptionId, id, start, end), {
|
|
52
|
+
refreshDeps: [subscriptionId, id, start, end],
|
|
26
53
|
});
|
|
27
54
|
|
|
28
55
|
if (error) {
|
|
@@ -30,8 +57,10 @@ export function UsageRecordDialog(props: { subscriptionId: string; id: string; o
|
|
|
30
57
|
<ConfirmDialog
|
|
31
58
|
title={t('admin.subscription.usage.current')}
|
|
32
59
|
message={<Alert severity="error">{error.message}</Alert>}
|
|
33
|
-
onConfirm={
|
|
34
|
-
onCancel={
|
|
60
|
+
onConfirm={onConfirm}
|
|
61
|
+
onCancel={onConfirm}
|
|
62
|
+
color="primary"
|
|
63
|
+
cancel={false}
|
|
35
64
|
/>
|
|
36
65
|
);
|
|
37
66
|
}
|
|
@@ -41,8 +70,10 @@ export function UsageRecordDialog(props: { subscriptionId: string; id: string; o
|
|
|
41
70
|
<ConfirmDialog
|
|
42
71
|
title={t('admin.subscription.usage.current')}
|
|
43
72
|
message={<CircularProgress />}
|
|
44
|
-
onConfirm={
|
|
45
|
-
onCancel={
|
|
73
|
+
onConfirm={onConfirm}
|
|
74
|
+
onCancel={onConfirm}
|
|
75
|
+
color="primary"
|
|
76
|
+
cancel={false}
|
|
46
77
|
/>
|
|
47
78
|
);
|
|
48
79
|
}
|
|
@@ -70,13 +101,25 @@ export function UsageRecordDialog(props: { subscriptionId: string; id: string; o
|
|
|
70
101
|
<YAxis mirror />
|
|
71
102
|
</BarChart>
|
|
72
103
|
}
|
|
73
|
-
onConfirm={
|
|
74
|
-
onCancel={
|
|
104
|
+
onConfirm={onConfirm}
|
|
105
|
+
onCancel={onConfirm}
|
|
106
|
+
color="primary"
|
|
107
|
+
cancel={false}
|
|
75
108
|
/>
|
|
76
109
|
);
|
|
77
110
|
}
|
|
78
111
|
|
|
79
|
-
export default function UsageRecords({
|
|
112
|
+
export default function UsageRecords({
|
|
113
|
+
subscriptionId,
|
|
114
|
+
id,
|
|
115
|
+
start = 0,
|
|
116
|
+
end = 0,
|
|
117
|
+
}: {
|
|
118
|
+
subscriptionId: string;
|
|
119
|
+
id: string;
|
|
120
|
+
start?: number;
|
|
121
|
+
end?: number;
|
|
122
|
+
}) {
|
|
80
123
|
const { t } = useLocaleContext();
|
|
81
124
|
const [open, setOpen] = useState(false);
|
|
82
125
|
return (
|
|
@@ -84,7 +127,15 @@ export default function UsageRecords({ subscriptionId, id }: { subscriptionId: s
|
|
|
84
127
|
<Button size="small" variant="text" color="info" onClick={() => setOpen(true)}>
|
|
85
128
|
{t('admin.subscription.usage.view')}
|
|
86
129
|
</Button>
|
|
87
|
-
{open &&
|
|
130
|
+
{open && (
|
|
131
|
+
<UsageRecordDialog
|
|
132
|
+
subscriptionId={subscriptionId}
|
|
133
|
+
id={id}
|
|
134
|
+
start={start}
|
|
135
|
+
end={end}
|
|
136
|
+
onConfirm={() => setOpen(false)}
|
|
137
|
+
/>
|
|
138
|
+
)}
|
|
88
139
|
</Box>
|
|
89
140
|
);
|
|
90
141
|
}
|
|
@@ -24,22 +24,23 @@ const fetchData = (params: Record<string, any> = {}): Promise<Paginated<TSubscri
|
|
|
24
24
|
|
|
25
25
|
type Props = {
|
|
26
26
|
id: string;
|
|
27
|
+
status: string;
|
|
27
28
|
onChange?: (action?: string) => any | Promise<any>;
|
|
28
29
|
onClickSubscription: (subscription: TSubscriptionExpanded) => void | Promise<void>;
|
|
29
30
|
} & Omit<StackProps, 'onChange'>;
|
|
30
31
|
|
|
31
32
|
const pageSize = 4;
|
|
32
33
|
|
|
33
|
-
export default function CurrentSubscriptions({ id, onChange, onClickSubscription, ...rest }: Props) {
|
|
34
|
+
export default function CurrentSubscriptions({ id, status, onChange, onClickSubscription, ...rest }: Props) {
|
|
34
35
|
const { t } = useLocaleContext();
|
|
35
36
|
|
|
36
37
|
const { data, loadMore, loadingMore, loading } = useInfiniteScroll<Paginated<TSubscriptionExpanded>>(
|
|
37
38
|
(d) => {
|
|
38
39
|
const page = d ? Math.ceil(d.list.length / pageSize) + 1 : 1;
|
|
39
|
-
return fetchData({ page, pageSize, status
|
|
40
|
+
return fetchData({ page, pageSize, status, customer_id: id });
|
|
40
41
|
},
|
|
41
42
|
{
|
|
42
|
-
reloadDeps: [id],
|
|
43
|
+
reloadDeps: [id, status],
|
|
43
44
|
}
|
|
44
45
|
);
|
|
45
46
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DID from '@arcblock/ux/lib/DID';
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
3
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
|
-
import { CustomerInvoiceList, formatError, getPrefix, usePaymentContext } from '@blocklet/payment-react';
|
|
4
|
+
import { CustomerInvoiceList, Switch, formatError, getPrefix, usePaymentContext } from '@blocklet/payment-react';
|
|
5
5
|
import type { GroupedBN, TCustomerExpanded } from '@blocklet/payment-types';
|
|
6
6
|
import { Edit } from '@mui/icons-material';
|
|
7
7
|
import { Alert, Box, Button, CircularProgress, Grid, Stack, Tooltip } from '@mui/material';
|
|
@@ -33,7 +33,7 @@ export default function CustomerHome() {
|
|
|
33
33
|
const { t } = useLocaleContext();
|
|
34
34
|
const { events } = useSessionContext();
|
|
35
35
|
const { livemode, setLivemode } = usePaymentContext();
|
|
36
|
-
const [state, setState] = useSetState({ editing: false, loading: false });
|
|
36
|
+
const [state, setState] = useSetState({ editing: false, loading: false, onlyActive: true });
|
|
37
37
|
const navigate = useNavigate();
|
|
38
38
|
const { isPending, startTransition } = useTransitionContext();
|
|
39
39
|
|
|
@@ -84,6 +84,10 @@ export default function CustomerHome() {
|
|
|
84
84
|
}
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
+
const onToggleActive = () => {
|
|
88
|
+
setState({ onlyActive: !state.onlyActive });
|
|
89
|
+
};
|
|
90
|
+
|
|
87
91
|
return (
|
|
88
92
|
<>
|
|
89
93
|
<ProgressBar pending={isPending} />
|
|
@@ -91,10 +95,27 @@ export default function CustomerHome() {
|
|
|
91
95
|
<Grid item xs={12} md={8}>
|
|
92
96
|
<Root direction="column" spacing={3} sx={{ my: 2 }}>
|
|
93
97
|
<Box className="section">
|
|
94
|
-
<SectionHeader title={t('payment.customer.subscriptions.current')} mb={0}
|
|
98
|
+
<SectionHeader title={t('payment.customer.subscriptions.current')} mb={0}>
|
|
99
|
+
<label
|
|
100
|
+
htmlFor="only-active-switch"
|
|
101
|
+
style={{
|
|
102
|
+
fontSize: 14,
|
|
103
|
+
fontWeight: 600,
|
|
104
|
+
cursor: 'pointer',
|
|
105
|
+
}}>
|
|
106
|
+
{t('payment.customer.subscriptions.viewAll')}
|
|
107
|
+
<Switch
|
|
108
|
+
id="only-active-switch"
|
|
109
|
+
sx={{ ml: 0.5 }}
|
|
110
|
+
checked={!state.onlyActive}
|
|
111
|
+
onChange={onToggleActive}
|
|
112
|
+
/>
|
|
113
|
+
</label>
|
|
114
|
+
</SectionHeader>
|
|
95
115
|
<Box className="section-body">
|
|
96
116
|
<CurrentSubscriptions
|
|
97
117
|
id={data.id}
|
|
118
|
+
status={state.onlyActive ? 'active,trialing' : 'active,trialing,paused,past_due,canceled'}
|
|
98
119
|
style={{
|
|
99
120
|
cursor: 'pointer',
|
|
100
121
|
}}
|
|
@@ -45,36 +45,30 @@ export default function CustomerInvoiceDetail() {
|
|
|
45
45
|
const action = searchParams.get('action');
|
|
46
46
|
|
|
47
47
|
const onPay = () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
});
|
|
73
|
-
} catch (err) {
|
|
74
|
-
Toast.error(formatError(err));
|
|
75
|
-
} finally {
|
|
76
|
-
setState({ paying: false });
|
|
77
|
-
}
|
|
48
|
+
setState({ paying: true });
|
|
49
|
+
connectApi.open({
|
|
50
|
+
action: 'collect',
|
|
51
|
+
messages: {
|
|
52
|
+
scan: '',
|
|
53
|
+
title: t(`payment.customer.invoice.${action || 'pay'}`),
|
|
54
|
+
success: t(`payment.customer.invoice.${action || 'pay'}Success`),
|
|
55
|
+
error: t(`payment.customer.invoice.${action || 'pay'}Error`),
|
|
56
|
+
confirm: '',
|
|
57
|
+
} as any,
|
|
58
|
+
extraParams: { invoiceId: params.id, action },
|
|
59
|
+
onSuccess: async () => {
|
|
60
|
+
connectApi.close();
|
|
61
|
+
await runAsync();
|
|
62
|
+
},
|
|
63
|
+
onClose: () => {
|
|
64
|
+
connectApi.close();
|
|
65
|
+
setState({ paying: false });
|
|
66
|
+
},
|
|
67
|
+
onError: (err: any) => {
|
|
68
|
+
setState({ paying: false });
|
|
69
|
+
Toast.error(formatError(err));
|
|
70
|
+
},
|
|
71
|
+
});
|
|
78
72
|
};
|
|
79
73
|
|
|
80
74
|
const closePay = () => {
|
|
@@ -86,7 +80,10 @@ export default function CustomerInvoiceDetail() {
|
|
|
86
80
|
// @ts-expect-error
|
|
87
81
|
if (error?.response?.status === 403) {
|
|
88
82
|
closePay();
|
|
89
|
-
} else if (
|
|
83
|
+
} else if (
|
|
84
|
+
['pay', 'renew'].includes(action as string) &&
|
|
85
|
+
['open', 'uncollectible'].includes(data?.status as string)
|
|
86
|
+
) {
|
|
90
87
|
onPay();
|
|
91
88
|
}
|
|
92
89
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|