@blocklet/payment-react 1.18.56 → 1.19.1

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.
Files changed (251) hide show
  1. package/es/checkout/donate.d.ts +1 -15
  2. package/es/checkout/donate.js +301 -189
  3. package/es/checkout/form.d.ts +1 -15
  4. package/es/checkout/form.js +5 -13
  5. package/es/checkout/table.js +3 -3
  6. package/es/components/blockchain/gas.d.ts +1 -5
  7. package/es/components/blockchain/gas.js +10 -2
  8. package/es/components/blockchain/tx.d.ts +1 -8
  9. package/es/components/blockchain/tx.js +29 -10
  10. package/es/components/confirm.d.ts +1 -10
  11. package/es/components/confirm.js +4 -10
  12. package/es/components/country-select.d.ts +3 -2
  13. package/es/components/country-select.js +375 -352
  14. package/es/components/date-range-picker.d.ts +13 -0
  15. package/es/components/date-range-picker.js +279 -0
  16. package/es/components/input.d.ts +14 -20
  17. package/es/components/input.js +51 -44
  18. package/es/components/label.d.ts +7 -0
  19. package/es/components/label.js +49 -0
  20. package/es/components/lazy-loader.js +1 -2
  21. package/es/components/link.d.ts +2 -9
  22. package/es/components/link.js +9 -6
  23. package/es/components/livemode.d.ts +2 -8
  24. package/es/components/livemode.js +1 -5
  25. package/es/components/loading-button.d.ts +6 -1
  26. package/es/components/loading-button.js +56 -66
  27. package/es/components/over-due-invoice-payment.d.ts +0 -18
  28. package/es/components/over-due-invoice-payment.js +138 -95
  29. package/es/components/payment-beneficiaries.d.ts +2 -7
  30. package/es/components/payment-beneficiaries.js +86 -40
  31. package/es/components/pricing-item.d.ts +0 -5
  32. package/es/components/pricing-item.js +1 -4
  33. package/es/components/pricing-table.d.ts +2 -10
  34. package/es/components/pricing-table.js +8 -7
  35. package/es/components/resume-subscription.d.ts +0 -10
  36. package/es/components/resume-subscription.js +42 -21
  37. package/es/components/truncated-text.d.ts +2 -9
  38. package/es/components/truncated-text.js +0 -5
  39. package/es/contexts/donate.d.ts +0 -7
  40. package/es/contexts/donate.js +10 -8
  41. package/es/contexts/payment.d.ts +1 -4
  42. package/es/contexts/payment.js +7 -2
  43. package/es/history/credit/grants-list.d.ts +14 -0
  44. package/es/history/credit/grants-list.js +215 -0
  45. package/es/history/credit/transactions-list.d.ts +13 -0
  46. package/es/history/credit/transactions-list.js +255 -0
  47. package/es/history/invoice/list.d.ts +2 -18
  48. package/es/history/invoice/list.js +172 -74
  49. package/es/history/payment/list.js +115 -38
  50. package/es/hooks/keyboard.d.ts +1 -1
  51. package/es/hooks/keyboard.js +2 -4
  52. package/es/index.d.ts +5 -1
  53. package/es/index.js +10 -1
  54. package/es/libs/cached-request.js +2 -4
  55. package/es/libs/phone-validator.js +1 -2
  56. package/es/libs/util.d.ts +2 -0
  57. package/es/libs/util.js +14 -4
  58. package/es/libs/validator.js +2 -4
  59. package/es/locales/en.js +20 -2
  60. package/es/locales/zh.js +20 -2
  61. package/es/payment/amount.d.ts +2 -7
  62. package/es/payment/amount.js +1 -5
  63. package/es/payment/donation-form.d.ts +2 -10
  64. package/es/payment/donation-form.js +196 -160
  65. package/es/payment/error.d.ts +2 -8
  66. package/es/payment/error.js +40 -20
  67. package/es/payment/footer.d.ts +2 -3
  68. package/es/payment/footer.js +19 -6
  69. package/es/payment/form/addon.js +14 -4
  70. package/es/payment/form/address.d.ts +2 -9
  71. package/es/payment/form/address.js +3 -6
  72. package/es/payment/form/currency.js +45 -25
  73. package/es/payment/form/index.d.ts +2 -8
  74. package/es/payment/form/index.js +151 -71
  75. package/es/payment/form/phone.js +2 -4
  76. package/es/payment/form/stripe/form.d.ts +2 -8
  77. package/es/payment/form/stripe/form.js +1 -3
  78. package/es/payment/header.js +38 -16
  79. package/es/payment/index.d.ts +2 -9
  80. package/es/payment/index.js +23 -17
  81. package/es/payment/product-card.d.ts +2 -11
  82. package/es/payment/product-card.js +84 -50
  83. package/es/payment/product-donation.js +175 -114
  84. package/es/payment/product-item.d.ts +9 -9
  85. package/es/payment/product-item.js +320 -145
  86. package/es/payment/product-skeleton.js +2 -2
  87. package/es/payment/skeleton/donation.js +27 -7
  88. package/es/payment/skeleton/overview.js +22 -2
  89. package/es/payment/skeleton/payment.js +33 -5
  90. package/es/payment/success.d.ts +2 -9
  91. package/es/payment/success.js +41 -14
  92. package/es/payment/summary.d.ts +4 -17
  93. package/es/payment/summary.js +193 -111
  94. package/es/theme/index.d.ts +0 -5
  95. package/es/theme/index.js +2 -5
  96. package/es/theme/typography.d.ts +2 -2
  97. package/lib/checkout/donate.d.ts +1 -15
  98. package/lib/checkout/donate.js +75 -54
  99. package/lib/checkout/form.d.ts +1 -15
  100. package/lib/checkout/form.js +7 -15
  101. package/lib/checkout/table.js +4 -4
  102. package/lib/components/blockchain/gas.d.ts +1 -5
  103. package/lib/components/blockchain/gas.js +3 -2
  104. package/lib/components/blockchain/tx.d.ts +1 -8
  105. package/lib/components/blockchain/tx.js +15 -10
  106. package/lib/components/confirm.d.ts +1 -10
  107. package/lib/components/confirm.js +5 -11
  108. package/lib/components/country-select.d.ts +3 -2
  109. package/lib/components/country-select.js +23 -22
  110. package/lib/components/date-range-picker.d.ts +13 -0
  111. package/lib/components/date-range-picker.js +329 -0
  112. package/lib/components/input.d.ts +14 -20
  113. package/lib/components/input.js +28 -27
  114. package/lib/components/label.d.ts +7 -0
  115. package/lib/components/label.js +60 -0
  116. package/lib/components/lazy-loader.js +1 -1
  117. package/lib/components/link.d.ts +2 -9
  118. package/lib/components/link.js +3 -8
  119. package/lib/components/livemode.d.ts +2 -8
  120. package/lib/components/livemode.js +3 -7
  121. package/lib/components/loading-button.d.ts +6 -1
  122. package/lib/components/loading-button.js +9 -17
  123. package/lib/components/over-due-invoice-payment.d.ts +0 -18
  124. package/lib/components/over-due-invoice-payment.js +31 -33
  125. package/lib/components/payment-beneficiaries.d.ts +2 -7
  126. package/lib/components/payment-beneficiaries.js +12 -11
  127. package/lib/components/pricing-item.d.ts +0 -5
  128. package/lib/components/pricing-item.js +2 -5
  129. package/lib/components/pricing-table.d.ts +2 -10
  130. package/lib/components/pricing-table.js +5 -11
  131. package/lib/components/resume-subscription.d.ts +0 -10
  132. package/lib/components/resume-subscription.js +16 -16
  133. package/lib/components/table.js +1 -1
  134. package/lib/components/truncated-text.d.ts +2 -9
  135. package/lib/components/truncated-text.js +1 -6
  136. package/lib/contexts/donate.d.ts +0 -7
  137. package/lib/contexts/donate.js +4 -7
  138. package/lib/contexts/payment.d.ts +1 -4
  139. package/lib/contexts/payment.js +4 -7
  140. package/lib/history/credit/grants-list.d.ts +14 -0
  141. package/lib/history/credit/grants-list.js +277 -0
  142. package/lib/history/credit/transactions-list.d.ts +13 -0
  143. package/lib/history/credit/transactions-list.js +301 -0
  144. package/lib/history/invoice/list.d.ts +2 -18
  145. package/lib/history/invoice/list.js +73 -37
  146. package/lib/history/payment/list.js +30 -16
  147. package/lib/hooks/keyboard.d.ts +1 -1
  148. package/lib/hooks/mobile.js +1 -1
  149. package/lib/hooks/subscription.js +1 -1
  150. package/lib/index.d.ts +5 -1
  151. package/lib/index.js +41 -2
  152. package/lib/libs/api.js +1 -1
  153. package/lib/libs/dayjs.js +1 -1
  154. package/lib/libs/phone-validator.js +0 -2
  155. package/lib/libs/theme.js +1 -1
  156. package/lib/libs/util.d.ts +2 -0
  157. package/lib/libs/util.js +15 -1
  158. package/lib/libs/validator.js +1 -1
  159. package/lib/locales/en.js +21 -3
  160. package/lib/locales/index.js +1 -1
  161. package/lib/locales/zh.js +21 -3
  162. package/lib/payment/amount.d.ts +2 -7
  163. package/lib/payment/amount.js +2 -6
  164. package/lib/payment/donation-form.d.ts +2 -10
  165. package/lib/payment/donation-form.js +33 -38
  166. package/lib/payment/error.d.ts +2 -8
  167. package/lib/payment/error.js +11 -13
  168. package/lib/payment/footer.d.ts +2 -3
  169. package/lib/payment/footer.js +5 -5
  170. package/lib/payment/form/addon.js +5 -3
  171. package/lib/payment/form/address.d.ts +2 -9
  172. package/lib/payment/form/address.js +5 -8
  173. package/lib/payment/form/currency.js +3 -3
  174. package/lib/payment/form/index.d.ts +2 -8
  175. package/lib/payment/form/index.js +64 -21
  176. package/lib/payment/form/phone.js +1 -1
  177. package/lib/payment/form/stripe/form.d.ts +2 -8
  178. package/lib/payment/form/stripe/form.js +3 -6
  179. package/lib/payment/header.js +8 -4
  180. package/lib/payment/index.d.ts +2 -9
  181. package/lib/payment/index.js +27 -18
  182. package/lib/payment/product-card.d.ts +2 -11
  183. package/lib/payment/product-card.js +13 -20
  184. package/lib/payment/product-donation.js +71 -66
  185. package/lib/payment/product-item.d.ts +9 -9
  186. package/lib/payment/product-item.js +168 -29
  187. package/lib/payment/product-skeleton.js +2 -2
  188. package/lib/payment/skeleton/donation.js +8 -4
  189. package/lib/payment/skeleton/overview.js +6 -2
  190. package/lib/payment/skeleton/payment.js +9 -3
  191. package/lib/payment/success.d.ts +2 -9
  192. package/lib/payment/success.js +12 -15
  193. package/lib/payment/summary.d.ts +4 -17
  194. package/lib/payment/summary.js +53 -45
  195. package/lib/theme/index.d.ts +0 -5
  196. package/lib/theme/index.js +2 -5
  197. package/lib/theme/typography.d.ts +2 -2
  198. package/package.json +40 -40
  199. package/src/checkout/donate.tsx +103 -35
  200. package/src/checkout/form.tsx +5 -14
  201. package/src/checkout/table.tsx +3 -3
  202. package/src/components/blockchain/gas.tsx +5 -3
  203. package/src/components/blockchain/tx.tsx +19 -11
  204. package/src/components/confirm.tsx +4 -11
  205. package/src/components/country-select.tsx +391 -378
  206. package/src/components/date-range-picker.tsx +310 -0
  207. package/src/components/input.tsx +61 -46
  208. package/src/components/label.tsx +58 -0
  209. package/src/components/link.tsx +9 -7
  210. package/src/components/livemode.tsx +2 -6
  211. package/src/components/loading-button.tsx +63 -76
  212. package/src/components/over-due-invoice-payment.tsx +43 -28
  213. package/src/components/payment-beneficiaries.tsx +33 -14
  214. package/src/components/pricing-item.tsx +1 -4
  215. package/src/components/pricing-table.tsx +8 -8
  216. package/src/components/resume-subscription.tsx +20 -14
  217. package/src/components/table.tsx +2 -2
  218. package/src/components/truncated-text.tsx +0 -6
  219. package/src/contexts/donate.tsx +6 -7
  220. package/src/contexts/payment.tsx +7 -3
  221. package/src/history/credit/grants-list.tsx +276 -0
  222. package/src/history/credit/transactions-list.tsx +317 -0
  223. package/src/history/invoice/list.tsx +92 -36
  224. package/src/history/payment/list.tsx +53 -16
  225. package/src/hooks/keyboard.ts +1 -1
  226. package/src/index.ts +9 -0
  227. package/src/libs/util.ts +14 -0
  228. package/src/locales/en.tsx +20 -0
  229. package/src/locales/zh.tsx +19 -0
  230. package/src/payment/amount.tsx +1 -6
  231. package/src/payment/donation-form.tsx +47 -29
  232. package/src/payment/error.tsx +16 -8
  233. package/src/payment/footer.tsx +11 -3
  234. package/src/payment/form/addon.tsx +6 -1
  235. package/src/payment/form/address.tsx +3 -7
  236. package/src/payment/form/currency.tsx +12 -2
  237. package/src/payment/form/index.tsx +121 -45
  238. package/src/payment/form/stripe/form.tsx +1 -5
  239. package/src/payment/header.tsx +14 -2
  240. package/src/payment/index.tsx +27 -22
  241. package/src/payment/product-card.tsx +41 -18
  242. package/src/payment/product-donation.tsx +85 -47
  243. package/src/payment/product-item.tsx +198 -28
  244. package/src/payment/product-skeleton.tsx +3 -2
  245. package/src/payment/skeleton/donation.tsx +12 -2
  246. package/src/payment/skeleton/overview.tsx +12 -2
  247. package/src/payment/skeleton/payment.tsx +16 -3
  248. package/src/payment/success.tsx +26 -15
  249. package/src/payment/summary.tsx +87 -44
  250. package/src/theme/index.tsx +5 -8
  251. package/src/theme/typography.ts +2 -2
