202 lines
5.2 KiB
JavaScript
202 lines
5.2 KiB
JavaScript
const express = require('express');
|
||
const router = express.Router();
|
||
const WechatPayService = require('../services/wechatPayService');
|
||
const { getDB } = require('../database');
|
||
const { auth, paymentAuth } = require('../middleware/auth');
|
||
|
||
// 创建微信支付服务实例
|
||
const wechatPayService = new WechatPayService();
|
||
|
||
/**
|
||
* 创建注册支付订单 (API v3 - H5支付)
|
||
* POST /api/wechat-pay/create-registration-order
|
||
*/
|
||
router.post('/create-registration-order', paymentAuth, async (req, res) => {
|
||
try {
|
||
const userId = req.user.id;
|
||
const username = req.user.username;
|
||
const phone = req.user.phone;
|
||
|
||
// 获取客户端IP
|
||
const clientIp = req.headers['x-forwarded-for'] ||
|
||
req.headers['x-real-ip'] ||
|
||
req.connection.remoteAddress ||
|
||
req.socket.remoteAddress ||
|
||
(req.connection.socket ? req.connection.socket.remoteAddress : null) ||
|
||
'127.0.0.1';
|
||
|
||
// 检查用户是否已经支付过
|
||
const db = getDB();
|
||
const [existingOrders] = await db.execute(
|
||
'SELECT id FROM payment_orders WHERE user_id = ? AND status = "paid"',
|
||
[userId]
|
||
);
|
||
|
||
if (existingOrders.length > 0) {
|
||
return res.status(400).json({
|
||
success: false,
|
||
message: '用户已完成支付,无需重复支付'
|
||
});
|
||
}
|
||
|
||
console.log('创建H5支付订单:', {
|
||
userId,
|
||
username,
|
||
phone,
|
||
clientIp
|
||
});
|
||
|
||
// 创建H5支付订单
|
||
const result = await wechatPayService.createRegistrationPayOrder({
|
||
userId,
|
||
username,
|
||
phone,
|
||
clientIp
|
||
});
|
||
|
||
if (result.success) {
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
outTradeNo: result.data.outTradeNo,
|
||
h5Url: result.data.h5Url,
|
||
paymentType: result.data.paymentType
|
||
}
|
||
});
|
||
} else {
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '创建支付订单失败'
|
||
});
|
||
}
|
||
} catch (error) {
|
||
console.error('创建H5支付订单异常:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: error.message || '服务器内部错误'
|
||
});
|
||
}
|
||
});
|
||
|
||
// H5支付不需要获取openid,移除相关接口
|
||
|
||
/**
|
||
* 微信支付回调接口 (API v3)
|
||
* POST /api/wechat-pay/notify
|
||
*/
|
||
router.post('/notify', async (req, res) => {
|
||
try {
|
||
// API v3 回调是JSON格式
|
||
const notifyData = req.body;
|
||
|
||
// 获取请求头中的签名信息
|
||
const signature = req.headers['wechatpay-signature'];
|
||
const timestamp = req.headers['wechatpay-timestamp'];
|
||
const nonce = req.headers['wechatpay-nonce'];
|
||
const serial = req.headers['wechatpay-serial'];
|
||
|
||
console.log('收到API v3支付回调:', {
|
||
signature,
|
||
timestamp,
|
||
nonce,
|
||
serial,
|
||
body: notifyData
|
||
});
|
||
|
||
// 验证签名和处理回调
|
||
const result = await wechatPayService.handleV3PaymentNotify({
|
||
signature,
|
||
timestamp,
|
||
nonce,
|
||
serial,
|
||
body: JSON.stringify(notifyData)
|
||
});
|
||
|
||
if (result.success) {
|
||
// API v3 成功响应
|
||
res.status(200).json({ code: 'SUCCESS', message: '成功' });
|
||
} else {
|
||
// API v3 失败响应
|
||
res.status(400).json({ code: 'FAIL', message: result.message || '处理失败' });
|
||
}
|
||
} catch (error) {
|
||
console.error('支付回调处理异常:', error);
|
||
res.status(500).json({ code: 'ERROR', message: '服务器内部错误' });
|
||
}
|
||
});
|
||
|
||
/**
|
||
* 查询支付状态
|
||
* GET /api/wechat-pay/query-status/:outTradeNo
|
||
*/
|
||
router.get('/query-status/:outTradeNo', paymentAuth, async (req, res) => {
|
||
try {
|
||
const { outTradeNo } = req.params;
|
||
const userId = req.user.id;
|
||
|
||
// 验证订单是否属于当前用户
|
||
const db = getDB();
|
||
const [orders] = await db.execute(
|
||
'SELECT id FROM payment_orders WHERE out_trade_no = ? AND user_id = ?',
|
||
[outTradeNo, userId]
|
||
);
|
||
|
||
if (orders.length === 0) {
|
||
return res.status(404).json({
|
||
success: false,
|
||
message: '订单不存在或无权限访问'
|
||
});
|
||
}
|
||
|
||
const result = await wechatPayService.queryPaymentStatus(outTradeNo);
|
||
res.json(result);
|
||
} catch (error) {
|
||
console.error('查询支付状态失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: error.message || '查询支付状态失败'
|
||
});
|
||
}
|
||
});
|
||
|
||
/**
|
||
* 检查用户支付状态
|
||
* GET /api/wechat-pay/check-user-payment
|
||
*/
|
||
router.get('/check-user-payment', auth, async (req, res) => {
|
||
try {
|
||
const userId = req.user.id;
|
||
const db = getDB();
|
||
|
||
// 查询用户支付状态
|
||
const [users] = await db.execute(
|
||
'SELECT payment_status FROM users WHERE id = ?',
|
||
[userId]
|
||
);
|
||
|
||
if (users.length === 0) {
|
||
return res.status(404).json({
|
||
success: false,
|
||
message: '用户不存在'
|
||
});
|
||
}
|
||
|
||
const paymentStatus = users[0].payment_status;
|
||
|
||
res.json({
|
||
success: true,
|
||
data: {
|
||
paymentStatus,
|
||
isPaid: paymentStatus === 'paid'
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('检查用户支付状态失败:', error);
|
||
res.status(500).json({
|
||
success: false,
|
||
message: '检查支付状态失败'
|
||
});
|
||
}
|
||
});
|
||
|
||
module.exports = router; |