当前位置 博文首页 > RunningOnMyWay的博客:nodejs实现微信app支付-创建订单与签名部

    RunningOnMyWay的博客:nodejs实现微信app支付-创建订单与签名部

    作者:[db:作者] 时间:2021-06-23 15:09

    1. 创建订单部分代码
    var requestlib = require("request");
      var urllib = require("url");
      var crypto = require('crypto');
      var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
      var urlObj = urllib.parse(url);
      var option = {
        "url": urlObj,
    
        "method": "POST"
      };
      option.headers = {
        "Content-Type": "application/x-www-form-urlencoded"
      };
      //1. 参数部分
      var dataobj = {
        "appid": "【微信开放平台审核通过的应用APPID】",
        "mch_id": "【微信支付分配的商户号】",
        "nonce_str": "【随机字符串】",
        "body": "商品描述",
        "out_trade_no": "【订单号 32字符以内 平台自己的订单号】",
        "total_fee": 1,//金额 原金额*100 以分为单位
        "spbill_create_ip": "【后台服务器IP地址】",
        "notify_url": "【回调接口地址】",
        "trade_type": "APP"
      };
      //2.字典排序用于签名,并同步拼接xml参数
      var keys = Object.keys(dataobj)
        .sort();
      var params = [];
      var final = "<xml>";
      for (let i = 0; i < keys.length; i++) {
          var v = keys[i];
          params.push(v + "=" + dataobj[v]);
        final += "<" + v + ">" + dataobj[v] + "</" + v + ">";
        }
      //3.此处注意需要加上支付密钥
      params.push("key=【这里是支付密钥】");
      var str = params.join("&");
      //4.开始MD5签名,注意转大写字母
      var sign = crypto.createHash("md5")
        .update(str)
        .digest('hex')
        .toUpperCase();
      //5.完成最后的拼接xml参数,并发起请求
      final += "<sign>" + sign + "</sign></xml>";
      option.body = final;
      return when.promise(function(resolve, reject, notify) {
        requestlib(option, function(e, r, b) {
          if (e) {
            reject(e);
          }
          resolve(b);
        });
      });
    
    1. 自行解析返回xml
    console.log(JSON.stringify(retX));//返回的结果,次数仅处理正确结果
      var dataobj = {};
      //去掉干扰手动解析项
      retX = retX.replace(/<\!\[CDATA\[/g,"").replace(/\]\]>/g,"").replace(/<\!\[CDATA\]>/g,"null");
      //提取所需参数的key
      var keys = ["appid","nonce_str","mch_id","prepay_id","trade_type"];
      for (let i = 0; i < keys.length; i++) {
          var v = keys[i];
      //拼接正则取值
        var re= new RegExp("<"+v+">(.*)</"+v+">");
        dataobj[v]=re.exec(retX)[1];
    //     console.log(re.exec(retX)[1]);
      }
      //最终的dataobj为返回数据解析结果
    
    1. 二次签名与调取支付参数
     var crypto = require('crypto');
    //   console.log(JSON.stringify(obj));
      var dataobj2 = {
        "appid": dataobj.appid,
        "partnerid": dataobj.mch_id,
        "prepayid": dataobj.prepay_id,
        "package": "Sign=WXPay",
        "noncestr": dataobj.nonce_str, //这里偷懒,直接使用返回值的随机字符串
        "timestamp": moment()
          .format("X") //使用moment获取时间秒数 注意是秒数
      };
      //字典排序
      var keys = Object.keys(dataobj2)
        .sort();
      var params = [];
      for (let i = 0; i < keys.length; i++) {
          var v = keys[i];
          params.push(v + "=" + dataobj2[v]);
        }
      params.push("key=【支付密钥】");
      var str = params.join("&");
      var sign = crypto.createHash("md5")
        .update(str)
        .digest('hex')
        .toUpperCase();
      dataobj2.sign = sign;
    //dataobj2 为最终的参数集,可用手机调用支付