@blocklet/payment-react 1.18.34 → 1.18.36

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 (42) hide show
  1. package/es/components/country-select.d.ts +1 -0
  2. package/es/components/country-select.js +359 -276
  3. package/es/contexts/payment.js +21 -1
  4. package/es/libs/cached-request.d.ts +1 -1
  5. package/es/libs/util.d.ts +1 -0
  6. package/es/libs/util.js +13 -0
  7. package/es/libs/validator.d.ts +1 -0
  8. package/es/libs/validator.js +14 -0
  9. package/es/locales/en.js +2 -1
  10. package/es/locales/zh.js +2 -1
  11. package/es/payment/form/address.d.ts +5 -1
  12. package/es/payment/form/address.js +27 -14
  13. package/es/payment/form/index.js +43 -10
  14. package/es/payment/form/phone.js +2 -1
  15. package/es/payment/form/stripe/form.js +1 -0
  16. package/lib/components/country-select.d.ts +1 -0
  17. package/lib/components/country-select.js +188 -80
  18. package/lib/contexts/payment.js +21 -0
  19. package/lib/libs/cached-request.d.ts +1 -1
  20. package/lib/libs/util.d.ts +1 -0
  21. package/lib/libs/util.js +16 -1
  22. package/lib/libs/validator.d.ts +1 -0
  23. package/lib/libs/validator.js +14 -0
  24. package/lib/locales/en.js +2 -1
  25. package/lib/locales/zh.js +2 -1
  26. package/lib/payment/form/address.d.ts +5 -1
  27. package/lib/payment/form/address.js +23 -13
  28. package/lib/payment/form/index.js +39 -10
  29. package/lib/payment/form/phone.js +2 -1
  30. package/lib/payment/form/stripe/form.js +1 -0
  31. package/package.json +6 -6
  32. package/src/components/country-select.tsx +381 -290
  33. package/src/contexts/payment.tsx +29 -1
  34. package/src/libs/cached-request.ts +1 -1
  35. package/src/libs/util.ts +15 -0
  36. package/src/libs/validator.ts +14 -0
  37. package/src/locales/en.tsx +1 -0
  38. package/src/locales/zh.tsx +1 -0
  39. package/src/payment/form/address.tsx +26 -11
  40. package/src/payment/form/index.tsx +39 -7
  41. package/src/payment/form/phone.tsx +1 -0
  42. package/src/payment/form/stripe/form.tsx +1 -0
@@ -10,11 +10,20 @@ var _material = require("@mui/material");
10
10
  var _reactHookForm = require("react-hook-form");
11
11
  var _reactInternationalPhone = require("react-international-phone");
12
12
  var _mobile = require("../hooks/mobile");
13
+ const Transition = (0, _react.forwardRef)(function Transition2(props, ref) {
14
+ return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Slide, {
15
+ direction: "up",
16
+ ref,
17
+ timeout: 200,
18
+ ...props
19
+ });
20
+ });
13
21
  const CountrySelect = (0, _react.forwardRef)(({
14
22
  value,
15
23
  onChange,
16
24
  name,
17
- sx
25
+ sx,
26
+ showDialCode = false
18
27
  }, ref) => {
19
28
  const {
20
29
  setValue
@@ -121,10 +130,6 @@ const CountrySelect = (0, _react.forwardRef)(({
121
130
  name: ""
122
131
  };
123
132
  }, [value]);
124
- const onCountryChange = e => {
125
- onChange(e.target.value);
126
- setValue(name, e.target.value);
127
- };
128
133
  const handleCountryClick = code => {
129
134
  onChange(code);
130
135
  setValue(name, code);
@@ -169,79 +174,7 @@ const CountrySelect = (0, _react.forwardRef)(({
169
174
  handleCountryClick(country.iso2);
170
175
  }
171
176
  };
172
- return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Select, {
173
- ref,
174
- open,
175
- onOpen: () => setOpen(true),
176
- onClose: () => setOpen(false),
177
- MenuProps: {
178
- style: {
179
- maxHeight: "300px",
180
- top: "10px"
181
- },
182
- anchorOrigin: {
183
- vertical: "bottom",
184
- horizontal: "left"
185
- },
186
- transformOrigin: {
187
- vertical: "top",
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
- }
201
- }
202
- },
203
- sx: {
204
- width: "100%",
205
- minWidth: "60px",
206
- fieldset: {
207
- display: "none"
208
- },
209
- '&.Mui-focused:has(div[aria-expanded="false"])': {
210
- fieldset: {
211
- display: "block"
212
- }
213
- },
214
- ".MuiSelect-select": {
215
- padding: "8px",
216
- paddingRight: "24px !important"
217
- },
218
- svg: {
219
- right: 0
220
- },
221
- ".MuiMenuItem-root": {
222
- justifyContent: "flex-start"
223
- },
224
- ...sx
225
- },
226
- value,
227
- onChange: onCountryChange,
228
- renderValue: code => /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
229
- display: "flex",
230
- alignItems: "center",
231
- flexWrap: "nowrap",
232
- gap: 0.5,
233
- sx: {
234
- cursor: "pointer"
235
- },
236
- children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactInternationalPhone.FlagEmoji, {
237
- iso2: code,
238
- style: {
239
- display: "flex"
240
- }
241
- }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
242
- children: countryDetail?.name
243
- })]
244
- }),
177
+ const countryListContent = /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
245
178
  children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
