@blocklet/payment-react 1.21.13 → 1.21.15
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/.aigne/doc-smith/config.yaml +2 -2
- package/es/components/country-select.d.ts +6 -2
- package/es/components/country-select.js +170 -30
- package/es/components/source-data-viewer.js +25 -14
- package/es/history/credit/transactions-list.js +11 -1
- package/es/index.d.ts +1 -0
- package/es/libs/validator.d.ts +161 -0
- package/es/libs/validator.js +172 -61
- package/es/locales/en.js +1 -0
- package/es/locales/zh.js +1 -0
- package/es/payment/form/address.d.ts +1 -2
- package/es/payment/form/address.js +52 -41
- package/es/payment/form/index.js +133 -13
- package/lib/components/country-select.d.ts +6 -2
- package/lib/components/country-select.js +173 -40
- package/lib/components/source-data-viewer.js +5 -3
- package/lib/history/credit/transactions-list.js +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/libs/validator.d.ts +161 -0
- package/lib/libs/validator.js +173 -6
- package/lib/locales/en.js +1 -0
- package/lib/locales/zh.js +1 -0
- package/lib/payment/form/address.d.ts +1 -2
- package/lib/payment/form/address.js +63 -55
- package/lib/payment/form/index.js +171 -12
- package/package.json +3 -3
- package/src/components/country-select.tsx +176 -25
- package/src/components/source-data-viewer.tsx +9 -3
- package/src/history/credit/transactions-list.tsx +6 -1
- package/src/index.ts +2 -0
- package/src/libs/validator.ts +173 -61
- package/src/locales/en.tsx +1 -0
- package/src/locales/zh.tsx +1 -0
- package/src/payment/form/address.tsx +56 -50
- package/src/payment/form/index.tsx +160 -12
|
@@ -9,13 +9,12 @@ import { getFieldValidation, validatePostalCode } from '../../libs/validator';
|
|
|
9
9
|
|
|
10
10
|
type Props = {
|
|
11
11
|
mode: string;
|
|
12
|
-
stripe: boolean;
|
|
13
12
|
sx?: SxProps;
|
|
14
13
|
fieldValidation?: Record<string, any>;
|
|
15
14
|
errorPosition?: 'right' | 'bottom';
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
export default function AddressForm({ mode,
|
|
17
|
+
export default function AddressForm({ mode, sx = {}, fieldValidation = {}, errorPosition = 'right' }: Props) {
|
|
19
18
|
const { t, locale } = useLocaleContext();
|
|
20
19
|
const { control } = useFormContext();
|
|
21
20
|
const country = useWatch({ control, name: 'billing_address.country' });
|
|
@@ -99,54 +98,61 @@ export default function AddressForm({ mode, stripe, sx = {}, fieldValidation = {
|
|
|
99
98
|
);
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<
|
|
105
|
-
<Stack className="cko-payment-
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
101
|
+
return (
|
|
102
|
+
<Fade in>
|
|
103
|
+
<Stack className="cko-payment-address cko-payment-form" sx={sx}>
|
|
104
|
+
<Stack direction="column" className="cko-payment-form" spacing={0}>
|
|
105
|
+
<FormLabel className="base-label">{t('payment.checkout.billing.state')}</FormLabel>
|
|
106
|
+
<FormInput
|
|
107
|
+
name="billing_address.state"
|
|
108
|
+
rules={{
|
|
109
|
+
required: t('payment.checkout.required'),
|
|
110
|
+
...getFieldValidation('billing_address.state', fieldValidation, locale),
|
|
111
|
+
}}
|
|
112
|
+
errorPosition={errorPosition}
|
|
113
|
+
variant="outlined"
|
|
114
|
+
placeholder={t('payment.checkout.billing.state')}
|
|
115
|
+
/>
|
|
116
|
+
<FormLabel className="base-label">{t('payment.checkout.billing.postal_code')}</FormLabel>
|
|
117
|
+
<Stack direction="row" spacing={0}>
|
|
118
|
+
<FormInput
|
|
119
|
+
name="billing_address.postal_code"
|
|
120
|
+
rules={{
|
|
121
|
+
required: t('payment.checkout.required'),
|
|
122
|
+
validate: (x: string) => {
|
|
123
|
+
const isValid = validatePostalCode(x, country);
|
|
124
|
+
return isValid ? true : t('payment.checkout.invalid');
|
|
125
|
+
},
|
|
126
|
+
...getFieldValidation('billing_address.postal_code', fieldValidation, locale),
|
|
127
|
+
}}
|
|
128
|
+
errorPosition={errorPosition}
|
|
129
|
+
variant="outlined"
|
|
130
|
+
placeholder={t('payment.checkout.billing.postal_code')}
|
|
131
|
+
InputProps={{
|
|
132
|
+
startAdornment: (
|
|
133
|
+
<InputAdornment position="start" style={{ marginRight: '2px', marginLeft: '-8px' }}>
|
|
134
|
+
<Controller
|
|
135
|
+
name="billing_address.country"
|
|
136
|
+
control={control}
|
|
137
|
+
render={({ field }) => (
|
|
138
|
+
<CountrySelect
|
|
139
|
+
{...field}
|
|
140
|
+
ref={field.ref as unknown as React.RefObject<HTMLDivElement | null>}
|
|
141
|
+
sx={{
|
|
142
|
+
'.MuiOutlinedInput-notchedOutline': {
|
|
143
|
+
borderColor: 'transparent !important',
|
|
144
|
+
},
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
)}
|
|
148
|
+
/>
|
|
149
|
+
</InputAdornment>
|
|
150
|
+
),
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
145
153
|
</Stack>
|
|
146
154
|
</Stack>
|
|
147
|
-
</
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return null;
|
|
155
|
+
</Stack>
|
|
156
|
+
</Fade>
|
|
157
|
+
);
|
|
152
158
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import 'react-international-phone/style.css';
|
|
3
3
|
|
|
4
4
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
5
|
+
import { FlagEmoji } from 'react-international-phone';
|
|
5
6
|
// import { useTheme } from '@arcblock/ux/lib/Theme';
|
|
6
7
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
7
8
|
import type {
|
|
@@ -52,7 +53,7 @@ import LoadingButton from '../../components/loading-button';
|
|
|
52
53
|
import OverdueInvoicePayment from '../../components/over-due-invoice-payment';
|
|
53
54
|
import { saveCurrencyPreference } from '../../libs/currency';
|
|
54
55
|
import ConfirmDialog from '../../components/confirm';
|
|
55
|
-
import { getFieldValidation } from '../../libs/validator';
|
|
56
|
+
import { getFieldValidation, validatePostalCode } from '../../libs/validator';
|
|
56
57
|
|
|
57
58
|
export const waitForCheckoutComplete = async (sessionId: string) => {
|
|
58
59
|
let result: CheckoutContext;
|
|
@@ -222,6 +223,7 @@ export default function PaymentForm({
|
|
|
222
223
|
creditInsufficientInfo: {
|
|
223
224
|
open: boolean;
|
|
224
225
|
} | null;
|
|
226
|
+
showEditForm: boolean;
|
|
225
227
|
}>({
|
|
226
228
|
submitting: false,
|
|
227
229
|
paying: false,
|
|
@@ -233,6 +235,7 @@ export default function PaymentForm({
|
|
|
233
235
|
stripePaying: false,
|
|
234
236
|
fastCheckoutInfo: null,
|
|
235
237
|
creditInsufficientInfo: null,
|
|
238
|
+
showEditForm: false,
|
|
236
239
|
});
|
|
237
240
|
|
|
238
241
|
const currencies = flattenPaymentMethods(paymentMethods);
|
|
@@ -368,25 +371,113 @@ export default function PaymentForm({
|
|
|
368
371
|
const showStake = method.type === 'arcblock' && !checkoutSession.subscription_data?.no_stake;
|
|
369
372
|
|
|
370
373
|
const isDonationMode = checkoutSession?.submit_type === 'donate' && isDonation;
|
|
371
|
-
|
|
374
|
+
|
|
375
|
+
const validateUserInfo = () => {
|
|
372
376
|
if (!session?.user) {
|
|
373
377
|
return false;
|
|
374
378
|
}
|
|
375
|
-
|
|
376
|
-
|
|
379
|
+
|
|
380
|
+
const { fullName, name, email, phone, address } = session.user;
|
|
381
|
+
const fieldValidation = checkoutSession.metadata?.page_info?.field_validation;
|
|
382
|
+
|
|
383
|
+
const hasName = !!(fullName || name);
|
|
384
|
+
if (!hasName) {
|
|
385
|
+
return false;
|
|
377
386
|
}
|
|
378
|
-
|
|
379
|
-
|
|
387
|
+
|
|
388
|
+
const hasValidEmail = email && isEmail(email);
|
|
389
|
+
if (!hasValidEmail) {
|
|
390
|
+
return false;
|
|
380
391
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
392
|
+
|
|
393
|
+
const nameValidation = getFieldValidation('customer_name', fieldValidation, locale);
|
|
394
|
+
if (nameValidation.pattern && fullName) {
|
|
395
|
+
const pattern = nameValidation.pattern.value;
|
|
396
|
+
if (!pattern.test(fullName)) {
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const emailValidation = getFieldValidation('customer_email', fieldValidation, locale);
|
|
402
|
+
if (emailValidation.pattern && email) {
|
|
403
|
+
const pattern = emailValidation.pattern.value;
|
|
404
|
+
if (!pattern.test(email)) {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (!address || !address.postalCode || !validatePostalCode(address.postalCode, address.country)) {
|
|
410
|
+
return false;
|
|
384
411
|
}
|
|
385
|
-
|
|
412
|
+
|
|
413
|
+
const postalCodeValidation = getFieldValidation('billing_address.postal_code', fieldValidation, locale);
|
|
414
|
+
if (postalCodeValidation.pattern) {
|
|
415
|
+
const pattern = postalCodeValidation.pattern.value;
|
|
416
|
+
if (!pattern.test(address.postalCode)) {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (!address.province) {
|
|
386
422
|
return false;
|
|
387
423
|
}
|
|
424
|
+
const stateValidation = getFieldValidation('billing_address.state', fieldValidation, locale);
|
|
425
|
+
if (stateValidation.pattern) {
|
|
426
|
+
const pattern = stateValidation.pattern.value;
|
|
427
|
+
if (!pattern.test(address.province)) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (checkoutSession.phone_number_collection?.enabled) {
|
|
433
|
+
if (!phone || phone.trim() === '') {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
const phoneValidation = getFieldValidation('customer_phone', fieldValidation, locale);
|
|
437
|
+
if (phoneValidation.pattern) {
|
|
438
|
+
const pattern = phoneValidation.pattern.value;
|
|
439
|
+
if (!pattern.test(phone)) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const addressMode = checkoutSession.billing_address_collection;
|
|
446
|
+
if (addressMode === 'required') {
|
|
447
|
+
if (!address?.country || !address?.province || !address?.line1 || !address?.city || !address?.postalCode) {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const line1Validation = getFieldValidation('billing_address.line1', fieldValidation, locale);
|
|
452
|
+
if (line1Validation.pattern) {
|
|
453
|
+
const pattern = line1Validation.pattern.value;
|
|
454
|
+
if (!pattern.test(address.line1)) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const cityValidation = getFieldValidation('billing_address.city', fieldValidation, locale);
|
|
460
|
+
if (cityValidation.pattern) {
|
|
461
|
+
const pattern = cityValidation.pattern.value;
|
|
462
|
+
if (!pattern.test(address.city)) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
388
468
|
return true;
|
|
389
|
-
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const showForm = useMemo(() => {
|
|
472
|
+
if (!session?.user) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
if (state.showEditForm) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
return !validateUserInfo();
|
|
479
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
480
|
+
}, [session?.user, method, state.showEditForm]);
|
|
390
481
|
|
|
391
482
|
const handleConnected = async () => {
|
|
392
483
|
if (processingRef.current) {
|
|
@@ -910,6 +1001,64 @@ export default function PaymentForm({
|
|
|
910
1001
|
)}
|
|
911
1002
|
</Stack>
|
|
912
1003
|
</Fade>
|
|
1004
|
+
{!showForm && session?.user && (
|
|
1005
|
+
<Stack
|
|
1006
|
+
spacing={1.25}
|
|
1007
|
+
sx={{
|
|
1008
|
+
mt: 2,
|
|
1009
|
+
p: 2,
|
|
1010
|
+
pt: 1,
|
|
1011
|
+
backgroundColor: 'background.paper',
|
|
1012
|
+
borderRadius: 1,
|
|
1013
|
+
border: '1px solid',
|
|
1014
|
+
borderColor: 'divider',
|
|
1015
|
+
}}>
|
|
1016
|
+
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 0.25 }}>
|
|
1017
|
+
<Typography variant="subtitle2" sx={{ color: 'text.primary', fontSize: '0.875rem' }}>
|
|
1018
|
+
{t('payment.checkout.customerInfo')}
|
|
1019
|
+
</Typography>
|
|
1020
|
+
<Button
|
|
1021
|
+
size="small"
|
|
1022
|
+
variant="text"
|
|
1023
|
+
onClick={() => setState({ showEditForm: true })}
|
|
1024
|
+
sx={{ minWidth: 0 }}>
|
|
1025
|
+
{t('common.edit')}
|
|
1026
|
+
</Button>
|
|
1027
|
+
</Stack>
|
|
1028
|
+
<Stack spacing={0.5}>
|
|
1029
|
+
<Typography variant="body2" sx={{ color: 'text.primary', fontWeight: 600, fontSize: '0.9375rem' }}>
|
|
1030
|
+
{session.user.fullName || session.user.name}
|
|
1031
|
+
</Typography>
|
|
1032
|
+
<Typography variant="body2" sx={{ color: 'text.secondary', fontSize: '0.8125rem' }}>
|
|
1033
|
+
{session.user.email}
|
|
1034
|
+
</Typography>
|
|
1035
|
+
{checkoutSession.phone_number_collection?.enabled && session.user.phone && (
|
|
1036
|
+
<Typography variant="body2" sx={{ color: 'text.secondary', fontSize: '0.8125rem' }}>
|
|
1037
|
+
{session.user.phone}
|
|
1038
|
+
</Typography>
|
|
1039
|
+
)}
|
|
1040
|
+
{session.user.address && (
|
|
1041
|
+
<Stack direction="row" alignItems="center" spacing={0.75}>
|
|
1042
|
+
{session.user.address.country && (
|
|
1043
|
+
<FlagEmoji iso2={session.user.address.country.toLowerCase()} style={{ width: 18, height: 14 }} />
|
|
1044
|
+
)}
|
|
1045
|
+
<Typography variant="body2" sx={{ color: 'text.secondary', fontSize: '0.8125rem' }}>
|
|
1046
|
+
{[
|
|
1047
|
+
session.user.address.line1,
|
|
1048
|
+
session.user.address.city,
|
|
1049
|
+
session.user.address.province,
|
|
1050
|
+
session.user.address.country?.toUpperCase(),
|
|
1051
|
+
]
|
|
1052
|
+
.filter(Boolean)
|
|
1053
|
+
.join(', ')}
|
|
1054
|
+
{session.user.address.postalCode &&
|
|
1055
|
+
` [ ${t('payment.checkout.billing.postal_code')}: ${session.user.address.postalCode} ]`}
|
|
1056
|
+
</Typography>
|
|
1057
|
+
</Stack>
|
|
1058
|
+
)}
|
|
1059
|
+
</Stack>
|
|
1060
|
+
</Stack>
|
|
1061
|
+
)}
|
|
913
1062
|
{showForm && (
|
|
914
1063
|
<Stack
|
|
915
1064
|
direction="column"
|
|
@@ -968,7 +1117,6 @@ export default function PaymentForm({
|
|
|
968
1117
|
)}
|
|
969
1118
|
<AddressForm
|
|
970
1119
|
mode={checkoutSession.billing_address_collection as string}
|
|
971
|
-
stripe={method?.type === 'stripe'}
|
|
972
1120
|
sx={{ marginTop: '0 !important' }}
|
|
973
1121
|
fieldValidation={checkoutSession.metadata?.page_info?.field_validation}
|
|
974
1122
|
errorPosition={formErrorPosition}
|