Files
jurong_circle_black/services/alipayservice.js

224 lines
6.6 KiB
JavaScript
Raw Normal View History

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<Object>} 支付结果
*/
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<Object>} 查询结果
*/
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;