支付回调内容

描述

  作为新手开发,哈哈,请大佬多加指点。

  nodejs开发微信公众号真的让我特别的烦,微信的沙箱功能一点都不好使。完成了支付功能后还要处理支付回调的业务逻辑,这次我要做的就是支付后完成推送模板消息的内容。

过程

  填写完成支付的回调地址notify_url后,进入到了公网能够直接访问的回调地址。(这里需要注意的是回调和支付都要加入到支付的安全目录,比如支付或者回调的路由为http://www.aaa.ccc/pay/notify,则支付目录直接填写http://www.aaa.ccc/pay)

  当支付功能实现后,微信服务器会以post的方式访问这个地址,并提供一串xml格式的数据(解析xml的方式我觉得用raw-body或者koa-xml-body都是蛮不错的)。

  支付回调微信服务器会多次post请求,我试过用xml包装

  <xml>
    <return_code><![CDATA[<%=return_code%>]]></return_code>
    <return_msg><![CDATA[<%=return_msg%>]]></return_msg>
  </xml>

但还是失败的,依然会多次请求。所以我就定义了一个变量,用作标量。但是这样会遇到的问题就是,一个人购买成功,推送了一条模板消息。接下来另外一个人购买,就会遇到推送不出去的模板消息。所以我做了一些调整,就是查询订单,然后再到数据库里面去查询订单,通过比较后再进行相应的逻辑处理。

代码

   Demo1 

const xmlParse = require('koa-xml-body');
const getRawBody = require('raw-body');
const heredoc = require('heredoc');
const ejs = require('ejs');

const util = require('../../utils/util');

let flag = 1;
/**
微信回调通知
*/
exports.notify = async(ctx,next)=>{
console.log('<===============================支付回调开始==================================>');
console.log('<===============================支付成功==================================>');
let backXml = {};
//console.log('支付回调后的数据:',ctx);
let data = await getRawBody(ctx.req,{
  length:ctx.length,
  limit:'1mb',
  encoding:ctx.charset
});
data = await util.parseXMLAsync(data);
data = util.formatMessage(data.xml);
console.log('data:',data);
ctx.data = data;
if(data.result_code === 'SUCCESS' && (flag++) === 1){
  await putMsg.payOk(ctx,next);
  backXml.code = 'SUCCESS';
  backXml.msg = 'OK'
}else{
  backXml.code = 'FAIL';
  backXml.msg = '报文为空';
}
console.log('<===============================支付回调结束==================================>');
  return backTemp(backXml);
}

/**
用于返回给微信服务器的数据
告诉微信服务器,我收到信息了,不要在调用回调action了
*/
let backTemp = (data)=>{
  let xmlDataTmpl = heredoc(function(body){/*
     <xml>
      <return_code><![CDATA[<%=return_code%>]]></return_code>
      <return_msg><![CDATA[<%=return_msg%>]]></return_msg>
     </xml>
  */});
  data = ejs.compile(xmlDataTmpl)({return_code:data.code,return_msg:data.msg});
  console.log(data);
  return data;
}

Demo2

  查询订单orderquery

  exports.orderquery = async(ctx)=>{

//请求路径

let url = 'https://api.mch.weixin.qq.com/pay/orderquery';
//请求参数
let data = {

appid : ctx.orderqueryData.appid,
mch_id : ctx.orderqueryData.mch_id,
out_trade_no : ctx.orderqueryData.out_trade_no,
nonce_str : ctx.orderqueryData.nonce_str,
transaction_id : ctx.orderqueryData.transaction_id,
sign_type : ctx.orderqueryData.sign_type||'MD5',
key : ctx.orderqueryData.key

}
let stringA = 'appid='+ data.appid
      +'&mch_id='+ data.mch_id
      +'&nonce_str='+ data.nonce_str
      +'&out_trade_no='+ data.out_trade_no
      +'&sign_type=' + data.sign_type
      +'&transaction_id='+ data.transaction_id;
let stringSignTemp = stringA + '&key=' + config.config.wechat.key;
console.log('加密的sign:',stringSignTemp);
data.sign = MD5(stringSignTemp).toUpperCase();
//封装成xml
let xmlDataTmpl = heredoc(function(body){/*
    <xml>
    <appid><%=appid%></appid>
    <mch_id><%=mch_id%></mch_id>
    <nonce_str><%=nonce_str%></nonce_str>
    <out_trade_no><%=out_trade_no%></out_trade_no>
    <sign_type><%=sign_type%></sign_type>
    <transaction_id><%=transaction_id%></transaction_id>
    <sign><%=sign%></sign>
  </xml>
*/});
data = ejs.compile(xmlDataTmpl)(data);
console.log('orderquery的ejs解析支付的xml数据为:',data);
data = await request({url:url,method:'post',body:data,xml:true});
console.log('orderquery通过接口请求后得到的数据:',data.body);
data = await util.parseXMLAsync(data.body);
data = util.formatMessage(data.xml);
console.log('经过处理后的data:',data);
return data;

}

  回调通知

exports.notify = async(ctx,next)=>{
console.log('<===============================支付回调开始==================================>');
//用于返回给微信服务的状态通知
let backXml = {};
//解析微信服务器发过来的xml数据
let data = await getRawBody(ctx.req,{
  length:ctx.length,
  limit:'1mb',
  encoding:ctx.charset
});
data = await util.parseXMLAsync(data);
data = util.formatMessage(data.xml);
//查询订单
ctx.orderqueryData = data;
data = await pay.orderquery(ctx);
console.log('查询订单返回的数据:',data);
//查询数据库里面的订单
dbData = await Order.findOne({transaction_id:data.transaction_id}).exec();
console.log('从数据库里面查询到的数据:',dbData);
console.log('dbData',dbData);
if(data.trade_state === 'SUCCESS' && !dbData){
  //生成订单
  let order = new Order({
  transaction_id : data.transaction_id
});
let doc = await order.save();
if(doc){
  ctx.data = data;
  putMsg.payOk(ctx);
  backXml.code = "SUCCESS";
  backXml.msg = '添加订单成功!';
}else{
  backXml.code = "FAIL";
  backXml.msg = '添加订单失败!';
}
  return backTemp(backXml);
}
}

 

 

posted @ 2018-07-02 11:10  甜珊贝奇  阅读(504)  评论(0编辑  收藏  举报