@blocklet/payment-react 1.18.19 → 1.18.21

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.
@@ -18,7 +18,6 @@ var _ufo = require("ufo");
18
18
  var _useBus = require("use-bus");
19
19
  var _isEmail = _interopRequireDefault(require("validator/es/lib/isEmail"));
20
20
  var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
21
- var _confirm = _interopRequireDefault(require("../../components/confirm"));
22
21
  var _input = _interopRequireDefault(require("../../components/input"));
23
22
  var _payment = require("../../contexts/payment");
24
23
  var _subscription = require("../../hooks/subscription");
@@ -31,6 +30,7 @@ var _stripe = _interopRequireDefault(require("./stripe"));
31
30
  var _mobile = require("../../hooks/mobile");
32
31
  var _phoneValidator = require("../../libs/phone-validator");
33
32
  var _loadingButton = _interopRequireDefault(require("../../components/loading-button"));
33
+ var _overDueInvoicePayment = _interopRequireDefault(require("../../components/over-due-invoice-payment"));
34
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
35
35
  const waitForCheckoutComplete = async sessionId => {
36
36
  let result;
@@ -58,6 +58,36 @@ const hasDidWallet = user => {
58
58
  return connected.some(x => x.provider === "wallet");
59
59
  };
60
60
  exports.hasDidWallet = hasDidWallet;
61
+ const setUserFormValues = (userInfo, currentValues, setValue, options = {}) => {
62
+ const {
63
+ preferExisting = true
64
+ } = options;
65
+ const basicFields = {
66
+ customer_name: userInfo.name || userInfo.fullName,
67
+ customer_email: userInfo.email,
68
+ customer_phone: (0, _phoneValidator.formatPhone)(userInfo.phone)
69
+ };
70
+ const addressFields = {
71
+ "billing_address.state": userInfo.address?.state || userInfo.address?.province,
72
+ "billing_address.line1": userInfo.address?.line1,
73
+ "billing_address.line2": userInfo.address?.line2,
74
+ "billing_address.city": userInfo.address?.city,
75
+ "billing_address.postal_code": userInfo.address?.postal_code || userInfo.address?.postalCode,
76
+ "billing_address.country": userInfo.address?.country
77
+ };
78
+ if (options.showPhone) {
79
+ addressFields["billing_address.country"] = userInfo.metadata?.phone?.country || userInfo.address?.country;
80
+ }
81
+ const allFields = {
82
+ ...addressFields,
83
+ ...basicFields
84
+ };
85
+ Object.entries(allFields).forEach(([field, value]) => {
86
+ if (!preferExisting || !currentValues[field.split(".")[0]]) {
87
+ setValue(field, value);
88
+ }
89
+ });
90
+ };
61
91
  PaymentForm.defaultProps = {
62
92
  onlyShowBtn: false,
63
93
  isDonation: false
@@ -148,22 +178,28 @@ function PaymentForm({
148
178
  (0, _react.useEffect)(() => {
149
179
  if (session?.user) {
150
180
  const values = getValues();
151
- if (!values.customer_name) {
152
- setValue("customer_name", session.user.fullName);
153
- }
154
- if (!values.customer_email) {
155
- setValue("customer_email", session.user.email);
156
- }
157
- if (!values.customer_phone) {
158
- setValue("customer_phone", session.user.phone);
159
- }
160
- }
161
- if (!session?.user) {
162
- setValue("customer_name", "");
163
- setValue("customer_email", "");
164
- setValue("customer_phone", "");
181
+ setUserFormValues(session.user, values, setValue, {
182
+ preferExisting: false,
183
+ showPhone: checkoutSession.phone_number_collection?.enabled
184
+ });
185
+ } else {
186
+ setUserFormValues({
187
+ name: "",
188
+ email: "",
189
+ phone: "",
190
+ address: {
191
+ state: "",
192
+ line1: "",
193
+ line2: "",
194
+ city: "",
195
+ postal_code: ""
196
+ }
197
+ }, {}, setValue, {
198
+ preferExisting: false,
199
+ showPhone: checkoutSession.phone_number_collection?.enabled
200
+ });
165
201
  }
166
- }, [session?.user, getValues, setValue]);
202
+ }, [session?.user, getValues, setValue, checkoutSession.phone_number_collection?.enabled]);
167
203
  (0, _react.useEffect)(() => {
168
204
  setValue("payment_method", currencies[paymentCurrencyIndex]?.method?.id);
169
205
  setValue("payment_currency", currencies[paymentCurrencyIndex]?.id);
@@ -199,7 +235,7 @@ function PaymentForm({
199
235
  });
200
236
  const method = paymentMethods.find(x => x.id === paymentMethod);
201
237
  const isDonationMode = checkoutSession?.submit_type === "donate" && isDonation;
202
- const showForm = session?.user;
238
+ const showForm = !!session?.user;
203
239
  const skipBindWallet = method.type === "stripe";
204
240
  const handleConnected = async () => {
205
241
  try {
@@ -232,33 +268,9 @@ function PaymentForm({
232
268
  } = await _api.default.get("/api/customers/me?fallback=1");
233
269
  if (profile) {
234
270
  const values = getValues();
235
- if (!values.customer_name) {
236
- setValue("customer_name", profile.name);
237
- }
238
- if (!values.customer_email) {
239
- setValue("customer_email", profile.email);
240
- }
241
- if (!values.customer_phone) {
242
- setValue("customer_phone", profile.phone);
243
- }
244
- if (profile.address?.country) {
245
- setValue("billing_address.country", profile.address.country);
246
- }
247
- if (profile.address?.state) {
248
- setValue("billing_address.state", profile.address.state);
249
- }
250
- if (profile.address?.line1) {
251
- setValue("billing_address.line1", profile.address.line1);
252
- }
253
- if (profile.address?.line2) {
254
- setValue("billing_address.line2", profile.address.line2);
255
- }
256
- if (profile.address?.city) {
257
- setValue("billing_address.city", profile.address.city);
258
- }
259
- if (profile.address?.postal_code) {
260
- setValue("billing_address.postal_code", profile.address.postal_code);
261
- }
271
+ setUserFormValues(profile, values, setValue, {
272
+ showPhone: checkoutSession.phone_number_collection?.enabled
273
+ });
262
274
  }
263
275
  };
264
276
  const onFormSubmit = async data => {
@@ -445,15 +457,31 @@ function PaymentForm({
445
457
  }
446
458
  }), state.submitting || state.paying ? t("payment.checkout.processing") : buttonText]
447
459
  })
448
- }), state.customerLimited && /* @__PURE__ */(0, _jsxRuntime.jsx)(_confirm.default, {
449
- onConfirm: () => window.open((0, _ufo.joinURL)((0, _util.getPrefix)(), `/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`), "_self"),
450
- onCancel: () => setState({
451
- customerLimited: false
452
- }),
453
- confirm: t("payment.customer.pastDue.alert.confirm"),
454
- title: t("payment.customer.pastDue.alert.title"),
455
- message: t("payment.customer.pastDue.alert.description"),
456
- color: "primary"
460
+ }), state.customerLimited && /* @__PURE__ */(0, _jsxRuntime.jsx)(_overDueInvoicePayment.default, {
461
+ customerId: customer?.id || session?.user?.did,
462
+ onPaid: () => {
463
+ setState({
464
+ customerLimited: false
465
+ });
466
+ onAction();
467
+ },
468
+ alertMessage: t("payment.customer.pastDue.alert.customMessage"),
469
+ detailLinkOptions: {
470
+ enabled: true,
471
+ onClick: () => {
472
+ setState({
473
+ customerLimited: false
474
+ });
475
+ window.open((0, _ufo.joinURL)((0, _util.getPrefix)(), `/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`), "_self");
476
+ }
477
+ },
478
+ dialogProps: {
479
+ open: state.customerLimited,
480
+ onClose: () => setState({
481
+ customerLimited: false
482
+ }),
483
+ title: t("payment.customer.pastDue.alert.title")
484
+ }
457
485
  })]
