const { express, requireAuth, isSystemAdmin, wechatPay, alipay, pool } = require("./context"); function registerPaymentRoutes(router) { // ── Payment ────────────────────────────────────────────────────────── function getNotifyBaseUrl() { return process.env.PAYMENT_NOTIFY_BASE_URL || ""; } router.post("/payment/create", requireAuth, async (req, res) => { const { orderNo, paymentMethod = "wechat" } = req.body; if (!orderNo) return res.status(400).json({ error: "缺少订单号" }); const { rows: [order], } = await pool.query("SELECT * FROM payment_orders WHERE order_no = $1 AND status = $2", [ orderNo, "pending", ]); if (!order) return res.status(404).json({ error: "订单不存在或已处理" }); // Verify order belongs to user const isOwnOrder = (order.enterprise_id && req.user.enterpriseId && order.enterprise_id === req.user.enterpriseId) || (order.user_id && order.user_id === req.user.id); if (!isOwnOrder && !isSystemAdmin(req.user)) { return res.status(403).json({ error: "无权操作此订单" }); } const notifyBase = getNotifyBaseUrl(); const description = order.type === "package" ? `套餐购买 - ${order.order_no}` : `积分充值 - ${order.order_no}`; try { if (paymentMethod === "wechat") { if (!wechatPay.isWechatPayEnabled()) return res.status(503).json({ error: "微信支付未配置" }); const notifyUrl = notifyBase ? `${notifyBase}/api/payment/notify/wechat` : ""; const result = await wechatPay.createNativeOrder( orderNo, order.amount_cents, description, notifyUrl, ); return res.json({ paymentMethod: "wechat", codeUrl: result.codeUrl, orderNo }); } if (paymentMethod === "alipay") { if (!alipay.isAlipayEnabled()) return res.status(503).json({ error: "支付宝未配置" }); const notifyUrl = notifyBase ? `${notifyBase}/api/payment/notify/alipay` : ""; const result = await alipay.createPrecreateOrder( orderNo, order.amount_cents, description, notifyUrl, ); return res.json({ paymentMethod: "alipay", codeUrl: result.qrCode, orderNo }); } return res.status(400).json({ error: "不支持的支付方式" }); } catch (err) { console.error("[payment/create] failed", err.message); res.status(500).json({ error: `创建支付失败: ${err.message}` }); } }); router.get("/payment/status", requireAuth, async (req, res) => { const { orderNo } = req.query; if (!orderNo) return res.status(400).json({ error: "缺少订单号" }); const { rows: [order], } = await pool.query( "SELECT order_no, status, amount_cents, payment_method, paid_at, enterprise_id, user_id FROM payment_orders WHERE order_no = $1", [orderNo], ); if (!order) return res.status(404).json({ error: "订单不存在" }); const isOwn = (order.enterprise_id && req.user.enterpriseId && order.enterprise_id === req.user.enterpriseId) || (order.user_id && order.user_id === req.user.id); if (!isOwn && !isSystemAdmin(req.user)) { return res.status(403).json({ error: "无权查看此订单" }); } res.json({ orderNo: order.order_no, status: order.status, amountCents: order.amount_cents, paymentMethod: order.payment_method, paidAt: order.paid_at, }); }); router.post("/payment/notify/wechat", express.raw({ type: "*/*" }), (req, res) => { try { let body = req.body; if (Buffer.isBuffer(body)) body = JSON.parse(body.toString("utf-8")); const result = wechatPay.verifyAndDecryptNotification(req.headers, body); if (!result) return res.status(400).json({ code: "FAIL", message: "签名验证失败" }); if (result.trade_state === "SUCCESS") { wechatPay.handlePaymentSuccess(result.out_trade_no, result.transaction_id); } res.json({ code: "SUCCESS", message: "OK" }); } catch (err) { console.error("[payment/notify/wechat] error:", err.message); res.status(500).json({ code: "FAIL", message: "Internal error" }); } }); router.post("/payment/notify/alipay", express.urlencoded({ extended: false }), (req, res) => { try { const body = req.body; const verified = alipay.verifyCallback(req.headers, body); if (!verified) return res.send("fail"); const orderNo = body.out_trade_no || body.trade_no; const tradeNo = body.trade_no || body.trade_id; if (body.trade_status === "TRADE_SUCCESS" || body.trade_status === "TRADE_FINISHED") { alipay.handlePaymentSuccess(orderNo, tradeNo); } res.send("success"); } catch (err) { console.error("[payment/notify/alipay] error:", err.message); res.send("fail"); } }); router.get("/payment/methods", (_req, res) => { res.json({ wechat: wechatPay.isWechatPayEnabled(), alipay: alipay.isAlipayEnabled() }); }); } module.exports = { registerPaymentRoutes, };