payment-kit 1.18.56 → 1.19.1
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/.eslintrc.js +6 -0
- package/api/src/crons/index.ts +8 -0
- package/api/src/index.ts +4 -0
- package/api/src/libs/credit-grant.ts +146 -0
- package/api/src/libs/env.ts +1 -0
- package/api/src/libs/invoice.ts +4 -3
- package/api/src/libs/notification/template/base.ts +388 -2
- package/api/src/libs/notification/template/customer-credit-grant-granted.ts +149 -0
- package/api/src/libs/notification/template/customer-credit-grant-low-balance.ts +151 -0
- package/api/src/libs/notification/template/customer-credit-insufficient.ts +254 -0
- package/api/src/libs/notification/template/subscription-canceled.ts +193 -202
- package/api/src/libs/notification/template/subscription-refund-succeeded.ts +215 -237
- package/api/src/libs/notification/template/subscription-renewed.ts +130 -200
- package/api/src/libs/notification/template/subscription-succeeded.ts +100 -202
- package/api/src/libs/notification/template/subscription-trial-start.ts +142 -188
- package/api/src/libs/notification/template/subscription-trial-will-end.ts +146 -174
- package/api/src/libs/notification/template/subscription-upgraded.ts +96 -192
- package/api/src/libs/notification/template/subscription-will-canceled.ts +94 -135
- package/api/src/libs/notification/template/subscription-will-renew.ts +220 -245
- package/api/src/libs/payment.ts +69 -0
- package/api/src/libs/queue/index.ts +3 -2
- package/api/src/libs/session.ts +8 -0
- package/api/src/libs/subscription.ts +74 -3
- package/api/src/libs/ws.ts +23 -1
- package/api/src/locales/en.ts +33 -0
- package/api/src/locales/zh.ts +31 -0
- package/api/src/queues/credit-consume.ts +715 -0
- package/api/src/queues/credit-grant.ts +572 -0
- package/api/src/queues/notification.ts +173 -128
- package/api/src/queues/payment.ts +210 -122
- package/api/src/queues/subscription.ts +179 -0
- package/api/src/routes/checkout-sessions.ts +157 -9
- package/api/src/routes/connect/shared.ts +3 -2
- package/api/src/routes/credit-grants.ts +241 -0
- package/api/src/routes/credit-transactions.ts +208 -0
- package/api/src/routes/index.ts +8 -0
- package/api/src/routes/meter-events.ts +347 -0
- package/api/src/routes/meters.ts +219 -0
- package/api/src/routes/payment-currencies.ts +14 -2
- package/api/src/routes/payment-links.ts +1 -1
- package/api/src/routes/payment-methods.ts +14 -2
- package/api/src/routes/prices.ts +43 -0
- package/api/src/routes/pricing-table.ts +13 -7
- package/api/src/routes/products.ts +63 -4
- package/api/src/routes/settings.ts +1 -1
- package/api/src/routes/subscriptions.ts +4 -0
- package/api/src/store/migrations/20250610-billing-credit.ts +43 -0
- package/api/src/store/models/credit-grant.ts +486 -0
- package/api/src/store/models/credit-transaction.ts +268 -0
- package/api/src/store/models/customer.ts +8 -0
- package/api/src/store/models/index.ts +52 -1
- package/api/src/store/models/meter-event.ts +423 -0
- package/api/src/store/models/meter.ts +176 -0
- package/api/src/store/models/payment-currency.ts +66 -14
- package/api/src/store/models/price.ts +6 -0
- package/api/src/store/models/product.ts +2 -2
- package/api/src/store/models/subscription.ts +24 -0
- package/api/src/store/models/types.ts +28 -2
- package/api/tests/libs/subscription.spec.ts +53 -0
- package/blocklet.yml +9 -1
- package/package.json +57 -58
- package/scripts/sdk.js +233 -1
- package/src/app.tsx +10 -0
- package/src/components/actions.tsx +22 -9
- package/src/components/balance-list.tsx +40 -12
- package/src/components/collapse.tsx +33 -15
- package/src/components/copyable.tsx +8 -7
- package/src/components/currency.tsx +15 -7
- package/src/components/customer/actions.tsx +1 -5
- package/src/components/customer/credit-grant-item-list.tsx +99 -0
- package/src/components/customer/credit-overview.tsx +233 -0
- package/src/components/customer/form.tsx +7 -2
- package/src/components/customer/link.tsx +4 -12
- package/src/components/customer/notification-preference.tsx +18 -9
- package/src/components/customer/overdraft-protection.tsx +112 -41
- package/src/components/drawer-form.tsx +42 -18
- package/src/components/error.tsx +1 -5
- package/src/components/event/list.tsx +9 -10
- package/src/components/filter-toolbar.tsx +20 -19
- package/src/components/info-card.tsx +32 -18
- package/src/components/info-metric.tsx +16 -6
- package/src/components/info-row-group.tsx +1 -7
- package/src/components/info-row.tsx +30 -24
- package/src/components/invoice/action.tsx +1 -7
- package/src/components/invoice/list.tsx +34 -26
- package/src/components/invoice/recharge.tsx +5 -7
- package/src/components/invoice/table.tsx +17 -12
- package/src/components/layout/user.tsx +1 -1
- package/src/components/metadata/form.tsx +290 -94
- package/src/components/metadata/list.tsx +11 -3
- package/src/components/meter/actions.tsx +101 -0
- package/src/components/meter/add-usage-dialog.tsx +239 -0
- package/src/components/meter/events-list.tsx +657 -0
- package/src/components/meter/form.tsx +245 -0
- package/src/components/meter/products.tsx +264 -0
- package/src/components/meter/usage-guide.tsx +174 -0
- package/src/components/passport/actions.tsx +9 -4
- package/src/components/payment-currency/add.tsx +16 -3
- package/src/components/payment-currency/form.tsx +14 -6
- package/src/components/payment-intent/actions.tsx +24 -16
- package/src/components/payment-intent/list.tsx +30 -9
- package/src/components/payment-link/actions.tsx +1 -5
- package/src/components/payment-link/after-pay.tsx +4 -2
- package/src/components/payment-link/before-pay.tsx +14 -4
- package/src/components/payment-link/item.tsx +27 -6
- package/src/components/payment-link/preview.tsx +9 -9
- package/src/components/payment-link/product-select.tsx +69 -15
- package/src/components/payment-method/arcblock.tsx +8 -1
- package/src/components/payment-method/base.tsx +8 -1
- package/src/components/payment-method/bitcoin.tsx +8 -1
- package/src/components/payment-method/ethereum.tsx +8 -1
- package/src/components/payment-method/evm-rpc-input.tsx +11 -7
- package/src/components/payment-method/form.tsx +2 -7
- package/src/components/payment-method/stripe.tsx +2 -0
- package/src/components/payouts/actions.tsx +1 -5
- package/src/components/payouts/list.tsx +30 -10
- package/src/components/payouts/portal/list.tsx +11 -9
- package/src/components/price/currency-select.tsx +63 -32
- package/src/components/price/form.tsx +895 -370
- package/src/components/price/upsell-select.tsx +10 -2
- package/src/components/price/upsell.tsx +7 -2
- package/src/components/pricing-table/actions.tsx +1 -5
- package/src/components/pricing-table/customer-settings.tsx +5 -1
- package/src/components/pricing-table/payment-settings.tsx +14 -4
- package/src/components/pricing-table/preview.tsx +9 -9
- package/src/components/pricing-table/price-item.tsx +6 -1
- package/src/components/pricing-table/product-item.tsx +6 -1
- package/src/components/pricing-table/product-settings.tsx +17 -4
- package/src/components/product/actions.tsx +1 -5
- package/src/components/product/add-price.tsx +9 -7
- package/src/components/product/create.tsx +8 -9
- package/src/components/product/cross-sell-select.tsx +5 -1
- package/src/components/product/cross-sell.tsx +7 -2
- package/src/components/product/edit-price.tsx +21 -12
- package/src/components/product/features.tsx +26 -6
- package/src/components/product/form.tsx +115 -72
- package/src/components/progress-bar.tsx +1 -1
- package/src/components/refund/actions.tsx +1 -7
- package/src/components/refund/list.tsx +31 -18
- package/src/components/section/header.tsx +12 -14
- package/src/components/subscription/actions/cancel.tsx +22 -5
- package/src/components/subscription/actions/index.tsx +9 -10
- package/src/components/subscription/actions/pause.tsx +32 -6
- package/src/components/subscription/actions/slash-stake.tsx +5 -3
- package/src/components/subscription/description.tsx +12 -8
- package/src/components/subscription/items/index.tsx +31 -16
- package/src/components/subscription/items/usage-records.tsx +19 -5
- package/src/components/subscription/list.tsx +5 -7
- package/src/components/subscription/metrics.tsx +62 -15
- package/src/components/subscription/portal/actions.tsx +78 -71
- package/src/components/subscription/portal/cancel.tsx +10 -3
- package/src/components/subscription/portal/list.tsx +48 -26
- package/src/components/uploader.tsx +5 -13
- package/src/components/webhook/attempts.tsx +51 -16
- package/src/components/webhook/request-info.tsx +8 -6
- package/src/contexts/products.tsx +27 -10
- package/src/hooks/subscription.ts +34 -0
- package/src/libs/meter-utils.ts +196 -0
- package/src/libs/util.ts +4 -0
- package/src/locales/en.tsx +385 -4
- package/src/locales/zh.tsx +364 -0
- package/src/pages/admin/billing/index.tsx +61 -33
- package/src/pages/admin/billing/invoices/detail.tsx +49 -13
- package/src/pages/admin/billing/meters/create.tsx +60 -0
- package/src/pages/admin/billing/meters/detail.tsx +435 -0
- package/src/pages/admin/billing/meters/index.tsx +210 -0
- package/src/pages/admin/billing/meters/meter-event.tsx +346 -0
- package/src/pages/admin/billing/subscriptions/detail.tsx +90 -25
- package/src/pages/admin/customers/customers/credit-grant/detail.tsx +391 -0
- package/src/pages/admin/customers/customers/detail.tsx +67 -14
- package/src/pages/admin/customers/customers/index.tsx +6 -1
- package/src/pages/admin/customers/index.tsx +5 -0
- package/src/pages/admin/developers/events/detail.tsx +37 -11
- package/src/pages/admin/developers/index.tsx +1 -1
- package/src/pages/admin/developers/webhooks/detail.tsx +41 -11
- package/src/pages/admin/index.tsx +15 -2
- package/src/pages/admin/overview.tsx +107 -19
- package/src/pages/admin/payments/intents/detail.tsx +58 -14
- package/src/pages/admin/payments/payouts/detail.tsx +63 -15
- package/src/pages/admin/payments/refunds/detail.tsx +58 -14
- package/src/pages/admin/products/index.tsx +11 -4
- package/src/pages/admin/products/links/create.tsx +22 -4
- package/src/pages/admin/products/links/detail.tsx +43 -14
- package/src/pages/admin/products/passports/index.tsx +23 -4
- package/src/pages/admin/products/prices/actions.tsx +16 -9
- package/src/pages/admin/products/prices/detail.tsx +73 -14
- package/src/pages/admin/products/prices/list.tsx +15 -3
- package/src/pages/admin/products/pricing-tables/create.tsx +45 -12
- package/src/pages/admin/products/pricing-tables/detail.tsx +45 -14
- package/src/pages/admin/products/products/create.tsx +233 -54
- package/src/pages/admin/products/products/detail.tsx +74 -18
- package/src/pages/admin/settings/index.tsx +8 -1
- package/src/pages/admin/settings/payment-methods/index.tsx +87 -19
- package/src/pages/admin/settings/vault-config/edit-form.tsx +42 -28
- package/src/pages/admin/settings/vault-config/index.tsx +57 -10
- package/src/pages/customer/credit-grant/detail.tsx +308 -0
- package/src/pages/customer/index.tsx +76 -17
- package/src/pages/customer/invoice/detail.tsx +63 -14
- package/src/pages/customer/invoice/past-due.tsx +11 -3
- package/src/pages/customer/payout/detail.tsx +56 -13
- package/src/pages/customer/recharge/account.tsx +78 -18
- package/src/pages/customer/recharge/subscription.tsx +86 -25
- package/src/pages/customer/refund/list.tsx +60 -24
- package/src/pages/customer/subscription/change-payment.tsx +17 -6
- package/src/pages/customer/subscription/change-plan.tsx +34 -7
- package/src/pages/customer/subscription/detail.tsx +134 -34
- package/src/pages/customer/subscription/embed.tsx +25 -5
- package/src/pages/home.tsx +26 -4
- package/src/pages/integrations/donations/edit-form.tsx +25 -9
- package/src/pages/integrations/donations/index.tsx +26 -9
- package/src/pages/integrations/donations/preview.tsx +59 -15
- package/src/pages/integrations/index.tsx +10 -1
- package/src/pages/integrations/overview.tsx +78 -17
- package/vite.config.ts +60 -30
|
@@ -117,7 +117,11 @@ export function UsageRecordDialog({
|
|
|
117
117
|
message={
|
|
118
118
|
<>
|
|
119
119
|
{start && end ? (
|
|
120
|
-
<Typography
|
|
120
|
+
<Typography
|
|
121
|
+
variant="h6"
|
|
122
|
+
sx={{
|
|
123
|
+
mb: 2,
|
|
124
|
+
}}>
|
|
121
125
|
{t('admin.subscription.usage.cycle')}: {formatTime(start * 1000)} - {formatTime(end * 1000)}
|
|
122
126
|
</Typography>
|
|
123
127
|
) : null}
|
|
@@ -148,17 +152,27 @@ export function UsageRecordDialog({
|
|
|
148
152
|
<Empty>{t('admin.usageRecord.empty')}</Empty>
|
|
149
153
|
)}
|
|
150
154
|
{!settings.livemode && window.location.pathname.includes('/admin/billing') && !disableAddUsageQuantity && (
|
|
151
|
-
<Box
|
|
155
|
+
<Box
|
|
156
|
+
sx={{
|
|
157
|
+
pt: 1,
|
|
158
|
+
pb: 1,
|
|
159
|
+
gap: 1,
|
|
160
|
+
display: 'flex',
|
|
161
|
+
justifyContent: 'center',
|
|
162
|
+
alignItems: 'center',
|
|
163
|
+
}}>
|
|
152
164
|
<TextField
|
|
153
165
|
id="add-usage-record"
|
|
154
166
|
label={t('admin.usageRecord.add.quantity')}
|
|
155
167
|
type="number"
|
|
156
168
|
size="small"
|
|
157
|
-
InputLabelProps={{
|
|
158
|
-
shrink: true,
|
|
159
|
-
}}
|
|
160
169
|
value={usageQuantity}
|
|
161
170
|
onChange={(e) => setUsageQuantity(+e.target.value)}
|
|
171
|
+
slotProps={{
|
|
172
|
+
inputLabel: {
|
|
173
|
+
shrink: true,
|
|
174
|
+
},
|
|
175
|
+
}}
|
|
162
176
|
/>
|
|
163
177
|
<Button onClick={handAddUsageQuantity} sx={{ color: 'text.link' }}>
|
|
164
178
|
{t('admin.usageRecord.add.label')}
|
|
@@ -56,16 +56,14 @@ const getListKey = (props: ListProps) => {
|
|
|
56
56
|
return 'subscriptions';
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
export default function SubscriptionList({
|
|
60
|
+
customer_id = '',
|
|
61
|
+
features = {
|
|
61
62
|
customer: true,
|
|
62
63
|
filter: true,
|
|
63
64
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export default function SubscriptionList({ customer_id, features, status }: ListProps) {
|
|
65
|
+
status = '',
|
|
66
|
+
}: ListProps) {
|
|
69
67
|
const listKey = getListKey({ customer_id });
|
|
70
68
|
|
|
71
69
|
const { t } = useLocaleContext();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
2
|
import { api, formatBNStr, formatTime } from '@blocklet/payment-react';
|
|
3
|
-
import type { TSubscriptionExpanded } from '@blocklet/payment-types';
|
|
3
|
+
import type { TSubscriptionExpanded, CreditGrantSummary } from '@blocklet/payment-types';
|
|
4
4
|
import { useRequest } from 'ahooks';
|
|
5
5
|
|
|
6
6
|
import { Button, Stack, Typography, Tooltip, Avatar, Box, CircularProgress, Skeleton } from '@mui/material';
|
|
@@ -23,8 +23,21 @@ const fetchPayer = (id: string): Promise<{ token: string; paymentAddress: string
|
|
|
23
23
|
return api.get(`/api/subscriptions/${id}/payer-token`).then((res) => res.data);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
const fetchCreditBalance = ({
|
|
27
|
+
customerId,
|
|
28
|
+
subscriptionId,
|
|
29
|
+
}: {
|
|
30
|
+
customerId: string;
|
|
31
|
+
subscriptionId: string;
|
|
32
|
+
}): Promise<{ [key: string]: CreditGrantSummary }> => {
|
|
33
|
+
return api
|
|
34
|
+
.get(`/api/credit-grants/summary?customer_id=${customerId}&subscription_id=${subscriptionId}`)
|
|
35
|
+
.then((res) => res.data);
|
|
36
|
+
};
|
|
37
|
+
|
|
26
38
|
export default function SubscriptionMetrics({ subscription, showBalance = true }: Props) {
|
|
27
39
|
const { t } = useLocaleContext();
|
|
40
|
+
const isCredit = subscription.paymentCurrency?.type === 'credit';
|
|
28
41
|
const { data: upcoming, loading: upcomingLoading } = useRequest(() => fetchUpcoming(subscription.id));
|
|
29
42
|
const navigate = useNavigate();
|
|
30
43
|
|
|
@@ -32,6 +45,17 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
32
45
|
ready: showBalance,
|
|
33
46
|
});
|
|
34
47
|
|
|
48
|
+
const { data: creditBalance } = useRequest(
|
|
49
|
+
() =>
|
|
50
|
+
fetchCreditBalance({
|
|
51
|
+
customerId: subscription.customer_id,
|
|
52
|
+
subscriptionId: subscription.id,
|
|
53
|
+
}),
|
|
54
|
+
{
|
|
55
|
+
ready: isCredit,
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
35
59
|
const supportShowBalance = showBalance && ['arcblock', 'ethereum', 'base'].includes(subscription.paymentMethod.type);
|
|
36
60
|
// let scheduleToCancelTime = 0;
|
|
37
61
|
// if (['active', 'trialing', 'past_due'].includes(subscription.status) && subscription.cancel_at) {
|
|
@@ -41,12 +65,20 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
41
65
|
// }
|
|
42
66
|
|
|
43
67
|
const isInsufficientBalance = new BN(payerValue?.token || '0').lt(new BN(upcoming?.amount || '0'));
|
|
68
|
+
|
|
69
|
+
const handleRecharge = () => {
|
|
70
|
+
if (isCredit) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
navigate(`/customer/subscription/${subscription.id}/recharge`);
|
|
74
|
+
};
|
|
44
75
|
const renderBalanceValue = () => {
|
|
76
|
+
const balance = isCredit ? creditBalance?.[subscription.paymentCurrency.id]?.remainingAmount : payerValue?.token;
|
|
45
77
|
if (upcomingLoading || payerLoading) {
|
|
46
78
|
return <CircularProgress size={16} />;
|
|
47
79
|
}
|
|
48
80
|
|
|
49
|
-
if (isInsufficientBalance) {
|
|
81
|
+
if (isInsufficientBalance && !isCredit) {
|
|
50
82
|
return (
|
|
51
83
|
<Button
|
|
52
84
|
component="a"
|
|
@@ -60,18 +92,27 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
60
92
|
|
|
61
93
|
return (
|
|
62
94
|
<Stack
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
95
|
+
sx={{
|
|
96
|
+
flexDirection: 'row',
|
|
97
|
+
alignItems: 'center',
|
|
98
|
+
gap: 0.5,
|
|
99
|
+
fontSize: '16px',
|
|
100
|
+
fontWeight: 500,
|
|
101
|
+
cursor: 'pointer',
|
|
102
|
+
'&:hover': { color: 'primary.main' },
|
|
103
|
+
}}
|
|
104
|
+
onClick={handleRecharge}>
|
|
68
105
|
<Avatar
|
|
69
106
|
src={subscription.paymentCurrency?.logo}
|
|
70
107
|
sx={{ width: 16, height: 16 }}
|
|
71
108
|
alt={subscription.paymentCurrency?.name}
|
|
72
109
|
/>
|
|
73
|
-
<Box
|
|
74
|
-
{
|
|
110
|
+
<Box
|
|
111
|
+
sx={{
|
|
112
|
+
display: 'flex',
|
|
113
|
+
alignItems: 'baseline',
|
|
114
|
+
}}>
|
|
115
|
+
{formatBNStr(balance, subscription.paymentCurrency.decimal)}
|
|
75
116
|
<Typography sx={{ fontSize: '14px', ml: 0.5 }}>{subscription.paymentCurrency.symbol}</Typography>
|
|
76
117
|
</Box>
|
|
77
118
|
</Stack>
|
|
@@ -90,7 +131,12 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
90
131
|
{['active', 'trialing'].includes(subscription.status) && upcoming?.amount && upcoming.amount !== '0' && (
|
|
91
132
|
<InfoMetric
|
|
92
133
|
label={
|
|
93
|
-
<Typography
|
|
134
|
+
<Typography
|
|
135
|
+
sx={{
|
|
136
|
+
display: 'flex',
|
|
137
|
+
alignItems: 'center',
|
|
138
|
+
gap: 0.5,
|
|
139
|
+
}}>
|
|
94
140
|
{t('admin.subscription.nextInvoiceAmount')}
|
|
95
141
|
<Tooltip title={t('admin.subscription.nextInvoiceAmountTip')} placement="top" arrow>
|
|
96
142
|
<InfoOutlined fontSize="small" sx={{ color: 'text.secondary', cursor: 'pointer', fontSize: '16px' }} />
|
|
@@ -106,7 +152,12 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
106
152
|
{supportShowBalance && ['active', 'trialing'].includes(subscription.status) && (
|
|
107
153
|
<InfoMetric
|
|
108
154
|
label={
|
|
109
|
-
<Stack
|
|
155
|
+
<Stack
|
|
156
|
+
direction="row"
|
|
157
|
+
spacing={1}
|
|
158
|
+
sx={{
|
|
159
|
+
alignItems: 'center',
|
|
160
|
+
}}>
|
|
110
161
|
<Typography>{t('admin.subscription.currentBalance')}</Typography>
|
|
111
162
|
<Tooltip
|
|
112
163
|
title={
|
|
@@ -149,7 +200,3 @@ export default function SubscriptionMetrics({ subscription, showBalance = true }
|
|
|
149
200
|
</>
|
|
150
201
|
);
|
|
151
202
|
}
|
|
152
|
-
|
|
153
|
-
SubscriptionMetrics.defaultProps = {
|
|
154
|
-
showBalance: true,
|
|
155
|
-
};
|
|
@@ -89,23 +89,6 @@ type Props = {
|
|
|
89
89
|
buttonSize?: 'small' | 'medium' | 'large';
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
SubscriptionActions.defaultProps = {
|
|
93
|
-
showExtra: false,
|
|
94
|
-
showRecharge: false,
|
|
95
|
-
showBalanceInfo: false,
|
|
96
|
-
showOverdraftProtection: false,
|
|
97
|
-
showDelegation: false,
|
|
98
|
-
onChange: null,
|
|
99
|
-
actionProps: {},
|
|
100
|
-
mode: 'all-buttons',
|
|
101
|
-
setUp: null,
|
|
102
|
-
showUnsubscribe: true,
|
|
103
|
-
includeActions: null,
|
|
104
|
-
excludeActions: null,
|
|
105
|
-
forceShowDetailAction: false,
|
|
106
|
-
buttonSize: 'small',
|
|
107
|
-
};
|
|
108
|
-
|
|
109
92
|
const fetchChangePlan = async (id: string): Promise<boolean> => {
|
|
110
93
|
try {
|
|
111
94
|
const res = await api.get(`/api/subscriptions/${id}/change-plan`);
|
|
@@ -130,26 +113,27 @@ const fetchBatchPay = async (id: string): Promise<string> => {
|
|
|
130
113
|
const supportRecharge = (subscription: TSubscriptionExpanded) => {
|
|
131
114
|
return (
|
|
132
115
|
['active', 'trialing', 'past_due'].includes(subscription?.status) &&
|
|
133
|
-
['arcblock', 'ethereum', 'base'].includes(subscription?.paymentMethod?.type)
|
|
116
|
+
['arcblock', 'ethereum', 'base'].includes(subscription?.paymentMethod?.type) &&
|
|
117
|
+
subscription.paymentCurrency?.type !== 'credit'
|
|
134
118
|
);
|
|
135
119
|
};
|
|
136
120
|
|
|
137
121
|
export function SubscriptionActionsInner({
|
|
138
122
|
subscription,
|
|
139
|
-
showExtra,
|
|
140
|
-
showRecharge,
|
|
141
|
-
showOverdraftProtection,
|
|
142
|
-
showDelegation,
|
|
143
|
-
showUnsubscribe,
|
|
144
|
-
onChange,
|
|
145
|
-
actionProps,
|
|
146
|
-
mode,
|
|
147
|
-
setUp,
|
|
148
|
-
showBalanceInfo,
|
|
149
|
-
includeActions,
|
|
150
|
-
excludeActions,
|
|
151
|
-
forceShowDetailAction,
|
|
152
|
-
buttonSize,
|
|
123
|
+
showExtra = false,
|
|
124
|
+
showRecharge = false,
|
|
125
|
+
showOverdraftProtection = false,
|
|
126
|
+
showDelegation = false,
|
|
127
|
+
showUnsubscribe = true,
|
|
128
|
+
onChange = undefined,
|
|
129
|
+
actionProps = {},
|
|
130
|
+
mode = 'all-buttons',
|
|
131
|
+
setUp = undefined,
|
|
132
|
+
showBalanceInfo = false,
|
|
133
|
+
includeActions = null,
|
|
134
|
+
excludeActions = null,
|
|
135
|
+
forceShowDetailAction = false,
|
|
136
|
+
buttonSize = 'small',
|
|
153
137
|
}: Props) {
|
|
154
138
|
const { t, locale } = useLocaleContext();
|
|
155
139
|
const { reset, getValues } = useFormContext();
|
|
@@ -396,7 +380,12 @@ export function SubscriptionActionsInner({
|
|
|
396
380
|
show: !!(showRecharge && supportRecharge(subscription)),
|
|
397
381
|
label: () => {
|
|
398
382
|
const balanceDisplay = (
|
|
399
|
-
<Stack
|
|
383
|
+
<Stack
|
|
384
|
+
direction="row"
|
|
385
|
+
spacing={0.5}
|
|
386
|
+
sx={{
|
|
387
|
+
alignItems: 'center',
|
|
388
|
+
}}>
|
|
400
389
|
<AddOutlined fontSize="small" />
|
|
401
390
|
{t('customer.recharge.title')}
|
|
402
391
|
</Stack>
|
|
@@ -408,19 +397,6 @@ export function SubscriptionActionsInner({
|
|
|
408
397
|
|
|
409
398
|
return (
|
|
410
399
|
<Tooltip
|
|
411
|
-
componentsProps={{
|
|
412
|
-
tooltip: {
|
|
413
|
-
sx: {
|
|
414
|
-
bgcolor: 'background.paper',
|
|
415
|
-
color: 'text.primary',
|
|
416
|
-
boxShadow: 2,
|
|
417
|
-
padding: '10px 16px',
|
|
418
|
-
maxWidth: 480,
|
|
419
|
-
minWidth: 350,
|
|
420
|
-
wordBreak: 'break-word',
|
|
421
|
-
},
|
|
422
|
-
},
|
|
423
|
-
}}
|
|
424
400
|
title={
|
|
425
401
|
<Box>
|
|
426
402
|
{isInsufficientBalance && (
|
|
@@ -429,7 +405,11 @@ export function SubscriptionActionsInner({
|
|
|
429
405
|
</Alert>
|
|
430
406
|
)}
|
|
431
407
|
<Stack spacing={0.5}>
|
|
432
|
-
<Box
|
|
408
|
+
<Box
|
|
409
|
+
sx={{
|
|
410
|
+
display: 'flex',
|
|
411
|
+
justifyContent: 'space-between',
|
|
412
|
+
}}>
|
|
433
413
|
<Typography sx={{ color: 'text.secondary' }} variant="body2">
|
|
434
414
|
{t('admin.subscription.currentBalance')}
|
|
435
415
|
</Typography>
|
|
@@ -437,7 +417,11 @@ export function SubscriptionActionsInner({
|
|
|
437
417
|
{formattedBalance} {subscription.paymentCurrency.symbol}
|
|
438
418
|
</Typography>
|
|
439
419
|
</Box>
|
|
440
|
-
<Box
|
|
420
|
+
<Box
|
|
421
|
+
sx={{
|
|
422
|
+
display: 'flex',
|
|
423
|
+
justifyContent: 'space-between',
|
|
424
|
+
}}>
|
|
441
425
|
<Typography sx={{ color: 'text.secondary' }} variant="body2">
|
|
442
426
|
{t('admin.subscription.nextInvoiceAmount')}
|
|
443
427
|
</Typography>
|
|
@@ -445,7 +429,11 @@ export function SubscriptionActionsInner({
|
|
|
445
429
|
{formattedUpcoming} {subscription.paymentCurrency.symbol}
|
|
446
430
|
</Typography>
|
|
447
431
|
</Box>
|
|
448
|
-
<Box
|
|
432
|
+
<Box
|
|
433
|
+
sx={{
|
|
434
|
+
display: 'flex',
|
|
435
|
+
justifyContent: 'space-between',
|
|
436
|
+
}}>
|
|
449
437
|
<Typography sx={{ color: 'text.secondary' }} variant="body2">
|
|
450
438
|
{t('admin.subscription.paymentAddress')}
|
|
451
439
|
</Typography>
|
|
@@ -454,7 +442,20 @@ export function SubscriptionActionsInner({
|
|
|
454
442
|
</Stack>
|
|
455
443
|
</Box>
|
|
456
444
|
}
|
|
457
|
-
placement="top"
|
|
445
|
+
placement="top"
|
|
446
|
+
slotProps={{
|
|
447
|
+
tooltip: {
|
|
448
|
+
sx: {
|
|
449
|
+
bgcolor: 'background.paper',
|
|
450
|
+
color: 'text.primary',
|
|
451
|
+
boxShadow: 2,
|
|
452
|
+
padding: '10px 16px',
|
|
453
|
+
maxWidth: 480,
|
|
454
|
+
minWidth: 350,
|
|
455
|
+
wordBreak: 'break-word',
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
}}>
|
|
458
459
|
{balanceDisplay}
|
|
459
460
|
</Tooltip>
|
|
460
461
|
);
|
|
@@ -632,7 +633,13 @@ export function SubscriptionActionsInner({
|
|
|
632
633
|
};
|
|
633
634
|
|
|
634
635
|
return (
|
|
635
|
-
<Stack
|
|
636
|
+
<Stack
|
|
637
|
+
direction="row"
|
|
638
|
+
sx={{
|
|
639
|
+
alignItems: 'center',
|
|
640
|
+
gap: 1,
|
|
641
|
+
flexWrap: 'wrap',
|
|
642
|
+
}}>
|
|
636
643
|
{renderActions()}
|
|
637
644
|
{state.action === 'cancel' && state.subscription && (
|
|
638
645
|
<ConfirmDialog
|
|
@@ -660,7 +667,6 @@ export function SubscriptionActionsInner({
|
|
|
660
667
|
}}
|
|
661
668
|
/>
|
|
662
669
|
)}
|
|
663
|
-
|
|
664
670
|
{state.openProtection && (
|
|
665
671
|
<OverdraftProtectionDialog
|
|
666
672
|
value={overdraftProtection}
|
|
@@ -675,7 +681,6 @@ export function SubscriptionActionsInner({
|
|
|
675
681
|
initValues={state.protectionInitValues}
|
|
676
682
|
/>
|
|
677
683
|
)}
|
|
678
|
-
|
|
679
684
|
{state.batchPay && (
|
|
680
685
|
<OverdueInvoicePayment
|
|
681
686
|
subscriptionId={subscription.id}
|
|
@@ -694,7 +699,26 @@ export function SubscriptionActionsInner({
|
|
|
694
699
|
);
|
|
695
700
|
}
|
|
696
701
|
|
|
697
|
-
export default function SubscriptionActions(
|
|
702
|
+
export default function SubscriptionActions(rawProps: Props) {
|
|
703
|
+
const props: Props = Object.assign(
|
|
704
|
+
{
|
|
705
|
+
showExtra: false,
|
|
706
|
+
showRecharge: false,
|
|
707
|
+
showBalanceInfo: false,
|
|
708
|
+
showOverdraftProtection: false,
|
|
709
|
+
showDelegation: false,
|
|
710
|
+
onChange: null,
|
|
711
|
+
actionProps: {},
|
|
712
|
+
mode: 'all-buttons',
|
|
713
|
+
setUp: null,
|
|
714
|
+
showUnsubscribe: true,
|
|
715
|
+
includeActions: null,
|
|
716
|
+
excludeActions: null,
|
|
717
|
+
forceShowDetailAction: false,
|
|
718
|
+
buttonSize: 'small',
|
|
719
|
+
},
|
|
720
|
+
rawProps
|
|
721
|
+
);
|
|
698
722
|
const methods = useForm({
|
|
699
723
|
defaultValues: {
|
|
700
724
|
cancel: {
|
|
@@ -711,20 +735,3 @@ export default function SubscriptionActions(props: Props) {
|
|
|
711
735
|
</FormProvider>
|
|
712
736
|
);
|
|
713
737
|
}
|
|
714
|
-
|
|
715
|
-
SubscriptionActionsInner.defaultProps = {
|
|
716
|
-
showExtra: false,
|
|
717
|
-
showRecharge: false,
|
|
718
|
-
showOverdraftProtection: false,
|
|
719
|
-
showBalanceInfo: false,
|
|
720
|
-
showDelegation: false,
|
|
721
|
-
showUnsubscribe: true,
|
|
722
|
-
onChange: null,
|
|
723
|
-
actionProps: {},
|
|
724
|
-
mode: 'all-buttons',
|
|
725
|
-
setUp: null,
|
|
726
|
-
includeActions: null,
|
|
727
|
-
excludeActions: null,
|
|
728
|
-
forceShowDetailAction: false,
|
|
729
|
-
buttonSize: 'small',
|
|
730
|
-
};
|
|
@@ -9,7 +9,12 @@ export default function CustomerCancelForm({ data }: { data: TSubscriptionExpand
|
|
|
9
9
|
const { control } = useFormContext();
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
|
-
<Stack
|
|
12
|
+
<Stack
|
|
13
|
+
direction="column"
|
|
14
|
+
spacing={1}
|
|
15
|
+
sx={{
|
|
16
|
+
alignItems: 'flex-start',
|
|
17
|
+
}}>
|
|
13
18
|
<Typography>
|
|
14
19
|
{data.status === 'trialing'
|
|
15
20
|
? t('payment.customer.cancel.trialDescription')
|
|
@@ -84,8 +89,10 @@ export default function CustomerCancelForm({ data }: { data: TSubscriptionExpand
|
|
|
84
89
|
maxRows={4}
|
|
85
90
|
placeholder={t('payment.customer.cancel.comment')}
|
|
86
91
|
{...field}
|
|
87
|
-
|
|
88
|
-
|
|
92
|
+
slotProps={{
|
|
93
|
+
htmlInput: {
|
|
94
|
+
maxLength: 200,
|
|
95
|
+
},
|
|
89
96
|
}}
|
|
90
97
|
/>
|
|
91
98
|
)}
|
|
@@ -52,9 +52,9 @@ type Props = {
|
|
|
52
52
|
export default function CurrentSubscriptions({
|
|
53
53
|
id,
|
|
54
54
|
status,
|
|
55
|
-
onChange,
|
|
55
|
+
onChange = () => {},
|
|
56
56
|
onClickSubscription,
|
|
57
|
-
onlyActive,
|
|
57
|
+
onlyActive = false,
|
|
58
58
|
changeActive = () => {},
|
|
59
59
|
setStatusState = () => {},
|
|
60
60
|
setHasSubscriptions = () => {},
|
|
@@ -74,10 +74,10 @@ export default function CurrentSubscriptions({
|
|
|
74
74
|
reloadDeps: [id, status],
|
|
75
75
|
onSuccess(res) {
|
|
76
76
|
if (res.totalCount > 0 || res.count > 0) {
|
|
77
|
-
setStatusState(true);
|
|
78
|
-
setHasSubscriptions(true);
|
|
77
|
+
setStatusState?.(true);
|
|
78
|
+
setHasSubscriptions?.(true);
|
|
79
79
|
} else {
|
|
80
|
-
setHasSubscriptions(false);
|
|
80
|
+
setHasSubscriptions?.(false);
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
...(isMobile
|
|
@@ -136,6 +136,7 @@ export default function CurrentSubscriptions({
|
|
|
136
136
|
<Stack
|
|
137
137
|
key={subscription.id}
|
|
138
138
|
sx={{
|
|
139
|
+
flexWrap: 'wrap',
|
|
139
140
|
padding: 2,
|
|
140
141
|
height: '100%',
|
|
141
142
|
borderRadius: 1,
|
|
@@ -146,21 +147,37 @@ export default function CurrentSubscriptions({
|
|
|
146
147
|
flexDirection: 'column',
|
|
147
148
|
justifyContent: 'space-between',
|
|
148
149
|
gap: 2,
|
|
150
|
+
|
|
149
151
|
'&:hover': {
|
|
150
152
|
backgroundColor: 'grey.50',
|
|
151
153
|
transition: 'background-color 200ms linear',
|
|
152
154
|
cursor: 'pointer',
|
|
153
155
|
},
|
|
154
|
-
}}
|
|
155
|
-
|
|
156
|
-
|
|
156
|
+
}}>
|
|
157
|
+
<Stack
|
|
158
|
+
direction="column"
|
|
159
|
+
spacing={2}
|
|
160
|
+
{...rest}
|
|
161
|
+
sx={[
|
|
162
|
+
{
|
|
163
|
+
flex: 1,
|
|
164
|
+
},
|
|
165
|
+
...(Array.isArray(rest.sx) ? rest.sx : [rest.sx]),
|
|
166
|
+
]}>
|
|
157
167
|
<Stack
|
|
158
168
|
direction="row"
|
|
159
169
|
spacing={1}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
170
|
+
onClick={() => onClickSubscription(subscription)}
|
|
171
|
+
sx={{
|
|
172
|
+
alignItems: 'flex-start',
|
|
173
|
+
justifyContent: 'space-between',
|
|
174
|
+
}}>
|
|
175
|
+
<Stack
|
|
176
|
+
direction="row"
|
|
177
|
+
spacing={1.5}
|
|
178
|
+
sx={{
|
|
179
|
+
alignItems: 'center',
|
|
180
|
+
}}>
|
|
164
181
|
{subscription.metadata?.appLogo ? (
|
|
165
182
|
<Avatar
|
|
166
183
|
src={formatProxyUrl(subscription.metadata?.appLogo)}
|
|
@@ -214,10 +231,10 @@ export default function CurrentSubscriptions({
|
|
|
214
231
|
|
|
215
232
|
<Divider />
|
|
216
233
|
<Stack
|
|
217
|
-
gap={1}
|
|
218
|
-
justifyContent="space-between"
|
|
219
|
-
flexWrap="nowrap"
|
|
220
234
|
sx={{
|
|
235
|
+
gap: 1,
|
|
236
|
+
justifyContent: 'space-between',
|
|
237
|
+
flexWrap: 'nowrap',
|
|
221
238
|
flexDirection: 'row',
|
|
222
239
|
alignItems: 'center',
|
|
223
240
|
}}>
|
|
@@ -242,7 +259,11 @@ export default function CurrentSubscriptions({
|
|
|
242
259
|
)}
|
|
243
260
|
</Typography>
|
|
244
261
|
{subscriptionTime && (
|
|
245
|
-
<Typography
|
|
262
|
+
<Typography
|
|
263
|
+
variant="body2"
|
|
264
|
+
sx={{
|
|
265
|
+
color: 'text.secondary',
|
|
266
|
+
}}>
|
|
246
267
|
({subscriptionTime})
|
|
247
268
|
</Typography>
|
|
248
269
|
)}
|
|
@@ -329,7 +350,13 @@ export default function CurrentSubscriptions({
|
|
|
329
350
|
})}
|
|
330
351
|
</Stack>
|
|
331
352
|
{hasMore && !isMobile && showLoadingMore && (
|
|
332
|
-
<Box
|
|
353
|
+
<Box
|
|
354
|
+
sx={{
|
|
355
|
+
alignItems: 'center',
|
|
356
|
+
gap: 0.5,
|
|
357
|
+
display: 'flex',
|
|
358
|
+
mt: 0.5,
|
|
359
|
+
}}>
|
|
333
360
|
{t('common.loadingMore', { resource: t('admin.subscriptions') })}
|
|
334
361
|
</Box>
|
|
335
362
|
)}
|
|
@@ -343,7 +370,10 @@ export default function CurrentSubscriptions({
|
|
|
343
370
|
</Button>
|
|
344
371
|
)}
|
|
345
372
|
{!hasMore && data.count > pageSize && (
|
|
346
|
-
<Typography
|
|
373
|
+
<Typography
|
|
374
|
+
sx={{
|
|
375
|
+
color: 'text.secondary',
|
|
376
|
+
}}>
|
|
347
377
|
{t('common.noMore', { resource: t('admin.subscriptions') })}
|
|
348
378
|
</Typography>
|
|
349
379
|
)}
|
|
@@ -369,11 +399,3 @@ export default function CurrentSubscriptions({
|
|
|
369
399
|
</Stack>
|
|
370
400
|
);
|
|
371
401
|
}
|
|
372
|
-
|
|
373
|
-
CurrentSubscriptions.defaultProps = {
|
|
374
|
-
onChange: null,
|
|
375
|
-
onlyActive: false,
|
|
376
|
-
changeActive: null,
|
|
377
|
-
setStatusState: null,
|
|
378
|
-
setHasSubscriptions: null,
|
|
379
|
-
};
|
|
@@ -21,11 +21,11 @@ type Props = {
|
|
|
21
21
|
|
|
22
22
|
export default function Uploader({
|
|
23
23
|
onUploaded,
|
|
24
|
-
preview,
|
|
25
|
-
maxFileSize,
|
|
26
|
-
maxNumberOfFiles,
|
|
27
|
-
allowedFileExts,
|
|
28
|
-
disabled,
|
|
24
|
+
preview = '',
|
|
25
|
+
maxFileSize = undefined,
|
|
26
|
+
maxNumberOfFiles = 1,
|
|
27
|
+
allowedFileExts = ['.png', '.jpeg', '.webp', '.svg', '.jpg'],
|
|
28
|
+
disabled = false,
|
|
29
29
|
}: Props) {
|
|
30
30
|
const uploaderRef = useRef<any>(null);
|
|
31
31
|
const handleOpen = useCallback(() => {
|
|
@@ -148,14 +148,6 @@ export default function Uploader({
|
|
|
148
148
|
);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
Uploader.defaultProps = {
|
|
152
|
-
preview: '',
|
|
153
|
-
maxFileSize: undefined,
|
|
154
|
-
maxNumberOfFiles: 1,
|
|
155
|
-
allowedFileExts: ['.png', '.jpeg', '.webp', '.svg', '.jpg'],
|
|
156
|
-
disabled: false,
|
|
157
|
-
};
|
|
158
|
-
|
|
159
151
|
const Div = styled(Box)`
|
|
160
152
|
border: 1px solid;
|
|
161
153
|
border-color: ${({ theme }) => theme.palette.grey[100]};
|