458
486
  });
459
487
  }
@@ -600,15 +628,31 @@ function PaymentForm({
600
628
  })
601
629
  })]
602
630
  })
603
- }), state.customerLimited && /* @__PURE__ */(0, _jsxRuntime.jsx)(_confirm.default, {
604
- onConfirm: () => window.open((0, _ufo.joinURL)((0, _util.getPrefix)(), `/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`), "_self"),
605
- onCancel: () => setState({
606
- customerLimited: false
607
- }),
608
- confirm: t("payment.customer.pastDue.alert.confirm"),
609
- title: t("payment.customer.pastDue.alert.title"),
610
- message: t("payment.customer.pastDue.alert.description"),
611
- color: "primary"
631
+ }), state.customerLimited && /* @__PURE__ */(0, _jsxRuntime.jsx)(_overDueInvoicePayment.default, {
632
+ customerId: customer?.id || session?.user?.didssion?.user?.did,
633
+ onPaid: () => {
634
+ setState({
635
+ customerLimited: false
636
+ });
637
+ onAction();
638
+ },
639
+ alertMessage: t("payment.customer.pastDue.alert.customMessage"),
640
+ detailLinkOptions: {
641
+ enabled: true,
642
+ onClick: () => {
643
+ setState({
644
+ customerLimited: false
645
+ });
646
+ window.open((0, _ufo.joinURL)((0, _util.getPrefix)(), `/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`), "_self");
647
+ }
648
+ },
649
+ dialogProps: {
650
+ open: state.customerLimited,
651
+ onClose: () => setState({
652
+ customerLimited: false
653
+ }),
654
+ title: t("payment.customer.pastDue.alert.title")
655
+ }
612
656
  })]
