import { useCallback, useEffect, useState } from 'react'; import { View, Text } from '@tarojs/components'; import '../../styles/order.css'; import Taro, { useDidShow, useRouter } from '@tarojs/taro'; import PageShell from '../../components/PageShell'; import SubPageHeader from '../../components/SubPageHeader'; import WechatLoginButton from '../../components/WechatLoginButton'; import { ensurePayReady } from '../../lib/pay-ready'; import { authorizeWechatForPay, fetchClientConfig, fetchUserProfile, isWechatAuthRequiredError, needsWechatAuthForPay, payOrder, saveWechatLoginResult, } from '../../lib/pay-wechat'; import { applyWechatLoginResult } from '../../lib/wechat-auth'; import { isWechatEnv } from '../../lib/weixin'; import { goLogin } from '../../lib/auth-nav'; import { request, toast } from '../../lib/api'; export default function PayPage() { const router = useRouter(); const orderId = router.params.orderId ?? ''; const [loading, setLoading] = useState(false); const [authLoading, setAuthLoading] = useState(false); const [mockMode, setMockMode] = useState(true); const [needsWechatAuth, setNeedsWechatAuth] = useState(false); const [msg, setMsg] = useState(''); const [orderNo, setOrderNo] = useState(''); const [payAmount, setPayAmount] = useState('—'); const [deliveryType, setDeliveryType] = useState(''); const returnPath = orderId ? `/pages/pay/index?orderId=${orderId}` : '/pages/pay/index'; const refreshPayReadiness = useCallback(async () => { try { const [config, profile] = await Promise.all([fetchClientConfig(), fetchUserProfile()]); setMockMode(config.mockPay); setNeedsWechatAuth(needsWechatAuthForPay(config, profile)); return profile; } catch { return null; } }, []); useDidShow(() => { void refreshPayReadiness(); }); useEffect(() => { if (!orderId) return; if (process.env.TARO_ENV === 'weapp') { void ensurePayReady(returnPath); } }, [orderId, returnPath]); useEffect(() => { if (!orderId) { setOrderNo(''); setPayAmount('—'); return; } request<{ orderNo?: string; payAmount?: number | string; totalAmount?: number | string; deliveryType?: string; }>(`/trade/orders/${orderId}`) .then((order) => { setOrderNo(order.orderNo || ''); setDeliveryType(order.deliveryType || ''); const amount = Number(order.payAmount ?? order.totalAmount ?? 0); if (Number.isFinite(amount) && amount > 0) { setPayAmount(amount.toFixed(2)); } }) .catch((e) => { setOrderNo(''); setDeliveryType(''); toast(e instanceof Error ? e.message : '加载订单失败'); }); }, [orderId]); async function wechatAuthorize() { setAuthLoading(true); setMsg(''); try { if (!isWechatEnv()) { setMsg('请在微信内打开以授权微信支付'); return; } if (process.env.TARO_ENV === 'weapp') { const ready = await ensurePayReady(returnPath); if (ready) await refreshPayReadiness(); return; } const result = await authorizeWechatForPay(); if (result) { if (result.needBindPhone && result.wxSessionKey) { goLogin(returnPath, { bindMode: '1', wxSessionKey: result.wxSessionKey }); return; } if (saveWechatLoginResult(result) || applyWechatLoginResult(result)) { setMsg(''); await refreshPayReadiness(); toast('微信授权成功', 'success'); } } } catch (e) { setMsg(e instanceof Error ? e.message : '微信授权失败'); } finally { setAuthLoading(false); } } async function pay() { if (!orderId) { toast('订单不存在'); return; } if (needsWechatAuth) { setMsg('请先完成微信授权后再支付'); if (process.env.TARO_ENV === 'h5') { await wechatAuthorize(); } else { await ensurePayReady(returnPath); } return; } const ready = await ensurePayReady(returnPath); if (!ready) return; setLoading(true); setMsg(''); try { const status = await payOrder(orderId); if (status === 'pending') { toast('支付结果确认中,请稍后在订单列表查看'); } else { toast('支付成功', 'success'); } if (deliveryType === 'ON_SITE_PICKUP') { // 现场提货支付即完成 → 订单详情;from=pay 返回强制回首页,避免 navigateBack 退出小程序 Taro.reLaunch({ url: `/pages/order-detail/index?id=${orderId}&from=pay` }); } else { Taro.reLaunch({ url: '/pages/orders/index?tab=paid&from=pay' }); } } catch (e) { if (isWechatAuthRequiredError(e)) { setNeedsWechatAuth(true); setMsg('微信支付需要先完成微信授权'); return; } const message = e instanceof Error ? e.message : '支付失败'; if (message.includes('取消')) { setMsg('已取消支付'); return; } setMsg(message); toast(message); } finally { setLoading(false); } } return ( ¥ {needsWechatAuth ? '需完成微信授权' : '待支付'} ¥{payAmount} {needsWechatAuth ? ( 尚未授权微信 授权后可安全调起微信支付,不会重复扣款 void wechatAuthorize()} /> ) : null} 订单号 {orderNo || '—'} 支付方式 微信支付 说明 {mockMode ? 'Mock 模式由服务端直接标记已付款' : '将调起微信收银台'} {msg ? ( {msg} ) : null} { if (loading) return; if (needsWechatAuth) { void wechatAuthorize(); return; } void pay(); }} > {loading ? '支付中…' : needsWechatAuth ? authLoading ? '授权中…' : '微信一键授权' : '立即支付'} ); }