CallBack.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. const API = require('../../lib/API')
  2. const { BaseStdResponse } = require('../../BaseStdResponse')
  3. const crypto = require('crypto')
  4. const { resolveBusinessOrderId } = require('../../lib/OrderPaymentAttempt')
  5. const { getPaymentConfig } = require('../../lib/PaymentClient')
  6. const { completePaidOrder } = require('../../lib/OrderSettlement')
  7. function buildSign(params, key) {
  8. const raw = Object.keys(params)
  9. .sort()
  10. .map(name => `${name}=${params[name]}`)
  11. .join('&') + key
  12. return crypto.createHash('md5').update(raw, 'utf8').digest('hex')
  13. }
  14. class CallBack extends API {
  15. constructor() {
  16. super()
  17. this.noEncrypt()
  18. this.setPath('/Order/CallBack')
  19. this.setMethod('GET')
  20. }
  21. async onRequest(req, res) {
  22. const {
  23. pid, trade_no, out_trade_no, type, name, money,
  24. trade_status, sign, sign_type
  25. } = req.query
  26. if ([pid, trade_no, out_trade_no, type, name, money, trade_status, sign, sign_type].some(v => v === undefined)) {
  27. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  28. }
  29. this.logger.info(`收到支付回调,网关订单号:${out_trade_no}`)
  30. const paymentConfig = await getPaymentConfig()
  31. const rawParams = { money, name, out_trade_no, pid, trade_no, trade_status, type }
  32. const localSign = buildSign(rawParams, paymentConfig.key)
  33. if (localSign.toLowerCase() !== String(sign).toLowerCase()) {
  34. this.logger.error(`支付回调签名校验失败,网关订单号:${out_trade_no}`)
  35. return res.send('sign fail')
  36. }
  37. const orderId = await resolveBusinessOrderId(out_trade_no)
  38. if (trade_status !== 'TRADE_SUCCESS') {
  39. this.logger.info(`支付回调未成功,忽略并等待订单超时处理。网关订单号:${out_trade_no},业务订单号:${orderId}`)
  40. return res.send('success')
  41. }
  42. const result = await completePaidOrder({
  43. orderId,
  44. payType: type,
  45. payId: trade_no,
  46. payTime: Date.now(),
  47. paidAmount: money,
  48. logger: this.logger
  49. })
  50. if (result.completed) return res.send('success')
  51. if (result.reason === 'state_changed') return res.send('success')
  52. this.logger.error(`支付回调处理失败,业务订单号:${orderId},原因:${result.reason}`)
  53. return res.send('fail')
  54. }
  55. }
  56. module.exports.CallBack = CallBack