payment-kit 1.13.201 → 1.13.202
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/.eslintrc.js +2 -2
- package/api/src/integrations/blockchain/stake.ts +28 -1
- package/api/src/libs/session.ts +5 -5
- package/api/src/routes/checkout-sessions.ts +7 -4
- package/api/src/routes/connect/change-payment.ts +3 -3
- package/api/src/routes/connect/change-plan.ts +3 -3
- package/api/src/routes/connect/collect.ts +1 -1
- package/api/src/routes/connect/setup.ts +6 -2
- package/api/src/routes/connect/shared.ts +6 -6
- package/api/src/routes/connect/subscribe.ts +6 -2
- package/api/src/routes/customers.ts +5 -4
- package/blocklet.yml +1 -1
- package/package.json +10 -10
- package/src/locales/en.tsx +1 -0
- package/src/locales/zh.tsx +1 -0
- package/src/pages/admin/customers/customers/detail.tsx +3 -2
- package/src/pages/admin/payments/index.tsx +0 -14
- package/src/pages/admin/products/coupons/index.tsx +3 -1
- package/src/pages/admin/products/index.tsx +12 -2
- package/src/pages/admin/{payments → products}/links/detail.tsx +2 -2
- package/src/pages/admin/{payments → products}/links/index.tsx +1 -1
- package/src/pages/admin/products/prices/actions.tsx +1 -1
- package/src/pages/customer/index.tsx +3 -2
- /package/src/pages/admin/{payments → products}/links/create.tsx +0 -0
package/.eslintrc.js
CHANGED
|
@@ -11,7 +11,7 @@ module.exports = {
|
|
|
11
11
|
'@typescript-eslint/no-use-before-define': 'off',
|
|
12
12
|
'@typescript-eslint/lines-between-class-members': 'off',
|
|
13
13
|
'import/prefer-default-export': 'off',
|
|
14
|
-
|
|
15
|
-
'jsx-a11y/no-noninteractive-element-interactions':
|
|
14
|
+
'react-hooks/exhaustive-deps': 'off',
|
|
15
|
+
'jsx-a11y/no-noninteractive-element-interactions': 'off',
|
|
16
16
|
},
|
|
17
17
|
};
|
|
@@ -9,7 +9,7 @@ import { fromUnitToToken, toBN } from '@ocap/util';
|
|
|
9
9
|
import { wallet } from '../../libs/auth';
|
|
10
10
|
import { events } from '../../libs/event';
|
|
11
11
|
import logger from '../../libs/logger';
|
|
12
|
-
import { Customer, PaymentCurrency, PaymentMethod, Subscription } from '../../store/models';
|
|
12
|
+
import { Customer, GroupedBN, PaymentCurrency, PaymentMethod, Subscription } from '../../store/models';
|
|
13
13
|
|
|
14
14
|
export async function ensureStakedForGas() {
|
|
15
15
|
const currencies = await PaymentCurrency.findAll({ where: { active: true, is_base_currency: true } });
|
|
@@ -172,3 +172,30 @@ export async function checkStakeRevokeTx() {
|
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
export async function getStakeSummaryByDid(did: string): Promise<GroupedBN> {
|
|
177
|
+
const methods = await PaymentMethod.findAll({
|
|
178
|
+
where: { type: 'arcblock' },
|
|
179
|
+
include: [{ model: PaymentCurrency, as: 'payment_currencies' }],
|
|
180
|
+
});
|
|
181
|
+
if (methods.length === 0) {
|
|
182
|
+
return {};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const address = toStakeAddress(did, wallet.address);
|
|
186
|
+
const results: GroupedBN = {};
|
|
187
|
+
await Promise.all(
|
|
188
|
+
methods.map(async (method: any) => {
|
|
189
|
+
const client = method.getOcapClient();
|
|
190
|
+
const { state } = await client.getStakeState({ address });
|
|
191
|
+
(state?.tokens || []).forEach((t: any) => {
|
|
192
|
+
const currency = method.payment_currencies.find((c: any) => t.address === c.contract);
|
|
193
|
+
if (currency) {
|
|
194
|
+
results[currency.id] = t.value;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return results;
|
|
201
|
+
}
|
package/api/src/libs/session.ts
CHANGED
|
@@ -58,7 +58,7 @@ export function getPriceCurrencyOptions(price: TPrice): PriceCurrency[] {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// FIXME: apply coupon for discounts
|
|
61
|
-
export function getCheckoutAmount(items: TLineItemExpanded[], currencyId: string,
|
|
61
|
+
export function getCheckoutAmount(items: TLineItemExpanded[], currencyId: string, trialing = false) {
|
|
62
62
|
let renew = new BN(0);
|
|
63
63
|
|
|
64
64
|
const total = items
|
|
@@ -67,7 +67,7 @@ export function getCheckoutAmount(items: TLineItemExpanded[], currencyId: string
|
|
|
67
67
|
if (price?.type === 'recurring') {
|
|
68
68
|
renew = renew.add(new BN(getPriceUintAmountByCurrency(price, currencyId)).mul(new BN(x.quantity)));
|
|
69
69
|
|
|
70
|
-
if (
|
|
70
|
+
if (trialing) {
|
|
71
71
|
return acc;
|
|
72
72
|
}
|
|
73
73
|
if (price?.recurring?.usage_type === 'metered') {
|
|
@@ -227,7 +227,7 @@ export function getFastCheckoutAmount(
|
|
|
227
227
|
items: TLineItemExpanded[],
|
|
228
228
|
mode: string,
|
|
229
229
|
currencyId: string,
|
|
230
|
-
|
|
230
|
+
trialing = false,
|
|
231
231
|
minimumCycle = 1
|
|
232
232
|
) {
|
|
233
233
|
if (minimumCycle < 1) {
|
|
@@ -235,7 +235,7 @@ export function getFastCheckoutAmount(
|
|
|
235
235
|
minimumCycle = 1;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
const { total, renew } = getCheckoutAmount(items, currencyId,
|
|
238
|
+
const { total, renew } = getCheckoutAmount(items, currencyId, trialing);
|
|
239
239
|
|
|
240
240
|
if (mode === 'payment') {
|
|
241
241
|
return total;
|
|
@@ -246,7 +246,7 @@ export function getFastCheckoutAmount(
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
if (mode === 'subscription') {
|
|
249
|
-
return new BN(total).add(new BN(renew).mul(new BN(
|
|
249
|
+
return new BN(total).add(new BN(renew).mul(new BN(trialing ? minimumCycle : minimumCycle - 1))).toString();
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
return '0';
|
|
@@ -192,9 +192,11 @@ export const formatCheckoutSession = async (payload: any, throwOnEmptyItems = tr
|
|
|
192
192
|
};
|
|
193
193
|
|
|
194
194
|
export async function getCheckoutSessionAmounts(checkoutSession: CheckoutSession) {
|
|
195
|
+
const now = dayjs().unix();
|
|
195
196
|
const items = await Price.expand(checkoutSession.line_items);
|
|
196
|
-
const
|
|
197
|
-
const
|
|
197
|
+
const trialInDays = Number(checkoutSession.subscription_data?.trial_period_days || 0);
|
|
198
|
+
const trialEnds = Number(checkoutSession.subscription_data?.trial_end || 0);
|
|
199
|
+
const amount = getCheckoutAmount(items, checkoutSession.currency_id, trialInDays > 0 || trialEnds > now);
|
|
198
200
|
return {
|
|
199
201
|
amount_subtotal: amount.subtotal,
|
|
200
202
|
amount_total: amount.total,
|
|
@@ -460,11 +462,12 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
460
462
|
await checkoutSession.update({ currency_id: paymentCurrency.id });
|
|
461
463
|
|
|
462
464
|
// always update payment amount in case currency has changed
|
|
465
|
+
const now = dayjs().unix();
|
|
463
466
|
const lineItems = await Price.expand(checkoutSession.line_items, { product: true, upsell: true });
|
|
464
467
|
const trialInDays = Number(checkoutSession.subscription_data?.trial_period_days || 0);
|
|
465
468
|
const trialEnds = Number(checkoutSession.subscription_data?.trial_end || 0);
|
|
466
469
|
const billingThreshold = Number(checkoutSession.subscription_data?.billing_threshold_amount || 0);
|
|
467
|
-
const amount = getCheckoutAmount(lineItems, paymentCurrency.id,
|
|
470
|
+
const amount = getCheckoutAmount(lineItems, paymentCurrency.id, trialInDays > 0 || trialEnds > now);
|
|
468
471
|
await checkoutSession.update({
|
|
469
472
|
amount_subtotal: amount.subtotal,
|
|
470
473
|
amount_total: amount.total,
|
|
@@ -726,7 +729,7 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
726
729
|
lineItems,
|
|
727
730
|
checkoutSession.mode,
|
|
728
731
|
paymentCurrency.id,
|
|
729
|
-
|
|
732
|
+
trialInDays > 0 || trialEnds > now
|
|
730
733
|
);
|
|
731
734
|
const paymentSettings = {
|
|
732
735
|
payment_method_types: checkoutSession.payment_method_types,
|
|
@@ -29,9 +29,9 @@ export default {
|
|
|
29
29
|
|
|
30
30
|
// @ts-ignore
|
|
31
31
|
const items = subscription!.items as TLineItemExpanded[];
|
|
32
|
-
const
|
|
32
|
+
const trialing = false;
|
|
33
33
|
const billingThreshold = Number(subscription.billing_thresholds?.amount_gte || 0);
|
|
34
|
-
const fastCheckoutAmount = getFastCheckoutAmount(items, 'setup', paymentCurrency.id,
|
|
34
|
+
const fastCheckoutAmount = getFastCheckoutAmount(items, 'setup', paymentCurrency.id, trialing);
|
|
35
35
|
const delegation = await isDelegationSufficientForPayment({
|
|
36
36
|
paymentMethod,
|
|
37
37
|
paymentCurrency,
|
|
@@ -51,7 +51,7 @@ export default {
|
|
|
51
51
|
data: getTxMetadata({ subscriptionId: subscription.id }),
|
|
52
52
|
paymentCurrency,
|
|
53
53
|
paymentMethod,
|
|
54
|
-
|
|
54
|
+
trialing,
|
|
55
55
|
billingThreshold,
|
|
56
56
|
items,
|
|
57
57
|
}),
|
|
@@ -31,9 +31,9 @@ export default {
|
|
|
31
31
|
|
|
32
32
|
// @ts-ignore
|
|
33
33
|
const items = subscription!.items as TLineItemExpanded[];
|
|
34
|
-
const
|
|
34
|
+
const trialing = false;
|
|
35
35
|
const billingThreshold = Number(subscription!.billing_thresholds?.amount_gte || 0);
|
|
36
|
-
const fastCheckoutAmount = getFastCheckoutAmount(items, 'subscription', paymentCurrency.id,
|
|
36
|
+
const fastCheckoutAmount = getFastCheckoutAmount(items, 'subscription', paymentCurrency.id, false);
|
|
37
37
|
const delegation = await isDelegationSufficientForPayment({
|
|
38
38
|
paymentMethod,
|
|
39
39
|
paymentCurrency,
|
|
@@ -53,7 +53,7 @@ export default {
|
|
|
53
53
|
data: getTxMetadata({ subscriptionId: subscription!.id }),
|
|
54
54
|
paymentCurrency,
|
|
55
55
|
paymentMethod,
|
|
56
|
-
|
|
56
|
+
trialing,
|
|
57
57
|
billingThreshold,
|
|
58
58
|
items,
|
|
59
59
|
}),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CallbackArgs } from '../../libs/auth';
|
|
2
|
+
import dayjs from '../../libs/dayjs';
|
|
2
3
|
import logger from '../../libs/logger';
|
|
3
4
|
import { isDelegationSufficientForPayment } from '../../libs/payment';
|
|
4
5
|
import { getFastCheckoutAmount } from '../../libs/session';
|
|
@@ -37,10 +38,13 @@ export default {
|
|
|
37
38
|
const claims: { [type: string]: [string, object] } = {};
|
|
38
39
|
|
|
39
40
|
// if we can complete purchase without any wallet interaction
|
|
41
|
+
const now = dayjs().unix();
|
|
40
42
|
const items = checkoutSession.line_items as TLineItemExpanded[];
|
|
41
43
|
const trialInDays = Number(checkoutSession.subscription_data?.trial_period_days || 0);
|
|
44
|
+
const trialEnds = Number(checkoutSession.subscription_data?.trial_end || 0);
|
|
45
|
+
const trialing = trialInDays > 0 || trialEnds > now;
|
|
42
46
|
const billingThreshold = Number(checkoutSession.subscription_data?.billing_threshold_amount || 0);
|
|
43
|
-
const fastCheckoutAmount = getFastCheckoutAmount(items, checkoutSession.mode, paymentCurrency.id,
|
|
47
|
+
const fastCheckoutAmount = getFastCheckoutAmount(items, checkoutSession.mode, paymentCurrency.id, trialing);
|
|
44
48
|
const delegation = await isDelegationSufficientForPayment({
|
|
45
49
|
paymentMethod,
|
|
46
50
|
paymentCurrency,
|
|
@@ -58,7 +62,7 @@ export default {
|
|
|
58
62
|
data: getTxMetadata({ subscriptionId: subscription.id, checkoutSessionId }),
|
|
59
63
|
paymentCurrency,
|
|
60
64
|
paymentMethod,
|
|
61
|
-
|
|
65
|
+
trialing,
|
|
62
66
|
billingThreshold,
|
|
63
67
|
items,
|
|
64
68
|
}),
|
|
@@ -573,7 +573,7 @@ export async function getDelegationTxClaim({
|
|
|
573
573
|
items,
|
|
574
574
|
paymentCurrency,
|
|
575
575
|
paymentMethod,
|
|
576
|
-
|
|
576
|
+
trialing = false,
|
|
577
577
|
billingThreshold = 0,
|
|
578
578
|
}: {
|
|
579
579
|
userDid: string;
|
|
@@ -584,7 +584,7 @@ export async function getDelegationTxClaim({
|
|
|
584
584
|
items: TLineItemExpanded[];
|
|
585
585
|
paymentCurrency: PaymentCurrency;
|
|
586
586
|
paymentMethod: PaymentMethod;
|
|
587
|
-
|
|
587
|
+
trialing: boolean;
|
|
588
588
|
billingThreshold?: number;
|
|
589
589
|
}) {
|
|
590
590
|
const amount = getFastCheckoutAmount(items, mode, paymentCurrency.id);
|
|
@@ -593,7 +593,7 @@ export async function getDelegationTxClaim({
|
|
|
593
593
|
const tokenRequirements = await getTokenRequirements({
|
|
594
594
|
items,
|
|
595
595
|
mode,
|
|
596
|
-
|
|
596
|
+
trialing,
|
|
597
597
|
billingThreshold,
|
|
598
598
|
paymentMethod,
|
|
599
599
|
paymentCurrency,
|
|
@@ -702,7 +702,7 @@ export type TokenRequirementArgs = {
|
|
|
702
702
|
mode: string;
|
|
703
703
|
paymentMethod: PaymentMethod;
|
|
704
704
|
paymentCurrency: PaymentCurrency;
|
|
705
|
-
|
|
705
|
+
trialing: boolean;
|
|
706
706
|
billingThreshold: number;
|
|
707
707
|
};
|
|
708
708
|
|
|
@@ -711,11 +711,11 @@ export async function getTokenRequirements({
|
|
|
711
711
|
mode,
|
|
712
712
|
paymentMethod,
|
|
713
713
|
paymentCurrency,
|
|
714
|
-
|
|
714
|
+
trialing = false,
|
|
715
715
|
billingThreshold = 0,
|
|
716
716
|
}: TokenRequirementArgs) {
|
|
717
717
|
const tokenRequirements = [];
|
|
718
|
-
let amount = getFastCheckoutAmount(items, mode, paymentCurrency.id, !!
|
|
718
|
+
let amount = getFastCheckoutAmount(items, mode, paymentCurrency.id, !!trialing);
|
|
719
719
|
|
|
720
720
|
// If the app has not staked, we need to add the gas fee to the amount
|
|
721
721
|
if ((await hasStakedForGas(paymentMethod)) === false) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CallbackArgs } from '../../libs/auth';
|
|
2
|
+
import dayjs from '../../libs/dayjs';
|
|
2
3
|
import logger from '../../libs/logger';
|
|
3
4
|
import { isDelegationSufficientForPayment } from '../../libs/payment';
|
|
4
5
|
import { getFastCheckoutAmount } from '../../libs/session';
|
|
@@ -37,10 +38,13 @@ export default {
|
|
|
37
38
|
if (paymentMethod.type === 'arcblock') {
|
|
38
39
|
const claims: { [type: string]: [string, object] } = {};
|
|
39
40
|
|
|
41
|
+
const now = dayjs().unix();
|
|
40
42
|
const items = checkoutSession.line_items as TLineItemExpanded[];
|
|
41
43
|
const trialInDays = Number(checkoutSession.subscription_data?.trial_period_days || 0);
|
|
44
|
+
const trialEnds = Number(checkoutSession.subscription_data?.trial_end || 0);
|
|
45
|
+
const trialing = trialInDays > 0 || trialEnds > now;
|
|
42
46
|
const billingThreshold = Number(checkoutSession.subscription_data?.billing_threshold_amount || 0);
|
|
43
|
-
const fastCheckoutAmount = getFastCheckoutAmount(items, checkoutSession.mode, paymentCurrency.id,
|
|
47
|
+
const fastCheckoutAmount = getFastCheckoutAmount(items, checkoutSession.mode, paymentCurrency.id, trialing);
|
|
44
48
|
const delegation = await isDelegationSufficientForPayment({
|
|
45
49
|
paymentMethod,
|
|
46
50
|
paymentCurrency,
|
|
@@ -60,7 +64,7 @@ export default {
|
|
|
60
64
|
data: getTxMetadata({ subscriptionId: subscription.id, checkoutSessionId }),
|
|
61
65
|
paymentCurrency,
|
|
62
66
|
paymentMethod,
|
|
63
|
-
|
|
67
|
+
trialing,
|
|
64
68
|
billingThreshold,
|
|
65
69
|
items,
|
|
66
70
|
}),
|
|
@@ -3,6 +3,7 @@ import { Router } from 'express';
|
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import pick from 'lodash/pick';
|
|
5
5
|
|
|
6
|
+
import { getStakeSummaryByDid } from '../integrations/blockchain/stake';
|
|
6
7
|
import { getWhereFromKvQuery, getWhereFromQuery } from '../libs/api';
|
|
7
8
|
import { authenticate } from '../libs/security';
|
|
8
9
|
import { formatMetadata } from '../libs/util';
|
|
@@ -110,8 +111,8 @@ router.get('/me', user(), async (req, res) => {
|
|
|
110
111
|
if (!doc) {
|
|
111
112
|
res.json(null);
|
|
112
113
|
} else {
|
|
113
|
-
const summary = await doc.getSummary();
|
|
114
|
-
res.json({ ...doc.toJSON(), summary });
|
|
114
|
+
const [summary, stake] = await Promise.all([doc.getSummary(), getStakeSummaryByDid(doc.did)]);
|
|
115
|
+
res.json({ ...doc.toJSON(), summary: { ...summary, stake } });
|
|
115
116
|
}
|
|
116
117
|
} catch (err) {
|
|
117
118
|
console.error(err);
|
|
@@ -141,8 +142,8 @@ router.get('/:id/summary', auth, async (req, res) => {
|
|
|
141
142
|
return;
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
const
|
|
145
|
-
res.json(
|
|
145
|
+
const [summary, stake] = await Promise.all([doc.getSummary(), getStakeSummaryByDid(doc.did)]);
|
|
146
|
+
res.json({ ...summary, stake });
|
|
146
147
|
} catch (err) {
|
|
147
148
|
console.error(err);
|
|
148
149
|
res.json(null);
|
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.202",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "cross-env COMPONENT_STORE_URL=https://test.store.blocklet.dev blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
"@abtnode/cron": "1.16.24",
|
|
46
46
|
"@arcblock/did": "^1.18.113",
|
|
47
47
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
48
|
-
"@arcblock/did-connect": "^2.9.
|
|
48
|
+
"@arcblock/did-connect": "^2.9.63",
|
|
49
49
|
"@arcblock/did-util": "^1.18.113",
|
|
50
50
|
"@arcblock/jwt": "^1.18.113",
|
|
51
|
-
"@arcblock/ux": "^2.9.
|
|
51
|
+
"@arcblock/ux": "^2.9.63",
|
|
52
52
|
"@blocklet/logger": "1.16.24",
|
|
53
|
-
"@blocklet/payment-react": "1.13.
|
|
53
|
+
"@blocklet/payment-react": "1.13.202",
|
|
54
54
|
"@blocklet/sdk": "1.16.24",
|
|
55
|
-
"@blocklet/ui-react": "^2.9.
|
|
56
|
-
"@blocklet/uploader": "^0.0.
|
|
55
|
+
"@blocklet/ui-react": "^2.9.63",
|
|
56
|
+
"@blocklet/uploader": "^0.0.75",
|
|
57
57
|
"@mui/icons-material": "^5.15.14",
|
|
58
58
|
"@mui/lab": "^5.0.0-alpha.169",
|
|
59
59
|
"@mui/material": "^5.15.14",
|
|
@@ -109,8 +109,8 @@
|
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@abtnode/types": "1.16.24",
|
|
112
|
-
"@arcblock/eslint-config-ts": "^0.
|
|
113
|
-
"@blocklet/payment-types": "1.13.
|
|
112
|
+
"@arcblock/eslint-config-ts": "^0.3.0",
|
|
113
|
+
"@blocklet/payment-types": "1.13.202",
|
|
114
114
|
"@types/cookie-parser": "^1.4.6",
|
|
115
115
|
"@types/cors": "^2.8.17",
|
|
116
116
|
"@types/dotenv-flow": "^3.3.3",
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
"type-fest": "^4.10.2",
|
|
135
135
|
"typescript": "^4.9.5",
|
|
136
136
|
"vite": "^4.5.2",
|
|
137
|
-
"vite-plugin-blocklet": "^0.7.
|
|
137
|
+
"vite-plugin-blocklet": "^0.7.5",
|
|
138
138
|
"vite-plugin-node-polyfills": "^0.7.0",
|
|
139
139
|
"vite-plugin-svgr": "^2.4.0",
|
|
140
140
|
"zx": "^7.2.3"
|
|
@@ -149,5 +149,5 @@
|
|
|
149
149
|
"parser": "typescript"
|
|
150
150
|
}
|
|
151
151
|
},
|
|
152
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "e9c7a403fee7506f92118581d659c91f210714a7"
|
|
153
153
|
}
|
package/src/locales/en.tsx
CHANGED
package/src/locales/zh.tsx
CHANGED
|
@@ -166,12 +166,13 @@ export default function CustomerDetail(props: { id: string }) {
|
|
|
166
166
|
<InfoMetric label={t('common.createdAt')} value={formatTime(data.customer.created_at)} divider />
|
|
167
167
|
<InfoMetric label={t('common.updatedAt')} value={formatTime(data.customer.updated_at)} divider />
|
|
168
168
|
<InfoMetric label={t('admin.customer.spent')} value={<BalanceList data={data.summary.paid} />} divider />
|
|
169
|
+
<InfoMetric label={t('admin.customer.stake')} value={<BalanceList data={data.summary.stake} />} divider />
|
|
170
|
+
<InfoMetric label={t('admin.customer.due')} value={<BalanceList data={data.summary.due} />} divider />
|
|
169
171
|
<InfoMetric
|
|
170
172
|
label={t('admin.customer.refund')}
|
|
171
173
|
value={<BalanceList data={data.summary.refunded} />}
|
|
172
174
|
divider
|
|
173
175
|
/>
|
|
174
|
-
<InfoMetric label={t('admin.customer.due')} value={<BalanceList data={data.summary.due} />} divider />
|
|
175
176
|
{tokenBalances.map((x) => (
|
|
176
177
|
<InfoMetric
|
|
177
178
|
key={x.currency}
|
|
@@ -197,7 +198,7 @@ export default function CustomerDetail(props: { id: string }) {
|
|
|
197
198
|
</Button>
|
|
198
199
|
</SectionHeader>
|
|
199
200
|
<Stack>
|
|
200
|
-
<InfoRow label={t('common.did')} value={<DidAddress did={data.customer.did} />} />
|
|
201
|
+
<InfoRow label={t('common.did')} value={<DidAddress did={data.customer.did} showQrcode />} />
|
|
201
202
|
<InfoRow label={t('admin.customer.name')} value={data.customer.name} />
|
|
202
203
|
<InfoRow label={t('admin.customer.phone')} value={data.customer.phone} />
|
|
203
204
|
<InfoRow label={t('admin.customer.email')} value={data.customer.email} />
|
|
@@ -6,14 +6,11 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|
|
6
6
|
|
|
7
7
|
import { useTransitionContext } from '../../../components/progress-bar';
|
|
8
8
|
|
|
9
|
-
const PaymentLinkCreate = React.lazy(() => import('./links/create'));
|
|
10
|
-
const PaymentLinkDetail = React.lazy(() => import('./links/detail'));
|
|
11
9
|
const PaymentIntentDetail = React.lazy(() => import('./intents/detail'));
|
|
12
10
|
const RefundDetail = React.lazy(() => import('./refunds/detail'));
|
|
13
11
|
|
|
14
12
|
const pages = {
|
|
15
13
|
intents: React.lazy(() => import('./intents')),
|
|
16
|
-
links: React.lazy(() => import('./links')),
|
|
17
14
|
refunds: React.lazy(() => import('./refunds')),
|
|
18
15
|
};
|
|
19
16
|
|
|
@@ -31,10 +28,6 @@ export default function PaymentIndex() {
|
|
|
31
28
|
return <RefundDetail id={page} />;
|
|
32
29
|
}
|
|
33
30
|
|
|
34
|
-
if (page.startsWith('plink_')) {
|
|
35
|
-
return <PaymentLinkDetail id={page} />;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
31
|
const onTabChange = (newTab: string) => {
|
|
39
32
|
startTransition(() => {
|
|
40
33
|
navigate(`/admin/payments/${newTab}`);
|
|
@@ -46,21 +39,14 @@ export default function PaymentIndex() {
|
|
|
46
39
|
const tabs = [
|
|
47
40
|
{ label: t('admin.paymentIntent.list'), value: 'intents' },
|
|
48
41
|
{ label: t('admin.refunds'), value: 'refunds' },
|
|
49
|
-
{ label: t('admin.paymentLinks'), value: 'links' },
|
|
50
42
|
];
|
|
51
43
|
|
|
52
|
-
let extra = null;
|
|
53
|
-
if (page === 'links') {
|
|
54
|
-
extra = <PaymentLinkCreate />;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
44
|
return (
|
|
58
45
|
<div>
|
|
59
46
|
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
60
47
|
<Typography variant="h5" sx={{ mb: 1, fontWeight: 600 }}>
|
|
61
48
|
{t('admin.payments')}
|
|
62
49
|
</Typography>
|
|
63
|
-
{extra}
|
|
64
50
|
</Stack>
|
|
65
51
|
<Tabs tabs={tabs} current={page} onChange={onTabChange} scrollButtons="auto" />
|
|
66
52
|
{isValidElement(TabComponent) ? TabComponent : <TabComponent />}
|
|
@@ -9,14 +9,17 @@ import { useTransitionContext } from '../../../components/progress-bar';
|
|
|
9
9
|
const ProductCreate = React.lazy(() => import('./products/create'));
|
|
10
10
|
const ProductDetail = React.lazy(() => import('./products/detail'));
|
|
11
11
|
const PriceDetail = React.lazy(() => import('./prices/detail'));
|
|
12
|
+
const PaymentLinkCreate = React.lazy(() => import('./links/create'));
|
|
13
|
+
const PaymentLinkDetail = React.lazy(() => import('./links/detail'));
|
|
12
14
|
const PricingTableCreate = React.lazy(() => import('./pricing-tables/create'));
|
|
13
15
|
const PricingTableDetail = React.lazy(() => import('./pricing-tables/detail'));
|
|
14
16
|
|
|
15
17
|
const pages = {
|
|
16
18
|
products: React.lazy(() => import('./products')),
|
|
17
|
-
|
|
19
|
+
links: React.lazy(() => import('./links')),
|
|
18
20
|
'pricing-tables': React.lazy(() => import('./pricing-tables')),
|
|
19
21
|
passports: React.lazy(() => import('./passports')),
|
|
22
|
+
// coupons: React.lazy(() => import('./coupons')),
|
|
20
23
|
};
|
|
21
24
|
|
|
22
25
|
export default function Products() {
|
|
@@ -37,18 +40,25 @@ export default function Products() {
|
|
|
37
40
|
return <PricingTableDetail id={page} />;
|
|
38
41
|
}
|
|
39
42
|
|
|
43
|
+
if (page.startsWith('plink_')) {
|
|
44
|
+
return <PaymentLinkDetail id={page} />;
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
// @ts-ignore
|
|
41
48
|
const TabComponent = pages[page] || pages.products;
|
|
42
49
|
const tabs = [
|
|
43
50
|
{ label: t('admin.products'), value: 'products' },
|
|
44
|
-
{ label: t('admin.
|
|
51
|
+
{ label: t('admin.paymentLinks'), value: 'links' },
|
|
45
52
|
{ label: t('admin.pricingTables'), value: 'pricing-tables' },
|
|
46
53
|
{ label: t('admin.passports'), value: 'passports' },
|
|
54
|
+
// { label: t('admin.coupons'), value: 'coupons' },
|
|
47
55
|
];
|
|
48
56
|
|
|
49
57
|
let extra = null;
|
|
50
58
|
if (page === 'products') {
|
|
51
59
|
extra = <ProductCreate />;
|
|
60
|
+
} else if (page === 'links') {
|
|
61
|
+
extra = <PaymentLinkCreate />;
|
|
52
62
|
} else if (page === 'pricing-tables') {
|
|
53
63
|
extra = <PricingTableCreate />;
|
|
54
64
|
}
|
|
@@ -87,7 +87,7 @@ export default function PaymentLinkDetail(props: { id: string }) {
|
|
|
87
87
|
const onUpdateMetadata = createUpdater('metadata');
|
|
88
88
|
const onChange = (action: string) => {
|
|
89
89
|
if (action === 'remove') {
|
|
90
|
-
navigate('/admin/
|
|
90
|
+
navigate('/admin/products/links');
|
|
91
91
|
} else {
|
|
92
92
|
runAsync();
|
|
93
93
|
}
|
|
@@ -99,7 +99,7 @@ export default function PaymentLinkDetail(props: { id: string }) {
|
|
|
99
99
|
<Grid container spacing={4} sx={{ mb: 4 }}>
|
|
100
100
|
<Grid item md={12}>
|
|
101
101
|
<Stack className="page-header" direction="row" justifyContent="space-between" alignItems="center">
|
|
102
|
-
<Link to="/admin/
|
|
102
|
+
<Link to="/admin/products/links">
|
|
103
103
|
<Stack direction="row" alignItems="center" sx={{ fontWeight: 'normal' }}>
|
|
104
104
|
<ArrowBackOutlined fontSize="small" sx={{ mr: 0.5, color: 'text.secondary' }} />
|
|
105
105
|
<Typography variant="h6" sx={{ color: 'text.secondary', fontWeight: 'normal' }}>
|
|
@@ -151,7 +151,7 @@ function PaymentLinks() {
|
|
|
151
151
|
onRowClick: (_: any, { dataIndex }: any) => {
|
|
152
152
|
const item = data.list[dataIndex] as TPaymentLinkExpanded;
|
|
153
153
|
startTransition(() => {
|
|
154
|
-
navigate(`/admin/
|
|
154
|
+
navigate(`/admin/products/${item.id}`);
|
|
155
155
|
});
|
|
156
156
|
},
|
|
157
157
|
}}
|
|
@@ -88,7 +88,7 @@ export default function PriceActions({ data, onChange, variant, setAsDefault }:
|
|
|
88
88
|
};
|
|
89
89
|
|
|
90
90
|
const onCreatePaymentLink = () => {
|
|
91
|
-
navigate(`/admin/
|
|
91
|
+
navigate(`/admin/products/links?price_id=${data.id}`);
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
const onCreatePricingTable = () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import DID from '@arcblock/ux/lib/
|
|
1
|
+
import DID from '@arcblock/ux/lib/DID';
|
|
2
2
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
3
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
4
4
|
import { CustomerInvoiceList, PaymentProvider, formatError, getPrefix } from '@blocklet/payment-react';
|
|
@@ -134,7 +134,7 @@ export default function CustomerHome() {
|
|
|
134
134
|
</Button>
|
|
135
135
|
</SectionHeader>
|
|
136
136
|
<Stack>
|
|
137
|
-
<InfoRow sizes={[1, 2]} label={t('common.did')} value={<DID
|
|
137
|
+
<InfoRow sizes={[1, 2]} label={t('common.did')} value={<DID did={data.did} copyable showQrcode />} />
|
|
138
138
|
<InfoRow sizes={[1, 2]} label={t('admin.customer.name')} value={data.name} />
|
|
139
139
|
<InfoRow sizes={[1, 2]} label={t('admin.customer.phone')} value={data.phone} />
|
|
140
140
|
<InfoRow sizes={[1, 2]} label={t('admin.customer.email')} value={data.email} />
|
|
@@ -178,6 +178,7 @@ export default function CustomerHome() {
|
|
|
178
178
|
justifyContent="flex-start"
|
|
179
179
|
sx={{ width: '100%' }}>
|
|
180
180
|
<InfoMetric label={t('admin.customer.spent')} value={<BalanceList data={data.summary.paid} />} />
|
|
181
|
+
<InfoMetric label={t('admin.customer.stake')} value={<BalanceList data={data.summary.stake} />} />
|
|
181
182
|
<InfoMetric label={t('admin.customer.due')} value={<BalanceList data={data.summary.due} />} />
|
|
182
183
|
<InfoMetric label={t('admin.customer.refund')} value={<BalanceList data={data.summary.refunded} />} />
|
|
183
184
|
</Stack>
|
|
File without changes
|