613
657
  });
614
658
  }
@@ -24,6 +24,18 @@ function PhoneInput({
24
24
  setValue
25
25
  } = (0, _reactHookForm.useFormContext)();
26
26
  const values = getValues();
27
+ const isUpdatingRef = (0, _react.useRef)(false);
28
+ const safeUpdate = (0, _react.useCallback)(callback => {
29
+ if (isUpdatingRef.current) return;
30
+ try {
31
+ isUpdatingRef.current = true;
32
+ callback();
33
+ } finally {
34
+ requestAnimationFrame(() => {
35
+ isUpdatingRef.current = false;
36
+ });
37
+ }
38
+ }, []);
27
39
  const {
28
40
  phone,
29
41
  handlePhoneValueChange,
@@ -35,8 +47,10 @@ function PhoneInput({
35
47
  value: values[props.name] || "",
36
48
  countries: _reactInternationalPhone.defaultCountries,
37
49
  onChange: data => {
38
- setValue(props.name, data.phone);
39
- setValue(countryFieldName, data.country);
50
+ safeUpdate(() => {
51
+ setValue(props.name, data.phone);
52
+ setValue(countryFieldName, data.country);
53
+ });
40
54
  }
41
55
  });
42
56
  const userCountry = (0, _reactHookForm.useWatch)({
@@ -44,14 +58,16 @@ function PhoneInput({
44
58
  name: countryFieldName
45
59
  });
46
60
  (0, _react.useEffect)(() => {
47
- if (userCountry !== country) {
61
+ if (!userCountry || userCountry === country) return;
62
+ safeUpdate(() => {
48
63
  setCountry(userCountry);
49
- }
50
- }, [userCountry]);
51
- const onCountryChange = v => {
52
- setCountry(v);
53
- setValue(countryFieldName, v);
54
- };
64
+ });
65
+ }, [userCountry, country, setCountry, safeUpdate]);
66
+ const onCountryChange = (0, _react.useCallback)(v => {
67
+ safeUpdate(() => {
68
+ setCountry(v);
69
+ });
70
+ }, [setCountry, safeUpdate]);
55
71
  return (
56
72
  // @ts-ignore
57
73
  /* @__PURE__ */
@@ -28,6 +28,7 @@ var _payment2 = _interopRequireDefault(require("./skeleton/payment"));
28
28
  var _success = _interopRequireDefault(require("./success"));
29
29
  var _summary = _interopRequireDefault(require("./summary"));
30
30
  var _mobile = require("../hooks/mobile");
31
+ var _phoneValidator = require("../libs/phone-validator");
31
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
32
33
  PaymentInner.defaultProps = {
33
34
  completed: false,
@@ -68,18 +69,18 @@ function PaymentInner({
68
69
  defaultValues: {
69
70
  customer_name: customer?.name || session?.user?.fullName || "",
70
71
  customer_email: customer?.email || session?.user?.email || "",
71
- customer_phone: customer?.phone || session?.user?.phone || "",
72
+ customer_phone: (0, _phoneValidator.formatPhone)(customer?.phone || session?.user?.phone || ""),
72
73
  payment_method: defaultMethodId,
73
74
  payment_currency: defaultCurrencyId,
74
75
  billing_address: Object.assign({
75
- country: "",
76
- state: "",
77
- city: "",
78
- line1: "",
79
- line2: "",
80
- postal_code: ""
76
+ country: session?.user?.address?.country || "",
77
+ state: session?.user?.address?.province || "",
78
+ city: session?.user?.address?.city || "",
79
+ line1: session?.user?.address?.line1 || "",
80
+ line2: session?.user?.address?.line2 || "",
81
+ postal_code: session?.user?.address?.postalCode || ""
81
82
  }, customer?.address || {}, {
82
- country: (0, _util2.isValidCountry)(customer?.address?.country || "") ? customer?.address?.country : "us"
83
+ country: (0, _util2.isValidCountry)(customer?.address?.country || session?.user?.address?.country || "") ? customer?.address?.country : "us"
83
84
  })
84
85
  }
85
86
  });
@@ -47,9 +47,6 @@ function ProductDonation({
47
47
  }
48
48
  };
49
49
  const getDefaultPreset = () => {
50
- if (settings?.amount?.preset) {
51
- return formatAmount(settings.amount.preset);
52
- }
53
50
  try {
54
51
  const savedPreset = localStorage.getItem(getUserStorageKey(DONATION_PRESET_KEY_BASE));
55
52
  if (savedPreset) {
@@ -65,7 +62,13 @@ function ProductDonation({
65
62
  }
66
63
  if (presets.length > 0) {
67
64
  const middleIndex = Math.floor(presets.length / 2);
68
- return presets[middleIndex] || presets[0];
65
+ return presets[middleIndex];
66
+ }
67
+ if (settings?.amount?.preset) {
68
+ return formatAmount(settings.amount.preset);
69
+ }
70
+ if (presets.length > 0) {
71
+ return presets[0];
69
72
  }
70
73
  return "0";
71
74
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/payment-react",
3
- "version": "1.18.19",
3
+ "version": "1.18.21",
4
4
  "description": "Reusable react components for payment kit v2",
5
5
  "keywords": [
6
6
  "react",
@@ -54,10 +54,10 @@
54
54
  }
55
55
  },
56
56
  "dependencies": {
57
- "@arcblock/did-connect": "^2.12.36",
58
- "@arcblock/ux": "^2.12.36",
57
+ "@arcblock/did-connect": "^2.12.43",
58
+ "@arcblock/ux": "^2.12.43",
59
59
  "@arcblock/ws": "^1.19.15",
60
- "@blocklet/ui-react": "^2.12.36",
60
+ "@blocklet/ui-react": "^2.12.43",
61
61
  "@mui/icons-material": "^5.16.6",
62
62
  "@mui/lab": "^5.0.0-alpha.173",
63
63
  "@mui/material": "^5.16.6",
@@ -93,7 +93,7 @@
93
93
  "@babel/core": "^7.25.2",
94
94
  "@babel/preset-env": "^7.25.2",
95
95
  "@babel/preset-react": "^7.24.7",
96
- "@blocklet/payment-types": "1.18.19",
96
+ "@blocklet/payment-types": "1.18.21",
97
97
  "@storybook/addon-essentials": "^7.6.20",
98
98
  "@storybook/addon-interactions": "^7.6.20",
99
99
  "@storybook/addon-links": "^7.6.20",
@@ -124,5 +124,5 @@
124
124
  "vite-plugin-babel": "^1.2.0",
125
125
  "vite-plugin-node-polyfills": "^0.21.0"
126
126
  },
127
- "gitHead": "eabd58598ad349a5177dca2e6302c82117d9b687"
127
+ "gitHead": "cf08902482dded20ee91402ed6d4678383965daf"
128
128
  }
@@ -35,6 +35,7 @@ type Props = {
35
35
  dialogProps?: DialogProps;
36
36
  detailLinkOptions?: DetailLinkOptions;
37
37
  successToast?: boolean;
38
+ alertMessage?: string; // only for customer
38
39
  children?: (
39
40
  handlePay: (item: SummaryItem) => void,
40
41
  data: {
@@ -88,6 +89,7 @@ function OverdueInvoicePayment({
88
89
  onPaid = () => {},
89
90
  detailLinkOptions = { enabled: true },
90
91
  successToast = true,
92
+ alertMessage = '',
91
93
  }: Props) {
92
94
  const { t } = useLocaleContext();
93
95
  const { connect } = usePaymentContext();
@@ -99,7 +101,6 @@ function OverdueInvoicePayment({
99
101
 
100
102
  const sourceType = subscriptionId ? 'subscription' : 'customer';
101
103
  const sourceId = subscriptionId || customerId;
102
-
103
104
  const {
104
105
  data = {
105
106
  summary: {},
@@ -340,19 +341,25 @@ function OverdueInvoicePayment({
340
341
  });
341
342
  }
342
343
  if (customerId) {
344
+ let title = '';
343
345
  if (summaryList.length === 1) {
344
- return t('payment.customer.overdue.title', {
346
+ title = t('payment.customer.overdue.title', {
345
347
  subscriptionCount: data.subscriptionCount || 0,
346
348
  count: data.invoices?.length,
347
349
  total: formatAmount(summaryList[0]?.amount, summaryList[0]?.currency?.decimal),
348
350
  symbol: summaryList[0]?.currency?.symbol,
349
351
  method: getMethodText(summaryList[0]?.method),
350
352
  });
353
+ } else {
354
+ title = t('payment.customer.overdue.simpleTitle', {
355
+ subscriptionCount: data.subscriptionCount || 0,
356
+ count: data.invoices?.length,
357
+ });
351
358
  }
352
- return t('payment.customer.overdue.simpleTitle', {
353
- subscriptionCount: data.subscriptionCount || 0,
354
- count: data.invoices?.length,
355
- });
359
+ if (alertMessage) {
360
+ return `${title}${alertMessage}`;
361
+ }
362
+ return `${title}${t('payment.customer.overdue.defaultAlert')}`;
356
363
  }
357
364
 
358
365
  return '';
@@ -512,6 +519,7 @@ OverdueInvoicePayment.defaultProps = {
512
519
  subscriptionId: undefined,
513
520
  customerId: undefined,
514
521
  successToast: true,
522
+ alertMessage: '',
515
523
  };
516
524
 
517
525
  export default OverdueInvoicePayment;
@@ -2,7 +2,11 @@ let phoneUtil: any = null;
2
2
 
3
3
  export const getPhoneUtil = async () => {
4
4
  if (!phoneUtil) {
5
- const { PhoneNumberUtil } = await import(/* webpackChunkName: "phone-util" */ 'google-libphonenumber');
5
+ const result = await import(/* webpackChunkName: "phone-util" */ 'google-libphonenumber');
6
+ const PhoneNumberUtil = (result.default || result)?.PhoneNumberUtil;
7
+ if (!PhoneNumberUtil) {
8
+ throw new Error('PhoneNumberUtil not found');
9
+ }
6
10
  phoneUtil = PhoneNumberUtil.getInstance();
7
11
  }
8
12
  return phoneUtil;
@@ -10,7 +14,14 @@ export const getPhoneUtil = async () => {
10
14
 
11
15
  export const validatePhoneNumber = async (phoneNumber: string) => {
12
16
  try {
13
- const util = await getPhoneUtil();
17
+ let util: any = null;
18
+ try {
19
+ util = await getPhoneUtil();
20
+ } catch (err) {
21
+ const pattern = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/im;
22
+ return pattern.test(phoneNumber);
23
+ }
24
+
14
25
  const parsed = util.parseAndKeepRawInput(phoneNumber);
15
26
  return util.isValidNumber(parsed);
16
27
  } catch (err) {
@@ -18,3 +29,79 @@ export const validatePhoneNumber = async (phoneNumber: string) => {
18
29
  return false;
19
30
  }
20
31
  };
32
+
33
+ /**
34
+ * Format a phone number to international format
35
+ * @param phoneNumber The original phone number
36
+ * @param defaultCountry Default country code (ISO 3166-1 alpha-2)
37
+ * @returns Formatted phone number
38
+ */
39
+ export const formatPhone = (phoneNumber: string | undefined, defaultCountry = 'US') => {
40
+ if (!phoneNumber || phoneNumber.trim() === '') {
41
+ return '';
42
+ }
43
+
44
+ // Remove all non-digit characters (preserve plus sign)
45
+ const cleanedNumber = phoneNumber.replace(/[^\d+]/g, '');
46
+
47
+ // If already in international format (starting with +), return cleaned number
48
+ if (cleanedNumber.startsWith('+')) {
49
+ return cleanedNumber;
50
+ }
51
+
52
+ // Country code mapping
53
+ const COUNTRY_CODES: Record<string, string> = {
54
+ US: '1', // United States
55
+ CA: '1', // Canada
56
+ CN: '86', // China
57
+ HK: '852', // Hong Kong
58
+ IN: '91', // India
59
+ UK: '44', // United Kingdom
60
+ GB: '44', // United Kingdom
61
+ JP: '81', // Japan
62
+ KR: '82', // South Korea
63
+ AU: '61', // Australia
64
+ DE: '49', // Germany
65
+ FR: '33', // France
66
+ IT: '39', // Italy
67
+ ES: '34', // Spain
68
+ BR: '55', // Brazil
69
+ RU: '7', // Russia
70
+ MX: '52', // Mexico
71
+ SG: '65', // Singapore
72
+ AE: '971', // UAE
73
+ };
74
+
75
+ // Country-specific patterns
76
+ const COUNTRY_PATTERNS: [RegExp, string][] = [
77
+ [/^1[3-9]\d{9}$/, '86'], // China mobile: 11 digits, starts with 1
78
+ [/^\d{10}$/, '1'], // US/Canada: 10 digits
79
+ [/^[6-9]\d{9}$/, '91'], // India: 10 digits, starts with 6-9
80
+ [/^0[1-9]\d{8,9}$/, '81'], // Japan: 10-11 digits, starts with 0
81
+ [/^07\d{9}$/, '44'], // UK mobile: 11 digits, starts with 07
82
+ [/^04\d{8}$/, '61'], // Australia mobile: 10 digits, starts with 04
83
+ [/^01[0-9]\d{7,8}$/, '82'], // Korea mobile: 10-11 digits, starts with 01
84
+ [/^[0-9]\d{8}$/, '86'], // China landline: 9 digits
85
+ ];
86
+
87
+ // Remove leading zero (common in many countries)
88
+ let numberToFormat = cleanedNumber;
89
+ if (numberToFormat.startsWith('0')) {
90
+ numberToFormat = numberToFormat.substring(1);
91
+ }
92
+
93
+ // Try to match with country-specific patterns
94
+ for (const [pattern, countryCode] of COUNTRY_PATTERNS) {
95
+ if (pattern.test(cleanedNumber)) {
96
+ // For numbers starting with 0 that need the zero removed
97
+ if (cleanedNumber.startsWith('0') && !['1', '86'].includes(countryCode)) {
98
+ return `+${countryCode}${cleanedNumber.substring(1)}`;
99
+ }
100
+ return `+${countryCode}${cleanedNumber}`;
101
+ }
102
+ }
103
+
104
+ // If no pattern matched, use default country code
105
+ const countryCode = COUNTRY_CODES[defaultCountry.toUpperCase()] || defaultCountry;
106
+ return `+${countryCode}${numberToFormat}`;
107
+ };
@@ -134,6 +134,7 @@ export default flat({
134
134
  empty: 'No supporters yet',
135
135
  gaveTips: '{count} people gave tips',
136
136
  tipAmount: 'Tip Amount',
137
+ tabHint: 'to switch amount',
137
138
  benefits: {
138
139
  one: '{name} will receive all tips',
139
140
  multiple: 'Tips will be distributed to {count} beneficiaries',
@@ -147,7 +148,7 @@ export default flat({
147
148
  later: 'Configure Later',
148
149
  configTip: 'Configure donation settings in Payment Kit',
149
150
  },
150
- cardPay: '{action} with card',
151
+ cardPay: '{action} with bank card',
151
152
  empty: 'No thing to pay',
152
153
  per: 'per',
153
154
  pay: 'Pay {payee}',
@@ -248,8 +249,7 @@ export default flat({
248
249
  warning: 'Past due invoices need to be paid immediately, otherwise you can not make new purchases anymore.',
249
250
  alert: {
250
251
  title: 'You have unpaid invoices',
251
- description:
252
- 'Seems you have unpaid invoices from previous subscriptions, new purchases are not allowed unless you have paid all past due invoices.',
252
+ customMessage: 'Please pay immediately, otherwise new purchases or subscriptions will be prohibited.',
253
253
  confirm: 'Pay Now',
254
254
  },
255
255
  view: 'View Due Invoices',
@@ -330,9 +330,10 @@ export default flat({
330
330
  },
331
331
  overdue: {
332
332
  title:
333
- 'You have {count} due invoices for {subscriptionCount} subscriptions, totaling {total} {symbol}{method}. Please pay immediately to avoid service disruption.',
334
- simpleTitle: 'You have {count} due invoices. Please pay now to ensure uninterrupted service.',
333
+ 'You have {count} due invoices for {subscriptionCount} subscriptions, totaling {total} {symbol}{method}. ',
334
+ simpleTitle: 'You have {count} due invoices. ',
335
335
  empty: 'Great! You have no due invoices.',
336
+ defaultAlert: 'Please pay immediately to avoid service disruption.',
336
337
  },
337
338
  },
338
339
  invoice: {
@@ -133,6 +133,7 @@ export default flat({
133
133
  empty: '❤️ 支持一下',
134
134
  gaveTips: '已有 {count} 人打赏',
135
135
  tipAmount: '打赏金额',
136
+ tabHint: '快速切换金额',
136
137
  benefits: {
137
138
  one: '{name} 将获得全部打赏',
138
139
  multiple: '打赏将按比例分配给 {count} 位受益人',
@@ -146,7 +147,7 @@ export default flat({
146
147
  later: '稍后配置',
147
148
  configTip: '前往 Payment Kit 配置打赏选项',
148
149
  },
149
- cardPay: '使用卡片{action}',
150
+ cardPay: '使用银行卡{action}',
150
151
  empty: '没有可支付的项目',
151
152
  per: '每',
152
153
  pay: '付款给 {payee}',
@@ -244,6 +245,7 @@ export default flat({
244
245
  alert: {
245
246
  title: '你有欠费账单',
246
247
  description: '看起来你有欠费的账单,在你支付所有欠费账单之前,新的购买或者订阅将被禁止,请不要调皮。',
248
+ customMessage: '请立即支付,否则新的购买或者订阅将被禁止。',
247
249
  confirm: '去支付',
248
250
  },
249
251
  view: '查看欠费明细',
@@ -320,10 +322,10 @@ export default flat({
320
322
  owner: '订阅拥有者',
321
323
  },
322
324
  overdue: {
323
- title:
324
- '您有 {count} 张欠费账单,涉及 {subscriptionCount} 个订阅,总金额 {total} {symbol}{method}。请立即支付,以免影响您的使用。',
325
- simpleTitle: '您有 {count} 张欠费账单,请立即支付,以免影响您的使用。',
325
+ title: '您有 {count} 张欠费账单,涉及 {subscriptionCount} 个订阅,总金额 {total} {symbol}{method}。',
326
+ simpleTitle: '您有 {count} 张欠费账单,',
326
327
  empty: '恭喜!您当前没有欠费账单。',
328
+ defaultAlert: '请立即支付,以免影响您的使用。',
327
329
  },
328
330
  },
329
331
  invoice: {