const API = require('../../lib/API') const { BaseStdResponse } = require('../../BaseStdResponse') const crypto = require('crypto') const { resolveBusinessOrderId } = require('../../lib/OrderPaymentAttempt') const { getPaymentConfig } = require('../../lib/PaymentClient') const { completePaidOrder } = require('../../lib/OrderSettlement') function buildSign(params, key) { const raw = Object.keys(params) .sort() .map(name => `${name}=${params[name]}`) .join('&') + key return crypto.createHash('md5').update(raw, 'utf8').digest('hex') } class CallBack extends API { constructor() { super() this.noEncrypt() this.setPath('/Order/CallBack') this.setMethod('GET') } async onRequest(req, res) { const { pid, trade_no, out_trade_no, type, name, money, trade_status, sign, sign_type } = req.query if ([pid, trade_no, out_trade_no, type, name, money, trade_status, sign, sign_type].some(v => v === undefined)) { return res.json({ ...BaseStdResponse.MISSING_PARAMETER }) } this.logger.info(`收到支付回调,网关订单号:${out_trade_no}`) const paymentConfig = await getPaymentConfig() const rawParams = { money, name, out_trade_no, pid, trade_no, trade_status, type } const localSign = buildSign(rawParams, paymentConfig.key) if (localSign.toLowerCase() !== String(sign).toLowerCase()) { this.logger.error(`支付回调签名校验失败,网关订单号:${out_trade_no}`) return res.send('sign fail') } const orderId = await resolveBusinessOrderId(out_trade_no) if (trade_status !== 'TRADE_SUCCESS') { this.logger.info(`支付回调未成功,忽略并等待订单超时处理。网关订单号:${out_trade_no},业务订单号:${orderId}`) return res.send('success') } const result = await completePaidOrder({ orderId, payType: type, payId: trade_no, payTime: Date.now(), paidAmount: money, logger: this.logger }) if (result.completed) return res.send('success') if (result.reason === 'state_changed') return res.send('success') this.logger.error(`支付回调处理失败,业务订单号:${orderId},原因:${result.reason}`) return res.send('fail') } } module.exports.CallBack = CallBack