@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.
- package/es/components/over-due-invoice-payment.d.ts +3 -1
- package/es/components/over-due-invoice-payment.js +15 -7
- package/es/libs/phone-validator.d.ts +7 -0
- package/es/libs/phone-validator.js +93 -2
- package/es/locales/en.js +7 -5
- package/es/locales/zh.js +7 -4
- package/es/payment/donation-form.js +62 -22
- package/es/payment/form/index.js +101 -65
- package/es/payment/form/phone.js +31 -10
- package/es/payment/index.js +11 -8
- package/es/payment/product-donation.js +7 -4
- package/lib/components/over-due-invoice-payment.d.ts +3 -1
- package/lib/components/over-due-invoice-payment.js +15 -7
- package/lib/libs/phone-validator.d.ts +7 -0
- package/lib/libs/phone-validator.js +97 -6
- package/lib/locales/en.js +7 -5
- package/lib/locales/zh.js +7 -4
- package/lib/payment/donation-form.js +51 -15
- package/lib/payment/form/index.js +106 -62
- package/lib/payment/form/phone.js +25 -9
- package/lib/payment/index.js +9 -8
- package/lib/payment/product-donation.js +7 -4
- package/package.json +6 -6
- package/src/components/over-due-invoice-payment.tsx +14 -6
- package/src/libs/phone-validator.ts +89 -2
- package/src/locales/en.tsx +6 -5
- package/src/locales/zh.tsx +6 -4
- package/src/payment/donation-form.tsx +57 -19
- package/src/payment/form/index.tsx +133 -69
- package/src/payment/form/phone.tsx +34 -12
- package/src/payment/index.tsx +13 -8
- package/src/payment/product-donation.tsx +7 -5
|
@@ -17,6 +17,7 @@ type Props = {
|
|
|
17
17
|
dialogProps?: DialogProps;
|
|
18
18
|
detailLinkOptions?: DetailLinkOptions;
|
|
19
19
|
successToast?: boolean;
|
|
20
|
+
alertMessage?: string;
|
|
20
21
|
children?: (handlePay: (item: SummaryItem) => void, data: {
|
|
21
22
|
subscription?: Subscription;
|
|
22
23
|
summary: {
|
|
@@ -32,7 +33,7 @@ type SummaryItem = {
|
|
|
32
33
|
currency: PaymentCurrency;
|
|
33
34
|
method: PaymentMethod;
|
|
34
35
|
};
|
|
35
|
-
declare function OverdueInvoicePayment({ subscriptionId, customerId, mode, dialogProps, children, onPaid, detailLinkOptions, successToast, }: Props): import("react").JSX.Element | null;
|
|
36
|
+
declare function OverdueInvoicePayment({ subscriptionId, customerId, mode, dialogProps, children, onPaid, detailLinkOptions, successToast, alertMessage, }: Props): import("react").JSX.Element | null;
|
|
36
37
|
declare namespace OverdueInvoicePayment {
|
|
37
38
|
var defaultProps: {
|
|
38
39
|
mode: string;
|
|
@@ -47,6 +48,7 @@ declare namespace OverdueInvoicePayment {
|
|
|
47
48
|
subscriptionId: undefined;
|
|
48
49
|
customerId: undefined;
|
|
49
50
|
successToast: boolean;
|
|
51
|
+
alertMessage: string;
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
54
|
export default OverdueInvoicePayment;
|
|
@@ -35,7 +35,8 @@ function OverdueInvoicePayment({
|
|
|
35
35
|
onPaid = () => {
|
|
36
36
|
},
|
|
37
37
|
detailLinkOptions = { enabled: true },
|
|
38
|
-
successToast = true
|
|
38
|
+
successToast = true,
|
|
39
|
+
alertMessage = ""
|
|
39
40
|
}) {
|
|
40
41
|
const { t } = useLocaleContext();
|
|
41
42
|
const { connect } = usePaymentContext();
|
|
@@ -245,19 +246,25 @@ function OverdueInvoicePayment({
|
|
|
245
246
|
});
|
|
246
247
|
}
|
|
247
248
|
if (customerId) {
|
|
249
|
+
let title = "";
|
|
248
250
|
if (summaryList.length === 1) {
|
|
249
|
-
|
|
251
|
+
title = t("payment.customer.overdue.title", {
|
|
250
252
|
subscriptionCount: data.subscriptionCount || 0,
|
|
251
253
|
count: data.invoices?.length,
|
|
252
254
|
total: formatAmount(summaryList[0]?.amount, summaryList[0]?.currency?.decimal),
|
|
253
255
|
symbol: summaryList[0]?.currency?.symbol,
|
|
254
256
|
method: getMethodText(summaryList[0]?.method)
|
|
255
257
|
});
|
|
258
|
+
} else {
|
|
259
|
+
title = t("payment.customer.overdue.simpleTitle", {
|
|
260
|
+
subscriptionCount: data.subscriptionCount || 0,
|
|
261
|
+
count: data.invoices?.length
|
|
262
|
+
});
|
|
256
263
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
})
|
|
264
|
+
if (alertMessage) {
|
|
265
|
+
return `${title}${alertMessage}`;
|
|
266
|
+
}
|
|
267
|
+
return `${title}${t("payment.customer.overdue.defaultAlert")}`;
|
|
261
268
|
}
|
|
262
269
|
return "";
|
|
263
270
|
};
|
|
@@ -388,6 +395,7 @@ OverdueInvoicePayment.defaultProps = {
|
|
|
388
395
|
detailLinkOptions: { enabled: true },
|
|
389
396
|
subscriptionId: void 0,
|
|
390
397
|
customerId: void 0,
|
|
391
|
-
successToast: true
|
|
398
|
+
successToast: true,
|
|
399
|
+
alertMessage: ""
|
|
392
400
|
};
|
|
393
401
|
export default OverdueInvoicePayment;
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
export declare const getPhoneUtil: () => Promise<any>;
|
|
2
2
|
export declare const validatePhoneNumber: (phoneNumber: string) => Promise<any>;
|
|
3
|
+
/**
|
|
4
|
+
* Format a phone number to international format
|
|
5
|
+
* @param phoneNumber The original phone number
|
|
6
|
+
* @param defaultCountry Default country code (ISO 3166-1 alpha-2)
|
|
7
|
+
* @returns Formatted phone number
|
|
8
|
+
*/
|
|
9
|
+
export declare const formatPhone: (phoneNumber: string | undefined, defaultCountry?: string) => string;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
let phoneUtil = null;
|
|
2
2
|
export const getPhoneUtil = async () => {
|
|
3
3
|
if (!phoneUtil) {
|
|
4
|
-
const
|
|
4
|
+
const result = await import(
|
|
5
5
|
/* webpackChunkName: "phone-util" */
|
|
6
6
|
"google-libphonenumber"
|
|
7
7
|
);
|
|
8
|
+
const PhoneNumberUtil = (result.default || result)?.PhoneNumberUtil;
|
|
9
|
+
if (!PhoneNumberUtil) {
|
|
10
|
+
throw new Error("PhoneNumberUtil not found");
|
|
11
|
+
}
|
|
8
12
|
phoneUtil = PhoneNumberUtil.getInstance();
|
|
9
13
|
}
|
|
10
14
|
return phoneUtil;
|
|
11
15
|
};
|
|
12
16
|
export const validatePhoneNumber = async (phoneNumber) => {
|
|
13
17
|
try {
|
|
14
|
-
|
|
18
|
+
let util = null;
|
|
19
|
+
try {
|
|
20
|
+
util = await getPhoneUtil();
|
|
21
|
+
} catch (err) {
|
|
22
|
+
const pattern = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/im;
|
|
23
|
+
return pattern.test(phoneNumber);
|
|
24
|
+
}
|
|
15
25
|
const parsed = util.parseAndKeepRawInput(phoneNumber);
|
|
16
26
|
return util.isValidNumber(parsed);
|
|
17
27
|
} catch (err) {
|
|
@@ -19,3 +29,84 @@ export const validatePhoneNumber = async (phoneNumber) => {
|
|
|
19
29
|
return false;
|
|
20
30
|
}
|
|
21
31
|
};
|
|
32
|
+
export const formatPhone = (phoneNumber, defaultCountry = "US") => {
|
|
33
|
+
if (!phoneNumber || phoneNumber.trim() === "") {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
const cleanedNumber = phoneNumber.replace(/[^\d+]/g, "");
|
|
37
|
+
if (cleanedNumber.startsWith("+")) {
|
|
38
|
+
return cleanedNumber;
|
|
39
|
+
}
|
|
40
|
+
const COUNTRY_CODES = {
|
|
41
|
+
US: "1",
|
|
42
|
+
// United States
|
|
43
|
+
CA: "1",
|
|
44
|
+
// Canada
|
|
45
|
+
CN: "86",
|
|
46
|
+
// China
|
|
47
|
+
HK: "852",
|
|
48
|
+
// Hong Kong
|
|
49
|
+
IN: "91",
|
|
50
|
+
// India
|
|
51
|
+
UK: "44",
|
|
52
|
+
// United Kingdom
|
|
53
|
+
GB: "44",
|
|
54
|
+
// United Kingdom
|
|
55
|
+
JP: "81",
|
|
56
|
+
// Japan
|
|
57
|
+
KR: "82",
|
|
58
|
+
// South Korea
|
|
59
|
+
AU: "61",
|
|
60
|
+
// Australia
|
|
61
|
+
DE: "49",
|
|
62
|
+
// Germany
|
|
63
|
+
FR: "33",
|
|
64
|
+
// France
|
|
65
|
+
IT: "39",
|
|
66
|
+
// Italy
|
|
67
|
+
ES: "34",
|
|
68
|
+
// Spain
|
|
69
|
+
BR: "55",
|
|
70
|
+
// Brazil
|
|
71
|
+
RU: "7",
|
|
72
|
+
// Russia
|
|
73
|
+
MX: "52",
|
|
74
|
+
// Mexico
|
|
75
|
+
SG: "65",
|
|
76
|
+
// Singapore
|
|
77
|
+
AE: "971"
|
|
78
|
+
// UAE
|
|
79
|
+
};
|
|
80
|
+
const COUNTRY_PATTERNS = [
|
|
81
|
+
[/^1[3-9]\d{9}$/, "86"],
|
|
82
|
+
// China mobile: 11 digits, starts with 1
|
|
83
|
+
[/^\d{10}$/, "1"],
|
|
84
|
+
// US/Canada: 10 digits
|
|
85
|
+
[/^[6-9]\d{9}$/, "91"],
|
|
86
|
+
// India: 10 digits, starts with 6-9
|
|
87
|
+
[/^0[1-9]\d{8,9}$/, "81"],
|
|
88
|
+
// Japan: 10-11 digits, starts with 0
|
|
89
|
+
[/^07\d{9}$/, "44"],
|
|
90
|
+
// UK mobile: 11 digits, starts with 07
|
|
91
|
+
[/^04\d{8}$/, "61"],
|
|
92
|
+
// Australia mobile: 10 digits, starts with 04
|
|
93
|
+
[/^01[0-9]\d{7,8}$/, "82"],
|
|
94
|
+
// Korea mobile: 10-11 digits, starts with 01
|
|
95
|
+
[/^[0-9]\d{8}$/, "86"]
|
|
96
|
+
// China landline: 9 digits
|
|
97
|
+
];
|
|
98
|
+
let numberToFormat = cleanedNumber;
|
|
99
|
+
if (numberToFormat.startsWith("0")) {
|
|
100
|
+
numberToFormat = numberToFormat.substring(1);
|
|
101
|
+
}
|
|
102
|
+
for (const [pattern, countryCode2] of COUNTRY_PATTERNS) {
|
|
103
|
+
if (pattern.test(cleanedNumber)) {
|
|
104
|
+
if (cleanedNumber.startsWith("0") && !["1", "86"].includes(countryCode2)) {
|
|
105
|
+
return `+${countryCode2}${cleanedNumber.substring(1)}`;
|
|
106
|
+
}
|
|
107
|
+
return `+${countryCode2}${cleanedNumber}`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const countryCode = COUNTRY_CODES[defaultCountry.toUpperCase()] || defaultCountry;
|
|
111
|
+
return `+${countryCode}${numberToFormat}`;
|
|
112
|
+
};
|
package/es/locales/en.js
CHANGED
|
@@ -131,6 +131,7 @@ export default flat({
|
|
|
131
131
|
empty: "No supporters yet",
|
|
132
132
|
gaveTips: "{count} people gave tips",
|
|
133
133
|
tipAmount: "Tip Amount",
|
|
134
|
+
tabHint: "to switch amount",
|
|
134
135
|
benefits: {
|
|
135
136
|
one: "{name} will receive all tips",
|
|
136
137
|
multiple: "Tips will be distributed to {count} beneficiaries",
|
|
@@ -144,7 +145,7 @@ export default flat({
|
|
|
144
145
|
later: "Configure Later",
|
|
145
146
|
configTip: "Configure donation settings in Payment Kit"
|
|
146
147
|
},
|
|
147
|
-
cardPay: "{action} with card",
|
|
148
|
+
cardPay: "{action} with bank card",
|
|
148
149
|
empty: "No thing to pay",
|
|
149
150
|
per: "per",
|
|
150
151
|
pay: "Pay {payee}",
|
|
@@ -241,7 +242,7 @@ export default flat({
|
|
|
241
242
|
warning: "Past due invoices need to be paid immediately, otherwise you can not make new purchases anymore.",
|
|
242
243
|
alert: {
|
|
243
244
|
title: "You have unpaid invoices",
|
|
244
|
-
|
|
245
|
+
customMessage: "Please pay immediately, otherwise new purchases or subscriptions will be prohibited.",
|
|
245
246
|
confirm: "Pay Now"
|
|
246
247
|
},
|
|
247
248
|
view: "View Due Invoices"
|
|
@@ -317,9 +318,10 @@ export default flat({
|
|
|
317
318
|
owner: "Subscription Owner"
|
|
318
319
|
},
|
|
319
320
|
overdue: {
|
|
320
|
-
title: "You have {count} due invoices for {subscriptionCount} subscriptions, totaling {total} {symbol}{method}.
|
|
321
|
-
simpleTitle: "You have {count} due invoices.
|
|
322
|
-
empty: "Great! You have no due invoices."
|
|
321
|
+
title: "You have {count} due invoices for {subscriptionCount} subscriptions, totaling {total} {symbol}{method}. ",
|
|
322
|
+
simpleTitle: "You have {count} due invoices. ",
|
|
323
|
+
empty: "Great! You have no due invoices.",
|
|
324
|
+
defaultAlert: "Please pay immediately to avoid service disruption."
|
|
323
325
|
}
|
|
324
326
|
},
|
|
325
327
|
invoice: {
|
package/es/locales/zh.js
CHANGED
|
@@ -131,6 +131,7 @@ export default flat({
|
|
|
131
131
|
empty: "\u2764\uFE0F \u652F\u6301\u4E00\u4E0B",
|
|
132
132
|
gaveTips: "\u5DF2\u6709 {count} \u4EBA\u6253\u8D4F",
|
|
133
133
|
tipAmount: "\u6253\u8D4F\u91D1\u989D",
|
|
134
|
+
tabHint: "\u5FEB\u901F\u5207\u6362\u91D1\u989D",
|
|
134
135
|
benefits: {
|
|
135
136
|
one: "{name} \u5C06\u83B7\u5F97\u5168\u90E8\u6253\u8D4F",
|
|
136
137
|
multiple: "\u6253\u8D4F\u5C06\u6309\u6BD4\u4F8B\u5206\u914D\u7ED9 {count} \u4F4D\u53D7\u76CA\u4EBA",
|
|
@@ -144,7 +145,7 @@ export default flat({
|
|
|
144
145
|
later: "\u7A0D\u540E\u914D\u7F6E",
|
|
145
146
|
configTip: "\u524D\u5F80 Payment Kit \u914D\u7F6E\u6253\u8D4F\u9009\u9879"
|
|
146
147
|
},
|
|
147
|
-
cardPay: "\u4F7F\u7528\u5361
|
|
148
|
+
cardPay: "\u4F7F\u7528\u94F6\u884C\u5361{action}",
|
|
148
149
|
empty: "\u6CA1\u6709\u53EF\u652F\u4ED8\u7684\u9879\u76EE",
|
|
149
150
|
per: "\u6BCF",
|
|
150
151
|
pay: "\u4ED8\u6B3E\u7ED9 {payee}",
|
|
@@ -242,6 +243,7 @@ export default flat({
|
|
|
242
243
|
alert: {
|
|
243
244
|
title: "\u4F60\u6709\u6B20\u8D39\u8D26\u5355",
|
|
244
245
|
description: "\u770B\u8D77\u6765\u4F60\u6709\u6B20\u8D39\u7684\u8D26\u5355\uFF0C\u5728\u4F60\u652F\u4ED8\u6240\u6709\u6B20\u8D39\u8D26\u5355\u4E4B\u524D\uFF0C\u65B0\u7684\u8D2D\u4E70\u6216\u8005\u8BA2\u9605\u5C06\u88AB\u7981\u6B62\uFF0C\u8BF7\u4E0D\u8981\u8C03\u76AE\u3002",
|
|
246
|
+
customMessage: "\u8BF7\u7ACB\u5373\u652F\u4ED8\uFF0C\u5426\u5219\u65B0\u7684\u8D2D\u4E70\u6216\u8005\u8BA2\u9605\u5C06\u88AB\u7981\u6B62\u3002",
|
|
245
247
|
confirm: "\u53BB\u652F\u4ED8"
|
|
246
248
|
},
|
|
247
249
|
view: "\u67E5\u770B\u6B20\u8D39\u660E\u7EC6"
|
|
@@ -317,9 +319,10 @@ export default flat({
|
|
|
317
319
|
owner: "\u8BA2\u9605\u62E5\u6709\u8005"
|
|
318
320
|
},
|
|
319
321
|
overdue: {
|
|
320
|
-
title: "\u60A8\u6709 {count} \u5F20\u6B20\u8D39\u8D26\u5355\uFF0C\u6D89\u53CA {subscriptionCount} \u4E2A\u8BA2\u9605\uFF0C\u603B\u91D1\u989D {total} {symbol}{method}\u3002
|
|
321
|
-
simpleTitle: "\u60A8\u6709 {count} \u5F20\u6B20\u8D39\u8D26\u5355
|
|
322
|
-
empty: "\u606D\u559C\uFF01\u60A8\u5F53\u524D\u6CA1\u6709\u6B20\u8D39\u8D26\u5355\u3002"
|
|
322
|
+
title: "\u60A8\u6709 {count} \u5F20\u6B20\u8D39\u8D26\u5355\uFF0C\u6D89\u53CA {subscriptionCount} \u4E2A\u8BA2\u9605\uFF0C\u603B\u91D1\u989D {total} {symbol}{method}\u3002",
|
|
323
|
+
simpleTitle: "\u60A8\u6709 {count} \u5F20\u6B20\u8D39\u8D26\u5355,",
|
|
324
|
+
empty: "\u606D\u559C\uFF01\u60A8\u5F53\u524D\u6CA1\u6709\u6B20\u8D39\u8D26\u5355\u3002",
|
|
325
|
+
defaultAlert: "\u8BF7\u7ACB\u5373\u652F\u4ED8\uFF0C\u4EE5\u514D\u5F71\u54CD\u60A8\u7684\u4F7F\u7528\u3002"
|
|
323
326
|
}
|
|
324
327
|
},
|
|
325
328
|
invoice: {
|
|
@@ -29,6 +29,7 @@ import ProductDonation from "./product-donation.js";
|
|
|
29
29
|
import ConfirmDialog from "../components/confirm.js";
|
|
30
30
|
import PaymentBeneficiaries from "../components/payment-beneficiaries.js";
|
|
31
31
|
import DonationSkeleton from "./skeleton/donation.js";
|
|
32
|
+
import { formatPhone } from "../libs/phone-validator.js";
|
|
32
33
|
const getBenefits = async (id, url) => {
|
|
33
34
|
const { data } = await api.get(`/api/payment-links/${id}/benefits?${url ? `url=${url}` : ""}`);
|
|
34
35
|
return data;
|
|
@@ -55,6 +56,7 @@ function PaymentInner({
|
|
|
55
56
|
}) {
|
|
56
57
|
const { t } = useLocaleContext();
|
|
57
58
|
const { settings, session } = usePaymentContext();
|
|
59
|
+
const { isMobile } = useMobile();
|
|
58
60
|
const [state, setState] = useSetState({
|
|
59
61
|
checkoutSession,
|
|
60
62
|
submitting: false,
|
|
@@ -79,20 +81,22 @@ function PaymentInner({
|
|
|
79
81
|
defaultValues: {
|
|
80
82
|
customer_name: customer?.name || session?.user?.fullName || "",
|
|
81
83
|
customer_email: customer?.email || session?.user?.email || "",
|
|
82
|
-
customer_phone: customer?.phone || session?.user?.phone || "",
|
|
84
|
+
customer_phone: formatPhone(customer?.phone || session?.user?.phone || ""),
|
|
83
85
|
payment_method: defaultMethodId,
|
|
84
86
|
payment_currency: defaultCurrencyId,
|
|
85
87
|
billing_address: Object.assign(
|
|
86
88
|
{
|
|
87
|
-
country: "",
|
|
88
|
-
state: "",
|
|
89
|
-
city: "",
|
|
90
|
-
line1: "",
|
|
91
|
-
line2: "",
|
|
92
|
-
postal_code: ""
|
|
89
|
+
country: session?.user?.address?.country || "",
|
|
90
|
+
state: session?.user?.address?.province || "",
|
|
91
|
+
city: session?.user?.address?.city || "",
|
|
92
|
+
line1: session?.user?.address?.line1 || "",
|
|
93
|
+
line2: session?.user?.address?.line2 || "",
|
|
94
|
+
postal_code: session?.user?.address?.postalCode || ""
|
|
93
95
|
},
|
|
94
96
|
customer?.address || {},
|
|
95
|
-
{
|
|
97
|
+
{
|
|
98
|
+
country: isValidCountry(customer?.address?.country || session?.user?.address?.country || "") ? customer?.address?.country : "us"
|
|
99
|
+
}
|
|
96
100
|
)
|
|
97
101
|
}
|
|
98
102
|
});
|
|
@@ -202,20 +206,56 @@ function PaymentInner({
|
|
|
202
206
|
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
203
207
|
benefitsState.open && /* @__PURE__ */ jsx(PaymentBeneficiaries, { data: benefits, currency, totalAmount: benefitsState.amount }),
|
|
204
208
|
/* @__PURE__ */ jsxs(Stack, { sx: { display: benefitsState.open ? "none" : "block" }, children: [
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
209
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { mb: 2 }, children: [
|
|
210
|
+
/* @__PURE__ */ jsx(
|
|
211
|
+
Typography,
|
|
212
|
+
{
|
|
213
|
+
title: t("payment.checkout.orderSummary"),
|
|
214
|
+
sx: {
|
|
215
|
+
color: "text.primary",
|
|
216
|
+
fontSize: "18px",
|
|
217
|
+
fontWeight: "500",
|
|
218
|
+
lineHeight: "24px"
|
|
219
|
+
},
|
|
220
|
+
children: t("payment.checkout.donation.tipAmount")
|
|
221
|
+
}
|
|
222
|
+
),
|
|
223
|
+
!isMobile && donationSettings?.amount?.presets && donationSettings.amount.presets.length > 0 && /* @__PURE__ */ jsxs(
|
|
224
|
+
Typography,
|
|
225
|
+
{
|
|
226
|
+
sx: {
|
|
227
|
+
color: "text.secondary",
|
|
228
|
+
fontSize: "13px",
|
|
229
|
+
display: "flex",
|
|
230
|
+
alignItems: "center",
|
|
231
|
+
gap: 0.5,
|
|
232
|
+
opacity: 0.8
|
|
233
|
+
},
|
|
234
|
+
children: [
|
|
235
|
+
/* @__PURE__ */ jsx(
|
|
236
|
+
Box,
|
|
237
|
+
{
|
|
238
|
+
component: "span",
|
|
239
|
+
sx: {
|
|
240
|
+
border: "1px solid",
|
|
241
|
+
borderColor: "divider",
|
|
242
|
+
borderRadius: 0.75,
|
|
243
|
+
px: 0.75,
|
|
244
|
+
py: 0.25,
|
|
245
|
+
fontSize: "12px",
|
|
246
|
+
lineHeight: 1,
|
|
247
|
+
color: "text.secondary",
|
|
248
|
+
fontWeight: "400",
|
|
249
|
+
bgcolor: "transparent"
|
|
250
|
+
},
|
|
251
|
+
children: "Tab"
|
|
252
|
+
}
|
|
253
|
+
),
|
|
254
|
+
t("payment.checkout.donation.tabHint")
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
)
|
|
258
|
+
] }),
|
|
219
259
|
items.map((x) => /* @__PURE__ */ jsx(
|
|
220
260
|
ProductDonation,
|
|
221
261
|
{
|
package/es/payment/form/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import { joinURL } from "ufo";
|
|
|
11
11
|
import { dispatch } from "use-bus";
|
|
12
12
|
import isEmail from "validator/es/lib/isEmail";
|
|
13
13
|
import isEmpty from "lodash/isEmpty";
|
|
14
|
-
import ConfirmDialog from "../../components/confirm.js";
|
|
15
14
|
import FormInput from "../../components/input.js";
|
|
16
15
|
import { usePaymentContext } from "../../contexts/payment.js";
|
|
17
16
|
import { useSubscription } from "../../hooks/subscription.js";
|
|
@@ -29,8 +28,9 @@ import CurrencySelector from "./currency.js";
|
|
|
29
28
|
import PhoneInput from "./phone.js";
|
|
30
29
|
import StripeCheckout from "./stripe/index.js";
|
|
31
30
|
import { useMobile } from "../../hooks/mobile.js";
|
|
32
|
-
import { validatePhoneNumber } from "../../libs/phone-validator.js";
|
|
31
|
+
import { formatPhone, validatePhoneNumber } from "../../libs/phone-validator.js";
|
|
33
32
|
import LoadingButton from "../../components/loading-button.js";
|
|
33
|
+
import OverdueInvoicePayment from "../../components/over-due-invoice-payment.js";
|
|
34
34
|
export const waitForCheckoutComplete = async (sessionId) => {
|
|
35
35
|
let result;
|
|
36
36
|
await pWaitFor(
|
|
@@ -53,6 +53,31 @@ export const hasDidWallet = (user) => {
|
|
|
53
53
|
const connected = user?.connectedAccounts || user?.extraConfigs?.connectedAccounts || [];
|
|
54
54
|
return connected.some((x) => x.provider === "wallet");
|
|
55
55
|
};
|
|
56
|
+
const setUserFormValues = (userInfo, currentValues, setValue, options = {}) => {
|
|
57
|
+
const { preferExisting = true } = options;
|
|
58
|
+
const basicFields = {
|
|
59
|
+
customer_name: userInfo.name || userInfo.fullName,
|
|
60
|
+
customer_email: userInfo.email,
|
|
61
|
+
customer_phone: formatPhone(userInfo.phone)
|
|
62
|
+
};
|
|
63
|
+
const addressFields = {
|
|
64
|
+
"billing_address.state": userInfo.address?.state || userInfo.address?.province,
|
|
65
|
+
"billing_address.line1": userInfo.address?.line1,
|
|
66
|
+
"billing_address.line2": userInfo.address?.line2,
|
|
67
|
+
"billing_address.city": userInfo.address?.city,
|
|
68
|
+
"billing_address.postal_code": userInfo.address?.postal_code || userInfo.address?.postalCode,
|
|
69
|
+
"billing_address.country": userInfo.address?.country
|
|
70
|
+
};
|
|
71
|
+
if (options.showPhone) {
|
|
72
|
+
addressFields["billing_address.country"] = userInfo.metadata?.phone?.country || userInfo.address?.country;
|
|
73
|
+
}
|
|
74
|
+
const allFields = { ...addressFields, ...basicFields };
|
|
75
|
+
Object.entries(allFields).forEach(([field, value]) => {
|
|
76
|
+
if (!preferExisting || !currentValues[field.split(".")[0]]) {
|
|
77
|
+
setValue(field, value);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
};
|
|
56
81
|
PaymentForm.defaultProps = {
|
|
57
82
|
onlyShowBtn: false,
|
|
58
83
|
isDonation: false
|
|
@@ -129,22 +154,30 @@ export default function PaymentForm({
|
|
|
129
154
|
useEffect(() => {
|
|
130
155
|
if (session?.user) {
|
|
131
156
|
const values = getValues();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
157
|
+
setUserFormValues(session.user, values, setValue, {
|
|
158
|
+
preferExisting: false,
|
|
159
|
+
showPhone: checkoutSession.phone_number_collection?.enabled
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
setUserFormValues(
|
|
163
|
+
{
|
|
164
|
+
name: "",
|
|
165
|
+
email: "",
|
|
166
|
+
phone: "",
|
|
167
|
+
address: {
|
|
168
|
+
state: "",
|
|
169
|
+
line1: "",
|
|
170
|
+
line2: "",
|
|
171
|
+
city: "",
|
|
172
|
+
postal_code: ""
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{},
|
|
176
|
+
setValue,
|
|
177
|
+
{ preferExisting: false, showPhone: checkoutSession.phone_number_collection?.enabled }
|
|
178
|
+
);
|
|
146
179
|
}
|
|
147
|
-
}, [session?.user, getValues, setValue]);
|
|
180
|
+
}, [session?.user, getValues, setValue, checkoutSession.phone_number_collection?.enabled]);
|
|
148
181
|
useEffect(() => {
|
|
149
182
|
setValue("payment_method", currencies[paymentCurrencyIndex]?.method?.id);
|
|
150
183
|
setValue("payment_currency", currencies[paymentCurrencyIndex]?.id);
|
|
@@ -175,7 +208,7 @@ export default function PaymentForm({
|
|
|
175
208
|
buttonText = session?.user || isDonation ? buttonText : t("payment.checkout.connect", { action: buttonText });
|
|
176
209
|
const method = paymentMethods.find((x) => x.id === paymentMethod);
|
|
177
210
|
const isDonationMode = checkoutSession?.submit_type === "donate" && isDonation;
|
|
178
|
-
const showForm = session?.user;
|
|
211
|
+
const showForm = !!session?.user;
|
|
179
212
|
const skipBindWallet = method.type === "stripe";
|
|
180
213
|
const handleConnected = async () => {
|
|
181
214
|
try {
|
|
@@ -199,33 +232,9 @@ export default function PaymentForm({
|
|
|
199
232
|
const { data: profile } = await api.get("/api/customers/me?fallback=1");
|
|
200
233
|
if (profile) {
|
|
201
234
|
const values = getValues();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
if (!values.customer_email) {
|
|
206
|
-
setValue("customer_email", profile.email);
|
|
207
|
-
}
|
|
208
|
-
if (!values.customer_phone) {
|
|
209
|
-
setValue("customer_phone", profile.phone);
|
|
210
|
-
}
|
|
211
|
-
if (profile.address?.country) {
|
|
212
|
-
setValue("billing_address.country", profile.address.country);
|
|
213
|
-
}
|
|
214
|
-
if (profile.address?.state) {
|
|
215
|
-
setValue("billing_address.state", profile.address.state);
|
|
216
|
-
}
|
|
217
|
-
if (profile.address?.line1) {
|
|
218
|
-
setValue("billing_address.line1", profile.address.line1);
|
|
219
|
-
}
|
|
220
|
-
if (profile.address?.line2) {
|
|
221
|
-
setValue("billing_address.line2", profile.address.line2);
|
|
222
|
-
}
|
|
223
|
-
if (profile.address?.city) {
|
|
224
|
-
setValue("billing_address.city", profile.address.city);
|
|
225
|
-
}
|
|
226
|
-
if (profile.address?.postal_code) {
|
|
227
|
-
setValue("billing_address.postal_code", profile.address.postal_code);
|
|
228
|
-
}
|
|
235
|
+
setUserFormValues(profile, values, setValue, {
|
|
236
|
+
showPhone: checkoutSession.phone_number_collection?.enabled
|
|
237
|
+
});
|
|
229
238
|
}
|
|
230
239
|
};
|
|
231
240
|
const onFormSubmit = async (data) => {
|
|
@@ -377,17 +386,32 @@ export default function PaymentForm({
|
|
|
377
386
|
}
|
|
378
387
|
) }),
|
|
379
388
|
state.customerLimited && /* @__PURE__ */ jsx(
|
|
380
|
-
|
|
389
|
+
OverdueInvoicePayment,
|
|
381
390
|
{
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
+
customerId: customer?.id || session?.user?.did,
|
|
392
|
+
onPaid: () => {
|
|
393
|
+
setState({ customerLimited: false });
|
|
394
|
+
onAction();
|
|
395
|
+
},
|
|
396
|
+
alertMessage: t("payment.customer.pastDue.alert.customMessage"),
|
|
397
|
+
detailLinkOptions: {
|
|
398
|
+
enabled: true,
|
|
399
|
+
onClick: () => {
|
|
400
|
+
setState({ customerLimited: false });
|
|
401
|
+
window.open(
|
|
402
|
+
joinURL(
|
|
403
|
+
getPrefix(),
|
|
404
|
+
`/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`
|
|
405
|
+
),
|
|
406
|
+
"_self"
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
dialogProps: {
|
|
411
|
+
open: state.customerLimited,
|
|
412
|
+
onClose: () => setState({ customerLimited: false }),
|
|
413
|
+
title: t("payment.customer.pastDue.alert.title")
|
|
414
|
+
}
|
|
391
415
|
}
|
|
392
416
|
)
|
|
393
417
|
] });
|
|
@@ -528,17 +552,29 @@ export default function PaymentForm({
|
|
|
528
552
|
["subscription", "setup"].includes(checkoutSession.mode) && /* @__PURE__ */ jsx(Typography, { sx: { mt: 2.5, color: "text.lighter", fontSize: "0.7875rem", lineHeight: "0.9625rem" }, children: t("payment.checkout.confirm", { payee }) })
|
|
529
553
|
] }) }),
|
|
530
554
|
state.customerLimited && /* @__PURE__ */ jsx(
|
|
531
|
-
|
|
555
|
+
OverdueInvoicePayment,
|
|
532
556
|
{
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
557
|
+
customerId: customer?.id || session?.user?.didssion?.user?.did,
|
|
558
|
+
onPaid: () => {
|
|
559
|
+
setState({ customerLimited: false });
|
|
560
|
+
onAction();
|
|
561
|
+
},
|
|
562
|
+
alertMessage: t("payment.customer.pastDue.alert.customMessage"),
|
|
563
|
+
detailLinkOptions: {
|
|
564
|
+
enabled: true,
|
|
565
|
+
onClick: () => {
|
|
566
|
+
setState({ customerLimited: false });
|
|
567
|
+
window.open(
|
|
568
|
+
joinURL(getPrefix(), `/customer/invoice/past-due?referer=${encodeURIComponent(window.location.href)}`),
|
|
569
|
+
"_self"
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
dialogProps: {
|
|
574
|
+
open: state.customerLimited,
|
|
575
|
+
onClose: () => setState({ customerLimited: false }),
|
|
576
|
+
title: t("payment.customer.pastDue.alert.title")
|
|
577
|
+
}
|
|
542
578
|
}
|
|
543
579
|
)
|
|
544
580
|
] });
|