246
179
  sx: {
247
180
  position: "sticky",
@@ -271,7 +204,7 @@ const CountrySelect = (0, _react.forwardRef)(({
271
204
  flex: 1,
272
205
  overflowY: "auto",
273
206
  overflowX: "hidden",
274
- maxHeight: "calc(300px - 65px)",
207
+ maxHeight: isMobile ? "calc(60vh - 80px)" : "calc(300px - 65px)",
275
208
  scrollBehavior: "smooth"
276
209
  },
277
210
  children: filteredCountries.length > 0 ? filteredCountries.map((c, index) => {
@@ -282,6 +215,8 @@ const CountrySelect = (0, _react.forwardRef)(({
282
215
  selected: parsed.iso2 === value,
283
216
  onClick: () => handleCountryClick(parsed.iso2),
284
217
  sx: {
218
+ display: "flex",
219
+ alignItems: "center",
285
220
  "&.Mui-selected": {
286
221
  backgroundColor: "rgba(0, 0, 0, 0.04)"
287
222
  },
@@ -300,6 +235,12 @@ const CountrySelect = (0, _react.forwardRef)(({
300
235
  }
301
236
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
302
237
  children: parsed.name
238
+ }), showDialCode && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
239
+ sx: {
240
+ ml: 1
241
+ },
242
+ color: "text.secondary",
243
+ children: `+${parsed.dialCode}`
303
244
  })]
304
245
  }, parsed.iso2);
305
246
  }) : /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.MenuItem, {
@@ -311,8 +252,175 @@ const CountrySelect = (0, _react.forwardRef)(({
311
252
  })
312
253
  })]
313
254
  });
