const { AlipaySdk } = require('alipay-sdk'); const { getDB } = require('../database'); const crypto = require('crypto'); const path = require('path'); const fs = require('fs'); class AlipayService { constructor() { // 读取密钥文件 const privateKeyPath = path.join(__dirname, '../certs/alipay-private-key.pem'); const publicKeyPath = path.join(__dirname, '../certs/alipay-public-key.pem'); const privateKey = fs.readFileSync(privateKeyPath, 'utf8'); const alipayPublicKey = fs.readFileSync(publicKeyPath, 'utf8'); // 支付宝配置 this.config = { appId: process.env.ALIPAY_APP_ID || '2021001161683774', // 替换为实际的应用ID privateKey: privateKey, // 从文件读取的应用私钥 alipayPublicKey: alipayPublicKey, // 从文件读取的支付宝公钥 gateway: 'https://openapi.alipay.com/gateway.do', // 支付宝网关地址 signType: 'RSA2', charset: 'utf-8', version: '1.0', timeout: 5000 }; // 初始化支付宝SDK this.alipaySdk = new AlipaySdk({ appId: this.config.appId, privateKey: this.config.privateKey, alipayPublicKey: this.config.alipayPublicKey, gateway: this.config.gateway, signType: this.config.signType, timeout: this.config.timeout }); } /** * 创建注册支付订单 * @param {Object} params - 支付参数 * @param {string} params.userId - 用户ID * @param {string} params.username - 用户名 * @param {string} params.phone - 手机号 * @param {string} params.clientIp - 客户端IP * @returns {Promise} 支付结果 */ async createRegistrationPayOrder({ userId, username, phone, clientIp }) { try { const db = getDB(); // 生成订单号 const outTradeNo = this.generateOrderNo(); const totalFee = 39900; // 399元,单位:分 const subject = '用户注册激活费用'; const body = `用户${username}(${phone})注册激活费用`; // 业务参数 const bizContent = { out_trade_no: outTradeNo, total_amount: (totalFee / 100).toFixed(2), // 转换为元 subject: subject, body: body, product_code: 'QUICK_WAP_WAY', quit_url: process.env.ALIPAY_QUIT_URL || 'https://your-domain.com/payment/cancel' }; // 使用新版SDK的pageExecute方法生成支付URL const payUrl = this.alipaySdk.pageExecute('alipay.trade.wap.pay', 'GET', { bizContent: bizContent, notifyUrl: process.env.ALIPAY_NOTIFY_URL || 'https://your-domain.com/api/payment/alipay/notify', returnUrl: process.env.ALIPAY_RETURN_URL || 'https://your-domain.com/payment/success' }); // 保存订单到数据库 await db.execute( `INSERT INTO payment_orders (user_id, out_trade_no, total_fee, body, trade_type, status, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())`, [userId, outTradeNo, totalFee, body, 'ALIPAY_WAP', 'pending'] ); console.log('支付宝支付订单创建成功:', { userId, outTradeNo, totalFee, payUrl }); return { success: true, data: { outTradeNo, payUrl, paymentType: 'alipay_wap', totalFee } }; } catch (error) { console.error('创建支付宝支付订单失败:', error); return { success: false, message: error.message || '创建支付订单失败' }; } } /** * 查询支付状态 * @param {string} outTradeNo - 商户订单号 * @returns {Promise} 查询结果 */ async queryPaymentStatus(outTradeNo) { try { const result = await this.alipaySdk.exec('alipay.trade.query', { bizContent: { out_trade_no: outTradeNo } }); if (result.code === '10000') { // 查询成功 const tradeStatus = result.tradeStatus; // 如果支付成功,更新数据库 if (tradeStatus === 'TRADE_SUCCESS') { await this.updatePaymentStatus(outTradeNo, { status: 'paid', transactionId: result.tradeNo, paidAt: new Date() }); } return { success: true, data: { trade_status: tradeStatus, trade_no: result.tradeNo, total_amount: result.totalAmount, buyer_pay_amount: result.buyerPayAmount, gmt_payment: result.gmtPayment } }; } else { return { success: false, message: result.msg || '查询支付状态失败' }; } } catch (error) { console.error('查询支付宝支付状态失败:', error); return { success: false, message: error.message || '查询支付状态失败' }; } } /** * 更新支付状态 * @param {string} outTradeNo - 商户订单号 * @param {Object} updateData - 更新数据 */ async updatePaymentStatus(outTradeNo, updateData) { try { const db = getDB(); // 更新订单状态 await db.execute( `UPDATE payment_orders SET status = ?, transaction_id = ?, paid_at = ? WHERE out_trade_no = ?`, [updateData.status, updateData.transactionId, updateData.paidAt, outTradeNo] ); // 如果支付成功,更新用户支付状态 if (updateData.status === 'paid') { const [orders] = await db.execute( 'SELECT user_id FROM payment_orders WHERE out_trade_no = ?', [outTradeNo] ); if (orders.length > 0) { const userId = orders[0].user_id; await db.execute( 'UPDATE users SET payment_status = ? WHERE id = ?', ['paid', userId] ); console.log('用户支付状态更新成功:', { userId, outTradeNo }); } } } catch (error) { console.error('更新支付状态失败:', error); throw error; } } /** * 验证支付宝回调签名 * @param {Object} params - 回调参数 * @returns {boolean} 验证结果 */ verifyNotifySign(params) { try { return this.alipaySdk.checkNotifySign(params); } catch (error) { console.error('验证支付宝回调签名失败:', error); return false; } } /** * 生成订单号 * @returns {string} 订单号 */ generateOrderNo() { const timestamp = Date.now(); const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); return `ALI${timestamp}${random}`; } } module.exports = AlipayService;