payment-kit 1.18.38 → 1.18.40

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.
Files changed (41) hide show
  1. package/api/src/integrations/stripe/handlers/invoice.ts +22 -0
  2. package/api/src/integrations/stripe/handlers/payment-intent.ts +9 -1
  3. package/api/src/integrations/stripe/handlers/subscription.ts +137 -1
  4. package/api/src/libs/subscription.ts +107 -97
  5. package/api/src/queues/payment.ts +4 -0
  6. package/api/src/routes/checkout-sessions.ts +3 -1
  7. package/api/src/routes/subscriptions.ts +27 -18
  8. package/blocklet.yml +1 -1
  9. package/package.json +19 -19
  10. package/scripts/sdk.js +27 -1
  11. package/src/components/customer/link.tsx +6 -0
  12. package/src/components/info-card.tsx +2 -2
  13. package/src/components/info-metric.tsx +1 -1
  14. package/src/components/metadata/list.tsx +4 -2
  15. package/src/components/subscription/description.tsx +8 -6
  16. package/src/components/subscription/portal/actions.tsx +224 -45
  17. package/src/components/subscription/portal/list.tsx +153 -74
  18. package/src/components/subscription/status.tsx +17 -5
  19. package/src/locales/en.tsx +12 -7
  20. package/src/locales/zh.tsx +6 -2
  21. package/src/pages/admin/billing/invoices/detail.tsx +1 -5
  22. package/src/pages/admin/billing/subscriptions/detail.tsx +1 -5
  23. package/src/pages/admin/customers/customers/detail.tsx +1 -5
  24. package/src/pages/admin/developers/events/detail.tsx +1 -5
  25. package/src/pages/admin/developers/index.tsx +1 -1
  26. package/src/pages/admin/developers/webhooks/detail.tsx +1 -3
  27. package/src/pages/admin/overview.tsx +4 -4
  28. package/src/pages/admin/payments/intents/detail.tsx +5 -6
  29. package/src/pages/admin/payments/payouts/detail.tsx +1 -5
  30. package/src/pages/admin/payments/refunds/detail.tsx +1 -5
  31. package/src/pages/admin/products/links/detail.tsx +1 -5
  32. package/src/pages/admin/products/prices/detail.tsx +1 -5
  33. package/src/pages/admin/products/pricing-tables/detail.tsx +1 -5
  34. package/src/pages/admin/products/products/detail.tsx +1 -5
  35. package/src/pages/admin/settings/payment-methods/index.tsx +1 -1
  36. package/src/pages/customer/index.tsx +67 -138
  37. package/src/pages/customer/payout/detail.tsx +37 -49
  38. package/src/pages/customer/subscription/change-payment.tsx +2 -35
  39. package/src/pages/customer/subscription/detail.tsx +5 -6
  40. package/src/pages/integrations/donations/index.tsx +1 -1
  41. package/src/pages/integrations/overview.tsx +1 -1
@@ -3,7 +3,17 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
3
3
  import Empty from '@arcblock/ux/lib/Empty';
4
4
  import { api, formatPrice, getSubscriptionTimeSummary, useMobile } from '@blocklet/payment-react';
5
5
  import type { TSubscriptionExpanded } from '@blocklet/payment-types';
6
- import { Avatar, AvatarGroup, Box, Button, CircularProgress, Stack, StackProps, Typography } from '@mui/material';
6
+ import {
7
+ Avatar,
8
+ AvatarGroup,
9
+ Box,
10
+ Button,
11
+ CircularProgress,
12
+ Divider,
13
+ Stack,
14
+ StackProps,
15
+ Typography,
16
+ } from '@mui/material';
7
17
  import { useInfiniteScroll } from 'ahooks';
8
18
 
9
19
  import { useRef } from 'react';
@@ -39,8 +49,6 @@ type Props = {
39
49
  setHasSubscriptions?: (state: boolean) => void;
40
50
  } & Omit<StackProps, 'onChange'>;
41
51
 
