update pay ui

This commit is contained in:
2025-12-13 10:31:46 +08:00
parent 1949d9b922
commit 5e8c2400a3
4 changed files with 253 additions and 27 deletions

View File

@@ -185,6 +185,79 @@ export default function SubscriptionContentNew() {
fetchSubscriptionPlans();
}, []);
// 检查是否从支付宝支付返回(手机端支付完成后会跳转回来)
useEffect(() => {
const checkAlipayReturn = async () => {
// 检查 URL 参数是否包含支付宝返回标记
const urlParams = new URLSearchParams(window.location.search);
const paymentReturn = urlParams.get('payment_return');
// 支付宝返回的参数是 out_trade_no后端重定向时会转成 order_no
const orderNo = urlParams.get('order_no') || urlParams.get('out_trade_no');
if (paymentReturn === 'alipay' && orderNo) {
// 从支付宝返回,检查支付状态
toast({
title: '正在确认支付结果...',
status: 'info',
duration: 2000,
isClosable: true,
});
try {
// 优先使用 sessionStorage 中的 orderId否则使用 order_no 查询
const orderId = sessionStorage.getItem('alipay_order_id');
const statusUrl = orderId
? `/api/payment/alipay/order/${orderId}/status`
: `/api/payment/alipay/order-by-no/${orderNo}/status`;
const response = await fetch(statusUrl, {
credentials: 'include',
});
if (response.ok) {
const data = await response.json();
if (data.success && (data.data?.status === 'paid' || data.payment_success)) {
toast({
title: '支付成功!',
description: '您的订阅已激活',
status: 'success',
duration: 5000,
isClosable: true,
});
// 清理 sessionStorage
sessionStorage.removeItem('alipay_order_id');
sessionStorage.removeItem('alipay_order_no');
// 清除 URL 参数并刷新页面
window.history.replaceState({}, document.title, window.location.pathname);
setTimeout(() => window.location.reload(), 2000);
} else {
toast({
title: '支付状态待确认',
description: '如已完成支付,请稍候或刷新页面',
status: 'warning',
duration: 5000,
isClosable: true,
});
// 清除 URL 参数
window.history.replaceState({}, document.title, window.location.pathname);
}
} else {
// 清除 URL 参数
window.history.replaceState({}, document.title, window.location.pathname);
}
} catch (error) {
logger.error('SubscriptionContentNew', 'checkAlipayReturn', error);
// 清除 URL 参数
window.history.replaceState({}, document.title, window.location.pathname);
}
}
};
checkAlipayReturn();
}, [toast]);
const fetchSubscriptionPlans = async () => {
try {
logger.debug('SubscriptionContentNew', '正在获取订阅套餐');
@@ -409,6 +482,9 @@ export default function SubscriptionContentNew() {
? '/api/payment/alipay/create-order'
: '/api/payment/create-order';
// 检测是否为移动端设备
const isMobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
@@ -419,6 +495,7 @@ export default function SubscriptionContentNew() {
plan_name: selectedPlan.name,
billing_cycle: selectedCycle,
promo_code: promoCodeApplied ? promoCode : null,
is_mobile: isMobileDevice, // 传递设备类型,用于支付宝选择 page/wap 支付
}),
});
@@ -428,22 +505,46 @@ export default function SubscriptionContentNew() {
if (paymentMethod === 'alipay') {
// 支付宝:跳转到支付页面
if (data.data.pay_url) {
setPaymentOrder(data.data);
setPaymentCountdown(30 * 60);
startAutoPaymentCheck(data.data.id, 'alipay');
// 检测是否为移动端设备
const isMobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
toast({
title: '订单创建成功',
description: '正在跳转到支付宝支付页面...',
status: 'success',
duration: 3000,
isClosable: true,
});
if (isMobileDevice) {
// 手机端直接在当前页面跳转可调起支付宝APP
toast({
title: '订单创建成功',
description: '正在跳转到支付宝...',
status: 'success',
duration: 2000,
isClosable: true,
});
// 延迟跳转,让用户看到提示
setTimeout(() => {
window.open(data.data.pay_url, '_blank');
}, 500);
// 保存订单信息到 sessionStorage支付完成后返回时可以用来检查状态
sessionStorage.setItem('alipay_order_id', data.data.id);
sessionStorage.setItem('alipay_order_no', data.data.order_no);
// 延迟跳转,让用户看到提示
setTimeout(() => {
window.location.href = data.data.pay_url;
}, 500);
} else {
// PC端新窗口打开
setPaymentOrder(data.data);
setPaymentCountdown(30 * 60);
startAutoPaymentCheck(data.data.id, 'alipay');
toast({
title: '订单创建成功',
description: '正在跳转到支付宝支付页面...',
status: 'success',
duration: 3000,
isClosable: true,
});
// 延迟跳转,让用户看到提示
setTimeout(() => {
window.open(data.data.pay_url, '_blank');
}, 500);
}
} else {
throw new Error('支付链接获取失败');
}