@blocklet/payment-react 1.13.130 → 1.13.132
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 +13 -0
- package/es/components/blockchain/tx.js +52 -0
- package/es/history/invoice/list.js +3 -2
- package/es/history/mini-invoice/list.js +33 -29
- package/es/history/payment/list.js +10 -1
- package/es/index.d.ts +2 -1
- package/es/index.js +3 -1
- package/es/locales/en.js +3 -3
- package/es/locales/zh.js +3 -3
- package/es/payment/index.js +5 -3
- package/es/types/index.d.ts +1 -1
- package/es/util.d.ts +1 -0
- package/es/util.js +17 -2
- package/lib/components/blockchain/tx.d.ts +13 -0
- package/lib/components/blockchain/tx.js +82 -0
- package/lib/history/invoice/list.js +2 -1
- package/lib/history/mini-invoice/list.js +30 -32
- package/lib/history/payment/list.js +13 -2
- package/lib/index.d.ts +2 -1
- package/lib/index.js +8 -0
- package/lib/locales/en.js +3 -3
- package/lib/locales/zh.js +3 -3
- package/lib/payment/index.js +5 -3
- package/lib/types/index.d.ts +1 -1
- package/lib/util.d.ts +1 -0
- package/lib/util.js +18 -2
- package/package.json +3 -3
- package/src/components/blockchain/tx.tsx +77 -0
- package/src/history/invoice/list.tsx +3 -2
- package/src/history/mini-invoice/list.tsx +37 -33
- package/src/history/payment/list.tsx +12 -2
- package/src/index.ts +2 -0
- package/src/locales/en.tsx +3 -3
- package/src/locales/zh.tsx +3 -3
- package/src/payment/index.tsx +5 -3
- package/src/types/index.ts +1 -1
- package/src/util.ts +18 -2
|
@@ -10,6 +10,7 @@ var _material = require("@mui/material");
|
|
|
10
10
|
var _util = require("@ocap/util");
|
|
11
11
|
var _ahooks = require("ahooks");
|
|
12
12
|
var _api = _interopRequireDefault(require("../../api"));
|
|
13
|
+
var _tx = _interopRequireDefault(require("../../components/blockchain/tx"));
|
|
13
14
|
var _status = _interopRequireDefault(require("../../components/status"));
|
|
14
15
|
var _util2 = require("../../util");
|
|
15
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -111,9 +112,19 @@ function CustomerPaymentList({
|
|
|
111
112
|
color: (0, _util2.getPaymentIntentStatusColor)(item.status)
|
|
112
113
|
})
|
|
113
114
|
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
114
|
-
flex:
|
|
115
|
+
flex: 3,
|
|
115
116
|
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
116
|
-
children: item.description ||
|
|
117
|
+
children: item.description || "-"
|
|
118
|
+
})
|
|
119
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
120
|
+
flex: 3,
|
|
121
|
+
sx: {
|
|
122
|
+
minWidth: "220px"
|
|
123
|
+
},
|
|
124
|
+
children: item.payment_details?.arcblock?.tx_hash && /* @__PURE__ */(0, _jsxRuntime.jsx)(_tx.default, {
|
|
125
|
+
details: item.payment_details,
|
|
126
|
+
method: item.paymentMethod,
|
|
127
|
+
mode: "customer"
|
|
117
128
|
})
|
|
118
129
|
})]
|
|
119
130
|
}, item.id))]
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import api from './api';
|
|
2
2
|
import CheckoutForm from './checkout/form';
|
|
3
3
|
import CheckoutTable from './checkout/table';
|
|
4
|
+
import TxLink from './components/blockchain/tx';
|
|
4
5
|
import ConfirmDialog from './components/confirm';
|
|
5
6
|
import FormInput from './components/input';
|
|
6
7
|
import Livemode from './components/livemode';
|
|
@@ -18,4 +19,4 @@ import ProductSkeleton from './payment/product-skeleton';
|
|
|
18
19
|
export * from './util';
|
|
19
20
|
export * from './contexts/payment';
|
|
20
21
|
export { translations, createTranslator } from './locales';
|
|
21
|
-
export { api, dayjs, FormInput, PhoneInput, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, Payment, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, MiniInvoiceList, };
|
|
22
|
+
export { api, dayjs, FormInput, PhoneInput, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, Payment, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, MiniInvoiceList, TxLink, };
|
package/lib/index.js
CHANGED
|
@@ -7,6 +7,7 @@ var _exportNames = {
|
|
|
7
7
|
api: true,
|
|
8
8
|
CheckoutForm: true,
|
|
9
9
|
CheckoutTable: true,
|
|
10
|
+
TxLink: true,
|
|
10
11
|
ConfirmDialog: true,
|
|
11
12
|
FormInput: true,
|
|
12
13
|
Livemode: true,
|
|
@@ -114,6 +115,12 @@ Object.defineProperty(exports, "Switch", {
|
|
|
114
115
|
return _switchButton.default;
|
|
115
116
|
}
|
|
116
117
|
});
|
|
118
|
+
Object.defineProperty(exports, "TxLink", {
|
|
119
|
+
enumerable: true,
|
|
120
|
+
get: function () {
|
|
121
|
+
return _tx.default;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
117
124
|
Object.defineProperty(exports, "api", {
|
|
118
125
|
enumerable: true,
|
|
119
126
|
get: function () {
|
|
@@ -141,6 +148,7 @@ Object.defineProperty(exports, "translations", {
|
|
|
141
148
|
var _api = _interopRequireDefault(require("./api"));
|
|
142
149
|
var _form = _interopRequireDefault(require("./checkout/form"));
|
|
143
150
|
var _table = _interopRequireDefault(require("./checkout/table"));
|
|
151
|
+
var _tx = _interopRequireDefault(require("./components/blockchain/tx"));
|
|
144
152
|
var _confirm = _interopRequireDefault(require("./components/confirm"));
|
|
145
153
|
var _input = _interopRequireDefault(require("./components/input"));
|
|
146
154
|
var _livemode = _interopRequireDefault(require("./components/livemode"));
|
package/lib/locales/en.js
CHANGED
|
@@ -209,17 +209,17 @@ module.exports = (0, _flat.default)({
|
|
|
209
209
|
pay: "Pay this invoice",
|
|
210
210
|
paySuccess: "You have successfully paid the invoice",
|
|
211
211
|
payError: "Failed to paid the invoice",
|
|
212
|
-
empty: "
|
|
212
|
+
empty: "There are no invoices here"
|
|
213
213
|
},
|
|
214
214
|
payment: {
|
|
215
|
-
empty: "
|
|
215
|
+
empty: "There are no payments here"
|
|
216
216
|
},
|
|
217
217
|
subscriptions: {
|
|
218
218
|
plan: "Plan",
|
|
219
219
|
nextInvoice: "Next Invoice",
|
|
220
220
|
title: "Manage subscriptions",
|
|
221
221
|
current: "Current subscription",
|
|
222
|
-
empty: "
|
|
222
|
+
empty: "There are no subscriptions here"
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
}
|
package/lib/locales/zh.js
CHANGED
|
@@ -209,17 +209,17 @@ module.exports = (0, _flat.default)({
|
|
|
209
209
|
pay: "\u652F\u4ED8\u6B64\u53D1\u7968",
|
|
210
210
|
paySuccess: "\u652F\u4ED8\u6210\u529F",
|
|
211
211
|
payError: "\u652F\u4ED8\u5931\u8D25",
|
|
212
|
-
empty: "\
|
|
212
|
+
empty: "\u6CA1\u6709\u4EFB\u4F55\u53D1\u7968"
|
|
213
213
|
},
|
|
214
214
|
payment: {
|
|
215
|
-
empty: "\
|
|
215
|
+
empty: "\u6CA1\u6709\u4EFB\u4F55\u652F\u4ED8"
|
|
216
216
|
},
|
|
217
217
|
subscriptions: {
|
|
218
218
|
plan: "\u8BA2\u9605",
|
|
219
219
|
nextInvoice: "\u4E0B\u4E00\u5F20\u53D1\u7968",
|
|
220
220
|
title: "\u8BA2\u9605\u7BA1\u7406",
|
|
221
221
|
current: "\u5F53\u524D\u8BA2\u9605",
|
|
222
|
-
empty: "\
|
|
222
|
+
empty: "\u6CA1\u6709\u4EFB\u4F55\u8BA2\u9605"
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
}
|
package/lib/payment/index.js
CHANGED
|
@@ -308,7 +308,7 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
308
308
|
|
|
309
309
|
.cko-container {
|
|
310
310
|
width: 100%;
|
|
311
|
-
max-width: 1000px;
|
|
311
|
+
max-width: ${props => props.mode.endsWith("-minimal") ? "400px" : "1000px"};
|
|
312
312
|
display: flex;
|
|
313
313
|
flex-direction: row;
|
|
314
314
|
justify-content: space-between;
|
|
@@ -317,9 +317,10 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
317
317
|
}
|
|
318
318
|
|
|
319
319
|
.cko-overview {
|
|
320
|
-
width: 400px;
|
|
320
|
+
width: ${props => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
321
321
|
min-height: ${props => props.mode === "standalone" ? "540px" : "auto"};
|
|
322
322
|
position: relative;
|
|
323
|
+
display: ${props => props.mode.endsWith("-minimal") ? "none" : "block"};
|
|
323
324
|
}
|
|
324
325
|
.cko-header {
|
|
325
326
|
left: 0;
|
|
@@ -336,7 +337,7 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
336
337
|
}
|
|
337
338
|
|
|
338
339
|
.cko-payment {
|
|
339
|
-
width: 400px;
|
|
340
|
+
width: ${props => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
340
341
|
.MuiInputBase-root {
|
|
341
342
|
border-radius: 0;
|
|
342
343
|
}
|
|
@@ -425,6 +426,7 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
425
426
|
bottom: 0;
|
|
426
427
|
left: 12px;
|
|
427
428
|
margin: 12px 0;
|
|
429
|
+
display: ${props => props.mode.endsWith("-minimal") ? "none" : "block"};
|
|
428
430
|
}
|
|
429
431
|
|
|
430
432
|
@media (max-width: ${({
|
package/lib/types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type CheckoutContext = {
|
|
|
11
11
|
export type CheckoutProps = Partial<CheckoutCallbacks> & {
|
|
12
12
|
id: string;
|
|
13
13
|
extraParams?: Record<string, any>;
|
|
14
|
-
mode?: LiteralUnion<'standalone' | 'inline' | 'popup', string>;
|
|
14
|
+
mode?: LiteralUnion<'standalone' | 'inline' | 'popup' | 'inline-minimal' | 'popup-minimal', string>;
|
|
15
15
|
};
|
|
16
16
|
export type CheckoutCallbacks = {
|
|
17
17
|
onPaid: (res: CheckoutContext) => void;
|
package/lib/util.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function formatLineItemPricing(item: TLineItemExpanded, currency:
|
|
|
22
22
|
};
|
|
23
23
|
export declare function getSubscriptionStatusColor(status: string): "success" | "primary" | "warning" | "error" | "default";
|
|
24
24
|
export declare function getPaymentIntentStatusColor(status: string): "success" | "warning" | "default";
|
|
25
|
+
export declare function getRefundStatusColor(status: string): "success" | "warning" | "default";
|
|
25
26
|
export declare function getInvoiceStatusColor(status: string): "success" | "warning" | "default" | "secondary";
|
|
26
27
|
export declare function getWebhookStatusColor(status: string): "success" | "default";
|
|
27
28
|
export declare function getCheckoutAmount(items: TLineItemExpanded[], currency: TPaymentCurrency, includeFreeTrial?: boolean, upsell?: boolean): {
|
package/lib/util.js
CHANGED
|
@@ -24,6 +24,7 @@ exports.getPrefix = void 0;
|
|
|
24
24
|
exports.getPriceCurrencyOptions = getPriceCurrencyOptions;
|
|
25
25
|
exports.getPriceUintAmountByCurrency = getPriceUintAmountByCurrency;
|
|
26
26
|
exports.getRecurringPeriod = getRecurringPeriod;
|
|
27
|
+
exports.getRefundStatusColor = getRefundStatusColor;
|
|
27
28
|
exports.getStatementDescriptor = getStatementDescriptor;
|
|
28
29
|
exports.getSubscriptionAction = void 0;
|
|
29
30
|
exports.getSubscriptionStatusColor = getSubscriptionStatusColor;
|
|
@@ -257,6 +258,18 @@ function getPaymentIntentStatusColor(status) {
|
|
|
257
258
|
return "default";
|
|
258
259
|
}
|
|
259
260
|
}
|
|
261
|
+
function getRefundStatusColor(status) {
|
|
262
|
+
switch (status) {
|
|
263
|
+
case "succeeded":
|
|
264
|
+
return "success";
|
|
265
|
+
case "requires_action":
|
|
266
|
+
return "warning";
|
|
267
|
+
case "canceled":
|
|
268
|
+
case "pending":
|
|
269
|
+
default:
|
|
270
|
+
return "default";
|
|
271
|
+
}
|
|
272
|
+
}
|
|
260
273
|
function getInvoiceStatusColor(status) {
|
|
261
274
|
switch (status) {
|
|
262
275
|
case "paid":
|
|
@@ -282,9 +295,12 @@ function getWebhookStatusColor(status) {
|
|
|
282
295
|
}
|
|
283
296
|
function getCheckoutAmount(items, currency, includeFreeTrial = false, upsell = true) {
|
|
284
297
|
let renew = new _util.BN(0);
|
|
285
|
-
const total = items.
|
|
298
|
+
const total = items.filter(x => {
|
|
299
|
+
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
300
|
+
return price != null;
|
|
301
|
+
}).reduce((acc, x) => {
|
|
286
302
|
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
287
|
-
if (price
|
|
303
|
+
if (price?.type === "recurring") {
|
|
288
304
|
renew = renew.add(new _util.BN(getPriceUintAmountByCurrency(price, currency)).mul(new _util.BN(x.quantity)));
|
|
289
305
|
if (includeFreeTrial) {
|
|
290
306
|
return acc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.132",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"@babel/core": "^7.19.3",
|
|
90
90
|
"@babel/preset-env": "^7.19.3",
|
|
91
91
|
"@babel/preset-react": "^7.18.6",
|
|
92
|
-
"@blocklet/payment-types": "1.13.
|
|
92
|
+
"@blocklet/payment-types": "1.13.132",
|
|
93
93
|
"@storybook/addon-essentials": "^7.6.10",
|
|
94
94
|
"@storybook/addon-interactions": "^7.6.10",
|
|
95
95
|
"@storybook/addon-links": "^7.6.10",
|
|
@@ -118,5 +118,5 @@
|
|
|
118
118
|
"vite-plugin-babel": "^1.2.0",
|
|
119
119
|
"vite-plugin-node-polyfills": "^0.19.0"
|
|
120
120
|
},
|
|
121
|
-
"gitHead": "
|
|
121
|
+
"gitHead": "d1b6e7bace2743798d22c33f245c32a4c5ba3200"
|
|
122
122
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { PaymentDetails, TPaymentMethod } from '@blocklet/payment-types';
|
|
2
|
+
import { OpenInNewOutlined } from '@mui/icons-material';
|
|
3
|
+
import { Link, Stack, Typography } from '@mui/material';
|
|
4
|
+
import { joinURL } from 'ufo';
|
|
5
|
+
|
|
6
|
+
const getTxLink = (method: TPaymentMethod, details: PaymentDetails) => {
|
|
7
|
+
if (method.type === 'arcblock' && details.arcblock?.tx_hash) {
|
|
8
|
+
return {
|
|
9
|
+
link: joinURL(method.settings.arcblock?.explorer_host as string, '/txs', details.arcblock?.tx_hash as string),
|
|
10
|
+
text: details.arcblock?.tx_hash as string,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (method.type === 'bitcoin' && details.bitcoin?.tx_hash) {
|
|
14
|
+
return {
|
|
15
|
+
link: joinURL(method.settings.bitcoin?.explorer_host as string, '/tx', details.bitcoin?.tx_hash as string),
|
|
16
|
+
text: details.bitcoin?.tx_hash as string,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (method.type === 'ethereum' && details.ethereum?.tx_hash) {
|
|
20
|
+
return {
|
|
21
|
+
link: joinURL(method.settings.ethereum?.explorer_host as string, '/tx', details.ethereum?.tx_hash as string),
|
|
22
|
+
text: details.ethereum?.tx_hash as string,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (method.type === 'stripe') {
|
|
26
|
+
const dashboard = method.livemode ? 'https://dashboard.stripe.com' : 'https://dashboard.stripe.com/test';
|
|
27
|
+
return {
|
|
28
|
+
link: joinURL(
|
|
29
|
+
method.settings.stripe?.dashboard || dashboard,
|
|
30
|
+
'payments',
|
|
31
|
+
details.stripe?.payment_intent_id as string
|
|
32
|
+
),
|
|
33
|
+
text: details.stripe?.payment_intent_id as string,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return { text: 'N/A', link: '' };
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
TxLink.defaultProps = {
|
|
41
|
+
mode: 'dashboard',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default function TxLink(props: {
|
|
45
|
+
details: PaymentDetails;
|
|
46
|
+
method: TPaymentMethod;
|
|
47
|
+
mode?: 'customer' | 'dashboard';
|
|
48
|
+
}) {
|
|
49
|
+
if (!props.details || (props.mode === 'customer' && props.method.type === 'stripe')) {
|
|
50
|
+
return (
|
|
51
|
+
<Typography component="small" color="text.secondary">
|
|
52
|
+
None
|
|
53
|
+
</Typography>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { text, link } = getTxLink(props.method, props.details);
|
|
58
|
+
|
|
59
|
+
if (link) {
|
|
60
|
+
return (
|
|
61
|
+
<Link href={link} target="_blank" rel="noopener noreferrer">
|
|
62
|
+
<Stack component="span" direction="row" alignItems="center" spacing={1}>
|
|
63
|
+
<Typography component="span" color="primary">
|
|
64
|
+
{text.length > 40 ? [text.slice(0, 8), text.slice(-8)].join('...') : text}
|
|
65
|
+
</Typography>
|
|
66
|
+
<OpenInNewOutlined fontSize="small" />
|
|
67
|
+
</Stack>
|
|
68
|
+
</Link>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<Typography component="small" color="text.secondary">
|
|
74
|
+
None
|
|
75
|
+
</Typography>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
@@ -4,10 +4,11 @@ import type { Paginated, TInvoiceExpanded } from '@blocklet/payment-types';
|
|
|
4
4
|
import { Box, Button, CircularProgress, Stack, Typography } from '@mui/material';
|
|
5
5
|
import { fromUnitToToken } from '@ocap/util';
|
|
6
6
|
import { useInfiniteScroll } from 'ahooks';
|
|
7
|
+
import { joinURL } from 'ufo';
|
|
7
8
|
|
|
8
9
|
import api from '../../api';
|
|
9
10
|
import Status from '../../components/status';
|
|
10
|
-
import { formatToDate, getInvoiceStatusColor } from '../../util';
|
|
11
|
+
import { formatToDate, getInvoiceStatusColor, getPrefix } from '../../util';
|
|
11
12
|
|
|
12
13
|
const groupByDate = (items: TInvoiceExpanded[]) => {
|
|
13
14
|
const grouped: { [key: string]: TInvoiceExpanded[] } = {};
|
|
@@ -83,7 +84,7 @@ export default function CustomerInvoiceList({ customer_id, subscription_id }: Pr
|
|
|
83
84
|
}}
|
|
84
85
|
flexWrap="nowrap">
|
|
85
86
|
<Box flex={3}>
|
|
86
|
-
<a href={`/customer/invoice/${invoice.id}`}>
|
|
87
|
+
<a href={joinURL(window.location.origin, getPrefix(), `/customer/invoice/${invoice.id}`)}>
|
|
87
88
|
<Typography component="span">{invoice.number}</Typography>
|
|
88
89
|
</a>
|
|
89
90
|
</Box>
|
|
@@ -4,6 +4,7 @@ import type { Paginated, TInvoiceExpanded, TSubscriptionExpanded } from '@blockl
|
|
|
4
4
|
import { Box, Button, CircularProgress, Divider, List, ListItem, ListSubheader, Typography } from '@mui/material';
|
|
5
5
|
import { fromUnitToToken } from '@ocap/util';
|
|
6
6
|
import { useRequest } from 'ahooks';
|
|
7
|
+
import { joinURL } from 'ufo';
|
|
7
8
|
|
|
8
9
|
import api from '../../api';
|
|
9
10
|
import Status from '../../components/status';
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
formatTime,
|
|
13
14
|
formatToDate,
|
|
14
15
|
getInvoiceStatusColor,
|
|
16
|
+
getPrefix,
|
|
15
17
|
getSubscriptionStatusColor,
|
|
16
18
|
} from '../../util';
|
|
17
19
|
|
|
@@ -37,7 +39,7 @@ export default function MiniInvoiceList() {
|
|
|
37
39
|
fetchInvoiceData({ page: 1, pageSize: 10, status: 'open,paid,uncollectible', subscription_id: subscriptionId })
|
|
38
40
|
);
|
|
39
41
|
|
|
40
|
-
if (!
|
|
42
|
+
if (!subscription || !data) {
|
|
41
43
|
return (
|
|
42
44
|
<Position>
|
|
43
45
|
<CircularProgress />
|
|
@@ -45,13 +47,7 @@ export default function MiniInvoiceList() {
|
|
|
45
47
|
);
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<Position>
|
|
51
|
-
<Typography color="text.secondary">{t('payment.customer.invoice.empty')}</Typography>
|
|
52
|
-
</Position>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
50
|
+
const invoices = data.list || [];
|
|
55
51
|
|
|
56
52
|
const infoList = [
|
|
57
53
|
{
|
|
@@ -66,8 +62,10 @@ export default function MiniInvoiceList() {
|
|
|
66
62
|
name: t('common.status'),
|
|
67
63
|
value: <Status label={subscription.status} color={getSubscriptionStatusColor(subscription.status)} />,
|
|
68
64
|
},
|
|
65
|
+
];
|
|
69
66
|
|
|
70
|
-
|
|
67
|
+
if (subscription.status === 'active' || subscription.status === 'trailing') {
|
|
68
|
+
infoList.push({
|
|
71
69
|
name: t('payment.customer.subscriptions.nextInvoice'),
|
|
72
70
|
value: (
|
|
73
71
|
<Typography
|
|
@@ -79,13 +77,14 @@ export default function MiniInvoiceList() {
|
|
|
79
77
|
{formatTime(subscription.current_period_end * 1000)}
|
|
80
78
|
</Typography>
|
|
81
79
|
),
|
|
82
|
-
}
|
|
83
|
-
|
|
80
|
+
});
|
|
81
|
+
}
|
|
84
82
|
|
|
85
83
|
return (
|
|
86
84
|
<Position>
|
|
87
85
|
<Typography title={t('payment.checkout.subscription')} />
|
|
88
86
|
<Box
|
|
87
|
+
className="mini-invoice-wrap"
|
|
89
88
|
sx={{
|
|
90
89
|
display: 'flex',
|
|
91
90
|
flexDirection: 'column',
|
|
@@ -111,34 +110,40 @@ export default function MiniInvoiceList() {
|
|
|
111
110
|
</List>
|
|
112
111
|
</Box>
|
|
113
112
|
<Divider />
|
|
114
|
-
<Box sx={{ marginTop: '12px' }}>
|
|
115
|
-
<List
|
|
116
|
-
sx={{ overflow: 'auto', maxHeight: { xs: '240px', md: '360px', padding: 0 } }}
|
|
117
|
-
className="mini-invoice-list">
|
|
113
|
+
<Box sx={{ marginTop: '12px', flex: 1 }}>
|
|
114
|
+
<List sx={{ overflow: 'auto' }} className="mini-invoice-list">
|
|
118
115
|
<ListSubheader disableGutters sx={{ padding: 0 }}>
|
|
119
116
|
<Typography component="h2" variant="h6" fontSize="16px">
|
|
120
117
|
{t('payment.customer.invoices')}
|
|
121
118
|
</Typography>
|
|
122
119
|
</ListSubheader>
|
|
123
|
-
{(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
120
|
+
{(invoices as any).length === 0 ? (
|
|
121
|
+
<Typography color="text.secondary">{t('payment.customer.invoice.empty')}</Typography>
|
|
122
|
+
) : (
|
|
123
|
+
(invoices as any).map((item: any) => {
|
|
124
|
+
return (
|
|
125
|
+
<ListItem key={item.id} disableGutters sx={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
126
|
+
<Typography component="span" sx={{ flex: 3 }}>
|
|
127
|
+
{formatToDate(item.created_at)}
|
|
128
|
+
</Typography>
|
|
129
|
+
<Typography component="span" sx={{ flex: 1, textAlign: 'right' }}>
|
|
130
|
+
{fromUnitToToken(item.total, item.paymentCurrency.decimal)}
|
|
131
|
+
{item.paymentCurrency.symbol}
|
|
132
|
+
</Typography>
|
|
133
|
+
<Typography component="span" sx={{ flex: 2, textAlign: 'right' }}>
|
|
134
|
+
<Status label={item.status} color={getInvoiceStatusColor(item.status)} sx={{ flex: 2 }} />
|
|
135
|
+
</Typography>
|
|
136
|
+
</ListItem>
|
|
137
|
+
);
|
|
138
|
+
})
|
|
139
|
+
)}
|
|
139
140
|
</List>
|
|
140
141
|
</Box>
|
|
141
|
-
<Button
|
|
142
|
+
<Button
|
|
143
|
+
target="_blank"
|
|
144
|
+
variant="contained"
|
|
145
|
+
sx={{ marginTop: '10px 0', width: '100%', color: '#fff!important' }}
|
|
146
|
+
href={joinURL(window.location.origin, getPrefix(), `/customer/subscription/${subscription.id}`)}>
|
|
142
147
|
{t('payment.customer.subscriptions.title')}
|
|
143
148
|
</Button>
|
|
144
149
|
</Box>
|
|
@@ -151,7 +156,6 @@ function Position({ children }: any) {
|
|
|
151
156
|
<Box
|
|
152
157
|
className="mini-invoice-box" // 预留 class 用于设置定位
|
|
153
158
|
sx={{
|
|
154
|
-
justifyContent: 'center',
|
|
155
159
|
padding: '8px',
|
|
156
160
|
width: '100%',
|
|
157
161
|
maxWidth: '500px',
|
|
@@ -6,6 +6,7 @@ import { fromUnitToToken } from '@ocap/util';
|
|
|
6
6
|
import { useInfiniteScroll } from 'ahooks';
|
|
7
7
|
|
|
8
8
|
import api from '../../api';
|
|
9
|
+
import TxLink from '../../components/blockchain/tx';
|
|
9
10
|
import Status from '../../components/status';
|
|
10
11
|
import { formatToDate, getPaymentIntentStatusColor } from '../../util';
|
|
11
12
|
|
|
@@ -91,8 +92,17 @@ export default function CustomerPaymentList({ customer_id }: Props) {
|
|
|
91
92
|
<Box flex={3}>
|
|
92
93
|
<Status label={item.status} color={getPaymentIntentStatusColor(item.status)} />
|
|
93
94
|
</Box>
|
|
94
|
-
<Box flex={
|
|
95
|
-
<Typography>{item.description ||
|
|
95
|
+
<Box flex={3}>
|
|
96
|
+
<Typography>{item.description || '-'}</Typography>
|
|
97
|
+
</Box>
|
|
98
|
+
<Box flex={3} sx={{ minWidth: '220px' }}>
|
|
99
|
+
{(item as any).payment_details?.arcblock?.tx_hash && (
|
|
100
|
+
<TxLink
|
|
101
|
+
details={(item as any).payment_details}
|
|
102
|
+
method={(item as any).paymentMethod}
|
|
103
|
+
mode="customer"
|
|
104
|
+
/>
|
|
105
|
+
)}
|
|
96
106
|
</Box>
|
|
97
107
|
</Stack>
|
|
98
108
|
))}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import api from './api';
|
|
2
2
|
import CheckoutForm from './checkout/form';
|
|
3
3
|
import CheckoutTable from './checkout/table';
|
|
4
|
+
import TxLink from './components/blockchain/tx';
|
|
4
5
|
import ConfirmDialog from './components/confirm';
|
|
5
6
|
import FormInput from './components/input';
|
|
6
7
|
import Livemode from './components/livemode';
|
|
@@ -39,4 +40,5 @@ export {
|
|
|
39
40
|
CustomerInvoiceList,
|
|
40
41
|
CustomerPaymentList,
|
|
41
42
|
MiniInvoiceList,
|
|
43
|
+
TxLink,
|
|
42
44
|
};
|
package/src/locales/en.tsx
CHANGED
|
@@ -207,17 +207,17 @@ export default flat({
|
|
|
207
207
|
pay: 'Pay this invoice',
|
|
208
208
|
paySuccess: 'You have successfully paid the invoice',
|
|
209
209
|
payError: 'Failed to paid the invoice',
|
|
210
|
-
empty: '
|
|
210
|
+
empty: 'There are no invoices here',
|
|
211
211
|
},
|
|
212
212
|
payment: {
|
|
213
|
-
empty: '
|
|
213
|
+
empty: 'There are no payments here',
|
|
214
214
|
},
|
|
215
215
|
subscriptions: {
|
|
216
216
|
plan: 'Plan',
|
|
217
217
|
nextInvoice: 'Next Invoice',
|
|
218
218
|
title: 'Manage subscriptions',
|
|
219
219
|
current: 'Current subscription',
|
|
220
|
-
empty: '
|
|
220
|
+
empty: 'There are no subscriptions here',
|
|
221
221
|
},
|
|
222
222
|
},
|
|
223
223
|
},
|
package/src/locales/zh.tsx
CHANGED
|
@@ -203,17 +203,17 @@ export default flat({
|
|
|
203
203
|
pay: '支付此发票',
|
|
204
204
|
paySuccess: '支付成功',
|
|
205
205
|
payError: '支付失败',
|
|
206
|
-
empty: '
|
|
206
|
+
empty: '没有任何发票',
|
|
207
207
|
},
|
|
208
208
|
payment: {
|
|
209
|
-
empty: '
|
|
209
|
+
empty: '没有任何支付',
|
|
210
210
|
},
|
|
211
211
|
subscriptions: {
|
|
212
212
|
plan: '订阅',
|
|
213
213
|
nextInvoice: '下一张发票',
|
|
214
214
|
title: '订阅管理',
|
|
215
215
|
current: '当前订阅',
|
|
216
|
-
empty: '
|
|
216
|
+
empty: '没有任何订阅',
|
|
217
217
|
},
|
|
218
218
|
},
|
|
219
219
|
},
|
package/src/payment/index.tsx
CHANGED
|
@@ -294,7 +294,7 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
294
294
|
|
|
295
295
|
.cko-container {
|
|
296
296
|
width: 100%;
|
|
297
|
-
max-width: 1000px;
|
|
297
|
+
max-width: ${(props) => (props.mode.endsWith('-minimal') ? '400px' : '1000px')};
|
|
298
298
|
display: flex;
|
|
299
299
|
flex-direction: row;
|
|
300
300
|
justify-content: space-between;
|
|
@@ -303,9 +303,10 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
.cko-overview {
|
|
306
|
-
width: 400px;
|
|
306
|
+
width: ${(props) => (props.mode.endsWith('-minimal') ? '100%' : '400px')};
|
|
307
307
|
min-height: ${(props) => (props.mode === 'standalone' ? '540px' : 'auto')};
|
|
308
308
|
position: relative;
|
|
309
|
+
display: ${(props) => (props.mode.endsWith('-minimal') ? 'none' : 'block')};
|
|
309
310
|
}
|
|
310
311
|
.cko-header {
|
|
311
312
|
left: 0;
|
|
@@ -322,7 +323,7 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
.cko-payment {
|
|
325
|
-
width: 400px;
|
|
326
|
+
width: ${(props) => (props.mode.endsWith('-minimal') ? '100%' : '400px')};
|
|
326
327
|
.MuiInputBase-root {
|
|
327
328
|
border-radius: 0;
|
|
328
329
|
}
|
|
@@ -411,6 +412,7 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
411
412
|
bottom: 0;
|
|
412
413
|
left: 12px;
|
|
413
414
|
margin: 12px 0;
|
|
415
|
+
display: ${(props) => (props.mode.endsWith('-minimal') ? 'none' : 'block')};
|
|
414
416
|
}
|
|
415
417
|
|
|
416
418
|
@media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
|
package/src/types/index.ts
CHANGED
|
@@ -20,7 +20,7 @@ export type CheckoutContext = {
|
|
|
20
20
|
export type CheckoutProps = Partial<CheckoutCallbacks> & {
|
|
21
21
|
id: string;
|
|
22
22
|
extraParams?: Record<string, any>;
|
|
23
|
-
mode?: LiteralUnion<'standalone' | 'inline' | 'popup', string>;
|
|
23
|
+
mode?: LiteralUnion<'standalone' | 'inline' | 'popup' | 'inline-minimal' | 'popup-minimal', string>;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export type CheckoutCallbacks = {
|
package/src/util.ts
CHANGED
|
@@ -292,6 +292,19 @@ export function getPaymentIntentStatusColor(status: string) {
|
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
+
export function getRefundStatusColor(status: string) {
|
|
296
|
+
switch (status) {
|
|
297
|
+
case 'succeeded':
|
|
298
|
+
return 'success';
|
|
299
|
+
case 'requires_action':
|
|
300
|
+
return 'warning';
|
|
301
|
+
case 'canceled':
|
|
302
|
+
case 'pending':
|
|
303
|
+
default:
|
|
304
|
+
return 'default';
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
295
308
|
export function getInvoiceStatusColor(status: string) {
|
|
296
309
|
switch (status) {
|
|
297
310
|
case 'paid':
|
|
@@ -324,11 +337,14 @@ export function getCheckoutAmount(
|
|
|
324
337
|
upsell = true
|
|
325
338
|
) {
|
|
326
339
|
let renew = new BN(0);
|
|
327
|
-
|
|
328
340
|
const total = items
|
|
341
|
+
.filter((x) => {
|
|
342
|
+
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
343
|
+
return price != null;
|
|
344
|
+
})
|
|
329
345
|
.reduce((acc, x) => {
|
|
330
346
|
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
331
|
-
if (price
|
|
347
|
+
if (price?.type === 'recurring') {
|
|
332
348
|
renew = renew.add(new BN(getPriceUintAmountByCurrency(price, currency)).mul(new BN(x.quantity)));
|
|
333
349
|
|
|
334
350
|
if (includeFreeTrial) {
|