payment-kit 1.16.18 → 1.17.0
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/libs/overdraft-protection.ts +3 -2
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/src/components/customer/overdraft-protection.tsx +29 -5
- package/src/components/product/edit-price.tsx +2 -2
- package/src/pages/admin/index.tsx +3 -1
- package/src/pages/admin/products/prices/detail.tsx +1 -1
- package/src/pages/admin/products/products/detail.tsx +6 -2
|
@@ -6,7 +6,8 @@ export const overdraftProtectionKey = 'overdraft-protection';
|
|
|
6
6
|
|
|
7
7
|
export async function ensureOverdraftProtectionPrice(livemode = true) {
|
|
8
8
|
try {
|
|
9
|
-
const
|
|
9
|
+
const lookUpKey = livemode ? overdraftProtectionKey : `${overdraftProtectionKey}-test`;
|
|
10
|
+
const exist = await Price.findOne({ where: { lookup_key: lookUpKey, livemode } });
|
|
10
11
|
if (exist) {
|
|
11
12
|
const product = await Product.findByPk(exist.product_id);
|
|
12
13
|
return {
|
|
@@ -44,7 +45,7 @@ export async function ensureOverdraftProtectionPrice(livemode = true) {
|
|
|
44
45
|
nickname: '',
|
|
45
46
|
type: 'one_time',
|
|
46
47
|
unit_amount: '1',
|
|
47
|
-
lookup_key:
|
|
48
|
+
lookup_key: lookUpKey,
|
|
48
49
|
recurring: {},
|
|
49
50
|
transform_quantity: { divide_by: 1, round: 'up' },
|
|
50
51
|
tiers: [],
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@arcblock/validator": "^1.18.165",
|
|
54
54
|
"@blocklet/js-sdk": "^1.16.36",
|
|
55
55
|
"@blocklet/logger": "^1.16.36",
|
|
56
|
-
"@blocklet/payment-react": "1.
|
|
56
|
+
"@blocklet/payment-react": "1.17.0",
|
|
57
57
|
"@blocklet/sdk": "^1.16.36",
|
|
58
58
|
"@blocklet/ui-react": "^2.11.15",
|
|
59
59
|
"@blocklet/uploader": "^0.1.60",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"devDependencies": {
|
|
121
121
|
"@abtnode/types": "^1.16.36",
|
|
122
122
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
123
|
-
"@blocklet/payment-types": "1.
|
|
123
|
+
"@blocklet/payment-types": "1.17.0",
|
|
124
124
|
"@types/cookie-parser": "^1.4.7",
|
|
125
125
|
"@types/cors": "^2.8.17",
|
|
126
126
|
"@types/debug": "^4.1.12",
|
|
@@ -166,5 +166,5 @@
|
|
|
166
166
|
"parser": "typescript"
|
|
167
167
|
}
|
|
168
168
|
},
|
|
169
|
-
"gitHead": "
|
|
169
|
+
"gitHead": "b25f7f7c1990a01db3c43dff90eecb65f37bd5d7"
|
|
170
170
|
}
|
|
@@ -19,9 +19,9 @@ import {
|
|
|
19
19
|
} from '@mui/material';
|
|
20
20
|
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
21
21
|
import { EventHandler, useState } from 'react';
|
|
22
|
-
import { api, Switch, useMobile } from '@blocklet/payment-react';
|
|
22
|
+
import { api, formatAmountPrecisionLimit, Switch, useMobile } from '@blocklet/payment-react';
|
|
23
23
|
import { useRequest } from 'ahooks';
|
|
24
|
-
import { BN, fromUnitToToken } from '@ocap/util';
|
|
24
|
+
import { BN, fromTokenToUnit, fromUnitToToken } from '@ocap/util';
|
|
25
25
|
import type { TPaymentCurrency, TSubscriptionExpanded } from '@blocklet/payment-types';
|
|
26
26
|
import Currency from '../currency';
|
|
27
27
|
|
|
@@ -32,6 +32,21 @@ const fetchCycleAmount = (
|
|
|
32
32
|
return api.get(`/api/subscriptions/${subscriptionId}/cycle-amount`, { params }).then((res) => res.data);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
function safeAdd(currency: { decimal: number }, ...numbers: string[]) {
|
|
36
|
+
if (!numbers.length) return '0';
|
|
37
|
+
if (!numbers.every((n) => /^-?\d*\.?\d*$/.test(n))) {
|
|
38
|
+
throw new Error('Invalid number format');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const decimal = currency?.decimal || 18;
|
|
42
|
+
const sum = numbers.reduce((total, num) => {
|
|
43
|
+
const unitAmount = fromTokenToUnit(num, decimal);
|
|
44
|
+
return new BN(total).add(new BN(unitAmount));
|
|
45
|
+
}, new BN(0));
|
|
46
|
+
|
|
47
|
+
return fromUnitToToken(sum.toString(), decimal);
|
|
48
|
+
}
|
|
49
|
+
|
|
35
50
|
type OverdraftProtectionDialogProps = {
|
|
36
51
|
value: {
|
|
37
52
|
enabled: boolean;
|
|
@@ -48,6 +63,7 @@ type OverdraftProtectionDialogProps = {
|
|
|
48
63
|
symbol: string;
|
|
49
64
|
logo: string;
|
|
50
65
|
decimal: number;
|
|
66
|
+
maximum_precision?: number;
|
|
51
67
|
};
|
|
52
68
|
subscription: TSubscriptionExpanded;
|
|
53
69
|
};
|
|
@@ -66,7 +82,7 @@ export default function OverdraftProtectionDialog({
|
|
|
66
82
|
currency,
|
|
67
83
|
subscription,
|
|
68
84
|
}: OverdraftProtectionDialogProps) {
|
|
69
|
-
const { t } = useLocaleContext();
|
|
85
|
+
const { t, locale } = useLocaleContext();
|
|
70
86
|
const { isMobile } = useMobile();
|
|
71
87
|
const [customAmount, setCustomAmount] = useState(false);
|
|
72
88
|
const [presetAmounts, setPresetAmounts] = useState<{ amount: string; cycles: number }[]>([]);
|
|
@@ -298,6 +314,14 @@ export default function OverdraftProtectionDialog({
|
|
|
298
314
|
symbol: currency.symbol,
|
|
299
315
|
});
|
|
300
316
|
}
|
|
317
|
+
const validPrecision = formatAmountPrecisionLimit(
|
|
318
|
+
val.toString(),
|
|
319
|
+
locale,
|
|
320
|
+
currency?.maximum_precision || 6
|
|
321
|
+
);
|
|
322
|
+
if (validPrecision) {
|
|
323
|
+
return validPrecision;
|
|
324
|
+
}
|
|
301
325
|
return true;
|
|
302
326
|
},
|
|
303
327
|
})}
|
|
@@ -325,11 +349,11 @@ export default function OverdraftProtectionDialog({
|
|
|
325
349
|
{amount && Number(amount) > 0 && !methods.formState.errors.amount && (
|
|
326
350
|
<Typography variant="body2" sx={{ color: 'text.lighter', mt: '8px !important' }} fontSize={12}>
|
|
327
351
|
{t('customer.overdraftProtection.total', {
|
|
328
|
-
total:
|
|
352
|
+
total: safeAdd(currency, amount, availableAmount),
|
|
329
353
|
symbol: currency.symbol,
|
|
330
354
|
})}
|
|
331
355
|
{formatEstimatedDuration(
|
|
332
|
-
Math.floor(
|
|
356
|
+
Math.floor(Number(safeAdd(currency, amount, availableAmount)) / Number(estimateAmount))
|
|
333
357
|
)}
|
|
334
358
|
</Typography>
|
|
335
359
|
)}
|
|
@@ -27,7 +27,7 @@ export default function EditPrice({
|
|
|
27
27
|
mode: 'onChange',
|
|
28
28
|
defaultValues: {
|
|
29
29
|
...price,
|
|
30
|
-
unit_amount: fromUnitToToken(price.unit_amount, price.currency
|
|
30
|
+
unit_amount: fromUnitToToken(price.unit_amount, price.currency?.decimal),
|
|
31
31
|
// @ts-ignore
|
|
32
32
|
model: getPricingModel(price as any),
|
|
33
33
|
metadata: isEmpty(price.metadata)
|
|
@@ -40,7 +40,7 @@ export default function EditPrice({
|
|
|
40
40
|
}
|
|
41
41
|
: DEFAULT_PRICE.recurring,
|
|
42
42
|
currency_options: cloneDeep(price.currency_options).map((x: any) => {
|
|
43
|
-
x.unit_amount = fromUnitToToken(x.unit_amount, x.currency
|
|
43
|
+
x.unit_amount = fromUnitToToken(x.unit_amount, x.currency?.decimal);
|
|
44
44
|
return x;
|
|
45
45
|
}),
|
|
46
46
|
},
|
|
@@ -122,7 +122,9 @@ function Admin() {
|
|
|
122
122
|
</label>
|
|
123
123
|
</Stack>
|
|
124
124
|
</Stack>
|
|
125
|
-
<div className="page-content"
|
|
125
|
+
<div className="page-content" key={settings.livemode ? 'live' : 'test'}>
|
|
126
|
+
{isValidElement(TabComponent) ? TabComponent : <TabComponent />}
|
|
127
|
+
</div>
|
|
126
128
|
</>
|
|
127
129
|
);
|
|
128
130
|
}
|
|
@@ -294,7 +294,7 @@ export default function PriceDetail(props: { id: string }) {
|
|
|
294
294
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
295
295
|
customBodyRenderLite: (_: any, index: number) => {
|
|
296
296
|
const item = data.currency_options[index] as any;
|
|
297
|
-
return <Currency logo={item.currency
|
|
297
|
+
return <Currency logo={item.currency?.logo} name={item.currency?.symbol} />;
|
|
298
298
|
},
|
|
299
299
|
},
|
|
300
300
|
},
|
|
@@ -46,7 +46,7 @@ export default function ProductDetail(props: { id: string }) {
|
|
|
46
46
|
const { t, locale } = useLocaleContext();
|
|
47
47
|
const { isMobile } = useMobile();
|
|
48
48
|
const navigate = useNavigate();
|
|
49
|
-
const { settings } = usePaymentContext();
|
|
49
|
+
const { settings, setLivemode } = usePaymentContext();
|
|
50
50
|
const [state, setState] = useSetState({
|
|
51
51
|
adding: {
|
|
52
52
|
price: false,
|
|
@@ -62,7 +62,11 @@ export default function ProductDetail(props: { id: string }) {
|
|
|
62
62
|
},
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
const { loading, error, data, runAsync } = useRequest(() => getProduct(props.id)
|
|
65
|
+
const { loading, error, data, runAsync } = useRequest(() => getProduct(props.id), {
|
|
66
|
+
onSuccess: (res) => {
|
|
67
|
+
setLivemode(!!res.livemode);
|
|
68
|
+
},
|
|
69
|
+
});
|
|
66
70
|
|
|
67
71
|
if (error) {
|
|
68
72
|
return <Alert severity="error">{error.message}</Alert>;
|