|
|
|
@ -1,9 +1,9 @@ |
|
|
|
/** |
|
|
|
* 订阅 / 积分支付弹窗 |
|
|
|
* |
|
|
|
* 微信:打开即预拉二维码;蒙层在首次同意前盖住二维码;同意一次后切回微信不再蒙层,并轮询。 |
|
|
|
* 支付宝:无二维码,蒙层始终存在;每次点「同意并支付」才下单拿链接并跳转,再轮询。 |
|
|
|
*/ |
|
|
|
* 订阅 / 积分支付弹窗 |
|
|
|
* |
|
|
|
* 微信:同意后下单拉二维码;拿到有效二维码后移除蒙层并轮询。 |
|
|
|
* 支付宝:无二维码,蒙层始终存在;每次点「同意并支付」才下单拿链接并跳转,再轮询。 |
|
|
|
*/ |
|
|
|
import { Message, Modal } from "@arco-design/web-react"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react"; |
|
|
|
@ -111,16 +111,20 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
afterPaySuccessRef.current = afterPaySuccess; |
|
|
|
}, [afterPaySuccess]); |
|
|
|
|
|
|
|
const [paymentMethod, setPaymentMethod] = useState<PaymentMethod>("WXPAY"); |
|
|
|
/** 微信侧是否已点过「同意并支付」(本会话内切回微信不再出蒙层) */ |
|
|
|
const [wxAgreed, setWxAgreed] = useState(false); |
|
|
|
const [submitting, setSubmitting] = useState(false); |
|
|
|
const [codeUrl, setCodeUrl] = useState(""); |
|
|
|
|
|
|
|
const [paymentMethod, setPaymentMethod] = useState<PaymentMethod>("WXPAY"); |
|
|
|
/** 微信侧是否已点过「同意并支付」(本会话内切回微信不再出蒙层) */ |
|
|
|
const [wxAgreed, setWxAgreed] = useState(false); |
|
|
|
const [submitting, setSubmitting] = useState(false); |
|
|
|
const [codeUrl, setCodeUrl] = useState(""); |
|
|
|
|
|
|
|
const wxOrderRef = useRef<PaymentOrderData | null>(null); |
|
|
|
const pollAbortRef = useRef(false); |
|
|
|
const pollStartTimeRef = useRef(0); |
|
|
|
const pollTimerRef = useRef<number | null>(null); |
|
|
|
const mountedRef = useRef(true); |
|
|
|
const requestSeqRef = useRef(0); |
|
|
|
const activePollSeqRef = useRef(0); |
|
|
|
const submittingRef = useRef(false); |
|
|
|
const pollAbortRef = useRef(false); |
|
|
|
const pollStartTimeRef = useRef(0); |
|
|
|
const pollTimerRef = useRef<number | null>(null); |
|
|
|
|
|
|
|
const paymentInfo = useMemo<PaymentInfo>(() => { |
|
|
|
if (payType === "subscribe") { |
|
|
|
@ -153,23 +157,9 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
/** 支付宝始终蒙层;微信仅首次同意前蒙层 */ |
|
|
|
const showAgreementOverlay = paymentMethod === "ALIPAY" || !wxAgreed; |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
return () => { |
|
|
|
pollAbortRef.current = true; |
|
|
|
if (pollTimerRef.current != null) { |
|
|
|
window.clearTimeout(pollTimerRef.current); |
|
|
|
pollTimerRef.current = null; |
|
|
|
} |
|
|
|
}; |
|
|
|
}, []); |
|
|
|
|
|
|
|
const safeClose = useCallback(() => { |
|
|
|
onClose(); |
|
|
|
}, [onClose]); |
|
|
|
|
|
|
|
const requireLogin = useCallback((): boolean => { |
|
|
|
if (!getToken() || !user) { |
|
|
|
Message.warning(t("auth.please_login_first")); |
|
|
|
const requireLogin = useCallback((): boolean => { |
|
|
|
if (!getToken() || !user) { |
|
|
|
Message.warning(t("auth.please_login_first")); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return true; |
|
|
|
@ -177,12 +167,39 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
|
|
|
|
const stopPolling = useCallback(() => { |
|
|
|
pollAbortRef.current = true; |
|
|
|
activePollSeqRef.current += 1; |
|
|
|
if (pollTimerRef.current != null) { |
|
|
|
window.clearTimeout(pollTimerRef.current); |
|
|
|
pollTimerRef.current = null; |
|
|
|
} |
|
|
|
}, []); |
|
|
|
const isPollingAborted = useCallback(() => pollAbortRef.current, []); |
|
|
|
const isPollingActive = useCallback((pollSeq: number) => mountedRef.current && !pollAbortRef.current && activePollSeqRef.current === pollSeq, []); |
|
|
|
const setSubmittingState = useCallback((nextSubmitting: boolean) => { |
|
|
|
submittingRef.current = nextSubmitting; |
|
|
|
if (mountedRef.current) { |
|
|
|
setSubmitting(nextSubmitting); |
|
|
|
} |
|
|
|
}, []); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
return () => { |
|
|
|
mountedRef.current = false; |
|
|
|
requestSeqRef.current += 1; |
|
|
|
stopPolling(); |
|
|
|
submittingRef.current = false; |
|
|
|
}; |
|
|
|
}, [stopPolling]); |
|
|
|
|
|
|
|
const safeClose = useCallback(() => { |
|
|
|
onClose(); |
|
|
|
}, [onClose]); |
|
|
|
|
|
|
|
const nextPaymentRequestSeq = useCallback(() => { |
|
|
|
requestSeqRef.current += 1; |
|
|
|
return requestSeqRef.current; |
|
|
|
}, []); |
|
|
|
|
|
|
|
const isPaymentRequestActive = useCallback((requestSeq: number) => mountedRef.current && requestSeqRef.current === requestSeq, []); |
|
|
|
|
|
|
|
// 轮询支付状态
|
|
|
|
const startPaymentPoll = useCallback( |
|
|
|
@ -190,18 +207,20 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
const tradeNo = orderRes.trade_no ?? orderRes.tradeNo; |
|
|
|
if (!tradeNo) return; |
|
|
|
|
|
|
|
stopPolling(); |
|
|
|
pollAbortRef.current = false; |
|
|
|
pollStartTimeRef.current = Date.now(); |
|
|
|
|
|
|
|
void (async () => { |
|
|
|
const { paymentMethod: method, payType: ctxPayType } = ctx; |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
if (pollAbortRef.current) return; |
|
|
|
|
|
|
|
if (Date.now() - pollStartTimeRef.current >= PAYMENT_POLL_MAX_MS) { |
|
|
|
openPayNoticeModal("warning", { |
|
|
|
stopPolling(); |
|
|
|
pollAbortRef.current = false; |
|
|
|
pollStartTimeRef.current = Date.now(); |
|
|
|
const pollSeq = activePollSeqRef.current + 1; |
|
|
|
activePollSeqRef.current = pollSeq; |
|
|
|
|
|
|
|
void (async () => { |
|
|
|
const { paymentMethod: method, payType: ctxPayType } = ctx; |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
if (!isPollingActive(pollSeq)) return; |
|
|
|
|
|
|
|
if (Date.now() - pollStartTimeRef.current >= PAYMENT_POLL_MAX_MS) { |
|
|
|
openPayNoticeModal("warning", { |
|
|
|
title: t("subscribe.pay_notice_timeout_title"), |
|
|
|
content: t("subscribe.pay_result_timeout"), |
|
|
|
okText: t("button.okay"), |
|
|
|
@ -212,11 +231,11 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
|
|
|
|
try { |
|
|
|
const { data: statusRes } = await fetchPaymentStatus(tradeNo, method, ctxPayType); |
|
|
|
if (isPollingAborted()) return; |
|
|
|
|
|
|
|
const tradeStatus = extractTradeStatus(statusRes, method); |
|
|
|
if (!tradeStatus) { |
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
if (!isPollingActive(pollSeq)) return; |
|
|
|
|
|
|
|
const tradeStatus = extractTradeStatus(statusRes, method); |
|
|
|
if (!tradeStatus) { |
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
@ -248,30 +267,31 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
}); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
} catch { |
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
} |
|
|
|
} |
|
|
|
})(); |
|
|
|
}, |
|
|
|
[isPollingAborted, safeClose, setUser, stopPolling, t], |
|
|
|
); |
|
|
|
|
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
} catch { |
|
|
|
if (!isPollingActive(pollSeq)) return; |
|
|
|
await sleep(PAYMENT_POLL_INTERVAL_MS); |
|
|
|
} |
|
|
|
} |
|
|
|
})(); |
|
|
|
}, |
|
|
|
[isPollingActive, safeClose, setUser, stopPolling, t], |
|
|
|
); |
|
|
|
|
|
|
|
// 调度轮询
|
|
|
|
const schedulePoll = useCallback( |
|
|
|
(orderRes: PaymentOrderData, method: PaymentMethod) => { |
|
|
|
if (pollTimerRef.current != null) { |
|
|
|
window.clearTimeout(pollTimerRef.current); |
|
|
|
} |
|
|
|
const ctx: PollContext = { paymentMethod: method, payType }; |
|
|
|
pollTimerRef.current = window.setTimeout(() => { |
|
|
|
startPaymentPoll(orderRes, ctx); |
|
|
|
}, PAYMENT_POLL_INTERVAL_MS); |
|
|
|
}, |
|
|
|
[payType, startPaymentPoll], |
|
|
|
); |
|
|
|
if (!mountedRef.current) return; |
|
|
|
stopPolling(); |
|
|
|
const ctx: PollContext = { paymentMethod: method, payType }; |
|
|
|
pollTimerRef.current = window.setTimeout(() => { |
|
|
|
if (!mountedRef.current) return; |
|
|
|
startPaymentPoll(orderRes, ctx); |
|
|
|
}, PAYMENT_POLL_INTERVAL_MS); |
|
|
|
}, |
|
|
|
[payType, startPaymentPoll, stopPolling], |
|
|
|
); |
|
|
|
|
|
|
|
// 解析套餐ID
|
|
|
|
const resolvePlanIds = useCallback(() => { |
|
|
|
@ -296,31 +316,29 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
return requireLogin(); |
|
|
|
}, [requireLogin, resolvePlanIds, safeClose, t]); |
|
|
|
|
|
|
|
/** 微信预下单:仅拉 code_url,不跳转 */ |
|
|
|
const fetchWxOrder = useCallback( |
|
|
|
async (options?: { silent?: boolean }) => { |
|
|
|
if (submitting) return null; |
|
|
|
|
|
|
|
const { id, subscriptionId, packageId } = resolvePlanIds(); |
|
|
|
if (!id) { |
|
|
|
if (!options?.silent) { |
|
|
|
openPayNoticeModal("warning", { |
|
|
|
title: t("subscribe.pay_notice_missing_plan_title"), |
|
|
|
content: t("subscribe.missing_plan_info"), |
|
|
|
okText: t("button.okay"), |
|
|
|
onOk: safeClose, |
|
|
|
}); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
if (options?.silent) { |
|
|
|
if (!getToken() || !user) return null; |
|
|
|
} else if (!requireLogin()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
setSubmitting(true); |
|
|
|
const returnUrl = buildPaymentReturnUrl(payType, "WXPAY"); |
|
|
|
/** 微信下单:仅拉 code_url,不跳转 */ |
|
|
|
const fetchWxOrder = useCallback( |
|
|
|
async () => { |
|
|
|
if (submittingRef.current) return null; |
|
|
|
|
|
|
|
const requestSeq = nextPaymentRequestSeq(); |
|
|
|
stopPolling(); |
|
|
|
const { id, subscriptionId, packageId } = resolvePlanIds(); |
|
|
|
if (!id) { |
|
|
|
openPayNoticeModal("warning", { |
|
|
|
title: t("subscribe.pay_notice_missing_plan_title"), |
|
|
|
content: t("subscribe.missing_plan_info"), |
|
|
|
okText: t("button.okay"), |
|
|
|
onOk: safeClose, |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
if (!requireLogin()) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
setSubmittingState(true); |
|
|
|
const returnUrl = buildPaymentReturnUrl(payType, "WXPAY"); |
|
|
|
|
|
|
|
try { |
|
|
|
if (payType === "subscribe") { |
|
|
|
@ -328,60 +346,93 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
returnUrl, |
|
|
|
subscriptionId, |
|
|
|
}); |
|
|
|
if (!isPaymentRequestActive(requestSeq)) return null; |
|
|
|
if (!res) return null; |
|
|
|
if (!res.code_url) { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
wxOrderRef.current = res; |
|
|
|
setCodeUrl(res.code_url ?? ""); |
|
|
|
setCodeUrl(res.code_url); |
|
|
|
return res; |
|
|
|
} |
|
|
|
const { data: res } = await createPointsOrderByWxPay({ returnUrl, packageId }); |
|
|
|
if (!isPaymentRequestActive(requestSeq)) return null; |
|
|
|
if (!res) return null; |
|
|
|
if (!res.code_url) { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} |
|
|
|
wxOrderRef.current = res; |
|
|
|
setCodeUrl(res.code_url ?? ""); |
|
|
|
setCodeUrl(res.code_url); |
|
|
|
return res; |
|
|
|
} catch { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
onOk: safeClose, |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} finally { |
|
|
|
setSubmitting(false); |
|
|
|
} |
|
|
|
}, |
|
|
|
[payType, requireLogin, resolvePlanIds, safeClose, submitting, t, user], |
|
|
|
); |
|
|
|
|
|
|
|
/** 支付宝下单:同意后才调用,拿链接并跳转 */ |
|
|
|
const fetchAlipayAndRedirect = useCallback(async () => { |
|
|
|
if (submitting) return null; |
|
|
|
if (!assertPlanAndLogin()) return null; |
|
|
|
|
|
|
|
const { subscriptionId, packageId } = resolvePlanIds(); |
|
|
|
setSubmitting(true); |
|
|
|
const returnUrl = buildPaymentReturnUrl(payType, "ALIPAY"); |
|
|
|
|
|
|
|
try { |
|
|
|
const res = payType === "subscribe" ? (await createSubscriptionOrder({ returnUrl, subscriptionId })).data : (await createPointsOrder({ returnUrl, packageId })).data; |
|
|
|
|
|
|
|
if (res?.url) { |
|
|
|
schedulePoll(res, "ALIPAY"); |
|
|
|
location.href = res.url; |
|
|
|
} |
|
|
|
return res; |
|
|
|
} catch { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
onOk: safeClose, |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} finally { |
|
|
|
setSubmitting(false); |
|
|
|
} |
|
|
|
}, [assertPlanAndLogin, payType, resolvePlanIds, safeClose, schedulePoll, submitting, t]); |
|
|
|
} catch { |
|
|
|
if (isPaymentRequestActive(requestSeq)) { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
}); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} finally { |
|
|
|
if (isPaymentRequestActive(requestSeq)) { |
|
|
|
setSubmittingState(false); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
[isPaymentRequestActive, nextPaymentRequestSeq, payType, requireLogin, resolvePlanIds, safeClose, setSubmittingState, stopPolling, t], |
|
|
|
); |
|
|
|
|
|
|
|
/** 支付宝下单:同意后才调用,拿链接并跳转 */ |
|
|
|
const fetchAlipayAndRedirect = useCallback(async () => { |
|
|
|
if (submittingRef.current) return null; |
|
|
|
if (!assertPlanAndLogin()) return null; |
|
|
|
|
|
|
|
const requestSeq = nextPaymentRequestSeq(); |
|
|
|
stopPolling(); |
|
|
|
const { subscriptionId, packageId } = resolvePlanIds(); |
|
|
|
setSubmittingState(true); |
|
|
|
const returnUrl = buildPaymentReturnUrl(payType, "ALIPAY"); |
|
|
|
|
|
|
|
try { |
|
|
|
const res = payType === "subscribe" ? (await createSubscriptionOrder({ returnUrl, subscriptionId })).data : (await createPointsOrder({ returnUrl, packageId })).data; |
|
|
|
if (!isPaymentRequestActive(requestSeq)) return null; |
|
|
|
|
|
|
|
if (res?.url) { |
|
|
|
schedulePoll(res, "ALIPAY"); |
|
|
|
location.href = res.url; |
|
|
|
return res; |
|
|
|
} |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
}); |
|
|
|
return null; |
|
|
|
} catch { |
|
|
|
if (isPaymentRequestActive(requestSeq)) { |
|
|
|
openPayNoticeModal("error", { |
|
|
|
title: t("subscribe.pay_notice_start_failed_title"), |
|
|
|
content: t("subscribe.pay_start_failed"), |
|
|
|
okText: t("button.okay"), |
|
|
|
}); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} finally { |
|
|
|
if (isPaymentRequestActive(requestSeq)) { |
|
|
|
setSubmittingState(false); |
|
|
|
} |
|
|
|
} |
|
|
|
}, [assertPlanAndLogin, isPaymentRequestActive, nextPaymentRequestSeq, payType, resolvePlanIds, schedulePoll, setSubmittingState, stopPolling, t]); |
|
|
|
|
|
|
|
const resumeWxPolling = useCallback(() => { |
|
|
|
if (wxOrderRef.current) { |
|
|
|
@ -389,65 +440,46 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
} |
|
|
|
}, [schedulePoll]); |
|
|
|
|
|
|
|
/** 换套餐:重置微信同意态,预拉微信码 */ |
|
|
|
useEffect(() => { |
|
|
|
if (!planId) return; |
|
|
|
|
|
|
|
const cancellation = { current: false }; |
|
|
|
/** 换套餐:重置支付态,不自动创建订单 */ |
|
|
|
useEffect(() => { |
|
|
|
nextPaymentRequestSeq(); |
|
|
|
stopPolling(); |
|
|
|
setSubmittingState(false); |
|
|
|
setWxAgreed(false); |
|
|
|
setPaymentMethod("WXPAY"); |
|
|
|
setCodeUrl(""); |
|
|
|
wxOrderRef.current = null; |
|
|
|
setCodeUrl(""); |
|
|
|
}, [nextPaymentRequestSeq, planId, setSubmittingState, stopPolling]); |
|
|
|
|
|
|
|
void (async () => { |
|
|
|
if (!cancellation.current) { |
|
|
|
await fetchWxOrder({ silent: true }); |
|
|
|
} |
|
|
|
})(); |
|
|
|
const handlePaymentMethodChange = useCallback( |
|
|
|
(method: PaymentMethod) => { |
|
|
|
if (method === paymentMethod) return; |
|
|
|
if (submittingRef.current) return; |
|
|
|
|
|
|
|
return () => { |
|
|
|
cancellation.current = true; |
|
|
|
}; |
|
|
|
}, [fetchWxOrder, planId, stopPolling]); |
|
|
|
|
|
|
|
const handlePaymentMethodChange = useCallback( |
|
|
|
(method: PaymentMethod) => { |
|
|
|
if (method === paymentMethod) return; |
|
|
|
|
|
|
|
stopPolling(); |
|
|
|
setPaymentMethod(method); |
|
|
|
|
|
|
|
if (method === "WXPAY") { |
|
|
|
if (!codeUrl && !wxOrderRef.current?.code_url) { |
|
|
|
void fetchWxOrder(); |
|
|
|
} else if (wxAgreed) { |
|
|
|
resumeWxPolling(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
[codeUrl, fetchWxOrder, paymentMethod, resumeWxPolling, stopPolling, wxAgreed], |
|
|
|
); |
|
|
|
|
|
|
|
const handleAgreeAndPay = useCallback(async () => { |
|
|
|
if (submitting) return; |
|
|
|
if (!assertPlanAndLogin()) return; |
|
|
|
|
|
|
|
if (paymentMethod === "ALIPAY") { |
|
|
|
await fetchAlipayAndRedirect(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
setWxAgreed(true); |
|
|
|
|
|
|
|
let order: PaymentOrderData | null = wxOrderRef.current; |
|
|
|
if (!order?.code_url && !codeUrl) { |
|
|
|
order = await fetchWxOrder(); |
|
|
|
nextPaymentRequestSeq(); |
|
|
|
stopPolling(); |
|
|
|
setPaymentMethod(method); |
|
|
|
setWxAgreed(false); |
|
|
|
setCodeUrl(""); |
|
|
|
wxOrderRef.current = null; |
|
|
|
}, |
|
|
|
[nextPaymentRequestSeq, paymentMethod, stopPolling], |
|
|
|
); |
|
|
|
|
|
|
|
const handleAgreeAndPay = useCallback(async () => { |
|
|
|
if (submittingRef.current) return; |
|
|
|
|
|
|
|
if (paymentMethod === "ALIPAY") { |
|
|
|
await fetchAlipayAndRedirect(); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (order) { |
|
|
|
resumeWxPolling(); |
|
|
|
} |
|
|
|
}, [assertPlanAndLogin, codeUrl, fetchAlipayAndRedirect, fetchWxOrder, paymentMethod, resumeWxPolling, submitting]); |
|
|
|
|
|
|
|
const order = await fetchWxOrder(); |
|
|
|
if (order?.code_url) { |
|
|
|
setWxAgreed(true); |
|
|
|
resumeWxPolling(); |
|
|
|
} |
|
|
|
}, [fetchAlipayAndRedirect, fetchWxOrder, paymentMethod, resumeWxPolling]); |
|
|
|
|
|
|
|
const wxLogo = new URL("@/assets/images/logo_wxpay.png", import.meta.url).href; |
|
|
|
const alipayLogo = new URL("@/assets/images/logo_alipay.png", import.meta.url).href; |
|
|
|
@ -461,6 +493,7 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
<button |
|
|
|
type="button" |
|
|
|
className={["pay_subscribe_modal__method", paymentMethod === "WXPAY" ? "is_active" : ""].filter(Boolean).join(" ")} |
|
|
|
disabled={submitting} |
|
|
|
onClick={() => { |
|
|
|
handlePaymentMethodChange("WXPAY"); |
|
|
|
}} |
|
|
|
@ -471,6 +504,7 @@ export default function PaySubscribe({ onClose, type, plan, afterPaySuccess }: P |
|
|
|
<button |
|
|
|
type="button" |
|
|
|
className={["pay_subscribe_modal__method", paymentMethod === "ALIPAY" ? "is_active" : ""].filter(Boolean).join(" ")} |
|
|
|
disabled={submitting} |
|
|
|
onClick={() => { |
|
|
|
handlePaymentMethodChange("ALIPAY"); |
|
|
|
}} |
|
|
|
|