42
- const pageSize = 5;
43
-
44
52
  export default function CurrentSubscriptions({
45
53
  id,
46
54
  status,
@@ -52,9 +60,10 @@ export default function CurrentSubscriptions({
52
60
  setHasSubscriptions = () => {},
53
61
  ...rest
54
62
  }: Props) {
55
- const { t } = useLocaleContext();
63
+ const { t, locale } = useLocaleContext();
56
64
  const { isMobile } = useMobile();
57
65
  const listRef = useRef<HTMLDivElement | null>(null);
66
+ const pageSize = isMobile ? 5 : 10;
58
67
 
59
68
  const { data, loadMore, loadingMore, loading, reload } = useInfiniteScroll<SubscriptionListResponse>(
60
69
  (d) => {
@@ -91,54 +100,76 @@ export default function CurrentSubscriptions({
91
100
  const hasAnySubscriptions = data.totalCount > 0;
92
101
 
93
102
  const hasMore = data && data.list?.length < data.count;
94
- const size = { width: 48, height: 48 };
95
-
103
+ const size = isMobile ? { width: 42, height: 42 } : { width: 44, height: 44 };
96
104
  return (
97
- <Stack direction="column" spacing={2} sx={{ mt: 2 }}>
105
+ <Stack direction="column" spacing={2} sx={{ mt: 2, containerType: 'inline-size' }}>
98
106
  {data.list?.length > 0 ? (
99
107
  <>
100
108
  <Stack
101
109
  ref={listRef}
102
- spacing={2}
103
110
  sx={{
104
111
  maxHeight: {
105
112
  xs: '100%',
106
- md: '500px',
113
+ md: '700px',
107
114
  },
108
115
  overflowY: 'auto',
109
116
  webkitOverflowScrolling: 'touch',
117
+ display: 'grid',
118
+ gridTemplateColumns: {
119
+ xs: 'repeat(1, 1fr)',
120
+ md: 'repeat(2, 1fr)',
121
+ },
122
+ '@container (max-width: 600px)': {
123
+ gridTemplateColumns: 'repeat(1, 1fr)',
124
+ },
125
+ gap: 2,
110
126
  }}>
111
127
  {data.list.map((subscription) => {
128
+ const summary = getSubscriptionTimeSummary(subscription, locale);
129
+ const subscriptionTime = summary
130
+ ? t(`admin.subscription.${summary?.action}`, {
131
+ date: summary?.time,
132
+ prefix: summary?.isToday ? 'at' : 'on',
133
+ })
134
+ : '';
112
135
  return (
113
136
  <Stack
114
137
  key={subscription.id}
115
- direction="row"
116
- justifyContent="space-between"
117
- gap={{
118
- xs: 1,
119
- sm: 2,
120
- }}
121
138
  sx={{
122
- padding: 1.5,
123
- background: 'grey.50',
139
+ padding: 2,
140
+ height: '100%',
141
+ borderRadius: 1,
142
+ border: '1px solid',
143
+ borderColor: 'divider',
144
+ boxShadow: 1,
145
+ display: 'flex',
146
+ flexDirection: 'column',
147
+ justifyContent: 'space-between',
148
+ gap: 2,
124
149
  '&:hover': {
125
- backgroundColor: 'grey.100',
150
+ backgroundColor: 'grey.50',
126
151
  transition: 'background-color 200ms linear',
127
152
  cursor: 'pointer',
128
153
  },
129
154
  }}
130
155
  flexWrap="wrap">
131
- <Stack direction="column" flex={1} spacing={0.5} {...rest}>
156
+ <Stack direction="column" flex={1} spacing={2} {...rest}>
132
157
  <Stack
133
- direction={isMobile ? 'column' : 'row'}
158
+ direction="row"
134
159
  spacing={1}
135
- alignItems={isMobile ? 'flex-start' : 'center'}
136
- flexWrap="wrap"
160
+ alignItems="flex-start"
137
161
  justifyContent="space-between"
138
162
  onClick={() => onClickSubscription(subscription)}>
139
- <Stack direction="row" spacing={1.5}>
140
- <AvatarGroup max={3}>
141
- {subscription.items.map((item) =>
163
+ <Stack direction="row" spacing={1.5} alignItems="center">
164
+ <AvatarGroup
165
+ max={2}
166
+ sx={{
167
+ '& .MuiAvatar-colorDefault': {
168
+ ...size,
169
+ boxSizing: 'border-box',
170
+ },
171
+ }}>
172
+ {subscription.items.slice(0, 2).map((item) =>
142
173
  item.price.product.images.length > 0 ? (
143
174
  // @ts-ignore
144
175
  <Avatar
@@ -155,15 +186,13 @@ export default function CurrentSubscriptions({
155
186
  )
156
187
  )}
157
188
  </AvatarGroup>
158
- <Stack
159
- direction="column"
160
- spacing={0.5}
161
- sx={{
162
- '.MuiTypography-body1': {
163
- fontSize: '16px',
164
- },
165
- }}>
166
- <SubscriptionDescription subscription={subscription} hideSubscription variant="body1" />
189
+ <Stack direction="column" spacing={0.25}>
190
+ <SubscriptionDescription
191
+ subscription={subscription}
192
+ hideSubscription
193
+ maxLength={isMobile ? 30 : 40}
194
+ variant={isMobile ? 'subtitle2' : 'subtitle1'}
195
+ />
167
196
  <SubscriptionStatus
168
197
  subscription={subscription}
169
198
  sx={{ height: 18, width: 'fit-content' }}
@@ -171,40 +200,40 @@ export default function CurrentSubscriptions({
171
200
  />
172
201
  </Stack>
173
202
  </Stack>
174
- <Stack>
175
- <Typography variant="subtitle1" fontWeight={500} fontSize={16}>
176
- {
177
- // @ts-ignore
178
- formatPrice(subscription.items[0].price, subscription.paymentCurrency)
179
- }
180
- </Typography>
181
- </Stack>
182
203
  </Stack>
204
+
205
+ <Divider />
183
206
  <Stack
184
207
  gap={1}
185
208
  justifyContent="space-between"
186
- flexWrap="wrap"
209
+ flexWrap="nowrap"
187
210
  sx={{
188
- flexDirection: {
189
- xs: 'column',
190
- lg: 'row',
191
- },
192
- alignItems: {
193
- xs: 'flex-start',
194
- lg: 'center',
195
- },
211
+ flexDirection: 'row',
212
+ alignItems: 'center',
196
213
  }}>
197
214
  <Box
198
215
  component="div"
199
216
  onClick={() => onClickSubscription(subscription)}
200
- sx={{ display: 'flex', gap: 0.5, flexDirection: isMobile ? 'column' : 'row' }}>
201
- {getSubscriptionTimeSummary(subscription)
202
- .split(',')
203
- .map((x) => (
204
- <Typography key={x} variant="body1" color="text.secondary">
205
- {x}
206
- </Typography>
207
- ))}
217
+ sx={{
218
+ display: 'flex',
219
+ gap: {
220
+ xs: 0.5,
221
+ md: 1,
222
+ },
223
+ flexDirection: 'row',
224
+ flexWrap: 'wrap',
225
+ }}>
226
+ <Typography variant={isMobile ? 'subtitle2' : 'subtitle1'} sx={{ whiteSpace: 'nowrap' }}>
227
+ {
228
+ // @ts-ignore
229
+ formatPrice(subscription.items[0].price, subscription.paymentCurrency)
230
+ }
231
+ </Typography>
232
+ {subscriptionTime && (
233
+ <Typography variant="body2" color="text.secondary">
234
+ ({subscriptionTime})
235
+ </Typography>
236
+ )}
208
237
  </Box>
209
238
  <SubscriptionActions
210
239
  subscription={subscription}
@@ -216,32 +245,82 @@ export default function CurrentSubscriptions({
216
245
  }}
217
246
  showUnsubscribe={false}
218
247
  showRecharge={!isWillCanceled(subscription)}
248
+ showBalanceInfo
249
+ includeActions={['recharge']}
219
250
  actionProps={{
220
- cancel: {
221
- variant: 'outlined',
222
- color: 'primary',
223
- },
224
- recover: {
225
- variant: 'outlined',
226
- color: 'info',
227
- },
228
- pastDue: {
229
- variant: 'outlined',
251
+ recharge: {
252
+ variant: 'text',
230
253
  color: 'primary',
254
+ sx: {
255
+ whiteSpace: 'nowrap',
256
+ },
231
257
  },
232
258
  }}
233
259
  />
234
260
  </Stack>
235
261
  </Stack>
262
+ <Stack
263
+ sx={{
264
+ display: 'flex',
265
+ justifyContent: 'flex-end',
266
+ '.action-button': {
267
+ flex: 1,
268
+ },
269
+ }}>
270
+ <SubscriptionActions
271
+ subscription={subscription}
272
+ onChange={(v) => {
273
+ reload();
274
+ if (onChange) {
275
+ onChange(v);
276
+ }
277
+ }}
278
+ forceShowDetailAction
279
+ showUnsubscribe={false}
280
+ excludeActions={['recharge']}
281
+ actionProps={{
282
+ cancel: {
283
+ variant: 'outlined',
284
+ color: 'primary',
285
+ },
286
+ recover: {
287
+ variant: 'outlined',
288
+ color: 'info',
289
+ },
290
+ pastDue: {
291
+ variant: 'outlined',
292
+ color: 'primary',
293
+ },
294
+ detail: {
295
+ variant: 'contained',
296
+ sx: {
297
+ color: 'text.primary',
298
+
299
+ backgroundColor: 'grey.100',
300
+ '&:hover': {
301
+ backgroundColor: 'grey.200',
302
+ },
303
+ },
304
+ },
305
+ menu: {
306
+ sx: {
307
+ color: 'text.primary',
308
+ },
309
+ },
310
+ }}
311
+ mode="menu-only"
312
+ buttonSize="medium"
313
+ />
314
+ </Stack>
236
315
  </Stack>
237
316
  );
238
317
  })}
239
- {hasMore && !isMobile && showLoadingMore && (
240
- <Box alignItems="center" gap={0.5} display="flex" mt={0.5}>
241
- {t('common.loadingMore', { resource: t('admin.subscriptions') })}
242
- </Box>
243
- )}
244
318
  </Stack>
319
+ {hasMore && !isMobile && showLoadingMore && (
320
+ <Box alignItems="center" gap={0.5} display="flex" mt={0.5}>
321
+ {t('common.loadingMore', { resource: t('admin.subscriptions') })}
322
+ </Box>
323
+ )}
245
324
  {isMobile && (
246
325
  <Box>
247
326
  {hasMore && (
@@ -1,5 +1,5 @@
1
1
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
2
- import { Status, formatToDate, getSubscriptionStatusColor, formatSubscriptionStatus } from '@blocklet/payment-react';
2
+ import { Status, getSubscriptionStatusColor, formatSubscriptionStatus, getLineTimeInfo } from '@blocklet/payment-react';
3
3
  import type { TSubscription } from '@blocklet/payment-types';
4
4
  import { AccessTimeOutlined } from '@mui/icons-material';
5
5
 
@@ -13,10 +13,14 @@ export default function SubscriptionStatus({
13
13
  const { t } = useLocaleContext();
14
14
  if (subscription.status === 'active' || subscription.status === 'trialing') {
15
15
  if (subscription.cancel_at_period_end && subscription.current_period_end > Date.now() / 1000) {
16
+ const dateInfo = getLineTimeInfo(subscription.current_period_end * 1000);
16
17
  return (
17
18
  <Status
18
19
  icon={<AccessTimeOutlined />}
19
- label={t('admin.subscription.cancel.will', { date: formatToDate(subscription.current_period_end * 1000) })}
20
+ label={t('admin.subscription.cancel.will', {
21
+ date: dateInfo.time,
22
+ prefix: dateInfo.isToday ? 'at' : 'on',
23
+ })}
20
24
  color="warning"
21
25
  {...rest}
22
26
  />
@@ -24,10 +28,14 @@ export default function SubscriptionStatus({
24
28
  }
25
29
 
26
30
  if (subscription.cancel_at && subscription.cancel_at >= Date.now() / 1000) {
31
+ const dateInfo = getLineTimeInfo(subscription.cancel_at * 1000);
27
32
  return (
28
33
  <Status
29
34
  icon={<AccessTimeOutlined />}
30
- label={t('admin.subscription.cancel.will', { date: formatToDate(subscription.cancel_at * 1000) })}
35
+ label={t('admin.subscription.cancel.will', {
36
+ date: dateInfo.time,
37
+ prefix: dateInfo.isToday ? 'at' : 'on',
38
+ })}
31
39
  color="warning"
32
40
  {...rest}
33
41
  />
@@ -35,10 +43,12 @@ export default function SubscriptionStatus({
35
43
  }
36
44
 
37
45
  if (subscription.trial_end && subscription.trial_end > Date.now() / 1000) {
46
+ const dateInfo = getLineTimeInfo(subscription.trial_end * 1000);
38
47
  return (
39
48
  <Status
40
49
  label={t('admin.subscription.trialEnd', {
41
- date: formatToDate(subscription.trial_end * 1000),
50
+ date: dateInfo.time,
51
+ prefix: dateInfo.isToday ? 'at' : 'on',
42
52
  })}
43
53
  color="info"
44
54
  {...rest}
@@ -49,11 +59,13 @@ export default function SubscriptionStatus({
49
59
 
50
60
  if (subscription.pause_collection && ['active', 'trialing'].includes(subscription.status)) {
51
61
  if (subscription.pause_collection.resumes_at && subscription.pause_collection.resumes_at > Date.now() / 1000) {
62
+ const dateInfo = getLineTimeInfo(subscription.pause_collection.resumes_at * 1000);
52
63
  return (
53
64
  <Status
54
65
  icon={<AccessTimeOutlined />}
55
66
  label={t('admin.subscription.pause.until.custom', {
56
- date: formatToDate(subscription.pause_collection.resumes_at * 1000),
67
+ date: dateInfo.time,
68
+ prefix: dateInfo.isToday ? 'at' : 'on',
57
69
  })}
58
70
  color="default"
59
71
  {...rest}
@@ -506,7 +506,7 @@ export default flat({
506
506
  attention: 'Uncollectible invoices',
507
507
  name: 'Invoice',
508
508
  from: 'Billed from',
509
- empty: 'No invoice',
509
+ empty: 'No invoices',
510
510
  number: 'Invoice Number',
511
511
  description: 'Billing Description',
512
512
  dueDate: 'Due',
@@ -522,7 +522,7 @@ export default flat({
522
522
  subscription: {
523
523
  view: 'View subscription',
524
524
  name: 'Subscription',
525
- empty: 'No subscription',
525
+ empty: 'No subscriptions',
526
526
  viewAll: 'View all subscriptions',
527
527
  noActiveEmpty: 'You currently have no active subscriptions. You can choose to view your subscription history.',
528
528
  attention: 'Past due subscriptions',
@@ -530,7 +530,10 @@ export default flat({
530
530
  collectionMethod: 'Billing',
531
531
  currentPeriod: 'Current Period',
532
532
  trialingPeriod: 'Trial Period',
533
- trialEnd: 'Trial ends {date}',
533
+ trialEnd: 'Trial ends {prefix} {date}',
534
+ willEnd: 'Will end {prefix} {date}',
535
+ ended: 'Ended {prefix} {date}',
536
+ renew: 'Renew {prefix} {date}',
534
537
  discount: 'Discount',
535
538
  startedAt: 'Started',
536
539
  nextInvoice: 'Next Invoice',
@@ -547,7 +550,7 @@ export default flat({
547
550
  schedule: 'Scheduled to cancel',
548
551
  title: 'Cancel subscription',
549
552
  required: 'Custom cancel time is required',
550
- will: 'End on {date}',
553
+ will: 'End {prefix} {date}',
551
554
  done: 'Canceled',
552
555
  at: {
553
556
  title: 'Cancel',
@@ -813,10 +816,12 @@ export default flat({
813
816
  customer: {
814
817
  subscription: {
815
818
  cancel: 'Cancel Subscription',
819
+ manage: 'Manage Subscription',
820
+ title: 'Subscriptions',
816
821
  },
817
822
  invoiceHistory: 'Invoice History',
818
823
  product: {
819
- empty: 'No Product',
824
+ empty: 'No Products',
820
825
  },
821
826
  recharge: {
822
827
  title: 'Add Funds',
@@ -885,12 +890,12 @@ export default flat({
885
890
  donation: 'Donation',
886
891
  },
887
892
  payout: {
888
- empty: 'No Payout',
893
+ empty: 'No Revenues',
889
894
  payer: 'Payer',
890
895
  receiver: 'Receiver',
891
896
  payTxHash: 'Payment TxHash',
892
897
  viewReference: 'View Reference',
893
- title: 'Revenue',
898
+ title: 'Revenues',
894
899
  },
895
900
  pastDue: {
896
901
  warning: 'You have due invoices, please pay them to keep your services active',
@@ -519,7 +519,10 @@ export default flat({
519
519
  collectionMethod: '计费',
520
520
  currentPeriod: '当前周期',
521
521
  trialingPeriod: '试用期',
522
- trialEnd: '试用期结束于{date}',
522
+ trialEnd: '试用期结束于 {date}',
523
+ willEnd: '将于 {date} 结束',
524
+ ended: '结束于 {date}',
525
+ renew: '下次续费: {date}',
523
526
  discount: '折扣',
524
527
  startedAt: '开始于',
525
528
  nextInvoice: '下次账单时间',
@@ -535,7 +538,7 @@ export default flat({
535
538
  schedule: '计划取消',
536
539
  title: '取消订阅',
537
540
  required: '必须指定自定义取消时间',
538
- will: '于{date}取消',
541
+ will: '于 {date} 取消',
539
542
  done: '已取消',
540
543
  at: {
541
544
  title: '取消',
@@ -789,6 +792,7 @@ export default flat({
789
792
  },
790
793
  customer: {
791
794
  subscription: {
795
+ manage: '管理订阅',
792
796
  cancel: '取消订阅',
793
797
  },
794
798
  invoiceHistory: '历史账单',
@@ -172,11 +172,7 @@ export default function InvoiceDetail(props: { id: string }) {
172
172
  sm: 'column',
173
173
  md: 'row',
174
174
  },
175
- alignItems: {
176
- xs: 'flex-start',
177
- sm: 'flex-start',
178
- md: 'center',
179
- },
175
+ alignItems: 'flex-start',
180
176
  gap: {
181
177
  xs: 1,
182
178
  sm: 1,
@@ -143,11 +143,7 @@ export default function SubscriptionDetail(props: { id: string }) {
143
143
  sm: 'column',
144
144
  md: 'row',
145
145
  },
146
- alignItems: {
147
- xs: 'flex-start',
148
- sm: 'flex-start',
149
- md: 'center',
150
- },
146
+ alignItems: 'flex-start',
151
147
  gap: {
152
148
  xs: 1,
153
149
  sm: 1,
@@ -232,11 +232,7 @@ export default function CustomerDetail(props: { id: string }) {
232
232
  sm: 'column',
233
233
  md: 'row',
234
234
  },
235
- alignItems: {
236
- xs: 'flex-start',
237
- sm: 'flex-start',
238
- md: 'center',
239
- },
235
+ alignItems: 'flex-start',
240
236
  gap: {
241
237
  xs: 1,
242
238
  sm: 1,
@@ -85,11 +85,7 @@ export default function EventDetail(props: { id: string }) {
85
85
  sm: 'column',
86
86
  md: 'row',
87
87
  },
88
- alignItems: {
89
- xs: 'flex-start',
90
- sm: 'flex-start',
91
- md: 'center',
92
- },
88
+ alignItems: 'flex-start',
93
89
  gap: {
94
90
  xs: 1,
95
91
  sm: 1,
@@ -47,7 +47,7 @@ export default function DevelopersIndex() {
47
47
 
48
48
  return (
49
49
  <div>
50
- <Typography variant="h5" sx={{ mb: 1, fontWeight: 600 }}>
50
+ <Typography variant="h5" sx={{ mb: 1 }}>
51
51
  {t('admin.developers')}
52
52
  </Typography>
53
53
  {/* @ts-ignore */}
@@ -49,9 +49,7 @@ export default function WebhookDetail(props: { id: string }) {
49
49
  <Box mt={2}>
50
50
  <Stack direction="row" justifyContent="space-between" alignItems="center">
51
51
  <Stack direction="column" alignItems="flex-start">
52
- <Typography variant="h5" fontWeight={600}>
53
- {data.url}
54
- </Typography>
52
+ <Typography variant="h5">{data.url}</Typography>
55
53
  <Typography variant="body1" color="text.secondary">
56
54
  {data.description}
57
55
  </Typography>
@@ -222,19 +222,19 @@ export default function Overview() {
222
222
  </Button>
223
223
  </Stack>
224
224
  <Stack direction="column" gap={1}>
225
- <Typography component="h4" variant="h5">
225
+ <Typography component="h4" variant="subtitle1">
226
226
  {t('admin.paymentIntent.list')}
227
227
  </Typography>
228
228
  <Chart loading={!trend.data} height={320} data={payments} currencies={currencies} />
229
229
  </Stack>
230
230
  <Stack direction="column" gap={1}>
231
- <Typography component="h4" variant="h5">
231
+ <Typography component="h4" variant="subtitle1">
232
232
  {t('admin.payouts')}
233
233
  </Typography>
234
234
  <Chart loading={!trend.data} height={320} data={payouts} currencies={currencies} />
235
235
  </Stack>
236
236
  <Stack direction="column" gap={1}>
237
- <Typography component="h4" variant="h5">
237
+ <Typography component="h4" variant="subtitle1">
238
238
  {t('admin.refunds')}
239
239
  </Typography>
240
240
  <Chart loading={!trend.data} height={320} data={refunds} currencies={currencies} />
@@ -298,7 +298,7 @@ export default function Overview() {
298
298
  sx={{ width: 36, height: 36 }}
299
299
  />
300
300
  <Box flex={1}>
301
- <Typography variant="h5" component="div" sx={{ fontSize: '1.75rem' }}>
301
+ <Typography variant="body1" component="div" sx={{ fontSize: '1.75rem' }}>
302
302
  {formatBNStr(
303
303
  summary.data?.balances?.[currencyId] as string,
304
304
  currencies[currencyId]?.decimal as number
@@ -140,7 +140,10 @@ export default function PaymentIntentDetail(props: { id: string }) {
140
140
  sx={{ width: '52px', height: '52px', borderRadius: 0.5 }}
141
141
  />
142
142
  <Stack direction="column" alignItems="flex-start" justifyContent="space-around">
143
- <Amount amount={received} sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }} />
143
+ <Amount
144
+ amount={data?.amount_received === '0' ? total : received}
145
+ sx={{ my: 0, fontSize: '1.75rem', lineHeight: '32px' }}
146
+ />
144
147
  <Copyable text={props.id} />
145
148
  </Stack>
146
149
  </Stack>
@@ -158,11 +161,7 @@ export default function PaymentIntentDetail(props: { id: string }) {
158
161
  sm: 'column',
159
162
  md: 'row',
160
163
  },
161
- alignItems: {
162
- xs: 'flex-start',
163
- sm: 'flex-start',
164
- md: 'center',
165
- },
164
+ alignItems: 'flex-start',
166
165
  gap: {
167
166
  xs: 1,
168
167
  sm: 1,
@@ -182,11 +182,7 @@ export default function PayoutDetail(props: { id: string }) {
182
182
  sm: 'column',
183
183
  md: 'row',
184
184
  },
185
- alignItems: {
186
- xs: 'flex-start',
187
- sm: 'flex-start',
188
- md: 'center',
189
- },
185
+ alignItems: 'flex-start',
190
186
  gap: {
191
187
  xs: 1,
192
188
  sm: 1,
@@ -156,11 +156,7 @@ export default function RefundDetail(props: { id: string }) {
156
156
  sm: 'column',
157
157
  md: 'row',
158
158
  },
159
- alignItems: {
160
- xs: 'flex-start',
161
- sm: 'flex-start',
162
- md: 'center',
163
- },
159
+ alignItems: 'flex-start',
164
160
  gap: {
165
161
  xs: 1,
166
162
  sm: 1,
@@ -171,11 +171,7 @@ export default function PaymentLinkDetail(props: { id: string }) {
171
171
  sm: 'column',
172
172
  md: 'row',
173
173
  },
174
- alignItems: {
175
- xs: 'flex-start',
176
- sm: 'flex-start',
177
- md: 'center',
178
- },
174
+ alignItems: 'flex-start',
179
175
  gap: {
180
176
  xs: 1,
181
177
  sm: 1,