payment-kit 1.19.11 → 1.19.13
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/libs/notification/template/one-time-payment-refund-succeeded.ts +274 -0
- package/api/src/libs/notification/template/one-time-payment-succeeded.ts +10 -21
- package/api/src/libs/notification/template/subscription-refund-succeeded.ts +23 -3
- package/api/src/libs/notification/template/subscription-will-renew.ts +15 -2
- package/api/src/libs/session.ts +70 -1
- package/api/src/locales/en.ts +10 -0
- package/api/src/locales/zh.ts +10 -0
- package/api/src/queues/credit-consume.ts +4 -1
- package/api/src/queues/notification.ts +16 -3
- package/api/src/routes/checkout-sessions.ts +9 -0
- package/blocklet.yml +6 -6
- package/package.json +16 -16
- package/screenshots/0ffe164ebe4aa2eb43f8d87f87683f7f.png +0 -0
- package/screenshots/1ef9e15ac36d4af5bef34941000ba3af.png +0 -0
- package/screenshots/3a4cab81c52c29662db8794b05ccc7c7.png +0 -0
- package/screenshots/77ac49b79ae920f0f253ce8c694ffd65.png +0 -0
- package/screenshots/7ea8ef758865ecf6edb712d3534d2974.png +0 -0
- package/src/components/chart.tsx +1 -1
- package/src/components/conditional-section.tsx +11 -1
- package/src/components/customer/credit-overview.tsx +51 -48
- package/src/components/drawer-form.tsx +1 -1
- package/src/components/filter-toolbar.tsx +1 -1
- package/src/components/info-card.tsx +1 -1
- package/src/components/invoice-pdf/pdf.tsx +1 -1
- package/src/components/layout/admin.tsx +0 -4
- package/src/components/metadata/form.tsx +1 -1
- package/src/components/meter/actions.tsx +1 -1
- package/src/components/meter/events-list.tsx +6 -0
- package/src/components/meter/usage-guide.tsx +1 -1
- package/src/components/payment-link/item.tsx +1 -1
- package/src/components/price/form.tsx +0 -19
- package/src/components/pricing-table/product-item.tsx +1 -1
- package/src/components/product/features.tsx +1 -1
- package/src/components/uploader.tsx +1 -1
- package/src/components/webhook/attempts.tsx +1 -1
- package/src/locales/en.tsx +7 -4
- package/src/locales/zh.tsx +6 -2
- package/src/pages/admin/developers/webhooks/detail.tsx +1 -1
- package/src/pages/admin/products/pricing-tables/create.tsx +2 -2
- package/src/pages/checkout/pricing-table.tsx +1 -1
- package/src/pages/customer/index.tsx +30 -14
- package/src/pages/customer/invoice/detail.tsx +1 -1
- package/src/pages/integrations/donations/preview.tsx +4 -4
- package/screenshots/checkout.png +0 -0
- package/screenshots/customer.png +0 -0
- package/screenshots/payment.png +0 -0
- package/screenshots/setting.png +0 -0
- package/screenshots/subscription_detail.png +0 -0
|
@@ -21,6 +21,10 @@ import {
|
|
|
21
21
|
SubscriptionRefundSucceededEmailTemplate,
|
|
22
22
|
SubscriptionRefundSucceededEmailTemplateOptions,
|
|
23
23
|
} from '../libs/notification/template/subscription-refund-succeeded';
|
|
24
|
+
import {
|
|
25
|
+
OneTimePaymentRefundSucceededEmailTemplate,
|
|
26
|
+
OneTimePaymentRefundSucceededEmailTemplateOptions,
|
|
27
|
+
} from '../libs/notification/template/one-time-payment-refund-succeeded';
|
|
24
28
|
import {
|
|
25
29
|
SubscriptionRenewFailedEmailTemplate,
|
|
26
30
|
SubscriptionRenewFailedEmailTemplateOptions,
|
|
@@ -187,7 +191,7 @@ function calculateNextNotificationTime(preference: NotificationPreference): numb
|
|
|
187
191
|
return Math.floor(nextTime.valueOf() / 1000);
|
|
188
192
|
}
|
|
189
193
|
|
|
190
|
-
function getNotificationTemplate(job: NotificationQueueJob): BaseEmailTemplate {
|
|
194
|
+
async function getNotificationTemplate(job: NotificationQueueJob): Promise<BaseEmailTemplate> {
|
|
191
195
|
if (job.type === 'usage.report.empty') {
|
|
192
196
|
return new UsageReportEmptyEmailTemplate(job.options as UsageReportEmptyEmailTemplateOptions);
|
|
193
197
|
}
|
|
@@ -225,7 +229,16 @@ function getNotificationTemplate(job: NotificationQueueJob): BaseEmailTemplate {
|
|
|
225
229
|
return new SubscriptionCanceledEmailTemplate(job.options as SubscriptionCanceledEmailTemplateOptions);
|
|
226
230
|
}
|
|
227
231
|
if (job.type === 'refund.succeeded') {
|
|
228
|
-
|
|
232
|
+
const { refundId } = job.options as { refundId: string };
|
|
233
|
+
const refund = await Refund.findByPk(refundId);
|
|
234
|
+
if (refund?.subscription_id) {
|
|
235
|
+
return new SubscriptionRefundSucceededEmailTemplate(
|
|
236
|
+
job.options as SubscriptionRefundSucceededEmailTemplateOptions
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
return new OneTimePaymentRefundSucceededEmailTemplate(
|
|
240
|
+
job.options as OneTimePaymentRefundSucceededEmailTemplateOptions
|
|
241
|
+
);
|
|
229
242
|
}
|
|
230
243
|
if (job.type === 'customer.reward.succeeded') {
|
|
231
244
|
return new CustomerRewardSucceededEmailTemplate(job.options as CustomerRewardSucceededEmailTemplateOptions);
|
|
@@ -264,7 +277,7 @@ function getNotificationTemplate(job: NotificationQueueJob): BaseEmailTemplate {
|
|
|
264
277
|
|
|
265
278
|
async function handleNotificationJob(job: NotificationQueueJob): Promise<void> {
|
|
266
279
|
try {
|
|
267
|
-
const template = getNotificationTemplate(job);
|
|
280
|
+
const template = await getNotificationTemplate(job);
|
|
268
281
|
|
|
269
282
|
await new Notification(template, job.type).send();
|
|
270
283
|
logger.info('handleImmediateNotificationJob.success', { job });
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
getCheckoutSessionSubscriptionIds,
|
|
42
42
|
getSubscriptionLineItems,
|
|
43
43
|
isCreditMeteredLineItems,
|
|
44
|
+
validatePaymentAmounts,
|
|
44
45
|
} from '../libs/session';
|
|
45
46
|
import { getDaysUntilCancel, getDaysUntilDue, getSubscriptionTrialSetup } from '../libs/subscription';
|
|
46
47
|
import {
|
|
@@ -1074,6 +1075,14 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
1074
1075
|
true
|
|
1075
1076
|
);
|
|
1076
1077
|
|
|
1078
|
+
// Validate payment amounts meet minimum requirements
|
|
1079
|
+
if (paymentMethod.type === 'stripe') {
|
|
1080
|
+
const result = validatePaymentAmounts(lineItems, paymentCurrency, checkoutSession);
|
|
1081
|
+
if (!result.valid) {
|
|
1082
|
+
return res.status(400).json({ error: result.error });
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1077
1086
|
let customer = await Customer.findOne({ where: { did: req.user.did } });
|
|
1078
1087
|
if (!customer) {
|
|
1079
1088
|
const { user: userInfo } = await blocklet.getUser(req.user.did);
|
package/blocklet.yml
CHANGED
|
@@ -14,7 +14,7 @@ repository:
|
|
|
14
14
|
type: git
|
|
15
15
|
url: git+https://github.com/blocklet/payment-kit.git
|
|
16
16
|
specVersion: 1.2.8
|
|
17
|
-
version: 1.19.
|
|
17
|
+
version: 1.19.13
|
|
18
18
|
logo: logo.png
|
|
19
19
|
files:
|
|
20
20
|
- dist
|
|
@@ -72,11 +72,11 @@ capabilities:
|
|
|
72
72
|
clusterMode: false
|
|
73
73
|
component: true
|
|
74
74
|
screenshots:
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
-
|
|
75
|
+
- 3a4cab81c52c29662db8794b05ccc7c7.png
|
|
76
|
+
- 77ac49b79ae920f0f253ce8c694ffd65.png
|
|
77
|
+
- 1ef9e15ac36d4af5bef34941000ba3af.png
|
|
78
|
+
- 7ea8ef758865ecf6edb712d3534d2974.png
|
|
79
|
+
- 0ffe164ebe4aa2eb43f8d87f87683f7f.png
|
|
80
80
|
components:
|
|
81
81
|
- name: image-bin
|
|
82
82
|
source:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.13",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
|
|
@@ -44,31 +44,31 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@abtnode/cron": "^1.16.46",
|
|
47
|
-
"@arcblock/did": "^1.21.
|
|
47
|
+
"@arcblock/did": "^1.21.1",
|
|
48
48
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
49
|
-
"@arcblock/did-connect": "^3.0.
|
|
50
|
-
"@arcblock/did-util": "^1.21.
|
|
51
|
-
"@arcblock/jwt": "^1.21.
|
|
52
|
-
"@arcblock/ux": "^3.0.
|
|
53
|
-
"@arcblock/validator": "^1.21.
|
|
49
|
+
"@arcblock/did-connect": "^3.0.41",
|
|
50
|
+
"@arcblock/did-util": "^1.21.1",
|
|
51
|
+
"@arcblock/jwt": "^1.21.1",
|
|
52
|
+
"@arcblock/ux": "^3.0.41",
|
|
53
|
+
"@arcblock/validator": "^1.21.1",
|
|
54
54
|
"@blocklet/did-space-js": "^1.1.13",
|
|
55
55
|
"@blocklet/error": "^0.2.5",
|
|
56
56
|
"@blocklet/js-sdk": "^1.16.46",
|
|
57
57
|
"@blocklet/logger": "^1.16.46",
|
|
58
|
-
"@blocklet/payment-react": "1.19.
|
|
58
|
+
"@blocklet/payment-react": "1.19.13",
|
|
59
59
|
"@blocklet/sdk": "^1.16.46",
|
|
60
|
-
"@blocklet/ui-react": "^3.0.
|
|
60
|
+
"@blocklet/ui-react": "^3.0.41",
|
|
61
61
|
"@blocklet/uploader": "^0.2.5",
|
|
62
62
|
"@blocklet/xss": "^0.2.3",
|
|
63
63
|
"@mui/icons-material": "^7.1.2",
|
|
64
64
|
"@mui/lab": "7.0.0-beta.14",
|
|
65
65
|
"@mui/material": "^7.1.2",
|
|
66
66
|
"@mui/system": "^7.1.1",
|
|
67
|
-
"@ocap/asset": "^1.21.
|
|
68
|
-
"@ocap/client": "^1.21.
|
|
69
|
-
"@ocap/mcrypto": "^1.21.
|
|
70
|
-
"@ocap/util": "^1.21.
|
|
71
|
-
"@ocap/wallet": "^1.21.
|
|
67
|
+
"@ocap/asset": "^1.21.1",
|
|
68
|
+
"@ocap/client": "^1.21.1",
|
|
69
|
+
"@ocap/mcrypto": "^1.21.1",
|
|
70
|
+
"@ocap/util": "^1.21.1",
|
|
71
|
+
"@ocap/wallet": "^1.21.1",
|
|
72
72
|
"@stripe/react-stripe-js": "^2.9.0",
|
|
73
73
|
"@stripe/stripe-js": "^2.4.0",
|
|
74
74
|
"ahooks": "^3.8.5",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"devDependencies": {
|
|
125
125
|
"@abtnode/types": "^1.16.46",
|
|
126
126
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
127
|
-
"@blocklet/payment-types": "1.19.
|
|
127
|
+
"@blocklet/payment-types": "1.19.13",
|
|
128
128
|
"@types/cookie-parser": "^1.4.9",
|
|
129
129
|
"@types/cors": "^2.8.19",
|
|
130
130
|
"@types/debug": "^4.1.12",
|
|
@@ -170,5 +170,5 @@
|
|
|
170
170
|
"parser": "typescript"
|
|
171
171
|
}
|
|
172
172
|
},
|
|
173
|
-
"gitHead": "
|
|
173
|
+
"gitHead": "07c6878eb9d455f3898adfda7d07ca9e321e866c"
|
|
174
174
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/components/chart.tsx
CHANGED
|
@@ -63,7 +63,7 @@ export default function Chart({
|
|
|
63
63
|
}}>
|
|
64
64
|
<CartesianGrid strokeDasharray="3 3" stroke={theme.palette.grey[200]} />
|
|
65
65
|
<Tooltip
|
|
66
|
-
contentStyle={{ backgroundColor: theme.palette.background.paper, borderColor: theme.palette.
|
|
66
|
+
contentStyle={{ backgroundColor: theme.palette.background.paper, borderColor: theme.palette.divider }}
|
|
67
67
|
/>
|
|
68
68
|
{Object.keys(currencies).map((x: string, i) => {
|
|
69
69
|
const dataKey = currencies[x]?.symbol as string;
|
|
@@ -15,6 +15,7 @@ interface ConditionalSectionProps {
|
|
|
15
15
|
skeleton: boolean;
|
|
16
16
|
children: ReactNode;
|
|
17
17
|
skeletonComponent?: ReactNode;
|
|
18
|
+
onStateChange?: (state: 'hidden' | 'visible' | 'none') => void;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -29,10 +30,19 @@ interface ConditionalSectionProps {
|
|
|
29
30
|
* 使用方式:
|
|
30
31
|
* - 在任意深度的子组件中调用 useConditionalSection()?.hideRender()
|
|
31
32
|
*/
|
|
32
|
-
export default function ConditionalSection({
|
|
33
|
+
export default function ConditionalSection({
|
|
34
|
+
skeleton,
|
|
35
|
+
children,
|
|
36
|
+
skeletonComponent = null,
|
|
37
|
+
onStateChange = () => {},
|
|
38
|
+
}: ConditionalSectionProps) {
|
|
33
39
|
const [renderState, setRenderState] = useState<'hidden' | 'visible' | 'none'>('hidden');
|
|
34
40
|
const timerRef = useRef<NodeJS.Timeout | null>(null);
|
|
35
41
|
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
onStateChange(renderState);
|
|
44
|
+
}, [renderState]);
|
|
45
|
+
|
|
36
46
|
const handleHideRender = useCallback((hide: boolean = true) => {
|
|
37
47
|
if (timerRef.current) {
|
|
38
48
|
clearTimeout(timerRef.current);
|
|
@@ -99,6 +99,7 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
|
|
|
99
99
|
borderColor: 'divider',
|
|
100
100
|
boxShadow: 1,
|
|
101
101
|
borderRadius: 1,
|
|
102
|
+
backgroundColor: 'background.default',
|
|
102
103
|
}}>
|
|
103
104
|
<CardContent sx={{ flexGrow: 1 }}>
|
|
104
105
|
<Stack spacing={2}>
|
|
@@ -190,60 +191,62 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
|
|
|
190
191
|
},
|
|
191
192
|
}}>
|
|
192
193
|
<Tab label={t('admin.creditGrants.overview')} value={CreditTab.OVERVIEW} />
|
|
193
|
-
<Tab label={t('admin.creditGrants.
|
|
194
|
-
<Tab label={t('admin.creditTransactions.
|
|
194
|
+
<Tab label={t('admin.creditGrants.tab')} value={CreditTab.GRANTS} />
|
|
195
|
+
<Tab label={t('admin.creditTransactions.tab')} value={CreditTab.TRANSACTIONS} />
|
|
195
196
|
</Tabs>
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
<Box
|
|
200
|
-
sx={{
|
|
201
|
-
display: 'grid',
|
|
202
|
-
gridTemplateColumns: {
|
|
203
|
-
xs: 'repeat(1, 1fr)',
|
|
204
|
-
md: 'repeat(2, 1fr)',
|
|
205
|
-
},
|
|
206
|
-
gap: 2,
|
|
207
|
-
'@container (max-width: 600px)': {
|
|
208
|
-
gridTemplateColumns: 'repeat(1, 1fr)',
|
|
209
|
-
},
|
|
210
|
-
}}>
|
|
211
|
-
{filteredCreditCurrencies.map(renderCreditOverviewCard)}
|
|
212
|
-
</Box>
|
|
213
|
-
|
|
214
|
-
{filteredCreditCurrencies.length === 0 && (
|
|
197
|
+
<Box className="section-body">
|
|
198
|
+
{/* 概览标签页 */}
|
|
199
|
+
{creditTab === CreditTab.OVERVIEW && (
|
|
200
|
+
<Box sx={{ width: '100%', mt: 1 }} key={creditTab}>
|
|
215
201
|
<Box
|
|
216
202
|
sx={{
|
|
217
|
-
display: '
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
203
|
+
display: 'grid',
|
|
204
|
+
gridTemplateColumns: {
|
|
205
|
+
xs: 'repeat(1, 1fr)',
|
|
206
|
+
md: 'repeat(2, 1fr)',
|
|
207
|
+
},
|
|
208
|
+
gap: 2,
|
|
209
|
+
'@container (max-width: 600px)': {
|
|
210
|
+
gridTemplateColumns: 'repeat(1, 1fr)',
|
|
211
|
+
},
|
|
223
212
|
}}>
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}}>
|
|
230
|
-
{t('admin.customer.creditGrants.noGrants')}
|
|
231
|
-
</Typography>
|
|
232
|
-
<Typography
|
|
233
|
-
variant="body2"
|
|
213
|
+
{filteredCreditCurrencies.map(renderCreditOverviewCard)}
|
|
214
|
+
</Box>
|
|
215
|
+
|
|
216
|
+
{filteredCreditCurrencies.length === 0 && (
|
|
217
|
+
<Box
|
|
234
218
|
sx={{
|
|
235
|
-
|
|
219
|
+
display: 'flex',
|
|
220
|
+
flexDirection: 'column',
|
|
221
|
+
alignItems: 'center',
|
|
222
|
+
justifyContent: 'center',
|
|
223
|
+
py: 8,
|
|
224
|
+
textAlign: 'center',
|
|
236
225
|
}}>
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
226
|
+
<Typography
|
|
227
|
+
variant="h6"
|
|
228
|
+
gutterBottom
|
|
229
|
+
sx={{
|
|
230
|
+
color: 'text.secondary',
|
|
231
|
+
}}>
|
|
232
|
+
{t('admin.customer.creditGrants.noGrants')}
|
|
233
|
+
</Typography>
|
|
234
|
+
<Typography
|
|
235
|
+
variant="body2"
|
|
236
|
+
sx={{
|
|
237
|
+
color: 'text.secondary',
|
|
238
|
+
}}>
|
|
239
|
+
{t('admin.customer.creditGrants.noGrantsDescription')}
|
|
240
|
+
</Typography>
|
|
241
|
+
</Box>
|
|
242
|
+
)}
|
|
243
|
+
</Box>
|
|
244
|
+
)}
|
|
245
|
+
{creditTab === CreditTab.GRANTS && <CreditGrantsList customer_id={customerId} mode={mode} key={creditTab} />}
|
|
246
|
+
{creditTab === CreditTab.TRANSACTIONS && (
|
|
247
|
+
<CreditTransactionsList customer_id={customerId} mode={mode} key={creditTab} />
|
|
248
|
+
)}
|
|
249
|
+
</Box>
|
|
247
250
|
</Stack>
|
|
248
251
|
);
|
|
249
252
|
}
|
|
@@ -522,7 +522,7 @@ const Root = styled(Box)`
|
|
|
522
522
|
padding: 0;
|
|
523
523
|
background: ${({ theme }) => theme.palette.background.paper};
|
|
524
524
|
border: 1px solid;
|
|
525
|
-
border-color: ${({ theme }) => theme.palette.
|
|
525
|
+
border-color: ${({ theme }) => theme.palette.divider};
|
|
526
526
|
z-index: 999999;
|
|
527
527
|
top: 15px;
|
|
528
528
|
display: block;
|
|
@@ -100,7 +100,7 @@ export function Download({ data }: { data: TInvoiceExpanded }) {
|
|
|
100
100
|
size="small"
|
|
101
101
|
onClick={generatePDF}
|
|
102
102
|
disabled={!isReady || isGenerating}
|
|
103
|
-
sx={{ borderColor: '
|
|
103
|
+
sx={{ borderColor: 'divider' }}>
|
|
104
104
|
{isGenerating ? (
|
|
105
105
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
106
106
|
<CircularProgress size={16} sx={{ color: 'inherit' }} />
|
|
@@ -66,7 +66,7 @@ export default function MeterActions({ data, variant = 'compact', onChange }: Me
|
|
|
66
66
|
if (variant === 'compact') {
|
|
67
67
|
actions.push({
|
|
68
68
|
label: t('admin.meter.view'),
|
|
69
|
-
handler: () => navigate(`/admin/billing
|
|
69
|
+
handler: () => navigate(`/admin/billing/${data.id}`),
|
|
70
70
|
color: 'primary',
|
|
71
71
|
});
|
|
72
72
|
}
|
|
@@ -418,10 +418,16 @@ export default function MeterEventsList({ meterId, paymentCurrency }: MeterEvent
|
|
|
418
418
|
variant="outlined"
|
|
419
419
|
startIcon={<CalendarTodayOutlined />}
|
|
420
420
|
onClick={onTogglePicker}
|
|
421
|
+
size="large"
|
|
421
422
|
sx={{
|
|
422
423
|
minWidth: isMobile ? '100%' : 200,
|
|
423
424
|
justifyContent: isMobile ? 'flex-start' : 'center',
|
|
424
425
|
color: 'text.secondary',
|
|
426
|
+
borderColor: 'grey.300',
|
|
427
|
+
'&:hover': {
|
|
428
|
+
borderColor: 'primary.main',
|
|
429
|
+
},
|
|
430
|
+
backgroundColor: 'grey.50',
|
|
425
431
|
}}>
|
|
426
432
|
{dayjs(state.startDate).format('YYYY-MM-DD')} - {dayjs(state.endDate).format('YYYY-MM-DD')}
|
|
427
433
|
</Button>
|
|
@@ -160,7 +160,7 @@ print("Event recorded:", response.json())`;
|
|
|
160
160
|
const CodeBlock = styled(Paper)(({ theme }) => ({
|
|
161
161
|
padding: theme.spacing(2),
|
|
162
162
|
backgroundColor: theme.palette.grey[50],
|
|
163
|
-
border: `1px solid ${theme.palette.
|
|
163
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
164
164
|
borderRadius: theme.shape.borderRadius,
|
|
165
165
|
overflow: 'auto',
|
|
166
166
|
'& pre': {
|
|
@@ -54,7 +54,7 @@ export default function LineItem({ prefix, product, valid, onUpdate, onRemove }:
|
|
|
54
54
|
p: 2,
|
|
55
55
|
borderWidth: valid ? 1 : 2,
|
|
56
56
|
borderStyle: 'solid',
|
|
57
|
-
borderColor: valid ? '
|
|
57
|
+
borderColor: valid ? 'divider' : 'error.main',
|
|
58
58
|
borderRadius: 2,
|
|
59
59
|
position: 'relative',
|
|
60
60
|
}}>
|
|
@@ -15,7 +15,6 @@ import type {
|
|
|
15
15
|
TMeter,
|
|
16
16
|
TMeterExpanded,
|
|
17
17
|
TPaymentCurrency,
|
|
18
|
-
TPaymentCurrencyExpanded,
|
|
19
18
|
TPaymentMethodExpanded,
|
|
20
19
|
TPrice,
|
|
21
20
|
TPriceExpanded,
|
|
@@ -102,16 +101,6 @@ const hasMoreCurrency = (methods: TPaymentMethodExpanded[] = []) => {
|
|
|
102
101
|
return methods.every((method) => method.payment_currencies.length > 1) || methods.length > 1;
|
|
103
102
|
};
|
|
104
103
|
|
|
105
|
-
function stripeCurrencyValidate(v: number, currency: TPaymentCurrencyExpanded | null) {
|
|
106
|
-
if (!currency) {
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
if (currency.paymentMethod?.type === 'stripe') {
|
|
110
|
-
return v >= 0.5;
|
|
111
|
-
}
|
|
112
|
-
return true;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
104
|
const fetchMeters = (): Promise<{ list: TMeterExpanded[]; count: number }> => {
|
|
116
105
|
return api.get('/api/meters?status=active&limit=100').then((res: any) => res.data);
|
|
117
106
|
};
|
|
@@ -397,10 +386,6 @@ export default function PriceForm({ prefix = '', simple = false, productType = u
|
|
|
397
386
|
required: t('admin.price.unit_amount.required'),
|
|
398
387
|
validate: (v) => {
|
|
399
388
|
const currency = findCurrency(settings.paymentMethods, defaultCurrencyId);
|
|
400
|
-
const hasStripError = !stripeCurrencyValidate(v, currency);
|
|
401
|
-
if (hasStripError) {
|
|
402
|
-
return t('admin.price.unit_amount.stripeTip');
|
|
403
|
-
}
|
|
404
389
|
return validateAmount(v, currency ?? {});
|
|
405
390
|
},
|
|
406
391
|
}}
|
|
@@ -482,10 +467,6 @@ export default function PriceForm({ prefix = '', simple = false, productType = u
|
|
|
482
467
|
rules={{
|
|
483
468
|
required: t('admin.price.unit_amount.required'),
|
|
484
469
|
validate: (v) => {
|
|
485
|
-
const hasStripError = !stripeCurrencyValidate(v, currency);
|
|
486
|
-
if (hasStripError) {
|
|
487
|
-
return t('admin.price.unit_amount.stripeTip');
|
|
488
|
-
}
|
|
489
470
|
return validateAmount(v, currency ?? {});
|
|
490
471
|
},
|
|
491
472
|
}}
|
|
@@ -47,7 +47,7 @@ export default function ProductItem({ product, prices, valid, onUpdate, onRemove
|
|
|
47
47
|
p: 2,
|
|
48
48
|
borderWidth: valid ? 1 : 2,
|
|
49
49
|
borderStyle: 'solid',
|
|
50
|
-
borderColor: valid ? '
|
|
50
|
+
borderColor: valid ? 'divider' : 'error.main',
|
|
51
51
|
borderRadius: 2,
|
|
52
52
|
position: 'relative',
|
|
53
53
|
}}>
|
|
@@ -150,7 +150,7 @@ export default function Uploader({
|
|
|
150
150
|
|
|
151
151
|
const Div = styled(Box)`
|
|
152
152
|
border: 1px solid;
|
|
153
|
-
border-color: ${({ theme }) => theme.palette.grey[
|
|
153
|
+
border-color: ${({ theme }) => theme.palette.grey[300]};
|
|
154
154
|
border-radius: 4px;
|
|
155
155
|
cursor: pointer;
|
|
156
156
|
width: 120px;
|
|
@@ -160,7 +160,7 @@ export default function WebhookAttempts({ event_id = '', webhook_endpoint_id = '
|
|
|
160
160
|
md: 8,
|
|
161
161
|
}}>
|
|
162
162
|
{selected && (
|
|
163
|
-
<Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid', borderColor: '
|
|
163
|
+
<Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid', borderColor: 'divider' }}>
|
|
164
164
|
<Typography variant="h6">{event_id ? selected.endpoint.url : selected.event.type}</Typography>
|
|
165
165
|
<Box>
|
|
166
166
|
<Typography variant="h6">Response ({selected.response_status})</Typography>
|
package/src/locales/en.tsx
CHANGED
|
@@ -63,7 +63,8 @@ export default flat({
|
|
|
63
63
|
scope: 'Scope',
|
|
64
64
|
effectiveDate: 'Effective Date',
|
|
65
65
|
expirationDate: 'Expiration Date',
|
|
66
|
-
creditGrant: '
|
|
66
|
+
creditGrant: 'Grant',
|
|
67
|
+
date: 'Date',
|
|
67
68
|
subscription: 'Subscription',
|
|
68
69
|
meterEvent: 'Meter Event',
|
|
69
70
|
creditAmount: 'Credit',
|
|
@@ -1144,11 +1145,12 @@ export default flat({
|
|
|
1144
1145
|
appBalance: 'App Balance',
|
|
1145
1146
|
},
|
|
1146
1147
|
creditGrants: {
|
|
1147
|
-
|
|
1148
|
+
tab: 'Grants',
|
|
1149
|
+
title: 'Credits',
|
|
1148
1150
|
summary: 'Credit Summary',
|
|
1149
1151
|
noGrants: 'No credit grants found',
|
|
1150
1152
|
grantDetail: 'Credit Grant Details',
|
|
1151
|
-
overview: '
|
|
1153
|
+
overview: 'Overview',
|
|
1152
1154
|
overviewDescription: 'Monitor credit balances, usage, and outstanding debt across all currencies.',
|
|
1153
1155
|
availableBalance: 'Available Balance',
|
|
1154
1156
|
usage: 'Usage',
|
|
@@ -1180,7 +1182,8 @@ export default flat({
|
|
|
1180
1182
|
viewDetails: 'View Details',
|
|
1181
1183
|
},
|
|
1182
1184
|
creditTransactions: {
|
|
1183
|
-
|
|
1185
|
+
tab: 'Transactions',
|
|
1186
|
+
title: 'Transactions',
|
|
1184
1187
|
summary: 'Transaction Summary',
|
|
1185
1188
|
noTransactions: 'No credit transactions found',
|
|
1186
1189
|
totalTransactions: 'Total Transactions',
|
package/src/locales/zh.tsx
CHANGED
|
@@ -63,6 +63,7 @@ export default flat({
|
|
|
63
63
|
effectiveDate: '生效时间',
|
|
64
64
|
expirationDate: '过期时间',
|
|
65
65
|
creditGrant: '信用额度',
|
|
66
|
+
date: '日期',
|
|
66
67
|
subscription: '订阅',
|
|
67
68
|
meterEvent: '计量事件',
|
|
68
69
|
creditAmount: '额度',
|
|
@@ -927,11 +928,12 @@ export default flat({
|
|
|
927
928
|
postal_code: '邮政编码',
|
|
928
929
|
},
|
|
929
930
|
creditGrants: {
|
|
931
|
+
tab: '信用额度',
|
|
930
932
|
title: '信用额度',
|
|
931
933
|
summary: '额度汇总',
|
|
932
934
|
noGrants: '未找到信用额度',
|
|
933
935
|
grantDetail: '信用额度详情',
|
|
934
|
-
overview: '
|
|
936
|
+
overview: '概览',
|
|
935
937
|
overviewDescription: '监控所有货币的信用余额、使用情况和未偿债务。',
|
|
936
938
|
availableBalance: '可用余额',
|
|
937
939
|
usage: '使用情况',
|
|
@@ -1103,7 +1105,8 @@ export default flat({
|
|
|
1103
1105
|
appBalance: '热钱包余额',
|
|
1104
1106
|
},
|
|
1105
1107
|
creditGrants: {
|
|
1106
|
-
|
|
1108
|
+
tab: '信用额度',
|
|
1109
|
+
title: '额度',
|
|
1107
1110
|
summary: '额度汇总',
|
|
1108
1111
|
noGrants: '未找到信用额度',
|
|
1109
1112
|
grantDetail: '信用额度详情',
|
|
@@ -1139,6 +1142,7 @@ export default flat({
|
|
|
1139
1142
|
viewDetails: '查看详情',
|
|
1140
1143
|
},
|
|
1141
1144
|
creditTransactions: {
|
|
1145
|
+
tab: '账单',
|
|
1142
1146
|
title: '额度账单',
|
|
1143
1147
|
summary: '账单汇总',
|
|
1144
1148
|
noTransactions: '未找到额度账单',
|
|
@@ -132,7 +132,7 @@ export default function CreatePricingTable() {
|
|
|
132
132
|
flex: 2,
|
|
133
133
|
position: 'relative',
|
|
134
134
|
borderRight: '1px solid',
|
|
135
|
-
borderColor: '
|
|
135
|
+
borderColor: 'divider',
|
|
136
136
|
}}>
|
|
137
137
|
<Stack
|
|
138
138
|
spacing={2}
|
|
@@ -159,7 +159,7 @@ export default function CreatePricingTable() {
|
|
|
159
159
|
justifyContent: 'flex-end',
|
|
160
160
|
position: 'absolute',
|
|
161
161
|
borderTop: '1px solid',
|
|
162
|
-
borderColor: '
|
|
162
|
+
borderColor: 'divider',
|
|
163
163
|
left: 0,
|
|
164
164
|
bottom: 0,
|
|
165
165
|
}}>
|
|
@@ -26,7 +26,7 @@ export default function PricingTablePage({ id }: Props) {
|
|
|
26
26
|
theme={undefined}
|
|
27
27
|
hideNavMenu={undefined}
|
|
28
28
|
maxWidth={false}
|
|
29
|
-
sx={{ borderBottom: '1px solid', borderColor: '
|
|
29
|
+
sx={{ borderBottom: '1px solid', borderColor: 'divider' }}
|
|
30
30
|
/>
|
|
31
31
|
|
|
32
32
|
<Stack
|