@blocklet/payment-react 1.19.0 → 1.19.2
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/es/components/blockchain/tx.d.ts +1 -1
- package/es/components/blockchain/tx.js +9 -11
- package/es/components/country-select.d.ts +1 -1
- package/es/components/date-range-picker.d.ts +13 -0
- package/es/components/date-range-picker.js +279 -0
- package/es/components/input.d.ts +5 -2
- package/es/components/input.js +6 -2
- package/es/components/label.d.ts +7 -0
- package/es/components/label.js +50 -0
- package/es/components/loading-button.d.ts +1 -1
- package/es/history/credit/grants-list.d.ts +14 -0
- package/es/history/credit/grants-list.js +215 -0
- package/es/history/credit/transactions-list.d.ts +13 -0
- package/es/history/credit/transactions-list.js +254 -0
- package/es/history/invoice/list.js +21 -1
- package/es/index.d.ts +5 -1
- package/es/index.js +10 -1
- package/es/libs/util.d.ts +2 -0
- package/es/libs/util.js +12 -0
- package/es/locales/en.js +20 -2
- package/es/locales/zh.js +20 -2
- package/es/payment/form/address.js +2 -1
- package/es/payment/form/index.js +46 -7
- package/es/payment/index.js +18 -3
- package/es/payment/product-item.d.ts +8 -1
- package/es/payment/product-item.js +137 -5
- package/es/payment/summary.d.ts +3 -1
- package/es/payment/summary.js +9 -0
- package/lib/components/blockchain/tx.d.ts +1 -1
- package/lib/components/blockchain/tx.js +9 -8
- package/lib/components/country-select.d.ts +1 -1
- package/lib/components/date-range-picker.d.ts +13 -0
- package/lib/components/date-range-picker.js +329 -0
- package/lib/components/input.d.ts +5 -2
- package/lib/components/input.js +8 -4
- package/lib/components/label.d.ts +7 -0
- package/lib/components/label.js +62 -0
- package/lib/components/loading-button.d.ts +1 -1
- package/lib/history/credit/grants-list.d.ts +14 -0
- package/lib/history/credit/grants-list.js +277 -0
- package/lib/history/credit/transactions-list.d.ts +13 -0
- package/lib/history/credit/transactions-list.js +300 -0
- package/lib/history/invoice/list.js +24 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +39 -0
- package/lib/libs/util.d.ts +2 -0
- package/lib/libs/util.js +14 -0
- package/lib/locales/en.js +20 -2
- package/lib/locales/zh.js +20 -2
- package/lib/payment/form/address.js +6 -5
- package/lib/payment/form/index.js +49 -9
- package/lib/payment/index.js +20 -2
- package/lib/payment/product-item.d.ts +8 -1
- package/lib/payment/product-item.js +144 -4
- package/lib/payment/summary.d.ts +3 -1
- package/lib/payment/summary.js +9 -0
- package/package.json +3 -3
- package/src/components/blockchain/tx.tsx +9 -15
- package/src/components/country-select.tsx +2 -2
- package/src/components/date-range-picker.tsx +310 -0
- package/src/components/input.tsx +14 -3
- package/src/components/label.tsx +59 -0
- package/src/components/loading-button.tsx +1 -1
- package/src/history/credit/grants-list.tsx +276 -0
- package/src/history/credit/transactions-list.tsx +316 -0
- package/src/history/invoice/list.tsx +18 -1
- package/src/index.ts +9 -0
- package/src/libs/util.ts +14 -0
- package/src/locales/en.tsx +20 -0
- package/src/locales/zh.tsx +19 -0
- package/src/payment/form/address.tsx +4 -3
- package/src/payment/form/index.tsx +112 -53
- package/src/payment/index.tsx +17 -1
- package/src/payment/product-item.tsx +152 -4
- package/src/payment/summary.tsx +13 -2
|
@@ -8,7 +8,7 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
|
8
8
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
9
9
|
import type { Paginated, TInvoiceExpanded, TSubscription } from '@blocklet/payment-types';
|
|
10
10
|
import { OpenInNewOutlined } from '@mui/icons-material';
|
|
11
|
-
import { Box, Button, CircularProgress, Stack, Typography, Tooltip } from '@mui/material';
|
|
11
|
+
import { Box, Button, CircularProgress, Stack, Typography, Tooltip, Avatar } from '@mui/material';
|
|
12
12
|
import { styled } from '@mui/system';
|
|
13
13
|
import { useInfiniteScroll, useRequest, useSetState } from 'ahooks';
|
|
14
14
|
import React, { useEffect, useRef, useState } from 'react';
|
|
@@ -207,6 +207,23 @@ const InvoiceTable = React.memo((props: Props & { onPay: (invoiceId: string) =>
|
|
|
207
207
|
},
|
|
208
208
|
},
|
|
209
209
|
},
|
|
210
|
+
{
|
|
211
|
+
label: t('common.paymentMethod'),
|
|
212
|
+
name: 'paymentMethod',
|
|
213
|
+
options: {
|
|
214
|
+
customBodyRenderLite: (_: string, index: number) => {
|
|
215
|
+
const invoice = data?.list[index] as TInvoiceExpanded;
|
|
216
|
+
return (
|
|
217
|
+
<Typography
|
|
218
|
+
sx={{ display: 'flex', alignItems: 'center', whiteSpace: 'nowrap' }}
|
|
219
|
+
onClick={(e) => handleLinkClick(e, invoice)}>
|
|
220
|
+
<Avatar src={invoice.paymentMethod.logo} sx={{ width: 18, height: 18, mr: 1 }} />
|
|
221
|
+
{invoice.paymentMethod.name}
|
|
222
|
+
</Typography>
|
|
223
|
+
);
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
210
227
|
{
|
|
211
228
|
label: t('common.type'),
|
|
212
229
|
name: 'billing_reason',
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import TxGas from './components/blockchain/gas';
|
|
|
5
5
|
import TxLink from './components/blockchain/tx';
|
|
6
6
|
import ConfirmDialog from './components/confirm';
|
|
7
7
|
import FormInput from './components/input';
|
|
8
|
+
import FormLabel from './components/label';
|
|
8
9
|
import Livemode from './components/livemode';
|
|
9
10
|
import PricingTable from './components/pricing-table';
|
|
10
11
|
import Table from './components/table';
|
|
@@ -13,6 +14,8 @@ import Status from './components/status';
|
|
|
13
14
|
import Switch from './components/switch-button';
|
|
14
15
|
import CustomerInvoiceList from './history/invoice/list';
|
|
15
16
|
import CustomerPaymentList from './history/payment/list';
|
|
17
|
+
import CreditGrantsList, { StatusChip as CreditStatusChip } from './history/credit/grants-list';
|
|
18
|
+
import CreditTransactionsList from './history/credit/transactions-list';
|
|
16
19
|
import api from './libs/api';
|
|
17
20
|
import dayjs from './libs/dayjs';
|
|
18
21
|
import Amount from './payment/amount';
|
|
@@ -32,6 +35,7 @@ import OverdueInvoicePayment from './components/over-due-invoice-payment';
|
|
|
32
35
|
import PaymentBeneficiaries from './components/payment-beneficiaries';
|
|
33
36
|
import LoadingButton from './components/loading-button';
|
|
34
37
|
import ResumeSubscription from './components/resume-subscription';
|
|
38
|
+
import DateRangePicker from './components/date-range-picker';
|
|
35
39
|
|
|
36
40
|
export { PaymentThemeProvider } from './theme';
|
|
37
41
|
|
|
@@ -55,6 +59,7 @@ export {
|
|
|
55
59
|
api,
|
|
56
60
|
dayjs,
|
|
57
61
|
FormInput,
|
|
62
|
+
FormLabel,
|
|
58
63
|
PhoneInput,
|
|
59
64
|
AddressForm,
|
|
60
65
|
StripeForm,
|
|
@@ -86,4 +91,8 @@ export {
|
|
|
86
91
|
LoadingButton,
|
|
87
92
|
DonateDetails,
|
|
88
93
|
ResumeSubscription,
|
|
94
|
+
CreditGrantsList,
|
|
95
|
+
CreditTransactionsList,
|
|
96
|
+
DateRangePicker,
|
|
97
|
+
CreditStatusChip,
|
|
89
98
|
};
|
package/src/libs/util.ts
CHANGED
|
@@ -1283,3 +1283,17 @@ export function getTokenBalanceLink(method: TPaymentMethod, address: string) {
|
|
|
1283
1283
|
}
|
|
1284
1284
|
return '';
|
|
1285
1285
|
}
|
|
1286
|
+
|
|
1287
|
+
export function isCreditMetered(price: TPrice): boolean {
|
|
1288
|
+
return !!(price.type === 'recurring' && price.recurring?.usage_type === 'metered' && price.recurring?.meter_id);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
export function showStaking(method: TPaymentMethod, currency: TPaymentCurrency, noStake: boolean) {
|
|
1292
|
+
if (noStake) {
|
|
1293
|
+
return false;
|
|
1294
|
+
}
|
|
1295
|
+
if (method.type === 'arcblock') {
|
|
1296
|
+
return currency.type !== 'credit';
|
|
1297
|
+
}
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
package/src/locales/en.tsx
CHANGED
|
@@ -30,6 +30,10 @@ export default flat({
|
|
|
30
30
|
remove: 'Remove',
|
|
31
31
|
removed: 'Resource removed',
|
|
32
32
|
confirm: 'Confirm',
|
|
33
|
+
clear: 'Clear',
|
|
34
|
+
selectTimeRange: 'Select time range',
|
|
35
|
+
startDate: 'Start date',
|
|
36
|
+
endDate: 'End date',
|
|
33
37
|
upload: 'Upload',
|
|
34
38
|
change: 'Change',
|
|
35
39
|
cancel: 'Cancel',
|
|
@@ -103,6 +107,7 @@ export default flat({
|
|
|
103
107
|
confirm: 'Confirm',
|
|
104
108
|
cancel: 'Cancel',
|
|
105
109
|
},
|
|
110
|
+
paymentMethod: 'Payment Method',
|
|
106
111
|
},
|
|
107
112
|
payment: {
|
|
108
113
|
checkout: {
|
|
@@ -209,6 +214,11 @@ export default flat({
|
|
|
209
214
|
add: 'Add to order',
|
|
210
215
|
remove: 'Remove from order',
|
|
211
216
|
},
|
|
217
|
+
credit: {
|
|
218
|
+
oneTimeInfo: 'You will receive {amount} {symbol} credits after payment',
|
|
219
|
+
recurringInfo: 'You will receive {amount} {symbol} credits {period}',
|
|
220
|
+
expiresIn: 'credits have a validity period of {duration} {unit}',
|
|
221
|
+
},
|
|
212
222
|
expired: {
|
|
213
223
|
title: 'Expired Link',
|
|
214
224
|
description:
|
|
@@ -241,6 +251,16 @@ export default flat({
|
|
|
241
251
|
amount: 'Amount',
|
|
242
252
|
failed: 'Account changed, please pay manually.',
|
|
243
253
|
balanceLink: 'View Balance',
|
|
254
|
+
credit: {
|
|
255
|
+
title: 'Confirm Credit Payment',
|
|
256
|
+
availableAmount: 'Available Credit: {amount}',
|
|
257
|
+
confirmMessage: 'You will use {amount} credits to subscribe to this service.',
|
|
258
|
+
meteringSubscriptionMessage:
|
|
259
|
+
'This subscription service will deduct credits in real-time based on actual usage. You currently have {available} credits available. Confirm to continue?',
|
|
260
|
+
insufficientTitle: 'Insufficient Credit',
|
|
261
|
+
insufficientMessage:
|
|
262
|
+
'This subscription service will deduct credits in real-time based on actual usage. You currently have insufficient credits. Please top up your credits first.',
|
|
263
|
+
},
|
|
244
264
|
},
|
|
245
265
|
},
|
|
246
266
|
customer: {
|
package/src/locales/zh.tsx
CHANGED
|
@@ -33,6 +33,10 @@ export default flat({
|
|
|
33
33
|
change: '更换',
|
|
34
34
|
confirm: '确认',
|
|
35
35
|
cancel: '取消',
|
|
36
|
+
clear: '清空',
|
|
37
|
+
selectTimeRange: '选择时间范围',
|
|
38
|
+
startDate: '开始日期',
|
|
39
|
+
endDate: '结束日期',
|
|
36
40
|
close: '关闭',
|
|
37
41
|
back: '返回',
|
|
38
42
|
every: '每',
|
|
@@ -103,6 +107,7 @@ export default flat({
|
|
|
103
107
|
confirm: '确认',
|
|
104
108
|
cancel: '取消',
|
|
105
109
|
},
|
|
110
|
+
paymentMethod: '支付方式',
|
|
106
111
|
},
|
|
107
112
|
payment: {
|
|
108
113
|
checkout: {
|
|
@@ -215,6 +220,11 @@ export default flat({
|
|
|
215
220
|
add: '添加到订单',
|
|
216
221
|
remove: '从订单移除',
|
|
217
222
|
},
|
|
223
|
+
credit: {
|
|
224
|
+
oneTimeInfo: '付款完成后您将获得 {amount} {symbol} 额度',
|
|
225
|
+
recurringInfo: '您将{period}获得 {amount} {symbol} 额度',
|
|
226
|
+
expiresIn: '额度有效期为 {duration} {unit}',
|
|
227
|
+
},
|
|
218
228
|
emptyItems: {
|
|
219
229
|
title: '没有任何购买项目',
|
|
220
230
|
description: '可能这个付款链接没有正确配置',
|
|
@@ -236,6 +246,15 @@ export default flat({
|
|
|
236
246
|
amount: '支付金额',
|
|
237
247
|
failed: '账户发生变化,无法自动完成支付,请手动支付。',
|
|
238
248
|
balanceLink: '查看余额',
|
|
249
|
+
credit: {
|
|
250
|
+
title: '确认额度支付',
|
|
251
|
+
availableAmount: '可用额度:{amount}',
|
|
252
|
+
confirmMessage: '您将使用 {amount} 额度来订阅此服务。',
|
|
253
|
+
meteringSubscriptionMessage:
|
|
254
|
+
'此订阅服务将根据实际使用情况实时扣除额度。您当前可用额度为 {available},确认是否继续?',
|
|
255
|
+
insufficientTitle: '额度不足',
|
|
256
|
+
insufficientMessage: '此订阅服务将根据实际使用情况实时扣除额度。您当前可用额度不足,请先充值额度。',
|
|
257
|
+
},
|
|
239
258
|
},
|
|
240
259
|
},
|
|
241
260
|
customer: {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
-
import { Fade,
|
|
2
|
+
import { Fade, InputAdornment, Stack } from '@mui/material';
|
|
3
3
|
import type { SxProps } from '@mui/material';
|
|
4
4
|
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
|
5
5
|
import FormInput from '../../components/input';
|
|
6
|
+
import FormLabel from '../../components/label';
|
|
6
7
|
import CountrySelect from '../../components/country-select';
|
|
7
8
|
import { getFieldValidation, validatePostalCode } from '../../libs/validator';
|
|
8
9
|
|
|
@@ -79,7 +80,7 @@ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation = {
|
|
|
79
80
|
render={({ field }) => (
|
|
80
81
|
<CountrySelect
|
|
81
82
|
{...field}
|
|
82
|
-
ref={field.ref as unknown as React.RefObject<HTMLDivElement>}
|
|
83
|
+
ref={field.ref as unknown as React.RefObject<HTMLDivElement | null>}
|
|
83
84
|
sx={{
|
|
84
85
|
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
|
|
85
86
|
borderColor: 'transparent',
|
|
@@ -127,7 +128,7 @@ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation = {
|
|
|
127
128
|
render={({ field }) => (
|
|
128
129
|
<CountrySelect
|
|
129
130
|
{...field}
|
|
130
|
-
ref={field.ref as unknown as React.RefObject<HTMLDivElement>}
|
|
131
|
+
ref={field.ref as unknown as React.RefObject<HTMLDivElement | null>}
|
|
131
132
|
sx={{
|
|
132
133
|
'.MuiOutlinedInput-notchedOutline': {
|
|
133
134
|
borderColor: 'transparent !important',
|
|
@@ -5,7 +5,7 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
|
5
5
|
// import { useTheme } from '@arcblock/ux/lib/Theme';
|
|
6
6
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
7
7
|
import type { TCheckoutSession, TCustomer, TPaymentIntent, TPaymentMethodExpanded } from '@blocklet/payment-types';
|
|
8
|
-
import { Box, Button, CircularProgress, Divider, Fade,
|
|
8
|
+
import { Box, Button, CircularProgress, Divider, Fade, Stack, Tooltip, Typography } from '@mui/material';
|
|
9
9
|
import { useMemoizedFn, useSetState } from 'ahooks';
|
|
10
10
|
import pWaitFor from 'p-wait-for';
|
|
11
11
|
import { useEffect, useMemo, useRef } from 'react';
|
|
@@ -19,6 +19,7 @@ import DID from '@arcblock/ux/lib/DID';
|
|
|
19
19
|
import isEmpty from 'lodash/isEmpty';
|
|
20
20
|
import { HelpOutline, OpenInNew } from '@mui/icons-material';
|
|
21
21
|
import FormInput from '../../components/input';
|
|
22
|
+
import FormLabel from '../../components/label';
|
|
22
23
|
import { usePaymentContext } from '../../contexts/payment';
|
|
23
24
|
import { useSubscription } from '../../hooks/subscription';
|
|
24
25
|
import api from '../../libs/api';
|
|
@@ -110,9 +111,11 @@ type UserInfo = {
|
|
|
110
111
|
type FastCheckoutInfo = {
|
|
111
112
|
open: boolean;
|
|
112
113
|
loading: boolean;
|
|
113
|
-
sourceType: 'balance' | 'delegation';
|
|
114
|
+
sourceType: 'balance' | 'delegation' | 'credit';
|
|
114
115
|
amount: string;
|
|
115
116
|
payer?: string;
|
|
117
|
+
availableCredit?: string;
|
|
118
|
+
balance?: string;
|
|
116
119
|
};
|
|
117
120
|
|
|
118
121
|
const setUserFormValues = (
|
|
@@ -206,6 +209,9 @@ export default function PaymentForm({
|
|
|
206
209
|
customerLimited?: boolean;
|
|
207
210
|
stripePaying: boolean;
|
|
208
211
|
fastCheckoutInfo: FastCheckoutInfo | null;
|
|
212
|
+
creditInsufficientInfo: {
|
|
213
|
+
open: boolean;
|
|
214
|
+
} | null;
|
|
209
215
|
}>({
|
|
210
216
|
submitting: false,
|
|
211
217
|
paying: false,
|
|
@@ -216,6 +222,7 @@ export default function PaymentForm({
|
|
|
216
222
|
customerLimited: false,
|
|
217
223
|
stripePaying: false,
|
|
218
224
|
fastCheckoutInfo: null,
|
|
225
|
+
creditInsufficientInfo: null,
|
|
219
226
|
});
|
|
220
227
|
|
|
221
228
|
const currencies = flattenPaymentMethods(paymentMethods);
|
|
@@ -418,6 +425,10 @@ export default function PaymentForm({
|
|
|
418
425
|
setState({ fastCheckoutInfo: null });
|
|
419
426
|
};
|
|
420
427
|
|
|
428
|
+
const handleCreditInsufficientClose = () => {
|
|
429
|
+
setState({ creditInsufficientInfo: null });
|
|
430
|
+
};
|
|
431
|
+
|
|
421
432
|
const openConnect = () => {
|
|
422
433
|
try {
|
|
423
434
|
if (!['arcblock', 'ethereum', 'base'].includes(method.type)) {
|
|
@@ -476,7 +487,30 @@ export default function PaymentForm({
|
|
|
476
487
|
});
|
|
477
488
|
|
|
478
489
|
if (['arcblock', 'ethereum', 'base'].includes(method.type)) {
|
|
479
|
-
|
|
490
|
+
// 优先判断 credit 支付
|
|
491
|
+
if (paymentCurrency?.type === 'credit') {
|
|
492
|
+
if (result.data.creditSufficient === true) {
|
|
493
|
+
// 如果是 credit 支付且有足够额度,显示 credit 确认弹窗
|
|
494
|
+
setState({
|
|
495
|
+
fastCheckoutInfo: {
|
|
496
|
+
open: true,
|
|
497
|
+
loading: false,
|
|
498
|
+
sourceType: 'credit',
|
|
499
|
+
amount: result.data.fastPayInfo?.amount || '0',
|
|
500
|
+
payer: result.data.fastPayInfo?.payer,
|
|
501
|
+
availableCredit: result.data.fastPayInfo?.amount || '0',
|
|
502
|
+
balance: result.data.fastPayInfo?.token?.balance || '0',
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
} else {
|
|
506
|
+
// 如果是 credit 支付但额度不足,显示额度不足弹窗
|
|
507
|
+
setState({
|
|
508
|
+
creditInsufficientInfo: {
|
|
509
|
+
open: true,
|
|
510
|
+
},
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
} else if (
|
|
480
514
|
(result.data.balance?.sufficient || result.data.delegation?.sufficient) &&
|
|
481
515
|
!isDonationMode &&
|
|
482
516
|
result.data.fastPayInfo
|
|
@@ -581,73 +615,96 @@ export default function PaymentForm({
|
|
|
581
615
|
}, [state.submitting, state.paying, state.stripePaying, quantityInventoryStatus, payable]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
582
616
|
|
|
583
617
|
const balanceLink = getTokenBalanceLink(method, state.fastCheckoutInfo?.payer || '');
|
|
618
|
+
|
|
584
619
|
const FastCheckoutConfirmDialog = state.fastCheckoutInfo && (
|
|
585
620
|
<ConfirmDialog
|
|
586
621
|
onConfirm={handleFastCheckoutConfirm}
|
|
587
622
|
onCancel={handleFastCheckoutCancel}
|
|
588
|
-
title={
|
|
623
|
+
title={
|
|
624
|
+
state.fastCheckoutInfo.sourceType === 'credit'
|
|
625
|
+
? t('payment.checkout.fastPay.credit.title')
|
|
626
|
+
: t('payment.checkout.fastPay.title')
|
|
627
|
+
}
|
|
589
628
|
message={
|
|
590
|
-
|
|
591
|
-
<Typography>
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
629
|
+
state.fastCheckoutInfo.sourceType === 'credit' ? (
|
|
630
|
+
<Typography>
|
|
631
|
+
{t('payment.checkout.fastPay.credit.meteringSubscriptionMessage', {
|
|
632
|
+
available: `${fromUnitToToken(state.fastCheckoutInfo?.balance || '0', paymentCurrency?.decimal || 18).toString()} ${paymentCurrency?.symbol}`,
|
|
633
|
+
})}
|
|
634
|
+
</Typography>
|
|
635
|
+
) : (
|
|
636
|
+
<Stack>
|
|
637
|
+
<Typography>{t('payment.checkout.fastPay.autoPaymentReason')}</Typography>
|
|
638
|
+
<Divider sx={{ mt: 1.5, mb: 1.5 }} />
|
|
639
|
+
<Stack spacing={1}>
|
|
640
|
+
<Stack
|
|
601
641
|
sx={{
|
|
602
|
-
|
|
603
|
-
|
|
642
|
+
flexDirection: 'row',
|
|
643
|
+
alignItems: 'center',
|
|
644
|
+
justifyContent: 'space-between',
|
|
604
645
|
}}>
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
<Typography
|
|
646
|
+
<Typography
|
|
647
|
+
sx={{
|
|
648
|
+
color: 'text.primary',
|
|
649
|
+
whiteSpace: 'nowrap',
|
|
650
|
+
}}>
|
|
651
|
+
{t('payment.checkout.fastPay.payer')}
|
|
652
|
+
</Typography>
|
|
653
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
|
|
654
|
+
<DID did={state.fastCheckoutInfo.payer || ''} compact responsive={false} />
|
|
655
|
+
{balanceLink && (
|
|
656
|
+
<Tooltip title={t('payment.checkout.fastPay.balanceLink')} placement="top">
|
|
657
|
+
<OpenInNew
|
|
658
|
+
sx={{
|
|
659
|
+
color: 'text.lighter',
|
|
660
|
+
fontSize: '0.85rem',
|
|
661
|
+
cursor: 'pointer',
|
|
662
|
+
'&:hover': { color: 'text.primary' },
|
|
663
|
+
}}
|
|
664
|
+
onClick={() => {
|
|
665
|
+
window.open(balanceLink, '_blank');
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
</Tooltip>
|
|
669
|
+
)}
|
|
670
|
+
</Box>
|
|
671
|
+
</Stack>
|
|
672
|
+
<Stack
|
|
633
673
|
sx={{
|
|
634
|
-
|
|
674
|
+
flexDirection: 'row',
|
|
675
|
+
alignItems: 'center',
|
|
676
|
+
justifyContent: 'space-between',
|
|
635
677
|
}}>
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
678
|
+
<Typography
|
|
679
|
+
sx={{
|
|
680
|
+
color: 'text.primary',
|
|
681
|
+
}}>
|
|
682
|
+
{t('payment.checkout.fastPay.amount')}
|
|
683
|
+
</Typography>
|
|
684
|
+
<Typography>
|
|
685
|
+
{fromUnitToToken(state.fastCheckoutInfo.amount, paymentCurrency?.decimal || 18).toString()}{' '}
|
|
686
|
+
{paymentCurrency?.symbol}
|
|
687
|
+
</Typography>
|
|
688
|
+
</Stack>
|
|
642
689
|
</Stack>
|
|
643
690
|
</Stack>
|
|
644
|
-
|
|
691
|
+
)
|
|
645
692
|
}
|
|
646
693
|
loading={state.fastCheckoutInfo.loading}
|
|
647
694
|
color="primary"
|
|
648
695
|
/>
|
|
649
696
|
);
|
|
650
697
|
|
|
698
|
+
const CreditInsufficientDialog = state.creditInsufficientInfo && (
|
|
699
|
+
<ConfirmDialog
|
|
700
|
+
onConfirm={handleCreditInsufficientClose}
|
|
701
|
+
onCancel={handleCreditInsufficientClose}
|
|
702
|
+
title={t('payment.checkout.fastPay.credit.insufficientTitle')}
|
|
703
|
+
message={<Typography>{t('payment.checkout.fastPay.credit.insufficientMessage')}</Typography>}
|
|
704
|
+
confirm={t('common.confirm')}
|
|
705
|
+
/>
|
|
706
|
+
);
|
|
707
|
+
|
|
651
708
|
if (onlyShowBtn) {
|
|
652
709
|
return (
|
|
653
710
|
<>
|
|
@@ -700,6 +757,7 @@ export default function PaymentForm({
|
|
|
700
757
|
/>
|
|
701
758
|
)}
|
|
702
759
|
{FastCheckoutConfirmDialog}
|
|
760
|
+
{CreditInsufficientDialog}
|
|
703
761
|
</>
|
|
704
762
|
);
|
|
705
763
|
}
|
|
@@ -890,6 +948,7 @@ export default function PaymentForm({
|
|
|
890
948
|
/>
|
|
891
949
|
)}
|
|
892
950
|
{FastCheckoutConfirmDialog}
|
|
951
|
+
{CreditInsufficientDialog}
|
|
893
952
|
</>
|
|
894
953
|
);
|
|
895
954
|
}
|
package/src/payment/index.tsx
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
getStatementDescriptor,
|
|
31
31
|
isMobileSafari,
|
|
32
32
|
isValidCountry,
|
|
33
|
+
showStaking,
|
|
33
34
|
} from '../libs/util';
|
|
34
35
|
import type { CheckoutCallbacks, CheckoutContext, CheckoutFormData } from '../types';
|
|
35
36
|
import PaymentError from './error';
|
|
@@ -208,6 +209,19 @@ function PaymentInner({
|
|
|
208
209
|
}
|
|
209
210
|
};
|
|
210
211
|
|
|
212
|
+
const onQuantityChange = async (itemId: string, quantity: number) => {
|
|
213
|
+
try {
|
|
214
|
+
const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/adjust-quantity`, {
|
|
215
|
+
itemId,
|
|
216
|
+
quantity,
|
|
217
|
+
});
|
|
218
|
+
setState({ checkoutSession: data });
|
|
219
|
+
} catch (err) {
|
|
220
|
+
console.error(err);
|
|
221
|
+
Toast.error(formatError(err));
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
211
225
|
const onCancelCrossSell = async () => {
|
|
212
226
|
try {
|
|
213
227
|
const { data } = await api.delete(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`);
|
|
@@ -263,10 +277,11 @@ function PaymentInner({
|
|
|
263
277
|
// @ts-ignore
|
|
264
278
|
state.checkoutSession.subscription_data?.min_stake_amount || 0
|
|
265
279
|
)}
|
|
266
|
-
showStaking={method
|
|
280
|
+
showStaking={showStaking(method, currency, !!state.checkoutSession.subscription_data?.no_stake)}
|
|
267
281
|
currency={currency}
|
|
268
282
|
onUpsell={onUpsell}
|
|
269
283
|
onDownsell={onDownsell}
|
|
284
|
+
onQuantityChange={onQuantityChange}
|
|
270
285
|
onApplyCrossSell={onApplyCrossSell}
|
|
271
286
|
onCancelCrossSell={onCancelCrossSell}
|
|
272
287
|
onChangeAmount={onChangeAmount}
|
|
@@ -274,6 +289,7 @@ function PaymentInner({
|
|
|
274
289
|
crossSellBehavior={state.checkoutSession.cross_sell_behavior}
|
|
275
290
|
donationSettings={paymentLink?.donation_settings}
|
|
276
291
|
action={action}
|
|
292
|
+
completed={completed}
|
|
277
293
|
/>
|
|
278
294
|
{mode === 'standalone' && !isMobile && (
|
|
279
295
|
<CheckoutFooter className="cko-footer" sx={{ color: 'text.lighter' }} />
|