255
+ if (!isMobile) {
256
+ return /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Select, {
257
+ ref,
258
+ open,
259
+ onOpen: () => setOpen(true),
260
+ onClose: () => setOpen(false),
261
+ MenuProps: {
262
+ style: {
263
+ maxHeight: "300px",
264
+ top: "10px"
265
+ },
266
+ anchorOrigin: {
267
+ vertical: "bottom",
268
+ horizontal: "left"
269
+ },
270
+ transformOrigin: {
271
+ vertical: "top",
272
+ horizontal: "left"
273
+ },
274
+ PaperProps: {
275
+ ref: menuRef,
276
+ sx: {
277
+ display: "flex",
278
+ "& .MuiList-root": {
279
+ pt: 0,
280
+ display: "flex",
281
+ flexDirection: "column",
282
+ overflowY: "hidden"
283
+ }
284
+ }
285
+ }
286
+ },
287
+ sx: {
288
+ width: "100%",
289
+ minWidth: "60px",
290
+ fieldset: {
291
+ display: "none"
292
+ },
293
+ '&.Mui-focused:has(div[aria-expanded="false"])': {
294
+ fieldset: {
295
+ display: "block"
296
+ }
297
+ },
298
+ ".MuiSelect-select": {
299
+ padding: "8px",
300
+ paddingRight: "24px !important"
301
+ },
302
+ svg: {
303
+ right: 0
304
+ },
305
+ ".MuiMenuItem-root": {
306
+ justifyContent: "flex-start"
307
+ },
308
+ ...sx
309
+ },
310
+ value,
311
+ onChange: e => {
312
+ onChange(e.target.value);
313
+ setValue(name, e.target.value);
314
+ },
315
+ renderValue: code => /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
316
+ display: "flex",
317
+ alignItems: "center",
318
+ flexWrap: "nowrap",
319
+ gap: 0.5,
320
+ sx: {
321
+ cursor: "pointer"
322
+ },
323
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactInternationalPhone.FlagEmoji, {
324
+ iso2: code,
325
+ style: {
326
+ display: "flex"
327
+ }
328
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
329
+ children: countryDetail?.name
330
+ })]
331
+ }),
332
+ children: countryListContent
333
+ });
334
+ }
335
+ return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
336
+ ref,
337
+ sx: {
338
+ ...sx
339
+ },
340
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
341
+ onClick: () => setOpen(true),
342
+ display: "flex",
343
+ alignItems: "center",
344
+ flexWrap: "nowrap",
345
+ gap: 0.5,
346
+ sx: {
347
+ cursor: "pointer",
348
+ padding: "8px",
349
+ paddingRight: "24px",
350
+ position: "relative",
351
+ border: "none",
352
+ "-webkit-tap-highlight-color": "transparent",
353
+ userSelect: "none",
354
+ background: "none",
355
+ "&:hover, &:focus, &:active": {
356
+ backgroundColor: "transparent",
357
+ outline: "none"
358
+ },
359
+ touchAction: "manipulation"
360
+ },
361
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_reactInternationalPhone.FlagEmoji, {
362
+ iso2: value,
363
+ style: {
364
+ display: "flex"
365
+ }
366
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
367
+ children: countryDetail?.name
368
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {
369
+ sx: {
370
+ position: "absolute",
371
+ right: "8px",
372
+ width: 0,
373
+ height: 0,
374
+ borderLeft: "5px solid transparent",
375
+ borderRight: "5px solid transparent",
376
+ borderTop: "5px solid currentColor"
377
+ }
378
+ })]
379
+ }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Dialog, {
380
+ open,
381
+ onClose: () => setOpen(false),
382
+ fullWidth: true,
383
+ maxWidth: "xs",
384
+ TransitionComponent: Transition,
385
+ PaperProps: {
386
+ sx: {
387
+ position: "absolute",
388
+ bottom: 0,
389
+ m: 0,
390
+ borderBottomLeftRadius: 0,
391
+ borderBottomRightRadius: 0,
392
+ width: "100%"
393
+ }
394
+ },
395
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
396
+ sx: {
397
+ p: 2,
398
+ display: "flex",
399
+ justifyContent: "space-between",
400
+ alignItems: "center"
401
+ },
402
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
403
+ variant: "h6",
404
+ children: "Select Country"
405
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.IconButton, {
406
+ edge: "end",
407
+ onClick: () => setOpen(false),
408
+ sx: {
409
+ "-webkit-tap-highlight-color": "transparent"
410
+ },
411
+ children: "\u2715"
412
+ })]
413
+ }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.DialogContent, {
414
+ sx: {
415
+ p: 0
416
+ },
417
+ children: countryListContent
418
+ })]
419
+ })]
420
+ });
314
421
  });
315
422
  CountrySelect.defaultProps = {
316
- sx: {}
423
+ sx: {},
424
+ showDialCode: false
317
425
  };
318
426
  module.exports = CountrySelect;
