Files
jurong_circle_black/routes/wechatPay.js

202 lines
5.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;