@@ -18,11 +18,24 @@ function getHeightStyle(mode: ModeType | undefined): any {
18
18
  return { height: 'auto', minHeight: 200 }; // 默认情况下,高度根据内容自动调整
19
19
  }
20
20
  }
21
- export default function PaymentError({ title, description, button, mode }: Props) {
21
+ export default function PaymentError({ title, description, button = 'Back', mode = 'standalone' }: Props) {
22
22
  const heightStyle = getHeightStyle(mode);
23
23
  return (
24
- <Stack sx={heightStyle} alignItems="center" justifyContent="center">
25
- <Stack sx={{ width: '280px' }} direction="column" alignItems="center" justifyContent="center">
24
+ <Stack
25
+ sx={[
26
+ {
27
+ alignItems: 'center',
28
+ justifyContent: 'center',
29
+ },
30
+ ...(Array.isArray(heightStyle) ? heightStyle : [heightStyle]),
31
+ ]}>
32
+ <Stack
33
+ direction="column"
34
+ sx={{
35
+ alignItems: 'center',
36
+ justifyContent: 'center',
37
+ width: '280px',
38
+ }}>
26
39
  <Typography variant="h5" sx={{ mb: 2 }}>
27
40
  {title}
28
41
  </Typography>
@@ -45,8 +58,3 @@ export default function PaymentError({ title, description, button, mode }: Props
45
58
  </Stack>
46
59
  );
47
60
  }
48
-
49
- PaymentError.defaultProps = {
50
- button: 'Back',
51
- mode: 'standalone',
52
- };
@@ -1,8 +1,16 @@
1
- import { Typography } from '@mui/material';
1
+ import { Typography, TypographyProps } from '@mui/material';
2
2
 
3
- export default function CheckoutFooter({ ...props }) {
3
+ export default function CheckoutFooter(props: TypographyProps) {
4
4
  return (
5
- <Typography color="text.lighter" fontSize={12} {...props}>
5
+ <Typography
6
+ {...props}
7
+ sx={[
8
+ {
9
+ color: 'text.lighter',
10
+ fontSize: 12,
11
+ },
12
+ ...(Array.isArray(props.sx) ? props.sx : [props.sx]),
13
+ ]}>
6
14
  Powered by{' '}
7
15
  <Typography component="span" sx={{ fontWeight: 'bold', fontSize: 12 }}>
8
16
  ArcBlock
@@ -10,7 +10,12 @@ export default function UserButtons() {
10
10
  const { session } = usePaymentContext();
11
11
 
12
12
  return (
13
- <Stack direction="row" alignItems="center" justifyContent="space-between">
13
+ <Stack
14
+ direction="row"
15
+ sx={{
16
+ alignItems: 'center',
17
+ justifyContent: 'space-between',
18
+ }}>
14
19
  <LocaleSelector showText={false} />
15
20
  {session?.user ? (
16
21
  <SessionManager session={session} />
@@ -14,13 +14,7 @@ type Props = {
14
14
  errorPosition?: 'right' | 'bottom';
15
15
  };
16
16
 
17
- AddressForm.defaultProps = {
18
- sx: {},
19
- fieldValidation: {},
20
- errorPosition: 'right',
21
- };
22
-
23
- export default function AddressForm({ mode, stripe, sx = {}, fieldValidation, errorPosition }: Props) {
17
+ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation = {}, errorPosition = 'right' }: Props) {
24
18
  const { t, locale } = useLocaleContext();
25
19
  const { control } = useFormContext();
26
20
  const country = useWatch({ control, name: 'billing_address.country' });
@@ -85,6 +79,7 @@ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation, er
85
79
  render={({ field }) => (
86
80
  <CountrySelect
87
81
  {...field}
82
+ ref={field.ref as unknown as React.RefObject<HTMLDivElement | null>}
88
83
  sx={{
89
84
  '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
90
85
  borderColor: 'transparent',
@@ -132,6 +127,7 @@ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation, er
132
127
  render={({ field }) => (
133
128
  <CountrySelect
134
129
  {...field}
130
+ ref={field.ref as unknown as React.RefObject<HTMLDivElement | null>}
135
131
  sx={{
136
132
  '.MuiOutlinedInput-notchedOutline': {
137
133
  borderColor: 'transparent !important',
@@ -27,7 +27,12 @@ export default function CurrencySelector({ value, currencies, onChange }: Props)
27
27
  variant="outlined"
28
28
  onClick={() => onChange(x.id, (x as any).method?.id)}
29
29
  className={selected ? 'cko-payment-card' : 'cko-payment-card-unselect'}>
30
- <Stack direction="row" alignItems="center" sx={{ position: 'relative' }}>
30
+ <Stack
31
+ direction="row"
32
+ sx={{
33
+ alignItems: 'center',
34
+ position: 'relative',
35
+ }}>
31
36
  <Avatar src={x.logo} alt={x.name} sx={{ width: 40, height: 40, marginRight: '12px' }} />
32
37
  <div>
33
38
  <Typography
@@ -36,7 +41,12 @@ export default function CurrencySelector({ value, currencies, onChange }: Props)
36
41
  sx={{ fontSize: '16px', color: 'text.primary', fontWeight: '500' }}>
37
42
  {x.symbol}
38
43
  </Typography>
39
- <Typography sx={{ fontSize: 14 }} color="text.lighter" gutterBottom>
44
+ <Typography
45
+ gutterBottom
46
+ sx={{
47
+ color: 'text.lighter',
48
+ fontSize: 14,
49
+ }}>
40
50
  {(x as any).method.name}
41
51
  </Typography>
42
52
  </div>
@@ -110,9 +110,11 @@ type UserInfo = {
110
110
  type FastCheckoutInfo = {
111
111
  open: boolean;
112
112
  loading: boolean;
113
- sourceType: 'balance' | 'delegation';
113
+ sourceType: 'balance' | 'delegation' | 'credit';
114
114
  amount: string;
115
115
  payer?: string;
116
+ availableCredit?: string;
117
+ balance?: string;
116
118
  };
117
119
 
118
120
  const setUserFormValues = (
@@ -149,11 +151,6 @@ const setUserFormValues = (
149
151
  });
150
152
  };
151
153
 
152
- PaymentForm.defaultProps = {
153
- onlyShowBtn: false,
154
- isDonation: false,
155
- };
156
-
157
154
  // FIXME: https://stripe.com/docs/elements/address-element
158
155
  // TODO: https://country-regions.github.io/react-country-region-selector/
159
156
  // https://www.npmjs.com/package/postal-codes-js
@@ -169,7 +166,7 @@ export default function PaymentForm({
169
166
  onError,
170
167
  // mode,
171
168
  action,
172
- onlyShowBtn,
169
+ onlyShowBtn = false,
173
170
  isDonation = false,
174
171
  }: PageData) {
175
172
  // const theme = useTheme();
@@ -211,6 +208,9 @@ export default function PaymentForm({
211
208
  customerLimited?: boolean;
212
209
  stripePaying: boolean;
213
210
  fastCheckoutInfo: FastCheckoutInfo | null;
211
+ creditInsufficientInfo: {
212
+ open: boolean;
213
+ } | null;
214
214
  }>({
215
215
  submitting: false,
216
216
  paying: false,
@@ -221,6 +221,7 @@ export default function PaymentForm({
221
221
  customerLimited: false,
222
222
  stripePaying: false,
223
223
  fastCheckoutInfo: null,
224
+ creditInsufficientInfo: null,
224
225
  });
225
226
 
226
227
  const currencies = flattenPaymentMethods(paymentMethods);
@@ -423,6 +424,10 @@ export default function PaymentForm({
423
424
  setState({ fastCheckoutInfo: null });
424
425
  };
425
426
 
427
+ const handleCreditInsufficientClose = () => {
428
+ setState({ creditInsufficientInfo: null });
429
+ };
430
+
426
431
  const openConnect = () => {
427
432
  try {
428
433
  if (!['arcblock', 'ethereum', 'base'].includes(method.type)) {
@@ -481,7 +486,30 @@ export default function PaymentForm({
481
486
  });
482
487
 
483
488
  if (['arcblock', 'ethereum', 'base'].includes(method.type)) {
484
- if (
489
+ // 优先判断 credit 支付
490
+ if (paymentCurrency?.type === 'credit') {
491
+ if (result.data.creditSufficient === true) {
492
+ // 如果是 credit 支付且有足够额度,显示 credit 确认弹窗
493
+ setState({
494
+ fastCheckoutInfo: {
495
+ open: true,
496
+ loading: false,
497
+ sourceType: 'credit',
498
+ amount: result.data.fastPayInfo?.amount || '0',
499
+ payer: result.data.fastPayInfo?.payer,
500
+ availableCredit: result.data.fastPayInfo?.amount || '0',
501
+ balance: result.data.fastPayInfo?.token?.balance || '0',
502
+ },
503
+ });
504
+ } else {
505
+ // 如果是 credit 支付但额度不足,显示额度不足弹窗
506
+ setState({
507
+ creditInsufficientInfo: {
508
+ open: true,
509
+ },
510
+ });
511
+ }
512
+ } else if (
485
513
  (result.data.balance?.sufficient || result.data.delegation?.sufficient) &&
486
514
  !isDonationMode &&
487
515
  result.data.fastPayInfo
@@ -586,54 +614,96 @@ export default function PaymentForm({
586
614
  }, [state.submitting, state.paying, state.stripePaying, quantityInventoryStatus, payable]); // eslint-disable-line react-hooks/exhaustive-deps
587
615
 
588
616
  const balanceLink = getTokenBalanceLink(method, state.fastCheckoutInfo?.payer || '');
617
+
589
618
  const FastCheckoutConfirmDialog = state.fastCheckoutInfo && (
590
619
  <ConfirmDialog
591
620
  onConfirm={handleFastCheckoutConfirm}
592
621
  onCancel={handleFastCheckoutCancel}
593
- title={t('payment.checkout.fastPay.title')}
622
+ title={
623
+ state.fastCheckoutInfo.sourceType === 'credit'
624
+ ? t('payment.checkout.fastPay.credit.title')
625
+ : t('payment.checkout.fastPay.title')
626
+ }
594
627
  message={
595
- <Stack>
596
- <Typography>{t('payment.checkout.fastPay.autoPaymentReason')}</Typography>
597
- <Divider sx={{ mt: 1.5, mb: 1.5 }} />
598
- <Stack spacing={1}>
599
- <Stack flexDirection="row" alignItems="center" justifyContent="space-between">
600
- <Typography color="text.primary" sx={{ whiteSpace: 'nowrap' }}>
601
- {t('payment.checkout.fastPay.payer')}
602
- </Typography>
603
- <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
604
- <DID did={state.fastCheckoutInfo.payer || ''} compact responsive={false} />
605
- {balanceLink && (
606
- <Tooltip title={t('payment.checkout.fastPay.balanceLink')} placement="top">
607
- <OpenInNew
608
- sx={{
609
- color: 'text.lighter',
610
- fontSize: '0.85rem',
611
- cursor: 'pointer',
612
- '&:hover': { color: 'text.primary' },
613
- }}
614
- onClick={() => {
615
- window.open(balanceLink, '_blank');
616
- }}
617
- />
618
- </Tooltip>
619
- )}
620
- </Box>
621
- </Stack>
622
- <Stack flexDirection="row" alignItems="center" justifyContent="space-between">
623
- <Typography color="text.primary">{t('payment.checkout.fastPay.amount')}</Typography>
624
- <Typography>
625
- {fromUnitToToken(state.fastCheckoutInfo.amount, paymentCurrency?.decimal || 18).toString()}{' '}
626
- {paymentCurrency?.symbol}
627
- </Typography>
628
+ state.fastCheckoutInfo.sourceType === 'credit' ? (
629
+ <Typography>
630
+ {t('payment.checkout.fastPay.credit.meteringSubscriptionMessage', {
631
+ available: `${fromUnitToToken(state.fastCheckoutInfo?.balance || '0', paymentCurrency?.decimal || 18).toString()} ${paymentCurrency?.symbol}`,
632
+ })}
633
+ </Typography>
634
+ ) : (
635
+ <Stack>
636
+ <Typography>{t('payment.checkout.fastPay.autoPaymentReason')}</Typography>
637
+ <Divider sx={{ mt: 1.5, mb: 1.5 }} />
638
+ <Stack spacing={1}>
639
+ <Stack
640
+ sx={{
641
+ flexDirection: 'row',
642
+ alignItems: 'center',
643
+ justifyContent: 'space-between',
644
+ }}>
645
+ <Typography
646
+ sx={{
647
+ color: 'text.primary',
648
+ whiteSpace: 'nowrap',
649
+ }}>
650
+ {t('payment.checkout.fastPay.payer')}
651
+ </Typography>
652
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
653
+ <DID did={state.fastCheckoutInfo.payer || ''} compact responsive={false} />
654
+ {balanceLink && (
655
+ <Tooltip title={t('payment.checkout.fastPay.balanceLink')} placement="top">
656
+ <OpenInNew
657
+ sx={{
658
+ color: 'text.lighter',
659
+ fontSize: '0.85rem',
660
+ cursor: 'pointer',
661
+ '&:hover': { color: 'text.primary' },
662
+ }}
663
+ onClick={() => {
664
+ window.open(balanceLink, '_blank');
665
+ }}
666
+ />
667
+ </Tooltip>
668
+ )}
669
+ </Box>
670
+ </Stack>
671
+ <Stack
672
+ sx={{
673
+ flexDirection: 'row',
674
+ alignItems: 'center',
675
+ justifyContent: 'space-between',
676
+ }}>
677
+ <Typography
678
+ sx={{
679
+ color: 'text.primary',
680
+ }}>
681
+ {t('payment.checkout.fastPay.amount')}
682
+ </Typography>
683
+ <Typography>
684
+ {fromUnitToToken(state.fastCheckoutInfo.amount, paymentCurrency?.decimal || 18).toString()}{' '}
685
+ {paymentCurrency?.symbol}
686
+ </Typography>
687
+ </Stack>
628
688
  </Stack>
629
689
  </Stack>
630
- </Stack>
690
+ )
631
691
  }
632
692
  loading={state.fastCheckoutInfo.loading}
633
693
  color="primary"
634
694
  />
635
695
  );
636
696
 
697
+ const CreditInsufficientDialog = state.creditInsufficientInfo && (
698
+ <ConfirmDialog
699
+ onConfirm={handleCreditInsufficientClose}
700
+ onCancel={handleCreditInsufficientClose}
701
+ title={t('payment.checkout.fastPay.credit.insufficientTitle')}
702
+ message={<Typography>{t('payment.checkout.fastPay.credit.insufficientMessage')}</Typography>}
703
+ confirm={t('common.confirm')}
704
+ />
705
+ );
706
+
637
707
  if (onlyShowBtn) {
638
708
  return (
639
709
  <>
@@ -686,6 +756,7 @@ export default function PaymentForm({
686
756
  />
687
757
  )}
688
758
  {FastCheckoutConfirmDialog}
759
+ {CreditInsufficientDialog}
689
760
  </>
690
761
  );
691
762
  }
@@ -708,7 +779,12 @@ export default function PaymentForm({
708
779
  {t('payment.checkout.paymentDetails')}
709
780
  </Typography>
710
781
  <Fade in>
711
- <Stack direction="column" alignItems="flex-start" className="cko-payment-methods">
782
+ <Stack
783
+ direction="column"
784
+ className="cko-payment-methods"
785
+ sx={{
786
+ alignItems: 'flex-start',
787
+ }}>
712
788
  <Stack direction="row" sx={{ width: '100%' }}>
713
789
  <Controller
714
790
  name="payment_currency"
@@ -808,7 +884,6 @@ export default function PaymentForm({
808
884
  </Stack>
809
885
  </Fade>
810
886
  <Divider sx={{ mt: 2.5, mb: 2.5 }} />
811
-
812
887
  <Fade in>
813
888
  <Stack className="cko-payment-submit">
814
889
  <Box className="cko-payment-submit-btn">
@@ -872,6 +947,7 @@ export default function PaymentForm({
872
947
  />
873
948
  )}
874
949
  {FastCheckoutConfirmDialog}
950
+ {CreditInsufficientDialog}
875
951
  </>
876
952
  );
877
953
  }
@@ -19,7 +19,7 @@ export type StripeCheckoutFormProps = {
19
19
  customer: TCustomer;
20
20
  mode: string;
21
21
  onConfirm: Function;
22
- returnUrl: string;
22
+ returnUrl?: string;
23
23
  };
24
24
 
25
25
  const PaymentElementContainer = styled('div')`
@@ -349,7 +349,3 @@ export default function StripeCheckout({
349
349
  </Dialog>
350
350
  );
351
351
  }
352
-
353
- StripeCheckout.defaultProps = {
354
- returnUrl: '',
355
- };
@@ -28,8 +28,20 @@ export default function PaymentHeader({ checkoutSession }: Props) {
28
28
  }, [domSize, theme]);
29
29
 
30
30
  return (
31
- <Stack className="cko-header" direction="row" spacing={1} alignItems="center" justifyContent="space-between">
32
- <Stack direction="row" spacing={1} alignItems="center">
31
+ <Stack
32
+ className="cko-header"
33
+ direction="row"
34
+ spacing={1}
35
+ sx={{
36
+ alignItems: 'center',
37
+ justifyContent: 'space-between',
38
+ }}>
39
+ <Stack
40
+ direction="row"
41
+ spacing={1}
42
+ sx={{
43
+ alignItems: 'center',
44
+ }}>
33
45
  <Avatar
34
46
  variant="square"
35
47
  src={window.blocklet.appLogo}
@@ -30,6 +30,7 @@ import {
30
30
  getStatementDescriptor,
31
31
  isMobileSafari,
32
32
  isValidCountry,
33
+ showStaking,
33
34
  } from '../libs/util';
34
35
  import type { CheckoutCallbacks, CheckoutContext, CheckoutFormData } from '../types';
35
36
  import PaymentError from './error';
@@ -47,18 +48,13 @@ import { getCurrencyPreference } from '../libs/currency';
47
48
  // eslint-disable-next-line react/no-unused-prop-types
48
49
  type Props = CheckoutContext & CheckoutCallbacks & { completed?: boolean; error?: any; showCheckoutSummary?: boolean };
49
50
 
50
- PaymentInner.defaultProps = {
51
- completed: false,
52
- showCheckoutSummary: true,
53
- };
54
-
55
51
  function PaymentInner({
56
52
  checkoutSession,
57
53
  paymentMethods,
58
54
  paymentLink,
59
55
  paymentIntent,
60
56
  customer,
61
- completed,
57
+ completed = false,
62
58
  mode,
63
59
  onPaid,
64
60
  onError,
@@ -213,6 +209,19 @@ function PaymentInner({
213
209
  }
214
210
  };
215
211
 
212
+ const onQuantityChange = async (itemId: string, quantity: number) => {
213
+ try {
214
+ const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/adjust-quantity`, {
215
+ itemId,
216
+ quantity,
217
+ });
218
+ setState({ checkoutSession: data });
219
+ } catch (err) {
220
+ console.error(err);
221
+ Toast.error(formatError(err));
222
+ }
223
+ };
224
+
216
225
  const onCancelCrossSell = async () => {
217
226
  try {
218
227
  const { data } = await api.delete(`/api/checkout-sessions/${state.checkoutSession.id}/cross-sell`);
@@ -268,10 +277,11 @@ function PaymentInner({
268
277
  // @ts-ignore
269
278
  state.checkoutSession.subscription_data?.min_stake_amount || 0
270
279
  )}
271
- showStaking={method.type === 'arcblock' && !state.checkoutSession.subscription_data?.no_stake}
280
+ showStaking={showStaking(method, currency, !!state.checkoutSession.subscription_data?.no_stake)}
272
281
  currency={currency}
273
282
  onUpsell={onUpsell}
274
283
  onDownsell={onDownsell}
284
+ onQuantityChange={onQuantityChange}
275
285
  onApplyCrossSell={onApplyCrossSell}
276
286
  onCancelCrossSell={onCancelCrossSell}
277
287
  onChangeAmount={onChangeAmount}
@@ -279,6 +289,7 @@ function PaymentInner({
279
289
  crossSellBehavior={state.checkoutSession.cross_sell_behavior}
280
290
  donationSettings={paymentLink?.donation_settings}
281
291
  action={action}
292
+ completed={completed}
282
293
  />
283
294
  {mode === 'standalone' && !isMobile && (
284
295
  <CheckoutFooter className="cko-footer" sx={{ color: 'text.lighter' }} />
@@ -332,20 +343,14 @@ function PaymentInner({
332
343
  );
333
344
  }
334
345
 
335
- Payment.defaultProps = {
336
- completed: false,
337
- error: null,
338
- showCheckoutSummary: true,
339
- };
340
-
341
346
  export default function Payment({
342
347
  checkoutSession,
343
348
  paymentMethods,
344
349
  paymentIntent,
345
350
  paymentLink,
346
351
  customer,
347
- completed,
348
- error,
352
+ completed = false,
353
+ error = null,
349
354
  mode,
350
355
  onPaid,
351
356
  onError,
@@ -435,9 +440,9 @@ export default function Payment({
435
440
 
436
441
  return (
437
442
  <Stack
438
- display="flex"
439
- flexDirection="column"
440
443
  sx={{
444
+ display: 'flex',
445
+ flexDirection: 'column',
441
446
  height: mode === 'standalone' ? '100vh' : 'auto',
442
447
  overflow: isMobileSafariEnv ? 'visible' : 'hidden',
443
448
  }}>
@@ -630,21 +635,21 @@ export const Root: React.FC<RootProps> = styled(Box)<RootProps>`
630
635
  }
631
636
 
632
637
  .product-item {
633
- border-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`};
638
+ border-radius: ${({ theme }) => `${2 * (theme.shape.borderRadius as number)}px`};
634
639
  border: 1px solid;
635
640
  border-color: ${({ theme }) => theme.palette.grey[100]};
636
641
  .product-item-content {
637
642
  padding: 16px;
638
643
  background: ${({ theme }) => theme.palette.grey[50]};
639
- border-top-left-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`};
640
- border-top-right-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`};
644
+ border-top-left-radius: ${({ theme }) => `${2 * (theme.shape.borderRadius as number)}px`};
645
+ border-top-right-radius: ${({ theme }) => `${2 * (theme.shape.borderRadius as number)}px`};
641
646
  }
642
647
  .product-item-upsell {
643
648
  margin-top: 0;
644
649
  padding: 16px;
645
650
  background: ${({ theme }) => theme.palette.grey[100]};
646
- border-bottom-left-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`};
647
- border-bottom-right-radius: ${({ theme }) => `${2 * theme.shape.borderRadius}px`};
651
+ border-bottom-left-radius: ${({ theme }) => `${2 * (theme.shape.borderRadius as number)}px`};
652
+ border-bottom-right-radius: ${({ theme }) => `${2 * (theme.shape.borderRadius as number)}px`};
648
653
  }
649
654
  }
650
655
 
@@ -11,10 +11,24 @@ type Props = {
11
11
  };
12
12
 
13
13
  // FIXME: @wangshijun add image filter for logo
14
- export default function ProductCard({ size, variant, name, logo, description, extra }: Props) {
14
+ export default function ProductCard({
15
+ size = 48,
16
+ variant = 'rounded',
17
+ name,
18
+ logo = '',
19
+ description = '',
20
+ extra = undefined,
21
+ }: Props) {
15
22
  const s = { width: size, height: size };
16
23
  return (
17
- <Stack direction="row" alignItems="center" spacing={1} flex={2} sx={{ width: '100%' }}>
24
+ <Stack
25
+ direction="row"
26
+ spacing={1}
27
+ sx={{
28
+ alignItems: 'center',
29
+ flex: 2,
30
+ width: '100%',
31
+ }}>
18
32
  {logo ? (
19
33
  // @ts-ignore
20
34
  <Avatar src={logo} alt={name} variant={variant} sx={s} />
@@ -26,28 +40,45 @@ export default function ProductCard({ size, variant, name, logo, description, ex
26
40
  )}
27
41
  <Stack
28
42
  direction="column"
29
- alignItems="flex-start"
30
- justifyContent="space-around"
31
- sx={{ flexShrink: 1, overflow: 'hidden' }}>
43
+ sx={{
44
+ alignItems: 'flex-start',
45
+ justifyContent: 'space-around',
46
+ flexShrink: 1,
47
+ overflow: 'hidden',
48
+ }}>
32
49
  <Typography
33
50
  className="cko-ellipsis"
34
51
  variant="body1"
35
52
  title={name}
36
- sx={{ fontWeight: 500, mb: 0.5, lineHeight: 1.2, fontSize: 16 }}
37
- color="text.primary">
53
+ sx={{
54
+ color: 'text.primary',
55
+ fontWeight: 500,
56
+ mb: 0.5,
57
+ lineHeight: 1.2,
58
+ fontSize: 16,
59
+ }}>
38
60
  {name}
39
61
  </Typography>
40
62
  {description && (
41
63
  <Typography
42
64
  variant="body1"
43
65
  title={description}
44
- sx={{ fontSize: '0.74375rem', mb: 0.5, lineHeight: 1.2, textAlign: 'left' }}
45
- color="text.lighter">
66
+ sx={{
67
+ color: 'text.lighter',
68
+ fontSize: '0.74375rem',
69
+ mb: 0.5,
70
+ lineHeight: 1.2,
71
+ textAlign: 'left',
72
+ }}>
46
73
  {description}
47
74
  </Typography>
48
75
  )}
49
76
  {extra && (
50
- <Box sx={{ fontSize: '0.74375rem' }} color="text.lighter">
77
+ <Box
78
+ sx={{
79
+ color: 'text.lighter',
80
+ fontSize: '0.74375rem',
81
+ }}>
51
82
  {extra}
52
83
  </Box>
53
84
  )}
@@ -55,11 +86,3 @@ export default function ProductCard({ size, variant, name, logo, description, ex
55
86
  </Stack>
56
87
  );
57
88
  }
58
-
59
- ProductCard.defaultProps = {
60
- logo: '',
61
- size: 48,
62
- description: '',
63
- variant: 'rounded',
64
- extra: undefined,
65
- };