payment-kit 1.18.13 → 1.18.14
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/index.ts +2 -0
- package/api/src/integrations/stripe/resource.ts +53 -11
- package/api/src/libs/auth.ts +14 -0
- package/api/src/libs/payment.ts +77 -2
- package/api/src/libs/util.ts +8 -0
- package/api/src/queues/payment.ts +50 -1
- package/api/src/queues/payout.ts +297 -0
- package/api/src/routes/checkout-sessions.ts +2 -7
- package/api/src/routes/payment-currencies.ts +117 -1
- package/api/src/routes/payment-methods.ts +19 -9
- package/api/src/routes/subscriptions.ts +2 -8
- package/api/src/store/migrations/20250305-vault-config.ts +21 -0
- package/api/src/store/models/payment-currency.ts +14 -0
- package/api/src/store/models/payout.ts +21 -0
- package/api/src/store/models/types.ts +6 -0
- package/blocklet.yml +1 -1
- package/package.json +18 -18
- package/src/app.tsx +116 -120
- package/src/components/customer/overdraft-protection.tsx +1 -0
- package/src/components/layout/admin.tsx +6 -0
- package/src/components/layout/user.tsx +1 -0
- package/src/components/metadata/editor.tsx +7 -1
- package/src/components/metadata/list.tsx +3 -0
- package/src/components/passport/assign.tsx +3 -0
- package/src/components/payment-link/rename.tsx +1 -0
- package/src/components/pricing-table/rename.tsx +1 -0
- package/src/components/product/add-price.tsx +1 -0
- package/src/components/product/edit-price.tsx +1 -0
- package/src/components/product/edit.tsx +1 -0
- package/src/components/subscription/actions/index.tsx +1 -0
- package/src/components/subscription/portal/actions.tsx +1 -0
- package/src/locales/en.tsx +42 -0
- package/src/locales/zh.tsx +37 -0
- package/src/pages/admin/payments/payouts/detail.tsx +47 -43
- package/src/pages/admin/settings/index.tsx +3 -3
- package/src/pages/admin/settings/payment-methods/index.tsx +33 -1
- package/src/pages/admin/settings/vault-config/edit-form.tsx +253 -0
- package/src/pages/admin/settings/vault-config/index.tsx +352 -0
- package/src/pages/integrations/donations/edit-form.tsx +0 -1
package/src/app.tsx
CHANGED
|
@@ -43,119 +43,113 @@ const IntegrationsPage = React.lazy(() => import('./pages/integrations'));
|
|
|
43
43
|
|
|
44
44
|
function App() {
|
|
45
45
|
return (
|
|
46
|
-
<
|
|
47
|
-
<
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
/>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
</Routes>
|
|
154
|
-
</Suspense>
|
|
155
|
-
</ErrorBoundary>
|
|
156
|
-
</LocaleProvider>
|
|
157
|
-
</TransitionProvider>
|
|
158
|
-
</PaymentThemeProvider>
|
|
46
|
+
<TransitionProvider>
|
|
47
|
+
<LocaleProvider translations={translations} fallbackLocale="en">
|
|
48
|
+
<ErrorBoundary FallbackComponent={ErrorFallback} onReset={window.location.reload}>
|
|
49
|
+
<Suspense
|
|
50
|
+
fallback={
|
|
51
|
+
<Center>
|
|
52
|
+
<CircularProgress />
|
|
53
|
+
</Center>
|
|
54
|
+
}>
|
|
55
|
+
<Routes>
|
|
56
|
+
<Route path="/" element={<HomePage />} />
|
|
57
|
+
<Route path="/checkout/:action/:id" element={<CheckoutPage />} />
|
|
58
|
+
<Route key="admin-index" path="/admin" element={<AdminPage />} />,
|
|
59
|
+
<Route key="admin-tabs" path="/admin/:group" element={<AdminPage />} />,
|
|
60
|
+
<Route key="admin-sub" path="/admin/:group/:page" element={<AdminPage />} />,
|
|
61
|
+
<Route key="admin-fallback" path="/admin/*" element={<AdminPage />} />,
|
|
62
|
+
<Route key="integrations-index" path="/integrations" element={<IntegrationsPage />} />
|
|
63
|
+
<Route key="integrations-tabs" path="/integrations/:group" element={<IntegrationsPage />} />
|
|
64
|
+
<Route key="integrations-sub" path="/integrations/:group/:page" element={<IntegrationsPage />} />
|
|
65
|
+
<Route key="integrations-fallback" path="/integrations/*" element={<IntegrationsPage />} />
|
|
66
|
+
<Route
|
|
67
|
+
key="customer-home"
|
|
68
|
+
path="/customer"
|
|
69
|
+
element={
|
|
70
|
+
<UserLayout>
|
|
71
|
+
<CustomerHome />
|
|
72
|
+
</UserLayout>
|
|
73
|
+
}
|
|
74
|
+
/>
|
|
75
|
+
<Route
|
|
76
|
+
key="customer-subscription"
|
|
77
|
+
path="/customer/subscription/:id"
|
|
78
|
+
element={
|
|
79
|
+
<UserLayout>
|
|
80
|
+
<CustomerSubscriptionDetail />
|
|
81
|
+
</UserLayout>
|
|
82
|
+
}
|
|
83
|
+
/>
|
|
84
|
+
<Route
|
|
85
|
+
key="customer-subscription-change-plan"
|
|
86
|
+
path="/customer/subscription/:id/change-plan"
|
|
87
|
+
element={
|
|
88
|
+
<UserLayout>
|
|
89
|
+
<CustomerSubscriptionChangePlan />
|
|
90
|
+
</UserLayout>
|
|
91
|
+
}
|
|
92
|
+
/>
|
|
93
|
+
<Route
|
|
94
|
+
key="customer-subscription-change-payment"
|
|
95
|
+
path="/customer/subscription/:id/change-payment"
|
|
96
|
+
element={
|
|
97
|
+
<UserLayout>
|
|
98
|
+
<CustomerSubscriptionChangePayment />
|
|
99
|
+
</UserLayout>
|
|
100
|
+
}
|
|
101
|
+
/>
|
|
102
|
+
<Route
|
|
103
|
+
key="customer-recharge"
|
|
104
|
+
path="/customer/subscription/:id/recharge"
|
|
105
|
+
element={
|
|
106
|
+
<UserLayout>
|
|
107
|
+
<CustomerRecharge />
|
|
108
|
+
</UserLayout>
|
|
109
|
+
}
|
|
110
|
+
/>
|
|
111
|
+
<Route key="customer-embed" path="/customer/embed/subscription" element={<CustomerSubscriptionEmbed />} />
|
|
112
|
+
,
|
|
113
|
+
<Route
|
|
114
|
+
key="subscription-embed"
|
|
115
|
+
path="/embed/customer/subscription"
|
|
116
|
+
element={<CustomerSubscriptionEmbed />}
|
|
117
|
+
/>
|
|
118
|
+
,
|
|
119
|
+
<Route
|
|
120
|
+
key="customer-due"
|
|
121
|
+
path="/customer/invoice/past-due"
|
|
122
|
+
element={
|
|
123
|
+
<UserLayout>
|
|
124
|
+
<CustomerInvoicePastDue />
|
|
125
|
+
</UserLayout>
|
|
126
|
+
}
|
|
127
|
+
/>
|
|
128
|
+
<Route
|
|
129
|
+
key="customer-invoice"
|
|
130
|
+
path="/customer/invoice/:id"
|
|
131
|
+
element={
|
|
132
|
+
<UserLayout>
|
|
133
|
+
<CustomerInvoiceDetail />
|
|
134
|
+
</UserLayout>
|
|
135
|
+
}
|
|
136
|
+
/>
|
|
137
|
+
<Route
|
|
138
|
+
key="customer-payout"
|
|
139
|
+
path="/customer/payout/:id"
|
|
140
|
+
element={
|
|
141
|
+
<UserLayout>
|
|
142
|
+
<CustomerPayoutDetail />
|
|
143
|
+
</UserLayout>
|
|
144
|
+
}
|
|
145
|
+
/>
|
|
146
|
+
<Route key="customer-fallback" path="/customer/*" element={<Navigate to="/customer" />} />,
|
|
147
|
+
<Route path="*" element={<Navigate to="/" />} />
|
|
148
|
+
</Routes>
|
|
149
|
+
</Suspense>
|
|
150
|
+
</ErrorBoundary>
|
|
151
|
+
</LocaleProvider>
|
|
152
|
+
</TransitionProvider>
|
|
159
153
|
);
|
|
160
154
|
}
|
|
161
155
|
|
|
@@ -169,13 +163,15 @@ export default function WrappedApp() {
|
|
|
169
163
|
|
|
170
164
|
return (
|
|
171
165
|
<ToastProvider>
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
166
|
+
<PaymentThemeProvider>
|
|
167
|
+
<SessionProvider
|
|
168
|
+
serviceHost={prefix}
|
|
169
|
+
protectedRoutes={['/admin/*', '/customer/*', '/integrations/*'].map((item) => joinURL(prefix, item))}>
|
|
170
|
+
<Router basename={prefix}>
|
|
171
|
+
<AppWithTracker />
|
|
172
|
+
</Router>
|
|
173
|
+
</SessionProvider>
|
|
174
|
+
</PaymentThemeProvider>
|
|
179
175
|
</ToastProvider>
|
|
180
176
|
);
|
|
181
177
|
}
|
|
@@ -22,6 +22,12 @@ const Root = styled(Dashboard)<{ padding: string }>`
|
|
|
22
22
|
min-width: auto;
|
|
23
23
|
font-size: 0.875rem;
|
|
24
24
|
}
|
|
25
|
+
.page-content .MuiTab-root {
|
|
26
|
+
font-size: 0.875rem;
|
|
27
|
+
&.Mui-selected {
|
|
28
|
+
font-size: 1.125rem;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
25
31
|
|
|
26
32
|
.MuiTabs-root {
|
|
27
33
|
min-height: 32px;
|
|
@@ -57,7 +57,13 @@ export default function MetadataEditor({
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
|
-
<Dialog
|
|
60
|
+
<Dialog
|
|
61
|
+
open
|
|
62
|
+
disableEscapeKeyDown
|
|
63
|
+
fullWidth
|
|
64
|
+
onClose={() => onCancel(null)}
|
|
65
|
+
title={t('common.metadata.edit')}
|
|
66
|
+
className="base-dialog">
|
|
61
67
|
<FormProvider {...methods}>
|
|
62
68
|
<MetadataForm
|
|
63
69
|
actions={
|
|
@@ -39,6 +39,7 @@ export default function AssignPassportDialog(props: { id: string; onCancel: any
|
|
|
39
39
|
message={<Alert severity="error">{error.message}</Alert>}
|
|
40
40
|
onConfirm={onConfirm}
|
|
41
41
|
onCancel={props.onCancel}
|
|
42
|
+
color="primary"
|
|
42
43
|
/>
|
|
43
44
|
);
|
|
44
45
|
}
|
|
@@ -50,6 +51,7 @@ export default function AssignPassportDialog(props: { id: string; onCancel: any
|
|
|
50
51
|
message={<CircularProgress />}
|
|
51
52
|
onConfirm={onConfirm}
|
|
52
53
|
onCancel={props.onCancel}
|
|
54
|
+
color="primary"
|
|
53
55
|
/>
|
|
54
56
|
);
|
|
55
57
|
}
|
|
@@ -75,6 +77,7 @@ export default function AssignPassportDialog(props: { id: string; onCancel: any
|
|
|
75
77
|
}
|
|
76
78
|
onConfirm={onConfirm}
|
|
77
79
|
onCancel={props.onCancel}
|
|
80
|
+
color="primary"
|
|
78
81
|
/>
|
|
79
82
|
);
|
|
80
83
|
}
|
|
@@ -181,6 +181,7 @@ function SubscriptionActionsInner({ data, variant, onChange }: Props) {
|
|
|
181
181
|
title={t('admin.subscription.resume')}
|
|
182
182
|
message={t('admin.subscription.resumeTip')}
|
|
183
183
|
loading={state.loading}
|
|
184
|
+
color="primary"
|
|
184
185
|
/>
|
|
185
186
|
)}
|
|
186
187
|
{state.action === 'slashStake' && (
|
package/src/locales/en.tsx
CHANGED
|
@@ -713,6 +713,48 @@ export default flat({
|
|
|
713
713
|
note: 'Note: mountLocation must be unique, used to identify the donation instance. After configuration, the instance will appear in the list, and you can make further settings.',
|
|
714
714
|
},
|
|
715
715
|
},
|
|
716
|
+
vaultConfig: {
|
|
717
|
+
title: 'Vault',
|
|
718
|
+
learnMore: 'Learn more about vault configuration',
|
|
719
|
+
goToConfig: 'Go to system configuration',
|
|
720
|
+
description:
|
|
721
|
+
'By enabling the vault wallet, you create a secure offline storage solution that automatically transfers excess funds when your hot wallet balance exceeds the threshold. This separation significantly enhances security by keeping the majority of your assets safely offline, protected from potential online threats.',
|
|
722
|
+
notConfigured: 'Vault wallet not configured',
|
|
723
|
+
configureFirst:
|
|
724
|
+
'Please #go to the dashboard# to configure the vault wallet address before setting up individual currencies.',
|
|
725
|
+
ownerOnly: 'Only administrators with owner permissions can modify vault wallet settings.',
|
|
726
|
+
permissionRequired: 'Owner permissions required',
|
|
727
|
+
enabled: 'Status',
|
|
728
|
+
enabledYes: 'Enabled',
|
|
729
|
+
enabledNo: 'Disabled',
|
|
730
|
+
depositThreshold: 'Deposit Threshold',
|
|
731
|
+
withdrawThreshold: 'Withdrawal Threshold',
|
|
732
|
+
edit: 'Configure',
|
|
733
|
+
enable: 'Enable',
|
|
734
|
+
editTitle: 'Configure {currency} Vault Settings',
|
|
735
|
+
enableTitle: 'Enable Vault Wallet for {currency}',
|
|
736
|
+
enableVault: 'Enable Vault Wallet',
|
|
737
|
+
enableVaultHelp:
|
|
738
|
+
'When enabled, excess funds automatically transfer to the vault wallet, and withdrawals exceeding the threshold require admin approval for security and risk control.',
|
|
739
|
+
depositThresholdHelp:
|
|
740
|
+
'When the hot wallet balance exceeds this amount, the excess funds will be automatically transferred to the vault wallet.',
|
|
741
|
+
withdrawThresholdHelp:
|
|
742
|
+
'For withdrawals exceeding this amount, approval from the vault wallet administrator is required.',
|
|
743
|
+
notConfig: 'Not configured',
|
|
744
|
+
noLimit: 'No limit',
|
|
745
|
+
withdrawThresholdNoLimit: '0 means no withdrawal limit',
|
|
746
|
+
depositThresholdRequired: 'Deposit threshold must be greater than 0',
|
|
747
|
+
withdrawThresholdInvalid: 'Withdrawal threshold must be greater or equal to 0',
|
|
748
|
+
enableSuccess: 'Successfully enabled vault wallet for {currency}',
|
|
749
|
+
disableSuccess: 'Successfully disabled vault wallet for {currency}',
|
|
750
|
+
updateSuccess: 'Successfully updated vault wallet settings for {currency}',
|
|
751
|
+
depositConfirmTitle: 'Deposit to Vault',
|
|
752
|
+
depositConfirmMessage:
|
|
753
|
+
'{currency} balance has exceeded the threshold, do you want to deposit to vault immediately?',
|
|
754
|
+
depositQueued: 'Deposit to vault request queued, please check the result later',
|
|
755
|
+
depositFailed: 'Deposit to vault request failed',
|
|
756
|
+
appBalance: 'App Balance',
|
|
757
|
+
},
|
|
716
758
|
},
|
|
717
759
|
empty: {
|
|
718
760
|
image: 'No Image',
|
package/src/locales/zh.tsx
CHANGED
|
@@ -696,6 +696,43 @@ export default flat({
|
|
|
696
696
|
note: '注意:mountLocation 必须是唯一的,用于标识打赏实例。配置完成后,该实例将出现在列表中,您可以进行进一步的设置。',
|
|
697
697
|
},
|
|
698
698
|
},
|
|
699
|
+
vaultConfig: {
|
|
700
|
+
title: '冷钱包配置',
|
|
701
|
+
description:
|
|
702
|
+
'启用冷钱包后,系统会在热钱包余额超过阈值时,自动将多余资金转移至安全的离线存储。这种隔离机制将大部分资产与在线环境分离,有效抵御网络攻击,显著提升资金安全性。',
|
|
703
|
+
learnMore: '了解更多',
|
|
704
|
+
goToConfig: '前往系统配置',
|
|
705
|
+
notConfigured: '冷钱包尚未配置',
|
|
706
|
+
configureFirst: '请先#前往仪表盘#配置冷钱包地址,然后再设置各币种参数。',
|
|
707
|
+
ownerOnly: '仅拥有所有者权限的管理员可修改冷钱包设置。',
|
|
708
|
+
permissionRequired: '需要所有者权限',
|
|
709
|
+
enabled: '状态',
|
|
710
|
+
enabledYes: '已启用',
|
|
711
|
+
enabledNo: '未启用',
|
|
712
|
+
depositThreshold: '存入阈值',
|
|
713
|
+
withdrawThreshold: '提取阈值',
|
|
714
|
+
edit: '配置',
|
|
715
|
+
enable: '启用',
|
|
716
|
+
editTitle: '配置 {currency} 冷钱包设置',
|
|
717
|
+
enableTitle: '为 {currency} 启用冷钱包',
|
|
718
|
+
enableVault: '启用冷钱包',
|
|
719
|
+
enableVaultHelp: '启用冷钱包后,超额资金将自动转入冷钱包,提款超出阈值需管理员审核,确保资产安全与风控。',
|
|
720
|
+
depositThresholdHelp: '当热钱包余额超过此金额时,多余资金将自动转入冷钱包。',
|
|
721
|
+
withdrawThresholdHelp: '当单笔提款超过此金额时,需由冷钱包管理员审核并批准。',
|
|
722
|
+
notConfig: '未配置',
|
|
723
|
+
noLimit: '无限制',
|
|
724
|
+
withdrawThresholdNoLimit: '0 表示无提款限制',
|
|
725
|
+
depositThresholdRequired: '存入阈值必须大于0',
|
|
726
|
+
withdrawThresholdInvalid: '提款阈值不能小于0',
|
|
727
|
+
enableSuccess: '{currency} 冷钱包已启用',
|
|
728
|
+
disableSuccess: '{currency} 冷钱包已关闭',
|
|
729
|
+
updateSuccess: '{currency} 冷钱包设置已更新',
|
|
730
|
+
depositConfirmTitle: '转入冷钱包',
|
|
731
|
+
depositConfirmMessage: '{currency}余额已超过阈值,是否立即转入冷钱包?',
|
|
732
|
+
depositQueued: '申请转入冷钱包成功,请稍后查看结果',
|
|
733
|
+
depositFailed: '申请转入冷钱包失败',
|
|
734
|
+
appBalance: '热钱包余额',
|
|
735
|
+
},
|
|
699
736
|
},
|
|
700
737
|
empty: {
|
|
701
738
|
image: '无图片',
|
|
@@ -194,48 +194,50 @@ export default function PayoutDetail(props: { id: string }) {
|
|
|
194
194
|
value={<Status label={data.status} color={getPayoutStatusColor(data.status)} />}
|
|
195
195
|
divider
|
|
196
196
|
/>
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
197
|
+
{paymentIntent?.id && (
|
|
198
|
+
<InfoMetric
|
|
199
|
+
label={t('customer.payout.payer')}
|
|
200
|
+
value={
|
|
201
|
+
<InfoCard
|
|
202
|
+
logo={getCustomerAvatar(
|
|
203
|
+
paymentIntent?.customer?.did,
|
|
204
|
+
paymentIntent?.customer?.updated_at
|
|
205
|
+
? new Date(paymentIntent?.customer?.updated_at).toISOString()
|
|
206
|
+
: '',
|
|
207
|
+
48
|
|
208
|
+
)}
|
|
209
|
+
name={
|
|
210
|
+
<Typography
|
|
211
|
+
variant="subtitle2"
|
|
212
|
+
sx={{
|
|
213
|
+
cursor: 'pointer',
|
|
214
|
+
'&:hover': {
|
|
215
|
+
color: 'text.link',
|
|
216
|
+
},
|
|
217
|
+
}}
|
|
218
|
+
onClick={() => {
|
|
219
|
+
const url = getCustomerProfileUrl({
|
|
220
|
+
userDid: paymentIntent?.customer?.did,
|
|
221
|
+
locale: 'zh',
|
|
222
|
+
});
|
|
223
|
+
window.open(url, '_blank');
|
|
224
|
+
}}>
|
|
225
|
+
{paymentIntent?.customer?.name} ({paymentIntent?.customer?.email})
|
|
226
|
+
</Typography>
|
|
227
|
+
}
|
|
228
|
+
description={
|
|
229
|
+
<DID
|
|
230
|
+
did={paymentIntent?.customer?.did}
|
|
231
|
+
{...(isMobile ? { responsive: false, compact: true } : {})}
|
|
232
|
+
/>
|
|
233
|
+
}
|
|
234
|
+
size={40}
|
|
235
|
+
variant="rounded"
|
|
236
|
+
/>
|
|
237
|
+
}
|
|
238
|
+
divider
|
|
239
|
+
/>
|
|
240
|
+
)}
|
|
239
241
|
{/* <InfoMetric label={t('common.createdAt')} value={formatTime(data.created_at)} divider /> */}
|
|
240
242
|
{/* <InfoMetric label={t('common.updatedAt')} value={formatTime(data.updated_at)} divider /> */}
|
|
241
243
|
</Stack>
|
|
@@ -385,13 +387,15 @@ export default function PayoutDetail(props: { id: string }) {
|
|
|
385
387
|
<Box className="section">
|
|
386
388
|
<SectionHeader title={t('admin.connections')} />
|
|
387
389
|
<Stack>
|
|
388
|
-
{data.payment_intent_id
|
|
390
|
+
{data.payment_intent_id ? (
|
|
389
391
|
<InfoRow
|
|
390
392
|
label={t('admin.paymentIntent.name')}
|
|
391
393
|
value={<Link to={`/admin/payments/${data.paymentIntent.id}`}>{data.paymentIntent.id}</Link>}
|
|
392
394
|
direction={InfoDirection}
|
|
393
395
|
alignItems={InfoAlignItems}
|
|
394
396
|
/>
|
|
397
|
+
) : (
|
|
398
|
+
t('common.none')
|
|
395
399
|
)}
|
|
396
400
|
</Stack>
|
|
397
401
|
</Box>
|
|
@@ -9,8 +9,8 @@ import { useTransitionContext } from '../../../components/progress-bar';
|
|
|
9
9
|
const PaymentMethodCreate = React.lazy(() => import('./payment-methods/create'));
|
|
10
10
|
|
|
11
11
|
const pages = {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
'payment-methods': React.lazy(() => import('./payment-methods')),
|
|
13
|
+
'vault-config': React.lazy(() => import('./vault-config')),
|
|
14
14
|
// business: React.lazy(() => import('./business')),
|
|
15
15
|
};
|
|
16
16
|
|
|
@@ -30,7 +30,7 @@ export default function SettingsIndex() {
|
|
|
30
30
|
const TabComponent = pages[page] || pages.paymentMethods;
|
|
31
31
|
const tabs = [
|
|
32
32
|
{ label: t('admin.paymentMethods'), value: 'payment-methods' },
|
|
33
|
-
|
|
33
|
+
{ label: t('admin.vaultConfig.title'), value: 'vault-config' },
|
|
34
34
|
// { label: t('admin.business'), value: 'business' },
|
|
35
35
|
];
|
|
36
36
|
|