payment-kit 1.13.250 → 1.13.251
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/integrations/ethereum/token.ts +0 -27
- package/api/src/integrations/ethereum/tx.ts +37 -0
- package/api/src/libs/ws.ts +7 -7
- package/api/src/routes/checkout-sessions.ts +21 -0
- package/api/src/routes/connect/change-payment.ts +1 -2
- package/api/src/routes/connect/change-plan.ts +1 -2
- package/api/src/routes/connect/pay.ts +2 -2
- package/api/src/routes/connect/setup.ts +3 -2
- package/api/src/routes/connect/subscribe.ts +3 -2
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/src/components/product/form.tsx +7 -2
- package/src/components/subscription/metrics.tsx +1 -1
- package/src/components/uploader.tsx +13 -5
- package/src/pages/customer/invoice/detail.tsx +16 -7
- package/src/pages/customer/subscription/change-plan.tsx +13 -6
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { JsonRpcProvider, TransactionReceipt, ethers } from 'ethers';
|
|
2
2
|
|
|
3
3
|
import { ethWallet } from '../../libs/auth';
|
|
4
|
-
import logger from '../../libs/logger';
|
|
5
|
-
import type { PaymentMethod } from '../../store/models/payment-method';
|
|
6
4
|
import { getApproveFunction } from './contract';
|
|
7
5
|
import erc20Abi from './erc20-abi.json';
|
|
8
|
-
import { waitForEvmTxReceipt } from './tx';
|
|
9
6
|
|
|
10
7
|
export async function fetchErc20Meta(provider: JsonRpcProvider, contractAddress: string) {
|
|
11
8
|
const contract = new ethers.Contract(contractAddress, erc20Abi, provider);
|
|
@@ -125,27 +122,3 @@ export async function sendErc20ToUser(
|
|
|
125
122
|
const receipt = await res.wait();
|
|
126
123
|
return receipt;
|
|
127
124
|
}
|
|
128
|
-
|
|
129
|
-
export async function executeEvmTransaction(
|
|
130
|
-
type: string,
|
|
131
|
-
userDid: string,
|
|
132
|
-
claims: any[],
|
|
133
|
-
paymentMethod: PaymentMethod
|
|
134
|
-
) {
|
|
135
|
-
const client = paymentMethod.getEvmClient();
|
|
136
|
-
const claim = claims.find((x) => x.type === 'signature');
|
|
137
|
-
logger.info('executeEvmTransaction', { type, userDid, claim });
|
|
138
|
-
const receipt = await waitForEvmTxReceipt(client, claim.hash);
|
|
139
|
-
if (!receipt.status) {
|
|
140
|
-
throw new Error(`EVM Transaction failed: ${claim.hash}`);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
type,
|
|
145
|
-
tx_hash: claim.hash,
|
|
146
|
-
payer: userDid,
|
|
147
|
-
block_height: receipt.blockNumber.toString(),
|
|
148
|
-
gas_used: receipt.gasUsed.toString(),
|
|
149
|
-
gas_price: receipt.gasPrice.toString(),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
@@ -2,6 +2,8 @@ import type { JsonRpcProvider, TransactionReceipt, TransactionResponse } from 'e
|
|
|
2
2
|
import waitFor from 'p-wait-for';
|
|
3
3
|
|
|
4
4
|
import logger from '../../libs/logger';
|
|
5
|
+
import { broadcast } from '../../libs/ws';
|
|
6
|
+
import type { PaymentMethod } from '../../store/models/payment-method';
|
|
5
7
|
|
|
6
8
|
export async function waitForEvmTxReceipt(provider: JsonRpcProvider, txHash: string) {
|
|
7
9
|
let mined: TransactionResponse;
|
|
@@ -41,3 +43,38 @@ export async function waitForEvmTxConfirm(provider: JsonRpcProvider, height: num
|
|
|
41
43
|
{ interval: 3000, timeout: 30 * 60 * 1000 }
|
|
42
44
|
);
|
|
43
45
|
}
|
|
46
|
+
|
|
47
|
+
export async function executeEvmTransaction(
|
|
48
|
+
type: string,
|
|
49
|
+
userDid: string,
|
|
50
|
+
claims: any[],
|
|
51
|
+
paymentMethod: PaymentMethod
|
|
52
|
+
) {
|
|
53
|
+
const client = paymentMethod.getEvmClient();
|
|
54
|
+
const claim = claims.find((x) => x.type === 'signature');
|
|
55
|
+
logger.info('executeEvmTransaction', { type, userDid, claim });
|
|
56
|
+
const receipt = await waitForEvmTxReceipt(client, claim.hash);
|
|
57
|
+
if (!receipt.status) {
|
|
58
|
+
throw new Error(`EVM Transaction failed: ${claim.hash}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
type,
|
|
63
|
+
tx_hash: claim.hash,
|
|
64
|
+
payer: userDid,
|
|
65
|
+
block_height: receipt.blockNumber.toString(),
|
|
66
|
+
gas_used: receipt.gasUsed.toString(),
|
|
67
|
+
gas_price: receipt.gasPrice.toString(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function broadcastEvmTransaction(checkoutSessionId: string, status: string, claims: any[]) {
|
|
72
|
+
const claim = claims.find((x) => x.type === 'signature');
|
|
73
|
+
if (claim?.hash) {
|
|
74
|
+
broadcast('checkout.session.evm_transaction', {
|
|
75
|
+
id: checkoutSessionId,
|
|
76
|
+
txHash: claim.hash,
|
|
77
|
+
status,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
package/api/src/libs/ws.ts
CHANGED
|
@@ -3,23 +3,23 @@ import { sendToRelay } from '@blocklet/sdk/service/notification';
|
|
|
3
3
|
import type { CheckoutSession, Invoice, PaymentIntent } from '../store/models';
|
|
4
4
|
import { events } from './event';
|
|
5
5
|
|
|
6
|
-
export function broadcast(
|
|
7
|
-
sendToRelay(
|
|
8
|
-
console.error(`Failed to broadcast
|
|
6
|
+
export function broadcast(eventName: string, data: any) {
|
|
7
|
+
sendToRelay('events', eventName, data).catch((err: any) => {
|
|
8
|
+
console.error(`Failed to broadcast event: ${eventName}`, err);
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export function initEventBroadcast() {
|
|
13
13
|
events.on('payment_intent.succeeded', (data: PaymentIntent) => {
|
|
14
|
-
broadcast('
|
|
14
|
+
broadcast('payment_intent.succeeded', data);
|
|
15
15
|
});
|
|
16
16
|
events.on('checkout.session.completed', (data: CheckoutSession) => {
|
|
17
|
-
broadcast('
|
|
17
|
+
broadcast('checkout.session.completed', data);
|
|
18
18
|
});
|
|
19
19
|
events.on('checkout.session.nft_minted', (data: CheckoutSession) => {
|
|
20
|
-
broadcast('
|
|
20
|
+
broadcast('checkout.session.nft_minted', data);
|
|
21
21
|
});
|
|
22
22
|
events.on('invoice.paid', (data: Invoice) => {
|
|
23
|
-
broadcast('
|
|
23
|
+
broadcast('invoice.paid', data);
|
|
24
24
|
});
|
|
25
25
|
}
|
|
@@ -1107,6 +1107,7 @@ const schema = Joi.object<{
|
|
|
1107
1107
|
customer_id?: string;
|
|
1108
1108
|
customer_did?: string;
|
|
1109
1109
|
payment_intent_id?: string;
|
|
1110
|
+
payment_link_id?: string;
|
|
1110
1111
|
subscription_id?: string;
|
|
1111
1112
|
livemode?: boolean;
|
|
1112
1113
|
}>({
|
|
@@ -1118,6 +1119,7 @@ const schema = Joi.object<{
|
|
|
1118
1119
|
customer_id: Joi.string().empty(''),
|
|
1119
1120
|
customer_did: Joi.string().empty(''),
|
|
1120
1121
|
payment_intent_id: Joi.string().empty(''),
|
|
1122
|
+
payment_link_id: Joi.string().empty(''),
|
|
1121
1123
|
subscription_id: Joi.string().empty(''),
|
|
1122
1124
|
livemode: Joi.boolean().empty(''),
|
|
1123
1125
|
});
|
|
@@ -1141,6 +1143,9 @@ router.get('/', auth, async (req, res) => {
|
|
|
1141
1143
|
if (query.payment_intent_id) {
|
|
1142
1144
|
where.payment_intent_id = query.payment_intent_id;
|
|
1143
1145
|
}
|
|
1146
|
+
if (query.payment_link_id) {
|
|
1147
|
+
where.payment_link_id = query.payment_link_id;
|
|
1148
|
+
}
|
|
1144
1149
|
if (query.subscription_id) {
|
|
1145
1150
|
where.subscription_id = query.subscription_id;
|
|
1146
1151
|
}
|
|
@@ -1191,4 +1196,20 @@ router.get('/', auth, async (req, res) => {
|
|
|
1191
1196
|
}
|
|
1192
1197
|
});
|
|
1193
1198
|
|
|
1199
|
+
router.put('/:id', auth, async (req, res) => {
|
|
1200
|
+
const doc = await CheckoutSession.findByPk(req.params.id);
|
|
1201
|
+
|
|
1202
|
+
if (!doc) {
|
|
1203
|
+
return res.status(404).json({ error: 'CheckoutSession not found' });
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
const raw = pick(req.body, ['metadata']);
|
|
1207
|
+
if (raw.metadata) {
|
|
1208
|
+
raw.metadata = formatMetadata(raw.metadata);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
await doc.update(raw);
|
|
1212
|
+
res.json(doc);
|
|
1213
|
+
});
|
|
1214
|
+
|
|
1194
1215
|
export default router;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { executeEvmTransaction } from '../../integrations/ethereum/
|
|
2
|
-
import { waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
1
|
+
import { executeEvmTransaction, waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
3
2
|
import type { CallbackArgs } from '../../libs/auth';
|
|
4
3
|
import { isDelegationSufficientForPayment } from '../../libs/payment';
|
|
5
4
|
import { getFastCheckoutAmount } from '../../libs/session';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { executeEvmTransaction } from '../../integrations/ethereum/
|
|
2
|
-
import { waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
1
|
+
import { executeEvmTransaction, waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
3
2
|
import type { CallbackArgs } from '../../libs/auth';
|
|
4
3
|
import { isDelegationSufficientForPayment } from '../../libs/payment';
|
|
5
4
|
import { getFastCheckoutAmount } from '../../libs/session';
|
|
@@ -2,8 +2,8 @@ import type { Transaction, TransferV3Tx } from '@ocap/client';
|
|
|
2
2
|
import { toBase58 } from '@ocap/util';
|
|
3
3
|
import { fromAddress } from '@ocap/wallet';
|
|
4
4
|
|
|
5
|
-
import { encodeTransferItx
|
|
6
|
-
import { waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
5
|
+
import { encodeTransferItx } from '../../integrations/ethereum/token';
|
|
6
|
+
import { executeEvmTransaction, waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
7
7
|
import { CallbackArgs, ethWallet } from '../../libs/auth';
|
|
8
8
|
import logger from '../../libs/logger';
|
|
9
9
|
import { getGasPayerExtra } from '../../libs/payment';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { executeEvmTransaction } from '../../integrations/ethereum/
|
|
2
|
-
import { waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
1
|
+
import { broadcastEvmTransaction, executeEvmTransaction, waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
3
2
|
import type { CallbackArgs } from '../../libs/auth';
|
|
4
3
|
import dayjs from '../../libs/dayjs';
|
|
5
4
|
import logger from '../../libs/logger';
|
|
@@ -182,10 +181,12 @@ export default {
|
|
|
182
181
|
|
|
183
182
|
if (paymentMethod.type === 'ethereum') {
|
|
184
183
|
await prepareTxExecution();
|
|
184
|
+
broadcastEvmTransaction(checkoutSessionId, 'pending', claims);
|
|
185
185
|
const paymentDetails = await executeEvmTransaction('approve', userDid, claims, paymentMethod);
|
|
186
186
|
waitForEvmTxConfirm(paymentMethod.getEvmClient(), +paymentDetails.block_height, paymentMethod.confirmation.block)
|
|
187
187
|
.then(async () => {
|
|
188
188
|
await afterTxExecution(paymentDetails);
|
|
189
|
+
broadcastEvmTransaction(checkoutSessionId, 'confirmed', claims);
|
|
189
190
|
})
|
|
190
191
|
.catch(console.error);
|
|
191
192
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { executeEvmTransaction } from '../../integrations/ethereum/
|
|
2
|
-
import { waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
1
|
+
import { broadcastEvmTransaction, executeEvmTransaction, waitForEvmTxConfirm } from '../../integrations/ethereum/tx';
|
|
3
2
|
import type { CallbackArgs } from '../../libs/auth';
|
|
4
3
|
import dayjs from '../../libs/dayjs';
|
|
5
4
|
import logger from '../../libs/logger';
|
|
@@ -165,6 +164,7 @@ export default {
|
|
|
165
164
|
if (paymentMethod.type === 'ethereum') {
|
|
166
165
|
await prepareTxExecution();
|
|
167
166
|
const { invoice } = await ensureInvoiceForCheckout({ checkoutSession, customer, subscription });
|
|
167
|
+
broadcastEvmTransaction(checkoutSessionId, 'pending', claims);
|
|
168
168
|
|
|
169
169
|
const paymentDetails = await executeEvmTransaction('approve', userDid, claims, paymentMethod);
|
|
170
170
|
waitForEvmTxConfirm(
|
|
@@ -174,6 +174,7 @@ export default {
|
|
|
174
174
|
)
|
|
175
175
|
.then(async () => {
|
|
176
176
|
await afterTxExecution(invoice!, paymentDetails);
|
|
177
|
+
broadcastEvmTransaction(checkoutSessionId, 'confirmed', claims);
|
|
177
178
|
})
|
|
178
179
|
.catch(console.error);
|
|
179
180
|
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.251",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@arcblock/ux": "^2.9.77",
|
|
52
52
|
"@arcblock/validator": "^1.18.116",
|
|
53
53
|
"@blocklet/logger": "1.16.26",
|
|
54
|
-
"@blocklet/payment-react": "1.13.
|
|
54
|
+
"@blocklet/payment-react": "1.13.251",
|
|
55
55
|
"@blocklet/sdk": "1.16.26",
|
|
56
56
|
"@blocklet/ui-react": "^2.9.77",
|
|
57
57
|
"@blocklet/uploader": "^0.1.6",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"devDependencies": {
|
|
117
117
|
"@abtnode/types": "1.16.26",
|
|
118
118
|
"@arcblock/eslint-config-ts": "^0.3.0",
|
|
119
|
-
"@blocklet/payment-types": "1.13.
|
|
119
|
+
"@blocklet/payment-types": "1.13.251",
|
|
120
120
|
"@types/cookie-parser": "^1.4.7",
|
|
121
121
|
"@types/cors": "^2.8.17",
|
|
122
122
|
"@types/dotenv-flow": "^3.3.3",
|
|
@@ -155,5 +155,5 @@
|
|
|
155
155
|
"parser": "typescript"
|
|
156
156
|
}
|
|
157
157
|
},
|
|
158
|
-
"gitHead": "
|
|
158
|
+
"gitHead": "46caad7baca15f2ba3876018589f78ba11179f59"
|
|
159
159
|
}
|
|
@@ -25,8 +25,13 @@ export default function ProductForm(props: Props) {
|
|
|
25
25
|
const images = useWatch({ control, name: 'images' });
|
|
26
26
|
|
|
27
27
|
const onUploaded = (result: any) => {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
console.warn('onUploaded', result);
|
|
29
|
+
if (result.url) {
|
|
30
|
+
const tmp = new URL(result.url);
|
|
31
|
+
setValue('images', [tmp.pathname]);
|
|
32
|
+
} else {
|
|
33
|
+
setValue('images', []);
|
|
34
|
+
}
|
|
30
35
|
};
|
|
31
36
|
|
|
32
37
|
return (
|
|
@@ -38,7 +38,7 @@ export default function SubscriptionMetrics({ subscription }: Props) {
|
|
|
38
38
|
divider
|
|
39
39
|
/>
|
|
40
40
|
)}
|
|
41
|
-
{upcoming && upcoming.amount !== '0' && (
|
|
41
|
+
{upcoming?.amount && upcoming.amount !== '0' && (
|
|
42
42
|
<InfoMetric
|
|
43
43
|
label={t('admin.subscription.nextInvoiceAmount')}
|
|
44
44
|
value={`${formatBNStr(upcoming.amount, subscription.paymentCurrency.decimal)} ${
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
2
|
import { Box, Button, Typography } from '@mui/material';
|
|
3
3
|
import { styled } from '@mui/system';
|
|
4
4
|
import { lazy, useCallback, useEffect, useRef } from 'react';
|
|
@@ -14,12 +14,17 @@ type Props = {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export default function Uploader({ onUploaded, preview, maxFileSize, maxNumberOfFiles, allowedFileExts }: Props) {
|
|
17
|
+
const { t } = useLocaleContext();
|
|
17
18
|
const uploaderRef = useRef<any>(null);
|
|
18
19
|
const handleOpen = useCallback(() => {
|
|
19
20
|
if (!uploaderRef.current) return;
|
|
20
21
|
uploaderRef.current.open();
|
|
21
22
|
}, []);
|
|
22
23
|
|
|
24
|
+
const handleRemove = () => {
|
|
25
|
+
onUploaded({ url: '' });
|
|
26
|
+
};
|
|
27
|
+
|
|
23
28
|
useEffect(() => {
|
|
24
29
|
if (uploaderRef.current) {
|
|
25
30
|
const uploader = uploaderRef.current.getUploader();
|
|
@@ -33,17 +38,20 @@ export default function Uploader({ onUploaded, preview, maxFileSize, maxNumberOf
|
|
|
33
38
|
display="flex"
|
|
34
39
|
alignItems={preview ? 'flex-end' : 'center'}
|
|
35
40
|
justifyContent="center"
|
|
36
|
-
onClick={handleOpen}
|
|
37
41
|
style={{
|
|
38
42
|
backgroundImage: preview ? `url(${preview})` : 'none',
|
|
39
43
|
backgroundRepeat: 'no-repeat',
|
|
40
44
|
backgroundSize: 'contain',
|
|
41
45
|
backgroundPosition: 'center',
|
|
42
46
|
}}>
|
|
43
|
-
<Button
|
|
44
|
-
<
|
|
45
|
-
<Typography>{preview ? 'Change' : 'Upload'}</Typography>
|
|
47
|
+
<Button variant={preview ? 'contained' : 'text'} color="inherit" size="small" onClick={handleOpen}>
|
|
48
|
+
<Typography>{t(`common.${preview ? 'change' : 'upload'}`)}</Typography>
|
|
46
49
|
</Button>
|
|
50
|
+
{preview && (
|
|
51
|
+
<Button variant="contained" color="error" size="small" onClick={handleRemove}>
|
|
52
|
+
<Typography>{t('common.remove')}</Typography>
|
|
53
|
+
</Button>
|
|
54
|
+
)}
|
|
47
55
|
</Div>
|
|
48
56
|
<UploaderComponent
|
|
49
57
|
// @ts-ignore
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
3
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Status,
|
|
6
|
+
TxGas,
|
|
7
|
+
TxLink,
|
|
8
|
+
api,
|
|
9
|
+
formatError,
|
|
10
|
+
formatTime,
|
|
11
|
+
getInvoiceStatusColor,
|
|
12
|
+
usePaymentContext,
|
|
13
|
+
} from '@blocklet/payment-react';
|
|
5
14
|
import type { TInvoiceExpanded } from '@blocklet/payment-types';
|
|
6
15
|
import { ArrowBackOutlined } from '@mui/icons-material';
|
|
7
16
|
import { Alert, Box, Button, CircularProgress, Stack, Typography } from '@mui/material';
|
|
@@ -16,7 +25,6 @@ import InfoRow from '../../../components/info-row';
|
|
|
16
25
|
import { Download } from '../../../components/invoice-pdf/pdf';
|
|
17
26
|
import InvoiceTable from '../../../components/invoice/table';
|
|
18
27
|
import SectionHeader from '../../../components/section/header';
|
|
19
|
-
import { useSessionContext } from '../../../contexts/session';
|
|
20
28
|
import { goBackOrFallback } from '../../../libs/util';
|
|
21
29
|
import CustomerRefundList from '../refund/list';
|
|
22
30
|
|
|
@@ -27,7 +35,7 @@ const fetchData = (id: string): Promise<TInvoiceExpanded> => {
|
|
|
27
35
|
export default function CustomerInvoiceDetail() {
|
|
28
36
|
const { t } = useLocaleContext();
|
|
29
37
|
const [searchParams] = useSearchParams();
|
|
30
|
-
const {
|
|
38
|
+
const { connect } = usePaymentContext();
|
|
31
39
|
const params = useParams<{ id: string }>();
|
|
32
40
|
const [state, setState] = useSetState({
|
|
33
41
|
downloading: false,
|
|
@@ -39,8 +47,9 @@ export default function CustomerInvoiceDetail() {
|
|
|
39
47
|
|
|
40
48
|
const onPay = () => {
|
|
41
49
|
setState({ paying: true });
|
|
42
|
-
|
|
50
|
+
connect.open({
|
|
43
51
|
action: 'collect',
|
|
52
|
+
saveConnect: false,
|
|
44
53
|
messages: {
|
|
45
54
|
scan: '',
|
|
46
55
|
title: t(`payment.customer.invoice.${action || 'pay'}`),
|
|
@@ -50,11 +59,11 @@ export default function CustomerInvoiceDetail() {
|
|
|
50
59
|
} as any,
|
|
51
60
|
extraParams: { invoiceId: params.id, action },
|
|
52
61
|
onSuccess: async () => {
|
|
53
|
-
|
|
62
|
+
connect.close();
|
|
54
63
|
await runAsync();
|
|
55
64
|
},
|
|
56
65
|
onClose: () => {
|
|
57
|
-
|
|
66
|
+
connect.close();
|
|
58
67
|
setState({ paying: false });
|
|
59
68
|
},
|
|
60
69
|
onError: (err: any) => {
|
|
@@ -66,7 +75,7 @@ export default function CustomerInvoiceDetail() {
|
|
|
66
75
|
|
|
67
76
|
const closePay = () => {
|
|
68
77
|
setState({ paying: true });
|
|
69
|
-
|
|
78
|
+
connect.close();
|
|
70
79
|
};
|
|
71
80
|
|
|
72
81
|
useEffect(() => {
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
/* eslint-disable react/no-unstable-nested-components */
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
3
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
PricingTable,
|
|
6
|
+
api,
|
|
7
|
+
formatBNStr,
|
|
8
|
+
formatError,
|
|
9
|
+
formatPrice,
|
|
10
|
+
formatTime,
|
|
11
|
+
usePaymentContext,
|
|
12
|
+
} from '@blocklet/payment-react';
|
|
5
13
|
import type { TLineItemExpanded, TPricingTableExpanded, TSubscriptionExpanded } from '@blocklet/payment-types';
|
|
6
14
|
import { ArrowBackOutlined } from '@mui/icons-material';
|
|
7
15
|
import { LoadingButton } from '@mui/lab';
|
|
@@ -12,7 +20,6 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|
|
12
20
|
import InfoCard from '../../../components/info-card';
|
|
13
21
|
import SectionHeader from '../../../components/section/header';
|
|
14
22
|
import SubscriptionDescription from '../../../components/subscription/description';
|
|
15
|
-
import { useSessionContext } from '../../../contexts/session';
|
|
16
23
|
import { goBackOrFallback } from '../../../libs/util';
|
|
17
24
|
|
|
18
25
|
const fetchData = async (
|
|
@@ -45,7 +52,7 @@ export default function CustomerSubscriptionChangePlan() {
|
|
|
45
52
|
const navigate = useNavigate();
|
|
46
53
|
const { id } = useParams() as { id: string };
|
|
47
54
|
const { t, locale } = useLocaleContext();
|
|
48
|
-
const {
|
|
55
|
+
const { connect } = usePaymentContext();
|
|
49
56
|
|
|
50
57
|
const { loading, error, data } = useRequest(() => fetchData(id));
|
|
51
58
|
const [state, setState] = useSetState({
|
|
@@ -142,7 +149,7 @@ export default function CustomerSubscriptionChangePlan() {
|
|
|
142
149
|
setState({ paying: true });
|
|
143
150
|
try {
|
|
144
151
|
setState({ paying: true });
|
|
145
|
-
|
|
152
|
+
connect.open({
|
|
146
153
|
action: result.data.connectAction,
|
|
147
154
|
saveConnect: false,
|
|
148
155
|
messages: {
|
|
@@ -156,12 +163,12 @@ export default function CustomerSubscriptionChangePlan() {
|
|
|
156
163
|
onSuccess: () => {
|
|
157
164
|
setState({ paid: true, paying: false });
|
|
158
165
|
setTimeout(() => {
|
|
159
|
-
|
|
166
|
+
connect.close();
|
|
160
167
|
handleBack();
|
|
161
168
|
}, 2000);
|
|
162
169
|
},
|
|
163
170
|
onClose: () => {
|
|
164
|
-
|
|
171
|
+
connect.close();
|
|
165
172
|
setState({ paying: false });
|
|
166
173
|
},
|
|
167
174
|
onError: (err: any) => {
|