@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.
@@ -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: 4,
115
+ flex: 3,
115
116
  children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
116
- children: item.description || item.id
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: "Seems you do not have any invoice here"
212
+ empty: "There are no invoices here"
213
213
  },
214
214
  payment: {
215
- empty: "Seems you do not have any payment here"
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: "Seems you do not have any subscriptions here"
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: "\u4F60\u6CA1\u6709\u4EFB\u4F55\u53D1\u7968"
212
+ empty: "\u6CA1\u6709\u4EFB\u4F55\u53D1\u7968"
213
213
  },
214
214
  payment: {
215
- empty: "\u4F60\u6CA1\u6709\u4EFB\u4F55\u652F\u4ED8"
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: "\u4F60\u8FD8\u6CA1\u6709\u4EFB\u4F55\u8BA2\u9605"
222
+ empty: "\u6CA1\u6709\u4EFB\u4F55\u8BA2\u9605"
223
223
  }
224
224
  }
225
225
  }
@@ -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: ${({
@@ -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.reduce((acc, x) => {
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.type === "recurring") {
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.130",
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.130",
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": "95aaa56f16ce303e514aa7dde9e542628d7acd2c"
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 (!data || !subscription) {
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
- if (data && data.list.length === 0) {
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
- {(data.list || []).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 }}>
130
- {fromUnitToToken(item.total, item.paymentCurrency.decimal)}&nbsp;
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
- })}
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)}&nbsp;
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 target="_top" variant="contained" sx={{ marginTop: '10px 0', width: '100%' }} href="">
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={4}>
95
- <Typography>{item.description || item.id}</Typography>
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
  };
@@ -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: 'Seems you do not have any invoice here',
210
+ empty: 'There are no invoices here',
211
211
  },
212
212
  payment: {
213
- empty: 'Seems you do not have any payment here',
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: 'Seems you do not have any subscriptions here',
220
+ empty: 'There are no subscriptions here',
221
221
  },
222
222
  },
223
223
  },
@@ -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
  },
@@ -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) {
@@ -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.type === 'recurring') {
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) {