@blocklet/payment-react 1.18.24 → 1.18.26
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/checkout/donate.js +11 -1
- package/es/components/country-select.js +243 -21
- package/es/components/over-due-invoice-payment.d.ts +3 -1
- package/es/components/over-due-invoice-payment.js +6 -4
- package/es/contexts/payment.d.ts +2 -1
- package/es/contexts/payment.js +8 -1
- package/es/hooks/keyboard.js +3 -0
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/libs/api.js +4 -0
- package/es/libs/currency.d.ts +3 -0
- package/es/libs/currency.js +22 -0
- package/es/libs/phone-validator.js +2 -0
- package/es/libs/util.d.ts +2 -2
- package/es/libs/util.js +7 -4
- package/es/libs/validator.d.ts +1 -0
- package/es/libs/validator.js +70 -0
- package/es/payment/form/address.js +17 -3
- package/es/payment/form/index.js +10 -1
- package/es/payment/form/phone.js +12 -1
- package/es/payment/form/stripe/form.js +72 -15
- package/es/payment/index.js +33 -11
- package/es/payment/product-donation.js +110 -12
- package/es/types/shims.d.ts +2 -0
- package/lib/checkout/donate.js +11 -1
- package/lib/components/country-select.js +243 -39
- package/lib/components/over-due-invoice-payment.d.ts +3 -1
- package/lib/components/over-due-invoice-payment.js +7 -4
- package/lib/contexts/payment.d.ts +2 -1
- package/lib/contexts/payment.js +9 -1
- package/lib/hooks/keyboard.js +3 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +12 -0
- package/lib/libs/api.js +4 -0
- package/lib/libs/currency.d.ts +3 -0
- package/lib/libs/currency.js +31 -0
- package/lib/libs/phone-validator.js +1 -0
- package/lib/libs/util.d.ts +2 -2
- package/lib/libs/util.js +7 -4
- package/lib/libs/validator.d.ts +1 -0
- package/lib/libs/validator.js +20 -0
- package/lib/payment/form/address.js +15 -2
- package/lib/payment/form/index.js +12 -1
- package/lib/payment/form/phone.js +13 -1
- package/lib/payment/form/stripe/form.js +98 -29
- package/lib/payment/index.js +34 -10
- package/lib/payment/product-donation.js +106 -15
- package/lib/types/shims.d.ts +2 -0
- package/package.json +8 -8
- package/src/checkout/donate.tsx +11 -1
- package/src/components/country-select.tsx +265 -20
- package/src/components/over-due-invoice-payment.tsx +6 -2
- package/src/contexts/payment.tsx +11 -1
- package/src/hooks/keyboard.ts +5 -3
- package/src/index.ts +1 -0
- package/src/libs/api.ts +4 -1
- package/src/libs/currency.ts +25 -0
- package/src/libs/phone-validator.ts +1 -0
- package/src/libs/util.ts +18 -4
- package/src/libs/validator.ts +70 -0
- package/src/payment/form/address.tsx +17 -4
- package/src/payment/form/index.tsx +11 -1
- package/src/payment/form/phone.tsx +15 -1
- package/src/payment/form/stripe/form.tsx +104 -32
- package/src/payment/index.tsx +45 -14
- package/src/payment/product-donation.tsx +129 -10
- package/src/types/shims.d.ts +2 -0
|
@@ -9,6 +9,7 @@ var _react = require("react");
|
|
|
9
9
|
var _material = require("@mui/material");
|
|
10
10
|
var _reactHookForm = require("react-hook-form");
|
|
11
11
|
var _reactInternationalPhone = require("react-international-phone");
|
|
12
|
+
var _mobile = require("../hooks/mobile");
|
|
12
13
|
const CountrySelect = (0, _react.forwardRef)(({
|
|
13
14
|
value,
|
|
14
15
|
onChange,
|
|
@@ -18,6 +19,102 @@ const CountrySelect = (0, _react.forwardRef)(({
|
|
|
18
19
|
const {
|
|
19
20
|
setValue
|
|
20
21
|
} = (0, _reactHookForm.useFormContext)();
|
|
22
|
+
const [open, setOpen] = (0, _react.useState)(false);
|
|
23
|
+
const [searchText, setSearchText] = (0, _react.useState)("");
|
|
24
|
+
const inputRef = (0, _react.useRef)(null);
|
|
25
|
+
const menuRef = (0, _react.useRef)(null);
|
|
26
|
+
const listRef = (0, _react.useRef)(null);
|
|
27
|
+
const [focusedIndex, setFocusedIndex] = (0, _react.useState)(-1);
|
|
28
|
+
const itemHeightRef = (0, _react.useRef)(40);
|
|
29
|
+
const {
|
|
30
|
+
isMobile
|
|
31
|
+
} = (0, _mobile.useMobile)();
|
|
32
|
+
const measuredRef = (0, _react.useRef)(false);
|
|
33
|
+
(0, _react.useEffect)(() => {
|
|
34
|
+
if (!open) return () => {};
|
|
35
|
+
const handleResize = () => {
|
|
36
|
+
measuredRef.current = false;
|
|
37
|
+
};
|
|
38
|
+
window.addEventListener("resize", handleResize);
|
|
39
|
+
return () => {
|
|
40
|
+
window.removeEventListener("resize", handleResize);
|
|
41
|
+
};
|
|
42
|
+
}, [open]);
|
|
43
|
+
const scrollToTop = () => {
|
|
44
|
+
if (listRef.current) {
|
|
45
|
+
listRef.current.scrollTop = 0;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const measureItemHeight = () => {
|
|
49
|
+
if (!listRef.current || !open) return;
|
|
50
|
+
const items = listRef.current.querySelectorAll(".MuiMenuItem-root");
|
|
51
|
+
if (items.length > 0) {
|
|
52
|
+
const firstItem = items[0];
|
|
53
|
+
if (firstItem.offsetHeight > 0) {
|
|
54
|
+
itemHeightRef.current = firstItem.offsetHeight;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const controlScrollPosition = index => {
|
|
59
|
+
if (!listRef.current) return;
|
|
60
|
+
if (open && !measuredRef.current) {
|
|
61
|
+
measureItemHeight();
|
|
62
|
+
measuredRef.current = true;
|
|
63
|
+
}
|
|
64
|
+
const listHeight = listRef.current.clientHeight;
|
|
65
|
+
const targetPosition = index * itemHeightRef.current;
|
|
66
|
+
if (index < 2) {
|
|
67
|
+
listRef.current.scrollTop = 0;
|
|
68
|
+
} else if (index > filteredCountries.length - 3) {
|
|
69
|
+
listRef.current.scrollTop = listRef.current.scrollHeight - listHeight;
|
|
70
|
+
} else {
|
|
71
|
+
const scrollPosition = targetPosition - listHeight / 2 + itemHeightRef.current / 2;
|
|
72
|
+
listRef.current.scrollTop = Math.max(0, scrollPosition);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
(0, _react.useEffect)(() => {
|
|
76
|
+
let timeout = null;
|
|
77
|
+
if (open) {
|
|
78
|
+
timeout = setTimeout(() => {
|
|
79
|
+
scrollToTop();
|
|
80
|
+
if (!isMobile && inputRef.current) {
|
|
81
|
+
inputRef.current.focus();
|
|
82
|
+
}
|
|
83
|
+
}, 100);
|
|
84
|
+
} else {
|
|
85
|
+
setSearchText("");
|
|
86
|
+
setFocusedIndex(-1);
|
|
87
|
+
}
|
|
88
|
+
return () => {
|
|
89
|
+
if (timeout) {
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}, [open, isMobile]);
|
|
94
|
+
const filteredCountries = (0, _react.useMemo)(() => {
|
|
95
|
+
if (!searchText) return _reactInternationalPhone.defaultCountries;
|
|
96
|
+
return _reactInternationalPhone.defaultCountries.filter(c => {
|
|
97
|
+
const parsed = (0, _reactInternationalPhone.parseCountry)(c);
|
|
98
|
+
return parsed.name.toLowerCase().includes(searchText.toLowerCase()) || parsed.iso2.toLowerCase().includes(searchText.toLowerCase()) || `+${parsed.dialCode}`.includes(searchText);
|
|
99
|
+
});
|
|
100
|
+
}, [searchText]);
|
|
101
|
+
(0, _react.useEffect)(() => {
|
|
102
|
+
scrollToTop();
|
|
103
|
+
setFocusedIndex(-1);
|
|
104
|
+
}, [searchText]);
|
|
105
|
+
(0, _react.useEffect)(() => {
|
|
106
|
+
let timeout = null;
|
|
107
|
+
if (focusedIndex >= 0) {
|
|
108
|
+
timeout = setTimeout(() => {
|
|
109
|
+
controlScrollPosition(focusedIndex);
|
|
110
|
+
}, 10);
|
|
111
|
+
}
|
|
112
|
+
return () => {
|
|
113
|
+
if (timeout) {
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}, [focusedIndex, filteredCountries.length]);
|
|
21
118
|
const countryDetail = (0, _react.useMemo)(() => {
|
|
22
119
|
const item = _reactInternationalPhone.defaultCountries.find(v => v[1] === value);
|
|
23
120
|
return value && item ? (0, _reactInternationalPhone.parseCountry)(item) : {
|
|
@@ -28,11 +125,58 @@ const CountrySelect = (0, _react.forwardRef)(({
|
|
|
28
125
|
onChange(e.target.value);
|
|
29
126
|
setValue(name, e.target.value);
|
|
30
127
|
};
|
|
31
|
-
|
|
128
|
+
const handleCountryClick = code => {
|
|
129
|
+
onChange(code);
|
|
130
|
+
setValue(name, code);
|
|
131
|
+
setOpen(false);
|
|
132
|
+
};
|
|
133
|
+
const handleSearchChange = e => {
|
|
134
|
+
e.stopPropagation();
|
|
135
|
+
setSearchText(e.target.value);
|
|
136
|
+
};
|
|
137
|
+
const handleKeyDown = e => {
|
|
138
|
+
e.stopPropagation();
|
|
139
|
+
if (e.key === "Escape") {
|
|
140
|
+
setOpen(false);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const handleNavigation = direction => {
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
setFocusedIndex(prev => {
|
|
146
|
+
if (direction === "next") {
|
|
147
|
+
if (prev === -1) return 0;
|
|
148
|
+
return prev >= filteredCountries.length - 1 ? 0 : prev + 1;
|
|
149
|
+
}
|
|
150
|
+
if (prev === -1) return filteredCountries.length - 1;
|
|
151
|
+
return prev <= 0 ? filteredCountries.length - 1 : prev - 1;
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
if (e.key === "Tab") {
|
|
155
|
+
handleNavigation(e.shiftKey ? "prev" : "next");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (e.key === "ArrowDown") {
|
|
159
|
+
handleNavigation("next");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (e.key === "ArrowUp") {
|
|
163
|
+
handleNavigation("prev");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (e.key === "Enter" && focusedIndex >= 0 && focusedIndex < filteredCountries.length) {
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
const country = (0, _reactInternationalPhone.parseCountry)(filteredCountries[focusedIndex]);
|
|
169
|
+
handleCountryClick(country.iso2);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Select, {
|
|
32
173
|
ref,
|
|
174
|
+
open,
|
|
175
|
+
onOpen: () => setOpen(true),
|
|
176
|
+
onClose: () => setOpen(false),
|
|
33
177
|
MenuProps: {
|
|
34
178
|
style: {
|
|
35
|
-
|
|
179
|
+
maxHeight: "300px",
|
|
36
180
|
top: "10px"
|
|
37
181
|
},
|
|
38
182
|
anchorOrigin: {
|
|
@@ -42,6 +186,18 @@ const CountrySelect = (0, _react.forwardRef)(({
|
|
|
42
186
|
transformOrigin: {
|
|
43
187
|
vertical: "top",
|
|
44
188
|
horizontal: "left"
|
|
189
|
+
},
|
|
190
|
+
PaperProps: {
|
|
191
|
+
ref: menuRef,
|
|
192
|
+
sx: {
|
|
193
|
+
display: "flex",
|
|
194
|
+
"& .MuiList-root": {
|
|
195
|
+
pt: 0,
|
|
196
|
+
display: "flex",
|
|
197
|
+
flexDirection: "column",
|
|
198
|
+
overflowY: "hidden"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
45
201
|
}
|
|
46
202
|
},
|
|
47
203
|
sx: {
|
|
@@ -68,43 +224,91 @@ const CountrySelect = (0, _react.forwardRef)(({
|
|
|
68
224
|
},
|
|
69
225
|
value,
|
|
70
226
|
onChange: onCountryChange,
|
|
71
|
-
renderValue: code => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
227
|
+
renderValue: code => /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
228
|
+
display: "flex",
|
|
229
|
+
alignItems: "center",
|
|
230
|
+
flexWrap: "nowrap",
|
|
231
|
+
gap: 0.5,
|
|
232
|
+
sx: {
|
|
233
|
+
cursor: "pointer"
|
|
234
|
+
},
|
|
235
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactInternationalPhone.FlagEmoji, {
|
|
236
|
+
iso2: code,
|
|
237
|
+
style: {
|
|
238
|
+
display: "flex"
|
|
239
|
+
}
|
|
240
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
241
|
+
children: countryDetail?.name
|
|
242
|
+
})]
|
|
243
|
+
}),
|
|
244
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
245
|
+
sx: {
|
|
246
|
+
position: "sticky",
|
|
247
|
+
top: 0,
|
|
248
|
+
zIndex: 1,
|
|
249
|
+
bgcolor: "background.paper",
|
|
250
|
+
p: 1
|
|
251
|
+
},
|
|
252
|
+
onClick: e => {
|
|
253
|
+
e.stopPropagation();
|
|
254
|
+
},
|
|
255
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.TextField, {
|
|
256
|
+
inputRef,
|
|
257
|
+
autoFocus: !isMobile,
|
|
258
|
+
fullWidth: true,
|
|
259
|
+
placeholder: "Search country...",
|
|
260
|
+
value: searchText,
|
|
261
|
+
onChange: handleSearchChange,
|
|
262
|
+
onKeyDown: handleKeyDown,
|
|
263
|
+
onClick: e => e.stopPropagation(),
|
|
264
|
+
size: "small",
|
|
265
|
+
variant: "outlined"
|
|
266
|
+
})
|
|
267
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
|
|
268
|
+
ref: listRef,
|
|
269
|
+
sx: {
|
|
270
|
+
flex: 1,
|
|
271
|
+
overflowY: "auto",
|
|
272
|
+
overflowX: "hidden",
|
|
273
|
+
maxHeight: "calc(300px - 65px)",
|
|
274
|
+
scrollBehavior: "smooth"
|
|
275
|
+
},
|
|
276
|
+
children: filteredCountries.length > 0 ? filteredCountries.map((c, index) => {
|
|
277
|
+
const parsed = (0, _reactInternationalPhone.parseCountry)(c);
|
|
278
|
+
const isFocused = index === focusedIndex;
|
|
279
|
+
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.MenuItem, {
|
|
280
|
+
value: parsed.iso2,
|
|
281
|
+
selected: parsed.iso2 === value,
|
|
282
|
+
onClick: () => handleCountryClick(parsed.iso2),
|
|
283
|
+
sx: {
|
|
284
|
+
"&.Mui-selected": {
|
|
285
|
+
backgroundColor: "rgba(0, 0, 0, 0.04)"
|
|
286
|
+
},
|
|
287
|
+
"&:hover": {
|
|
288
|
+
backgroundColor: "var(--backgrounds-bg-highlight, #eff6ff)"
|
|
289
|
+
},
|
|
290
|
+
...(isFocused ? {
|
|
291
|
+
backgroundColor: "var(--backgrounds-bg-highlight, #eff6ff)",
|
|
292
|
+
outline: "none"
|
|
293
|
+
} : {})
|
|
294
|
+
},
|
|
295
|
+
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactInternationalPhone.FlagEmoji, {
|
|
296
|
+
iso2: parsed.iso2,
|
|
297
|
+
style: {
|
|
298
|
+
marginRight: "8px"
|
|
299
|
+
}
|
|
300
|
+
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
301
|
+
children: parsed.name
|
|
302
|
+
})]
|
|
303
|
+
}, parsed.iso2);
|
|
304
|
+
}) : /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.MenuItem, {
|
|
305
|
+
disabled: true,
|
|
306
|
+
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
|
|
307
|
+
color: "text.secondary",
|
|
308
|
+
children: "No countries found"
|
|
309
|
+
})
|
|
310
|
+
})
|
|
311
|
+
})]
|
|
108
312
|
});
|
|
109
313
|
});
|
|
110
314
|
CountrySelect.defaultProps = {
|
|
@@ -27,13 +27,14 @@ type Props = {
|
|
|
27
27
|
subscriptionCount?: number;
|
|
28
28
|
detailUrl: string;
|
|
29
29
|
}) => React.ReactNode;
|
|
30
|
+
authToken?: string;
|
|
30
31
|
};
|
|
31
32
|
type SummaryItem = {
|
|
32
33
|
amount: string;
|
|
33
34
|
currency: PaymentCurrency;
|
|
34
35
|
method: PaymentMethod;
|
|
35
36
|
};
|
|
36
|
-
declare function OverdueInvoicePayment({ subscriptionId, customerId, mode, dialogProps, children, onPaid, detailLinkOptions, successToast, alertMessage, }: Props): import("react").JSX.Element | null;
|
|
37
|
+
declare function OverdueInvoicePayment({ subscriptionId, customerId, mode, dialogProps, children, onPaid, detailLinkOptions, successToast, alertMessage, authToken, }: Props): import("react").JSX.Element | null;
|
|
37
38
|
declare namespace OverdueInvoicePayment {
|
|
38
39
|
var defaultProps: {
|
|
39
40
|
mode: string;
|
|
@@ -49,6 +50,7 @@ declare namespace OverdueInvoicePayment {
|
|
|
49
50
|
customerId: undefined;
|
|
50
51
|
successToast: boolean;
|
|
51
52
|
alertMessage: string;
|
|
53
|
+
authToken: undefined;
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
56
|
export default OverdueInvoicePayment;
|
|
@@ -30,7 +30,7 @@ const fetchOverdueInvoices = async params => {
|
|
|
30
30
|
} else {
|
|
31
31
|
url = `/api/customers/${params.customerId}/overdue/invoices`;
|
|
32
32
|
}
|
|
33
|
-
const res = await _api.default.get(url);
|
|
33
|
+
const res = await _api.default.get(params.authToken ? (0, _ufo.joinURL)(url, `?authToken=${params.authToken}`) : url);
|
|
34
34
|
return res.data;
|
|
35
35
|
};
|
|
36
36
|
function OverdueInvoicePayment({
|
|
@@ -44,7 +44,8 @@ function OverdueInvoicePayment({
|
|
|
44
44
|
enabled: true
|
|
45
45
|
},
|
|
46
46
|
successToast = true,
|
|
47
|
-
alertMessage = ""
|
|
47
|
+
alertMessage = "",
|
|
48
|
+
authToken
|
|
48
49
|
}) {
|
|
49
50
|
const {
|
|
50
51
|
t
|
|
@@ -69,7 +70,8 @@ function OverdueInvoicePayment({
|
|
|
69
70
|
runAsync: refresh
|
|
70
71
|
} = (0, _ahooks.useRequest)(() => fetchOverdueInvoices({
|
|
71
72
|
subscriptionId,
|
|
72
|
-
customerId
|
|
73
|
+
customerId,
|
|
74
|
+
authToken
|
|
73
75
|
}), {
|
|
74
76
|
ready: !!subscriptionId || !!customerId
|
|
75
77
|
});
|
|
@@ -450,6 +452,7 @@ OverdueInvoicePayment.defaultProps = {
|
|
|
450
452
|
subscriptionId: void 0,
|
|
451
453
|
customerId: void 0,
|
|
452
454
|
successToast: true,
|
|
453
|
-
alertMessage: ""
|
|
455
|
+
alertMessage: "",
|
|
456
|
+
authToken: void 0
|
|
454
457
|
};
|
|
455
458
|
module.exports = OverdueInvoicePayment;
|
|
@@ -25,10 +25,11 @@ export type PaymentContextProps = {
|
|
|
25
25
|
connect: import('@arcblock/did-connect/lib/types').SessionContext['connectApi'];
|
|
26
26
|
children: any;
|
|
27
27
|
baseUrl?: string;
|
|
28
|
+
authToken?: string;
|
|
28
29
|
};
|
|
29
30
|
declare const PaymentContext: import("react").Context<PaymentContextType>;
|
|
30
31
|
declare const Consumer: import("react").Consumer<PaymentContextType>;
|
|
31
|
-
declare function PaymentProvider({ session, connect, children, baseUrl }: PaymentContextProps): import("react").JSX.Element | null;
|
|
32
|
+
declare function PaymentProvider({ session, connect, children, baseUrl, authToken }: PaymentContextProps): import("react").JSX.Element | null;
|
|
32
33
|
declare namespace PaymentProvider {
|
|
33
34
|
var defaultProps: {};
|
|
34
35
|
}
|
package/lib/contexts/payment.js
CHANGED
|
@@ -57,10 +57,18 @@ function PaymentProvider({
|
|
|
57
57
|
session,
|
|
58
58
|
connect,
|
|
59
59
|
children,
|
|
60
|
-
baseUrl
|
|
60
|
+
baseUrl,
|
|
61
|
+
authToken
|
|
61
62
|
}) {
|
|
62
63
|
if (baseUrl) {
|
|
63
64
|
window.__PAYMENT_KIT_BASE_URL = baseUrl;
|
|
65
|
+
} else {
|
|
66
|
+
window.__PAYMENT_KIT_BASE_URL = "";
|
|
67
|
+
}
|
|
68
|
+
if (authToken) {
|
|
69
|
+
window.__PAYMENT_KIT_AUTH_TOKEN = authToken;
|
|
70
|
+
} else {
|
|
71
|
+
window.__PAYMENT_KIT_AUTH_TOKEN = "";
|
|
64
72
|
}
|
|
65
73
|
const [livemode, setLivemode] = (0, _ahooks.useLocalStorageState)("livemode", {
|
|
66
74
|
defaultValue: true
|
package/lib/hooks/keyboard.js
CHANGED
|
@@ -44,6 +44,9 @@ const useTabNavigation = (items, onSelect, options) => {
|
|
|
44
44
|
return i;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
if (includeCustom && navigableElements.length > 0) {
|
|
48
|
+
return navigableElements.length - 1;
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
return -1;
|
|
49
52
|
}, [items, includeCustom, isCustomSelected, currentValue, valueType, compareValue, findNavigableElements]);
|
package/lib/index.d.ts
CHANGED
|
@@ -43,5 +43,6 @@ export * from './hooks/mobile';
|
|
|
43
43
|
export * from './hooks/table';
|
|
44
44
|
export * from './hooks/scroll';
|
|
45
45
|
export * from './hooks/keyboard';
|
|
46
|
+
export * from './libs/validator';
|
|
46
47
|
export { translations, createTranslator } from './locales';
|
|
47
48
|
export { createLazyComponent, api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, Link, OverdueInvoicePayment, PaymentBeneficiaries, LoadingButton, DonateDetails, };
|
package/lib/index.js
CHANGED
|
@@ -430,6 +430,18 @@ Object.keys(_keyboard).forEach(function (key) {
|
|
|
430
430
|
}
|
|
431
431
|
});
|
|
432
432
|
});
|
|
433
|
+
var _validator = require("./libs/validator");
|
|
434
|
+
Object.keys(_validator).forEach(function (key) {
|
|
435
|
+
if (key === "default" || key === "__esModule") return;
|
|
436
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
437
|
+
if (key in exports && exports[key] === _validator[key]) return;
|
|
438
|
+
Object.defineProperty(exports, key, {
|
|
439
|
+
enumerable: true,
|
|
440
|
+
get: function () {
|
|
441
|
+
return _validator[key];
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
});
|
|
433
445
|
var _locales = require("./locales");
|
|
434
446
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
435
447
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
package/lib/libs/api.js
CHANGED
|
@@ -19,6 +19,10 @@ api.interceptors.request.use(config => {
|
|
|
19
19
|
...(config.params || {}),
|
|
20
20
|
locale
|
|
21
21
|
};
|
|
22
|
+
const authToken = window.__PAYMENT_KIT_AUTH_TOKEN;
|
|
23
|
+
if (authToken && typeof config.params.authToken === "undefined" && !query.has("authToken")) {
|
|
24
|
+
config.params.authToken = authToken;
|
|
25
|
+
}
|
|
22
26
|
if (typeof config.params.livemode === "undefined" && query.has("livemode") === false) {
|
|
23
27
|
const livemode = localStorage.getItem("livemode");
|
|
24
28
|
config.params.livemode = (0, _isNull.default)(livemode) ? true : JSON.parse(livemode);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const getUserStorageKey: (base: string, did?: string) => string;
|
|
2
|
+
export declare const saveCurrencyPreference: (currencyId: string, did?: string) => void;
|
|
3
|
+
export declare const getCurrencyPreference: (did?: string, availableCurrencyIds?: string[]) => string | null;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.saveCurrencyPreference = exports.getUserStorageKey = exports.getCurrencyPreference = void 0;
|
|
7
|
+
const CURRENCY_PREFERENCE_KEY_BASE = "payment-currency-preference";
|
|
8
|
+
const getUserStorageKey = (base, did) => {
|
|
9
|
+
return did ? `${base}:${did}` : base;
|
|
10
|
+
};
|
|
11
|
+
exports.getUserStorageKey = getUserStorageKey;
|
|
12
|
+
const saveCurrencyPreference = (currencyId, did) => {
|
|
13
|
+
try {
|
|
14
|
+
localStorage.setItem(getUserStorageKey(CURRENCY_PREFERENCE_KEY_BASE, did), currencyId);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
console.warn("Failed to save currency preference", e);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
exports.saveCurrencyPreference = saveCurrencyPreference;
|
|
20
|
+
const getCurrencyPreference = (did, availableCurrencyIds) => {
|
|
21
|
+
try {
|
|
22
|
+
const saved = localStorage.getItem(getUserStorageKey(CURRENCY_PREFERENCE_KEY_BASE, did));
|
|
23
|
+
if (saved && (!availableCurrencyIds || availableCurrencyIds.includes(saved))) {
|
|
24
|
+
return saved;
|
|
25
|
+
}
|
|
26
|
+
} catch (e) {
|
|
27
|
+
console.warn("Failed to access localStorage", e);
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
exports.getCurrencyPreference = getCurrencyPreference;
|
package/lib/libs/util.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ export declare function formatDateTime(date: Date | string | number, locale?: st
|
|
|
10
10
|
export declare const formatLocale: (locale?: string) => string;
|
|
11
11
|
export declare const formatPrettyMsLocale: (locale: string) => "zh_CN" | "en_US";
|
|
12
12
|
export declare const formatError: (err: any) => any;
|
|
13
|
-
export declare function formatBNStr(str?: string, decimals?: number, precision?: number, trim?: boolean): string;
|
|
14
|
-
export declare function formatNumber(n: number | string, precision?: number, trim?: boolean): string;
|
|
13
|
+
export declare function formatBNStr(str?: string, decimals?: number, precision?: number, trim?: boolean, thousandSeparated?: boolean): string;
|
|
14
|
+
export declare function formatNumber(n: number | string, precision?: number, trim?: boolean, thousandSeparated?: boolean): string;
|
|
15
15
|
export declare const formatPrice: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean, locale?: string) => string;
|
|
16
16
|
export declare const formatPriceAmount: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean) => string;
|
|
17
17
|
export declare function getStatementDescriptor(items: any[]): any;
|
package/lib/libs/util.js
CHANGED
|
@@ -156,16 +156,19 @@ const formatError = err => {
|
|
|
156
156
|
return err.message;
|
|
157
157
|
};
|
|
158
158
|
exports.formatError = formatError;
|
|
159
|
-
function formatBNStr(str = "", decimals = 18, precision = 6, trim = true) {
|
|
160
|
-
|
|
159
|
+
function formatBNStr(str = "", decimals = 18, precision = 6, trim = true, thousandSeparated = true) {
|
|
160
|
+
if (!str) {
|
|
161
|
+
return "0";
|
|
162
|
+
}
|
|
163
|
+
return formatNumber((0, _util.fromUnitToToken)(str, decimals), precision, trim, thousandSeparated);
|
|
161
164
|
}
|
|
162
|
-
function formatNumber(n, precision = 6, trim = true) {
|
|
165
|
+
function formatNumber(n, precision = 6, trim = true, thousandSeparated = true) {
|
|
163
166
|
if (!n || n === "0") {
|
|
164
167
|
return "0";
|
|
165
168
|
}
|
|
166
169
|
const num = (0, _numbro.default)(n);
|
|
167
170
|
const options = {
|
|
168
|
-
thousandSeparated
|
|
171
|
+
thousandSeparated,
|
|
169
172
|
...((precision || precision === 0) && {
|
|
170
173
|
mantissa: precision
|
|
171
174
|
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function validatePostalCode(postalCode: string, country?: string): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.validatePostalCode = validatePostalCode;
|
|
7
|
+
var _isPostalCode = _interopRequireDefault(require("validator/lib/isPostalCode"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
const POSTAL_CODE_SUPPORTED_COUNTRIES = ["AD", "AT", "AU", "BE", "BG", "BR", "CA", "CH", "CN", "CZ", "DE", "DK", "DZ", "EE", "ES", "FI", "FR", "GB", "GR", "HR", "HU", "ID", "IE", "IL", "IN", "IR", "IS", "IT", "JP", "KE", "KR", "LI", "LT", "LU", "LV", "MX", "MT", "NL", "NO", "NZ", "PL", "PR", "PT", "RO", "RU", "SA", "SE", "SI", "SK", "TN", "TW", "UA", "US", "ZA", "ZM"];
|
|
10
|
+
function validatePostalCode(postalCode, country) {
|
|
11
|
+
if (!postalCode) return true;
|
|
12
|
+
const countryUpper = country?.toUpperCase();
|
|
13
|
+
const isSupported = country && POSTAL_CODE_SUPPORTED_COUNTRIES.includes(countryUpper);
|
|
14
|
+
try {
|
|
15
|
+
return (0, _isPostalCode.default)(postalCode, isSupported ? countryUpper : "any");
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error(error);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -10,6 +10,7 @@ var _material = require("@mui/material");
|
|
|
10
10
|
var _reactHookForm = require("react-hook-form");
|
|
11
11
|
var _input = _interopRequireDefault(require("../../components/input"));
|
|
12
12
|
var _countrySelect = _interopRequireDefault(require("../../components/country-select"));
|
|
13
|
+
var _validator = require("../../libs/validator");
|
|
13
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
15
|
AddressForm.defaultProps = {
|
|
15
16
|
sx: {}
|
|
@@ -25,6 +26,10 @@ function AddressForm({
|
|
|
25
26
|
const {
|
|
26
27
|
control
|
|
27
28
|
} = (0, _reactHookForm.useFormContext)();
|
|
29
|
+
const country = (0, _reactHookForm.useWatch)({
|
|
30
|
+
control,
|
|
31
|
+
name: "billing_address.country"
|
|
32
|
+
});
|
|
28
33
|
if (mode === "required") {
|
|
29
34
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Fade, {
|
|
30
35
|
in: true,
|
|
@@ -74,7 +79,11 @@ function AddressForm({
|
|
|
74
79
|
}), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
|
|
75
80
|
name: "billing_address.postal_code",
|
|
76
81
|
rules: {
|
|
77
|
-
required: t("payment.checkout.required")
|
|
82
|
+
required: t("payment.checkout.required"),
|
|
83
|
+
validate: x => {
|
|
84
|
+
const isValid = (0, _validator.validatePostalCode)(x, country);
|
|
85
|
+
return isValid ? true : t("payment.checkout.invalid");
|
|
86
|
+
}
|
|
78
87
|
},
|
|
79
88
|
errorPosition: "right",
|
|
80
89
|
variant: "outlined",
|
|
@@ -126,7 +135,11 @@ function AddressForm({
|
|
|
126
135
|
children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
|
|
127
136
|
name: "billing_address.postal_code",
|
|
128
137
|
rules: {
|
|
129
|
-
required: t("payment.checkout.required")
|
|
138
|
+
required: t("payment.checkout.required"),
|
|
139
|
+
validate: x => {
|
|
140
|
+
const isValid = (0, _validator.validatePostalCode)(x, country);
|
|
141
|
+
return isValid ? true : t("payment.checkout.invalid");
|
|
142
|
+
}
|
|
130
143
|
},
|
|
131
144
|
errorPosition: "right",
|
|
132
145
|
variant: "outlined",
|
|
@@ -31,6 +31,7 @@ var _mobile = require("../../hooks/mobile");
|
|
|
31
31
|
var _phoneValidator = require("../../libs/phone-validator");
|
|
32
32
|
var _loadingButton = _interopRequireDefault(require("../../components/loading-button"));
|
|
33
33
|
var _overDueInvoicePayment = _interopRequireDefault(require("../../components/over-due-invoice-payment"));
|
|
34
|
+
var _currency2 = require("../../libs/currency");
|
|
34
35
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
36
|
const waitForCheckoutComplete = async sessionId => {
|
|
36
37
|
let result;
|
|
@@ -155,6 +156,13 @@ function PaymentForm({
|
|
|
155
156
|
const index = currencies.findIndex(x => x.id === queryCurrencyId);
|
|
156
157
|
return index >= 0 ? index : 0;
|
|
157
158
|
});
|
|
159
|
+
const handleCurrencyChange = index => {
|
|
160
|
+
setPaymentCurrencyIndex(index);
|
|
161
|
+
const selectedCurrencyId = currencies[index]?.id;
|
|
162
|
+
if (selectedCurrencyId) {
|
|
163
|
+
(0, _currency2.saveCurrencyPreference)(selectedCurrencyId, session?.user?.did);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
158
166
|
const onCheckoutComplete = (0, _ahooks.useMemoizedFn)(async ({
|
|
159
167
|
response
|
|
160
168
|
}) => {
|
|
@@ -277,6 +285,9 @@ function PaymentForm({
|
|
|
277
285
|
const showForm = !!session?.user;
|
|
278
286
|
const skipBindWallet = method.type === "stripe";
|
|
279
287
|
const handleConnected = async () => {
|
|
288
|
+
setState({
|
|
289
|
+
paying: true
|
|
290
|
+
});
|
|
280
291
|
try {
|
|
281
292
|
const result = await waitForCheckoutComplete(checkoutSession.id);
|
|
282
293
|
if (state.paid === false) {
|
|
@@ -561,7 +572,7 @@ function PaymentForm({
|
|
|
561
572
|
render: () => /* @__PURE__ */(0, _jsxRuntime.jsx)(_currency.default, {
|
|
562
573
|
value: paymentCurrencyIndex,
|
|
563
574
|
currencies,
|
|
564
|
-
onChange:
|
|
575
|
+
onChange: handleCurrencyChange
|
|
565
576
|
})
|
|
566
577
|
})
|
|
567
578
|
}), state.stripePaying && state.stripeContext && /* @__PURE__ */(0, _jsxRuntime.jsx)(_stripe.default, {
|