@@ -53,6 +53,20 @@ const getCurrency = (currencyId, methods) => {
53
53
  const getMethod = (methodId, methods) => {
54
54
  return methods.find(x => x.id === methodId);
55
55
  };
56
+ const syncToSpaceRequest = (userDid, spaceDid) => {
57
+ const cacheKey = `sync-space-${userDid}-${spaceDid}`;
58
+ const cachedRequest = new _cachedRequest.CachedRequest(cacheKey, () => _api.default.post("/api/customers/sync-to-space"), {
59
+ ttl: 1e3 * 60 * 60
60
+ // 1 hour
61
+ });
62
+
63
+ return cachedRequest.fetch(false).then(res => {
64
+ if (!res.success) {
65
+ cachedRequest.clearCache();
66
+ }
67
+ return res;
68
+ });
69
+ };
56
70
  function PaymentProvider({
57
71
  session,
58
72
  connect,
@@ -84,6 +98,13 @@ function PaymentProvider({
84
98
  } = (0, _ahooks.useRequest)(getSettings, {
85
99
  refreshDeps: [livemode]
86
100
  });
101
+ (0, _react.useEffect)(() => {
102
+ const didSpace = session?.user?.didSpace;
103
+ const userDid = session?.user?.did;
104
+ if (userDid && didSpace && didSpace.endpoint && didSpace.did) {
105
+ syncToSpaceRequest(userDid, didSpace.did);
106
+ }
107
+ }, [session?.user]);
87
108
  const prefix = (0, _util.getPrefix)();
88
109
  const [payable, setPayable] = (0, _react.useState)(true);
89
110
  if (error) {
@@ -11,7 +11,7 @@ export declare class CachedRequest {
11
11
  private getCache;
12
12
  private getCachedData;
13
13
  private setCachedData;
14
- private clearCache;
14
+ clearCache(): void;
15
15
  fetch(forceRefresh?: boolean): Promise<any>;
16
16
  }
17
17
  export {};
@@ -120,3 +120,4 @@ export declare function parseMarkedText(text: string): Array<{
120
120
  type: 'text' | 'marked';
121
121
  content: string;
122
122
  }>;
123
+ export declare function getTokenBalanceLink(method: TPaymentMethod, address: string): string;
package/lib/libs/util.js CHANGED
@@ -44,7 +44,9 @@ exports.getRefundStatusColor = getRefundStatusColor;
44
44
  exports.getStatementDescriptor = getStatementDescriptor;
45
45
  exports.getSubscriptionAction = void 0;
46
46
  exports.getSubscriptionStatusColor = getSubscriptionStatusColor;
47
- exports.getTxLink = exports.getSubscriptionTimeSummary = void 0;
47
+ exports.getSubscriptionTimeSummary = void 0;
48
+ exports.getTokenBalanceLink = getTokenBalanceLink;
49
+ exports.getTxLink = void 0;
48
50
  exports.getUserProfileLink = getUserProfileLink;
49
51
  exports.getWebhookStatusColor = getWebhookStatusColor;
50
52
  exports.getWordBreakStyle = getWordBreakStyle;
@@ -1169,4 +1171,17 @@ function parseMarkedText(text) {
1169
1171
  }
1170
1172
  }
1171
1173
  return result.filter(p => p.content !== "");
1174
+ }
1175
+ function getTokenBalanceLink(method, address) {
1176
+ if (!method || !address) {
1177
+ return "";
1178
+ }
1179
+ const explorerHost = method?.settings?.[method?.type]?.explorer_host || "";
1180
+ if (method.type === "arcblock" && address) {
1181
+ return (0, _ufo.joinURL)(explorerHost, "accounts", address, "tokens");
1182
+ }
1183
+ if (["ethereum", "base"].includes(method.type) && address) {
1184
+ return (0, _ufo.joinURL)(explorerHost, "address", address);
1185
+ }
1186
+ return "";
1172
1187
  }
@@ -1 +1,2 @@
1
1
  export declare function validatePostalCode(postalCode: string, country?: string): boolean;
2
+ export declare function getFieldValidation(fieldName: string, validations?: Record<string, any>, locale?: string): Record<string, any>;
@@ -3,8 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.getFieldValidation = getFieldValidation;
6
7
  exports.validatePostalCode = validatePostalCode;
7
8
  var _isPostalCode = _interopRequireDefault(require("validator/lib/isPostalCode"));
9
+ var _locales = require("../locales");
8
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
11
  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
12
  function validatePostalCode(postalCode, country) {
@@ -17,4 +19,16 @@ function validatePostalCode(postalCode, country) {
17
19
  console.error(error);
18
20
  return false;
19
21
  }
22
+ }
23
+ function getFieldValidation(fieldName, validations, locale = "en") {
24
+ if (!validations || !validations[fieldName]) return {};
25
+ const fieldValidation = validations[fieldName];
26
+ const rules = {};
27
+ if (fieldValidation.pattern) {
28
+ rules.pattern = {
29
+ value: new RegExp(fieldValidation.pattern),
30
+ message: fieldValidation.pattern_message?.[locale] || (0, _locales.t)("payment.checkout.invalid", locale)
31
+ };
32
+ }
33
+ return rules;
20
34
  }
package/lib/locales/en.js CHANGED
@@ -239,7 +239,8 @@ module.exports = (0, _flat.default)({
239
239
  confirmPrompt: "Please confirm the details before proceeding.",
240
240
  payer: "Account",
241
241
  amount: "Amount",
242
- failed: "Account changed, please pay manually."
242
+ failed: "Account changed, please pay manually.",
243
+ balanceLink: "View Balance"
243
244
  }
244
245
  },
245
246
  customer: {
package/lib/locales/zh.js CHANGED
@@ -239,7 +239,8 @@ module.exports = (0, _flat.default)({
239
239
  confirmPrompt: "\u8BF7\u786E\u8BA4\u652F\u4ED8\u4FE1\u606F\u65E0\u8BEF\u540E\u7EE7\u7EED\u3002",
240
240
  payer: "\u8D26\u6237\u5730\u5740",
241
241
  amount: "\u652F\u4ED8\u91D1\u989D",
242
- failed: "\u8D26\u6237\u53D1\u751F\u53D8\u5316\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5B8C\u6210\u652F\u4ED8\uFF0C\u8BF7\u624B\u52A8\u652F\u4ED8\u3002"
242
+ failed: "\u8D26\u6237\u53D1\u751F\u53D8\u5316\uFF0C\u65E0\u6CD5\u81EA\u52A8\u5B8C\u6210\u652F\u4ED8\uFF0C\u8BF7\u624B\u52A8\u652F\u4ED8\u3002",
243
+ balanceLink: "\u67E5\u770B\u4F59\u989D"
243
244
  }
244
245
  },
245
246
  customer: {
@@ -3,11 +3,15 @@ type Props = {
3
3
  mode: string;
4
4
  stripe: boolean;
5
5
  sx?: SxProps;
6
+ fieldValidation?: Record<string, any>;
7
+ errorPosition?: 'right' | 'bottom';
6
8
  };
7
- declare function AddressForm({ mode, stripe, sx }: Props): import("react").JSX.Element | null;
9
+ declare function AddressForm({ mode, stripe, sx, fieldValidation, errorPosition }: Props): import("react").JSX.Element | null;
8
10
  declare namespace AddressForm {
9
11
  var defaultProps: {
10
12
  sx: {};
13
+ fieldValidation: {};
14
+ errorPosition: string;
11
15
  };
12
16
  }
13
17
  export default AddressForm;
@@ -13,15 +13,20 @@ var _countrySelect = _interopRequireDefault(require("../../components/country-se
13
13
  var _validator = require("../../libs/validator");
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
  AddressForm.defaultProps = {
16
- sx: {}
16
+ sx: {},
17
+ fieldValidation: {},
18
+ errorPosition: "right"
17
19
  };
18
20
  function AddressForm({
19
21
  mode,
20
22
  stripe,
21
- sx = {}
23
+ sx = {},
24
+ fieldValidation,
25
+ errorPosition
22
26
  }) {
23
27
  const {
24
- t
28
+ t,
29
+ locale
25
30
  } = (0, _context.useLocaleContext)();
26
31
  const {
27
32
  control
@@ -46,9 +51,10 @@ function AddressForm({
46
51
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
47
52
  name: "billing_address.line1",
48
53
  rules: {
49
- required: t("payment.checkout.required")
54
+ required: t("payment.checkout.required"),
55
+ ...(0, _validator.getFieldValidation)("billing_address.line1", fieldValidation, locale)
50
56
  },
51
- errorPosition: "right",
57
+ errorPosition,
52
58
  variant: "outlined",
53
59
  placeholder: t("payment.checkout.billing.line1")
54
60
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.FormLabel, {
@@ -57,9 +63,10 @@ function AddressForm({
57
63
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
58
64
  name: "billing_address.city",
59
65
  rules: {
60
- required: t("payment.checkout.required")
66
+ required: t("payment.checkout.required"),
67
+ ...(0, _validator.getFieldValidation)("billing_address.city", fieldValidation, locale)
61
68
  },
62
- errorPosition: "right",
69
+ errorPosition,
63
70
  variant: "outlined",
64
71
  placeholder: t("payment.checkout.billing.city")
65
72
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.FormLabel, {
@@ -68,9 +75,10 @@ function AddressForm({
68
75
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
69
76
  name: "billing_address.state",
70
77
  rules: {
71
- required: t("payment.checkout.required")
78
+ required: t("payment.checkout.required"),
79
+ ...(0, _validator.getFieldValidation)("billing_address.state", fieldValidation, locale)
72
80
  },
73
- errorPosition: "right",
81
+ errorPosition,
74
82
  variant: "outlined",
75
83
  placeholder: t("payment.checkout.billing.state")
76
84
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.FormLabel, {
@@ -83,9 +91,10 @@ function AddressForm({
83
91
  validate: x => {
84
92
  const isValid = (0, _validator.validatePostalCode)(x, country);
85
93
  return isValid ? true : t("payment.checkout.invalid");
86
- }
94
+ },
95
+ ...(0, _validator.getFieldValidation)("billing_address.postal_code", fieldValidation, locale)
87
96
  },
88
- errorPosition: "right",
97
+ errorPosition,
89
98
  variant: "outlined",
90
99
  placeholder: t("payment.checkout.billing.postal_code"),
91
100
  InputProps: {
@@ -139,9 +148,10 @@ function AddressForm({
139
148
  validate: x => {
140
149
  const isValid = (0, _validator.validatePostalCode)(x, country);
141
150
  return isValid ? true : t("payment.checkout.invalid");
142
- }
151
+ },
152
+ ...(0, _validator.getFieldValidation)("billing_address.postal_code", fieldValidation, locale)
143
153
  },
144
- errorPosition: "right",
154
+ errorPosition,
145
155
  variant: "outlined",
146
156
  placeholder: t("payment.checkout.billing.postal_code"),
147
157
  wrapperStyle: {
@@ -36,6 +36,7 @@ var _loadingButton = _interopRequireDefault(require("../../components/loading-bu
36
36
  var _overDueInvoicePayment = _interopRequireDefault(require("../../components/over-due-invoice-payment"));
37
37
  var _currency2 = require("../../libs/currency");
38
38
  var _confirm = _interopRequireDefault(require("../../components/confirm"));
39
+ var _validator = require("../../libs/validator");
39
40
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
40
41
  const waitForCheckoutComplete = async sessionId => {
41
42
  let result;
@@ -123,6 +124,7 @@ function PaymentForm({
123
124
  payable
124
125
  } = (0, _payment.usePaymentContext)();
125
126
  const subscription = (0, _subscription.useSubscription)("events");
127
+ const formErrorPosition = "bottom";
126
128
  const {
127
129
  control,
128
130
  getValues,
@@ -535,6 +537,7 @@ function PaymentForm({
535
537
  window.removeEventListener("keydown", handleKeyDown);
536
538
  };
537
539
  }, [state.submitting, state.paying, state.stripePaying, quantityInventoryStatus, payable]);
540
+ const balanceLink = (0, _util2.getTokenBalanceLink)(method, state.fastCheckoutInfo?.payer || "");
538
541
  const FastCheckoutConfirmDialog = state.fastCheckoutInfo && /* @__PURE__ */(0, _jsxRuntime.jsx)(_confirm.default, {
539
542
  onConfirm: handleFastCheckoutConfirm,
540
543
  onCancel: handleFastCheckoutCancel,
@@ -561,12 +564,33 @@ function PaymentForm({
561
564
  whiteSpace: "nowrap"
562
565
  },
563
566
  children: t("payment.checkout.fastPay.payer")
564
- }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, {
565
- children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_DID.default, {
567
+ }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, {
568
+ sx: {
569
+ display: "flex",
570
+ alignItems: "center",
571
+ gap: 0.5
572
+ },
573
+ children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_DID.default, {
566
574
  did: state.fastCheckoutInfo.payer || "",
567
575
  compact: true,
568
576
  responsive: false
569
- })
577
+ }), balanceLink && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Tooltip, {
578
+ title: t("payment.checkout.fastPay.balanceLink"),
579
+ placement: "top",
580
+ children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_iconsMaterial.OpenInNew, {
581
+ sx: {
582
+ color: "text.lighter",
583
+ fontSize: "0.85rem",
584
+ cursor: "pointer",
585
+ "&:hover": {
586
+ color: "text.primary"
587
+ }
588
+ },
589
+ onClick: () => {
590
+ window.open(balanceLink, "_blank");
591
+ }
592
+ })
593
+ })]
570
594
  })]
571
595
  }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
572
596
  flexDirection: "row",
@@ -709,9 +733,10 @@ function PaymentForm({
709
733
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
710
734
  name: "customer_name",
711
735
  variant: "outlined",
712
- errorPosition: "right",
736
+ errorPosition: formErrorPosition,
713
737
  rules: {
714
- required: t("payment.checkout.required")
738
+ required: t("payment.checkout.required"),
739
+ ...(0, _validator.getFieldValidation)("customer_name", checkoutSession.metadata?.page_info?.field_validation, locale)
715
740
  }
716
741
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.FormLabel, {
717
742
  className: "base-label",
@@ -719,10 +744,11 @@ function PaymentForm({
719
744
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_input.default, {
720
745
  name: "customer_email",
721
746
  variant: "outlined",
722
- errorPosition: "right",
747
+ errorPosition: formErrorPosition,
723
748
  rules: {
724
749
  required: t("payment.checkout.required"),
725
- validate: x => (0, _isEmail.default)(x) ? true : t("payment.checkout.invalid")
750
+ validate: x => (0, _isEmail.default)(x) ? true : t("payment.checkout.invalid"),
751
+ ...(0, _validator.getFieldValidation)("customer_email", checkoutSession.metadata?.page_info?.field_validation, locale)
726
752
  }
727
753
  }), checkoutSession.phone_number_collection?.enabled && /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
728
754
  children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.FormLabel, {
@@ -731,14 +757,15 @@ function PaymentForm({
731
757
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_phone.default, {
732
758
  name: "customer_phone",
733
759
  variant: "outlined",
734
- errorPosition: "right",
760
+ errorPosition: formErrorPosition,
735
761
  placeholder: "Phone number",
736
762
  rules: {
737
763
  required: t("payment.checkout.required"),
738
764
  validate: async x => {
739
765
  const isValid = await (0, _phoneValidator.validatePhoneNumber)(x);
740
766
  return isValid ? true : t("payment.checkout.invalid");
741
- }
767
+ },
768
+ ...(0, _validator.getFieldValidation)("customer_phone", checkoutSession.metadata?.page_info?.field_validation, locale)
742
769
  }
743
770
  })]
744
771
  }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_address.default, {
@@ -746,7 +773,9 @@ function PaymentForm({
746
773
  stripe: method?.type === "stripe",
747
774
  sx: {
748
775
  marginTop: "0 !important"
749
- }
776
+ },
777
+ fieldValidation: checkoutSession.metadata?.page_info?.field_validation,
778
+ errorPosition: formErrorPosition
750
779
  })]
751
780
  })]
752
781
  })
@@ -103,7 +103,8 @@ function PhoneInput({
103
103
  "&.Mui-focused .MuiOutlinedInput-notchedOutline": {
104
104
  borderColor: "transparent"
105
105
  }
106
- }
106
+ },
107
+ showDialCode: true
107
108
  })
108
109
  })
109
110
  },