@blocklet/payment-react 1.13.121 → 1.13.122
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/payment/form/index.js +59 -41
- package/es/payment/index.js +46 -0
- package/lib/payment/form/index.js +53 -68
- package/lib/payment/index.js +46 -0
- package/package.json +3 -3
- package/src/payment/form/index.tsx +56 -42
- package/src/payment/index.tsx +46 -0
package/es/payment/form/index.js
CHANGED
|
@@ -4,11 +4,11 @@ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
|
4
4
|
import { useTheme } from "@arcblock/ux/lib/Theme";
|
|
5
5
|
import Toast from "@arcblock/ux/lib/Toast";
|
|
6
6
|
import { LoadingButton } from "@mui/lab";
|
|
7
|
-
import { Avatar, Fade, InputAdornment,
|
|
7
|
+
import { Avatar, Card, Fade, InputAdornment, Stack, Typography } from "@mui/material";
|
|
8
8
|
import { useCreation, useSetState, useSize } from "ahooks";
|
|
9
9
|
import { PhoneNumberUtil } from "google-libphonenumber";
|
|
10
10
|
import pWaitFor from "p-wait-for";
|
|
11
|
-
import { useEffect } from "react";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
12
|
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
|
13
13
|
import { dispatch } from "use-bus";
|
|
14
14
|
import isEmail from "validator/es/lib/isEmail";
|
|
@@ -36,6 +36,19 @@ const waitForCheckoutComplete = async (sessionId) => {
|
|
|
36
36
|
);
|
|
37
37
|
return result;
|
|
38
38
|
};
|
|
39
|
+
const flatPaymentMethods = (methods = []) => {
|
|
40
|
+
const out = [];
|
|
41
|
+
methods.forEach((method) => {
|
|
42
|
+
const currencies = method.paymentCurrencies || method.payment_currencies || [];
|
|
43
|
+
currencies.forEach((currency) => {
|
|
44
|
+
out.push({
|
|
45
|
+
...currency,
|
|
46
|
+
method
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
39
52
|
PaymentForm.defaultProps = {};
|
|
40
53
|
export default function PaymentForm({
|
|
41
54
|
checkoutSession,
|
|
@@ -59,6 +72,8 @@ export default function PaymentForm({
|
|
|
59
72
|
customer,
|
|
60
73
|
stripePaying: false
|
|
61
74
|
});
|
|
75
|
+
const currencies = flatPaymentMethods(paymentMethods);
|
|
76
|
+
const [paymentCurrencyIndex, setPaymentCurrencyIndex] = useState(0);
|
|
62
77
|
useEffect(() => {
|
|
63
78
|
if (session?.user) {
|
|
64
79
|
const values = getValues();
|
|
@@ -73,9 +88,11 @@ export default function PaymentForm({
|
|
|
73
88
|
}
|
|
74
89
|
}
|
|
75
90
|
}, [session?.user, getValues, setValue]);
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
setValue("payment_method", currencies[paymentCurrencyIndex].method.id);
|
|
93
|
+
setValue("payment_currency", currencies[paymentCurrencyIndex].id);
|
|
94
|
+
}, [paymentCurrencyIndex, currencies, setValue]);
|
|
76
95
|
const paymentMethod = useWatch({ control, name: "payment_method" });
|
|
77
|
-
const paymentCurrency = useWatch({ control, name: "payment_currency" });
|
|
78
|
-
const paymentCurrencies = paymentMethods.find((x) => x.id === paymentMethod)?.payment_currencies || [];
|
|
79
96
|
const domSize = useSize(document.body);
|
|
80
97
|
const isColumnLayout = useCreation(() => {
|
|
81
98
|
if (domSize) {
|
|
@@ -88,12 +105,8 @@ export default function PaymentForm({
|
|
|
88
105
|
const payee = getStatementDescriptor(checkoutSession.line_items);
|
|
89
106
|
const buttonText = session?.user ? t(`payment.checkout.${checkoutSession.mode}`) : t("payment.checkout.connect", { action: t(`payment.checkout.${checkoutSession.mode}`) });
|
|
90
107
|
const method = paymentMethods.find((x) => x.id === paymentMethod);
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const currencies = paymentMethods.find((x) => x.id === e.target.value)?.payment_currencies || [];
|
|
94
|
-
if (currencies.some((x) => x.id === paymentCurrency) === false) {
|
|
95
|
-
setValue("payment_currency", currencies[0]?.id);
|
|
96
|
-
}
|
|
108
|
+
const handleCurrencyChange = (index) => {
|
|
109
|
+
setPaymentCurrencyIndex(index);
|
|
97
110
|
};
|
|
98
111
|
const handleConnected = async () => {
|
|
99
112
|
try {
|
|
@@ -267,36 +280,42 @@ export default function PaymentForm({
|
|
|
267
280
|
/* @__PURE__ */ jsx(AddressForm, { mode: checkoutSession.billing_address_collection, stripe: method?.type === "stripe" }),
|
|
268
281
|
/* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", className: "cko-payment-methods", children: [
|
|
269
282
|
/* @__PURE__ */ jsx(Typography, { sx: { mb: 2, color: "text.primary", fontWeight: 600 }, children: t("payment.checkout.method") }),
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
283
|
+
/* @__PURE__ */ jsx(Stack, { direction: "row", sx: { width: "100%" }, children: /* @__PURE__ */ jsx(
|
|
284
|
+
Controller,
|
|
285
|
+
{
|
|
286
|
+
name: "payment_currency",
|
|
287
|
+
control,
|
|
288
|
+
render: () => /* @__PURE__ */ jsx(
|
|
289
|
+
"section",
|
|
290
|
+
{
|
|
291
|
+
style: {
|
|
292
|
+
display: currencies.length > 1 ? "grid" : "block",
|
|
293
|
+
gridTemplateColumns: "50% 50%",
|
|
294
|
+
width: "100%"
|
|
295
|
+
},
|
|
296
|
+
children: currencies.map((x, i) => {
|
|
297
|
+
const selected = i === paymentCurrencyIndex;
|
|
298
|
+
return /* @__PURE__ */ jsx(
|
|
299
|
+
Card,
|
|
300
|
+
{
|
|
301
|
+
variant: "outlined",
|
|
302
|
+
onClick: () => handleCurrencyChange(i),
|
|
303
|
+
className: selected ? "cko-payment-card" : "cko-payment-card-unselect",
|
|
304
|
+
children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", children: [
|
|
305
|
+
/* @__PURE__ */ jsx(Avatar, { src: x.logo, alt: x.name, sx: { width: 30, height: 30, marginRight: "10px" } }),
|
|
306
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
307
|
+
/* @__PURE__ */ jsx(Typography, { variant: "h5", component: "div", children: x.symbol }),
|
|
308
|
+
/* @__PURE__ */ jsx(Typography, { sx: { fontSize: 14 }, color: "text.secondary", gutterBottom: true, children: x.method.name })
|
|
309
|
+
] })
|
|
310
|
+
] })
|
|
311
|
+
},
|
|
312
|
+
x.id
|
|
313
|
+
);
|
|
314
|
+
})
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
) }),
|
|
300
319
|
state.stripePaying && state.stripeContext && /* @__PURE__ */ jsx(
|
|
301
320
|
StripeCheckout,
|
|
302
321
|
{
|
|
@@ -319,7 +338,6 @@ export default function PaymentForm({
|
|
|
319
338
|
size: "large",
|
|
320
339
|
onClick: onAction,
|
|
321
340
|
fullWidth: true,
|
|
322
|
-
loadingPosition: "end",
|
|
323
341
|
disabled: state.submitting || state.paying || state.stripePaying,
|
|
324
342
|
loading: state.submitting || state.paying,
|
|
325
343
|
children: state.submitting || state.paying ? t("payment.checkout.processing") : buttonText
|
package/es/payment/index.js
CHANGED
|
@@ -286,6 +286,52 @@ export const Root = styled(Box)`
|
|
|
286
286
|
.cko-payment-methods {
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
+
.cko-payment-card {
|
|
290
|
+
position: relative;
|
|
291
|
+
border: 2px solid #3773f2;
|
|
292
|
+
padding: 5px 10px;
|
|
293
|
+
margin: 5px 0;
|
|
294
|
+
cursor: pointer;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.cko-payment-card::before {
|
|
298
|
+
content: '';
|
|
299
|
+
position: absolute;
|
|
300
|
+
right: 0;
|
|
301
|
+
top: 0;
|
|
302
|
+
border: 12px solid #3773f2;
|
|
303
|
+
border-bottom-color: transparent;
|
|
304
|
+
border-left-color: transparent;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.cko-payment-card-unselect {
|
|
308
|
+
border: 2px solid #bbb;
|
|
309
|
+
padding: 5px 10px;
|
|
310
|
+
margin: 5px 0;
|
|
311
|
+
cursor: pointer;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.cko-payment-card:nth-child(odd) {
|
|
315
|
+
margin-right: 5px;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.cko-payment-card-unselect:nth-child(odd) {
|
|
319
|
+
margin-right: 5px;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.cko-payment-card::after {
|
|
323
|
+
content: '';
|
|
324
|
+
width: 6px;
|
|
325
|
+
height: 10px;
|
|
326
|
+
position: absolute;
|
|
327
|
+
right: 3px;
|
|
328
|
+
top: 0px;
|
|
329
|
+
border: 2px solid #fff;
|
|
330
|
+
border-top-color: transparent;
|
|
331
|
+
border-left-color: transparent;
|
|
332
|
+
transform: rotate(35deg);
|
|
333
|
+
}
|
|
334
|
+
|
|
289
335
|
.cko-payment-submit {
|
|
290
336
|
.MuiButtonBase-root {
|
|
291
337
|
border-radius: 0;
|
|
@@ -45,6 +45,19 @@ const waitForCheckoutComplete = async sessionId => {
|
|
|
45
45
|
});
|
|
46
46
|
return result;
|
|
47
47
|
};
|
|
48
|
+
const flatPaymentMethods = (methods = []) => {
|
|
49
|
+
const out = [];
|
|
50
|
+
methods.forEach(method => {
|
|
51
|
+
const currencies = method.paymentCurrencies || method.payment_currencies || [];
|
|
52
|
+
currencies.forEach(currency => {
|
|
53
|
+
out.push({
|
|
54
|
+
...currency,
|
|
55
|
+
method
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
return out;
|
|
60
|
+
};
|
|
48
61
|
PaymentForm.defaultProps = {};
|
|
49
62
|
function PaymentForm({
|
|
50
63
|
checkoutSession,
|
|
@@ -78,6 +91,8 @@ function PaymentForm({
|
|
|
78
91
|
customer,
|
|
79
92
|
stripePaying: false
|
|
80
93
|
});
|
|
94
|
+
const currencies = flatPaymentMethods(paymentMethods);
|
|
95
|
+
const [paymentCurrencyIndex, setPaymentCurrencyIndex] = (0, _react.useState)(0);
|
|
81
96
|
(0, _react.useEffect)(() => {
|
|
82
97
|
if (session?.user) {
|
|
83
98
|
const values = getValues();
|
|
@@ -92,15 +107,14 @@ function PaymentForm({
|
|
|
92
107
|
}
|
|
93
108
|
}
|
|
94
109
|
}, [session?.user, getValues, setValue]);
|
|
110
|
+
(0, _react.useEffect)(() => {
|
|
111
|
+
setValue("payment_method", currencies[paymentCurrencyIndex].method.id);
|
|
112
|
+
setValue("payment_currency", currencies[paymentCurrencyIndex].id);
|
|
113
|
+
}, [paymentCurrencyIndex, currencies, setValue]);
|
|
95
114
|
const paymentMethod = (0, _reactHookForm.useWatch)({
|
|
96
115
|
control,
|
|
97
116
|
name: "payment_method"
|
|
98
117
|
});
|
|
99
|
-
const paymentCurrency = (0, _reactHookForm.useWatch)({
|
|
100
|
-
control,
|
|
101
|
-
name: "payment_currency"
|
|
102
|
-
});
|
|
103
|
-
const paymentCurrencies = paymentMethods.find(x => x.id === paymentMethod)?.payment_currencies || [];
|
|
104
118
|
const domSize = (0, _ahooks.useSize)(document.body);
|
|
105
119
|
const isColumnLayout = (0, _ahooks.useCreation)(() => {
|
|
106
120
|
if (domSize) {
|
|
@@ -115,12 +129,8 @@ function PaymentForm({
|
|
|
115
129
|
action: t(`payment.checkout.${checkoutSession.mode}`)
|
|
116
130
|
});
|
|
117
131
|
const method = paymentMethods.find(x => x.id === paymentMethod);
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
const currencies = paymentMethods.find(x => x.id === e.target.value)?.payment_currencies || [];
|
|
121
|
-
if (currencies.some(x => x.id === paymentCurrency) === false) {
|
|
122
|
-
setValue("payment_currency", currencies[0]?.id);
|
|
123
|
-
}
|
|
132
|
+
const handleCurrencyChange = index => {
|
|
133
|
+
setPaymentCurrencyIndex(index);
|
|
124
134
|
};
|
|
125
135
|
const handleConnected = async () => {
|
|
126
136
|
try {
|
|
@@ -348,80 +358,56 @@ function PaymentForm({
|
|
|
348
358
|
fontWeight: 600
|
|
349
359
|
},
|
|
350
360
|
children: t("payment.checkout.method")
|
|
351
|
-
}), /* @__PURE__ */(0, _jsxRuntime.
|
|
361
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, {
|
|
352
362
|
direction: "row",
|
|
353
363
|
sx: {
|
|
354
|
-
width:
|
|
364
|
+
width: "100%"
|
|
355
365
|
},
|
|
356
|
-
|
|
357
|
-
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactHookForm.Controller, {
|
|
358
|
-
name: "payment_method",
|
|
359
|
-
control,
|
|
360
|
-
render: ({
|
|
361
|
-
field
|
|
362
|
-
}) => /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Select, {
|
|
363
|
-
...field,
|
|
364
|
-
onChange: handleMethodChange,
|
|
365
|
-
sx: {
|
|
366
|
-
flex: 1
|
|
367
|
-
},
|
|
368
|
-
size: "small",
|
|
369
|
-
children: paymentMethods.map(x => {
|
|
370
|
-
const selected = x.id === paymentMethod;
|
|
371
|
-
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.MenuItem, {
|
|
372
|
-
value: x.id,
|
|
373
|
-
children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
374
|
-
direction: "row",
|
|
375
|
-
spacing: 1,
|
|
376
|
-
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Avatar, {
|
|
377
|
-
src: x.logo,
|
|
378
|
-
alt: x.name,
|
|
379
|
-
sx: {
|
|
380
|
-
width: 20,
|
|
381
|
-
height: 20
|
|
382
|
-
}
|
|
383
|
-
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
384
|
-
color: selected ? "text.primary" : "text.secondary",
|
|
385
|
-
children: x.name
|
|
386
|
-
})]
|
|
387
|
-
})
|
|
388
|
-
}, x.id);
|
|
389
|
-
})
|
|
390
|
-
})
|
|
391
|
-
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_reactHookForm.Controller, {
|
|
366
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_reactHookForm.Controller, {
|
|
392
367
|
name: "payment_currency",
|
|
393
368
|
control,
|
|
394
|
-
render: ({
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
flex: 1
|
|
369
|
+
render: () => /* @__PURE__ */(0, _jsxRuntime.jsx)("section", {
|
|
370
|
+
style: {
|
|
371
|
+
display: currencies.length > 1 ? "grid" : "block",
|
|
372
|
+
gridTemplateColumns: "50% 50%",
|
|
373
|
+
width: "100%"
|
|
400
374
|
},
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
375
|
+
children: currencies.map((x, i) => {
|
|
376
|
+
const selected = i === paymentCurrencyIndex;
|
|
377
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Card, {
|
|
378
|
+
variant: "outlined",
|
|
379
|
+
onClick: () => handleCurrencyChange(i),
|
|
380
|
+
className: selected ? "cko-payment-card" : "cko-payment-card-unselect",
|
|
406
381
|
children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
407
382
|
direction: "row",
|
|
408
|
-
|
|
383
|
+
alignItems: "center",
|
|
409
384
|
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Avatar, {
|
|
410
385
|
src: x.logo,
|
|
411
386
|
alt: x.name,
|
|
412
387
|
sx: {
|
|
413
|
-
width:
|
|
414
|
-
height:
|
|
388
|
+
width: 30,
|
|
389
|
+
height: 30,
|
|
390
|
+
marginRight: "10px"
|
|
415
391
|
}
|
|
416
|
-
}), /* @__PURE__ */(0, _jsxRuntime.
|
|
417
|
-
|
|
418
|
-
|
|
392
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsxs)("div", {
|
|
393
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
394
|
+
variant: "h5",
|
|
395
|
+
component: "div",
|
|
396
|
+
children: x.symbol
|
|
397
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
398
|
+
sx: {
|
|
399
|
+
fontSize: 14
|
|
400
|
+
},
|
|
401
|
+
color: "text.secondary",
|
|
402
|
+
gutterBottom: true,
|
|
403
|
+
children: x.method.name
|
|
404
|
+
})]
|
|
419
405
|
})]
|
|
420
406
|
})
|
|
421
407
|
}, x.id);
|
|
422
408
|
})
|
|
423
409
|
})
|
|
424
|
-
})
|
|
410
|
+
})
|
|
425
411
|
}), state.stripePaying && state.stripeContext && /* @__PURE__ */(0, _jsxRuntime.jsx)(_stripe.default, {
|
|
426
412
|
clientSecret: state.stripeContext.client_secret,
|
|
427
413
|
intentType: state.stripeContext.intent_type,
|
|
@@ -442,7 +428,6 @@ function PaymentForm({
|
|
|
442
428
|
size: "large",
|
|
443
429
|
onClick: onAction,
|
|
444
430
|
fullWidth: true,
|
|
445
|
-
loadingPosition: "end",
|
|
446
431
|
disabled: state.submitting || state.paying || state.stripePaying,
|
|
447
432
|
loading: state.submitting || state.paying,
|
|
448
433
|
children: state.submitting || state.paying ? t("payment.checkout.processing") : buttonText
|
package/lib/payment/index.js
CHANGED
|
@@ -344,6 +344,52 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
344
344
|
.cko-payment-methods {
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
+
.cko-payment-card {
|
|
348
|
+
position: relative;
|
|
349
|
+
border: 2px solid #3773f2;
|
|
350
|
+
padding: 5px 10px;
|
|
351
|
+
margin: 5px 0;
|
|
352
|
+
cursor: pointer;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.cko-payment-card::before {
|
|
356
|
+
content: '';
|
|
357
|
+
position: absolute;
|
|
358
|
+
right: 0;
|
|
359
|
+
top: 0;
|
|
360
|
+
border: 12px solid #3773f2;
|
|
361
|
+
border-bottom-color: transparent;
|
|
362
|
+
border-left-color: transparent;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.cko-payment-card-unselect {
|
|
366
|
+
border: 2px solid #bbb;
|
|
367
|
+
padding: 5px 10px;
|
|
368
|
+
margin: 5px 0;
|
|
369
|
+
cursor: pointer;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.cko-payment-card:nth-child(odd) {
|
|
373
|
+
margin-right: 5px;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.cko-payment-card-unselect:nth-child(odd) {
|
|
377
|
+
margin-right: 5px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.cko-payment-card::after {
|
|
381
|
+
content: '';
|
|
382
|
+
width: 6px;
|
|
383
|
+
height: 10px;
|
|
384
|
+
position: absolute;
|
|
385
|
+
right: 3px;
|
|
386
|
+
top: 0px;
|
|
387
|
+
border: 2px solid #fff;
|
|
388
|
+
border-top-color: transparent;
|
|
389
|
+
border-left-color: transparent;
|
|
390
|
+
transform: rotate(35deg);
|
|
391
|
+
}
|
|
392
|
+
|
|
347
393
|
.cko-payment-submit {
|
|
348
394
|
.MuiButtonBase-root {
|
|
349
395
|
border-radius: 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.122",
|
|
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.122",
|
|
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": "015a834e0971d7d0d9947953daeb96a240248c2f"
|
|
122
122
|
}
|
|
@@ -3,13 +3,13 @@ import 'react-international-phone/style.css';
|
|
|
3
3
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
4
4
|
import { useTheme } from '@arcblock/ux/lib/Theme';
|
|
5
5
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
6
|
-
import type { TCustomer, TPaymentIntent, TPaymentMethodExpanded } from '@blocklet/payment-types';
|
|
6
|
+
import type { PaymentCurrency, TCustomer, TPaymentIntent, TPaymentMethodExpanded } from '@blocklet/payment-types';
|
|
7
7
|
import { LoadingButton } from '@mui/lab';
|
|
8
|
-
import { Avatar, Fade, InputAdornment,
|
|
8
|
+
import { Avatar, Card, Fade, InputAdornment, Stack, Typography } from '@mui/material';
|
|
9
9
|
import { useCreation, useSetState, useSize } from 'ahooks';
|
|
10
10
|
import { PhoneNumberUtil } from 'google-libphonenumber';
|
|
11
11
|
import pWaitFor from 'p-wait-for';
|
|
12
|
-
import { useEffect } from 'react';
|
|
12
|
+
import { useEffect, useState } from 'react';
|
|
13
13
|
import { Controller, useFormContext, useWatch } from 'react-hook-form';
|
|
14
14
|
import { dispatch } from 'use-bus';
|
|
15
15
|
import isEmail from 'validator/es/lib/isEmail';
|
|
@@ -56,6 +56,22 @@ const waitForCheckoutComplete = async (sessionId: string) => {
|
|
|
56
56
|
|
|
57
57
|
type PageData = CheckoutContext & CheckoutCallbacks;
|
|
58
58
|
|
|
59
|
+
const flatPaymentMethods = (methods: TPaymentMethodExpanded[] = []) => {
|
|
60
|
+
const out: PaymentCurrency[] = [];
|
|
61
|
+
|
|
62
|
+
methods.forEach((method: any) => {
|
|
63
|
+
const currencies = method.paymentCurrencies || method.payment_currencies || [];
|
|
64
|
+
currencies.forEach((currency: any) => {
|
|
65
|
+
out.push({
|
|
66
|
+
...currency,
|
|
67
|
+
method,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return out;
|
|
73
|
+
};
|
|
74
|
+
|
|
59
75
|
PaymentForm.defaultProps = {};
|
|
60
76
|
|
|
61
77
|
// FIXME: https://stripe.com/docs/elements/address-element
|
|
@@ -98,6 +114,9 @@ export default function PaymentForm({
|
|
|
98
114
|
stripePaying: false,
|
|
99
115
|
});
|
|
100
116
|
|
|
117
|
+
const currencies = flatPaymentMethods(paymentMethods);
|
|
118
|
+
const [paymentCurrencyIndex, setPaymentCurrencyIndex] = useState(0);
|
|
119
|
+
|
|
101
120
|
useEffect(() => {
|
|
102
121
|
if (session?.user) {
|
|
103
122
|
const values = getValues();
|
|
@@ -113,9 +132,12 @@ export default function PaymentForm({
|
|
|
113
132
|
}
|
|
114
133
|
}, [session?.user, getValues, setValue]);
|
|
115
134
|
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
setValue('payment_method', (currencies[paymentCurrencyIndex] as any).method.id);
|
|
137
|
+
setValue('payment_currency', currencies[paymentCurrencyIndex].id);
|
|
138
|
+
}, [paymentCurrencyIndex, currencies, setValue]);
|
|
139
|
+
|
|
116
140
|
const paymentMethod = useWatch({ control, name: 'payment_method' });
|
|
117
|
-
const paymentCurrency = useWatch({ control, name: 'payment_currency' });
|
|
118
|
-
const paymentCurrencies = paymentMethods.find((x) => x.id === paymentMethod)?.payment_currencies || [];
|
|
119
141
|
|
|
120
142
|
const domSize = useSize(document.body);
|
|
121
143
|
|
|
@@ -135,12 +157,8 @@ export default function PaymentForm({
|
|
|
135
157
|
|
|
136
158
|
const method = paymentMethods.find((x) => x.id === paymentMethod) as TPaymentMethodExpanded;
|
|
137
159
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
const currencies = paymentMethods.find((x) => x.id === e.target.value)?.payment_currencies || [];
|
|
141
|
-
if (currencies.some((x) => x.id === paymentCurrency) === false) {
|
|
142
|
-
setValue('payment_currency', currencies[0]?.id);
|
|
143
|
-
}
|
|
160
|
+
const handleCurrencyChange = (index: number) => {
|
|
161
|
+
setPaymentCurrencyIndex(index);
|
|
144
162
|
};
|
|
145
163
|
|
|
146
164
|
const handleConnected = async () => {
|
|
@@ -322,43 +340,40 @@ export default function PaymentForm({
|
|
|
322
340
|
<Fade in>
|
|
323
341
|
<Stack direction="column" alignItems="flex-start" className="cko-payment-methods">
|
|
324
342
|
<Typography sx={{ mb: 2, color: 'text.primary', fontWeight: 600 }}>{t('payment.checkout.method')}</Typography>
|
|
325
|
-
<Stack direction="row" sx={{ width:
|
|
326
|
-
<Controller
|
|
327
|
-
name="payment_method"
|
|
328
|
-
control={control}
|
|
329
|
-
render={({ field }) => (
|
|
330
|
-
<Select {...field} onChange={handleMethodChange} sx={{ flex: 1 }} size="small">
|
|
331
|
-
{paymentMethods.map((x) => {
|
|
332
|
-
const selected = x.id === paymentMethod;
|
|
333
|
-
return (
|
|
334
|
-
<MenuItem key={x.id} value={x.id}>
|
|
335
|
-
<Stack direction="row" spacing={1}>
|
|
336
|
-
<Avatar src={x.logo} alt={x.name} sx={{ width: 20, height: 20 }} />
|
|
337
|
-
<Typography color={selected ? 'text.primary' : 'text.secondary'}>{x.name}</Typography>
|
|
338
|
-
</Stack>
|
|
339
|
-
</MenuItem>
|
|
340
|
-
);
|
|
341
|
-
})}
|
|
342
|
-
</Select>
|
|
343
|
-
)}
|
|
344
|
-
/>
|
|
343
|
+
<Stack direction="row" sx={{ width: '100%' }}>
|
|
345
344
|
<Controller
|
|
346
345
|
name="payment_currency"
|
|
347
346
|
control={control}
|
|
348
|
-
render={(
|
|
349
|
-
<
|
|
350
|
-
{
|
|
351
|
-
|
|
347
|
+
render={() => (
|
|
348
|
+
<section
|
|
349
|
+
style={{
|
|
350
|
+
display: currencies.length > 1 ? 'grid' : 'block',
|
|
351
|
+
gridTemplateColumns: '50% 50%',
|
|
352
|
+
width: '100%',
|
|
353
|
+
}}>
|
|
354
|
+
{currencies.map((x, i) => {
|
|
355
|
+
const selected = i === paymentCurrencyIndex;
|
|
352
356
|
return (
|
|
353
|
-
<
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
+
<Card
|
|
358
|
+
key={x.id}
|
|
359
|
+
variant="outlined"
|
|
360
|
+
onClick={() => handleCurrencyChange(i)}
|
|
361
|
+
className={selected ? 'cko-payment-card' : 'cko-payment-card-unselect'}>
|
|
362
|
+
<Stack direction="row" alignItems="center">
|
|
363
|
+
<Avatar src={x.logo} alt={x.name} sx={{ width: 30, height: 30, marginRight: '10px' }} />
|
|
364
|
+
<div>
|
|
365
|
+
<Typography variant="h5" component="div">
|
|
366
|
+
{x.symbol}
|
|
367
|
+
</Typography>
|
|
368
|
+
<Typography sx={{ fontSize: 14 }} color="text.secondary" gutterBottom>
|
|
369
|
+
{(x as any).method.name}
|
|
370
|
+
</Typography>
|
|
371
|
+
</div>
|
|
357
372
|
</Stack>
|
|
358
|
-
</
|
|
373
|
+
</Card>
|
|
359
374
|
);
|
|
360
375
|
})}
|
|
361
|
-
</
|
|
376
|
+
</section>
|
|
362
377
|
)}
|
|
363
378
|
/>
|
|
364
379
|
</Stack>
|
|
@@ -383,7 +398,6 @@ export default function PaymentForm({
|
|
|
383
398
|
size="large"
|
|
384
399
|
onClick={onAction}
|
|
385
400
|
fullWidth
|
|
386
|
-
loadingPosition="end"
|
|
387
401
|
disabled={state.submitting || state.paying || state.stripePaying}
|
|
388
402
|
loading={state.submitting || state.paying}>
|
|
389
403
|
{state.submitting || state.paying ? t('payment.checkout.processing') : buttonText}
|
package/src/payment/index.tsx
CHANGED
|
@@ -331,6 +331,52 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
331
331
|
.cko-payment-methods {
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
.cko-payment-card {
|
|
335
|
+
position: relative;
|
|
336
|
+
border: 2px solid #3773f2;
|
|
337
|
+
padding: 5px 10px;
|
|
338
|
+
margin: 5px 0;
|
|
339
|
+
cursor: pointer;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.cko-payment-card::before {
|
|
343
|
+
content: '';
|
|
344
|
+
position: absolute;
|
|
345
|
+
right: 0;
|
|
346
|
+
top: 0;
|
|
347
|
+
border: 12px solid #3773f2;
|
|
348
|
+
border-bottom-color: transparent;
|
|
349
|
+
border-left-color: transparent;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.cko-payment-card-unselect {
|
|
353
|
+
border: 2px solid #bbb;
|
|
354
|
+
padding: 5px 10px;
|
|
355
|
+
margin: 5px 0;
|
|
356
|
+
cursor: pointer;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.cko-payment-card:nth-child(odd) {
|
|
360
|
+
margin-right: 5px;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.cko-payment-card-unselect:nth-child(odd) {
|
|
364
|
+
margin-right: 5px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.cko-payment-card::after {
|
|
368
|
+
content: '';
|
|
369
|
+
width: 6px;
|
|
370
|
+
height: 10px;
|
|
371
|
+
position: absolute;
|
|
372
|
+
right: 3px;
|
|
373
|
+
top: 0px;
|
|
374
|
+
border: 2px solid #fff;
|
|
375
|
+
border-top-color: transparent;
|
|
376
|
+
border-left-color: transparent;
|
|
377
|
+
transform: rotate(35deg);
|
|
378
|
+
}
|
|
379
|
+
|
|
334
380
|
.cko-payment-submit {
|
|
335
381
|
.MuiButtonBase-root {
|
|
336
382
|
border-radius: 0;
|