微信应用开发之支付统一下单
凌雪 2018-09-13 来源 :网络 阅读 1311 评论 0

摘要:本文将带你了解微信应用开发之支付统一下单,希望本文对大家学微信有所帮助。

本文将带你了解微信应用开发之支付统一下单,希望本文对大家学微信有所帮助。



    在做小程序支付希望你已经熟读微信的文档微信支付-小程序-手机端和微信支付-小程序-后台。且你已经有了
   
   
   
        AppID: "wx****************",  // 小程序ID 
    Secret: "********************************",  // 小程序Secret
    Mch_id: "**********",   // 商户号
    Mch_key: "********************", //   商户key1234
   
    关于上面的这4个数据的获取,请自行在自己的账号中获取和设置。且你已经有了用户的openid。《微信小程序开发(四)获取用户openid》。
   
   
   
    小程序接口
   
   
   
    wx.requestPayment({
       'timeStamp': '',
   'nonceStr': '',
   'package':   '',
   'signType': 'MD5',
   'paySign': '',
   'success':function(res){
   },
   'fail':function(res){
   }
    })
   
    小程序接口就暴露这一个方法。这个方法有4个参数是需要后台去获取的。
     
    其实大部分工作都是后台的事情。
   
   
   
    后端实现
   
    后端主要是统一下单的这个接口https://api.mch.weixin.qq.com/pay/unifiedorder。
    这里主要就是几个签名算法:
   
   
   
    统一下单签名
   
   
   
    // 生成签名
    function paysignjsapi(appid,body,mch_id,nonce_str,notify_url,openid,out_trade_no,spbill_create_ip,total_fee)   {
    var ret = {
        appid: appid,
        body: body,
        mch_id: mch_id,
        nonce_str: nonce_str,
        notify_url:notify_url,
        openid:openid,
          out_trade_no:out_trade_no,
          spbill_create_ip:spbill_create_ip,
        total_fee:total_fee,
        trade_type: 'JSAPI'
    };
    var str = raw(ret);
    str = str +   '&key='+key;
    var md5Str =   cryptoMO.createHash('md5').update(str).digest('hex');
    md5Str =   md5Str.toUpperCase();
    return md5Str;
    };
    function raw(args) {
        var keys =   Object.keys(args);
    keys = keys.sort();
    var newArgs = {};
    keys.forEach(function(key)   {
        newArgs[key.toLowerCase()] =   args[key];
    });
   
        var str = '';
    for(var k in newArgs) {
        str += '&' + k + '=' +   newArgs[k];
    }
    str = str.substr(1);
    return str;
    };
   
   
   
    小程序paySign
   
   
   
    function paysignjs(appid, nonceStr, package, signType, timeStamp) {
    var ret = {
        appId: appid,
        nonceStr: nonceStr,
        package: package,
        signType: signType,
        timeStamp: timeStamp
    };
    var str = raw1(ret);
    str = str +   '&key='+key;
    return cryptoMO.createHash('md5').update(str).digest('hex');
    };
   
    function raw1(args) {
        var keys =   Object.keys(args);
    keys = keys.sort()
    var newArgs = {};
    keys.forEach(function(key)   {
        newArgs[key] =   args[key];
    });
   
        var str = '';
    for(var k in newArgs) {
        str += '&' + k + '=' +   newArgs[k];
    }
    str = str.substr(1);
    return str;
    };
   
   
   
    统一下单后端实现
   
   
   
    var wxConfig = require('../wx_pay/wx_x_config');
    var cryptoMO =   require('crypto'); // MD5算法
    var parseString = require('xml2js').parseString; // xml转js对象
   
    var key = wxConfig.Mch_key;
    /*
 * 根据openid 发起微信支付 
 */
    router.all('/api/wxpay/unifiedorder',   function(req, res, next) {
    var param = req.query || req.params;
    var openid = param.openid;
   
        var spbill_create_ip = req.ip.replace(/::ffff:/, ''); // 获取客户端ip
    var body = '测试支付'; // 商品描述
    var notify_url = 'https://www.hgdqdev.cn/api/wxpay' // 支付成功的回调地址  可访问 不带参数
    var nonce_str = getNonceStr(); //   随机字符串
    var out_trade_no = wxConfig.getWxPayOrdrID(); // 商户订单号
    var total_fee =   '1'; // 订单价格 单位是 分
    var timestamp = Math.round(new Date().getTime()/1000); // 当前时间
   
        var bodyData = '';
    bodyData += '' + wxConfig.AppID + '';  // 小程序ID
    bodyData   += ''   + body + ''; // 商品描述
    bodyData += '' + wxConfig.Mch_id + ''; // 商户号
    bodyData += '' +   nonce_str + ''; // 随机字符串
    bodyData += ''   + notify_url + ''; // 支付成功的回调地址
    bodyData += '' +   openid + '';   // 用户标识
    bodyData += '' +   out_trade_no +   '';   // 商户订单号
    bodyData +=   '' + spbill_create_ip + ''; // 终端IP
    bodyData += '' + total_fee +   ''; //   总金额 单位为分
    bodyData += 'JSAPI';   // 交易类型 小程序取值如下:JSAPI
    // 签名
    var sign = paysignjsapi(
        wxConfig.AppID,
        body,
        wxConfig.Mch_id,
        nonce_str,
        notify_url,
        openid,
        out_trade_no,
        spbill_create_ip,
        total_fee
    );
    bodyData += '' + sign   + '';
    bodyData += '
';
    // 微信小程序统一下单接口
    var urlStr =   'https://api.mch.weixin.qq.com/pay/unifiedorder';
    request({
        url: urlStr,
        method: 'POST',
        body: bodyData
    }, function (error, response, body) {
        if (!error &&   response.statusCode == 200) {
            var returnValue =   {};
            parseString(body,   function (err, result) {
                if   (result.xml.return_code[0] == 'SUCCESS') {
                    returnValue.msg =   '操作成功';
                      returnValue.status = '100';
                    returnValue.out_trade_no =   out_trade_no;  // 商户订单号
                    // 小程序 客户端支付需要   nonceStr,timestamp,package,paySign  这四个参数
                    returnValue.nonceStr   = result.xml.nonce_str[0];   // 随机字符串
                    returnValue.timestamp = timestamp.toString(); // 时间戳
                    returnValue.package = 'prepay_id=' + result.xml.prepay_id[0]; // 统一下单接口返回的   prepay_id 参数值
                    returnValue.paySign = paysignjs(wxConfig.AppID, returnValue.nonceStr,   returnValue.package, 'MD5',timestamp); // 签名
                    res.end(JSON.stringify(returnValue));
                } else{
                    returnValue.msg =   result.xml.return_msg[0];
                    returnValue.status = '102';
                      res.end(JSON.stringify(returnValue));
                }
            });
        }
    })
      });


    wxConfig代码:
   
   
   
   
    /* 微信参数AppID 和 Secret */
    var wxConfig = {
        AppID: "wx****************",  // 小程序ID 
    Secret:   "********************************",    // 小程序Secret
    Mch_id: "**********",   // 商户号
    Mch_key: "********************",   // 商户key
    // 生成商户订单号
    getWxPayOrdrID: function(){
        var   myDate = new Date();
        var year = myDate.getFullYear();
        var mouth = myDate.getMonth() + 1;
        var day = myDate.getDate();
          var hour = myDate.getHours();
        var minute =   myDate.getMinutes();
        var second =   myDate.getSeconds();
        var msecond =   myDate.getMilliseconds(); //获取当前毫秒数(0-999)
        if(mouth < 10){   /*月份小于10  就在前面加个0*/
            mouth =   String(String(0) + String(mouth));
        }
        if(day < 10){   /*日期小于10  就在前面加个0*/
            day = String(String(0) + String(day));
        }
        if(hour < 10){   /*时小于10  就在前面加个0*/
            hour = String(String(0) +   String(hour));
        }
        if(minute < 10){ /*分小于10    就在前面加个0*/
            minute = String(String(0)   + String(minute));
        }
        if(second < 10){ /*秒小于10  就在前面加个0*/
            second = String(String(0)   + String(second));
        }
        if (msecond < 10) {
            msecond =   String(String(00) + String(second));
        } else if(msecond   >= 10 && msecond < 100){
            msecond =   String(String(0) + String(second));
        }
   
            var currentDate =   String(year) + String(mouth) + String(day) + String(hour) + String(minute) +   String(second) + String(msecond);
        return currentDate;
    }
    };
    module.exports = wxConfig;
   
    实例
   
   
   
    // 支付按钮点击事件
      payTap: function(){
    var self = this;
    wx.request({
      url:   'https://www.hgdqdev.cn/api/wxpay/unifiedorder',
      data: {
        openid: self.data.openid   // 这里正常项目不会只有openid一个参数
      },
      success: function(res){
        if(res.data.status   == 100){
          var payModel =   res.data;
          wx.requestPayment({
            'timeStamp':   payModel.timestamp,
            'nonceStr':   payModel.nonceStr,
            'package': payModel.package,
            'signType': 'MD5',
            'paySign':   payModel.paySign,
            'success': function (res)   {
              wx.showToast({
                title: '支付成功',
                icon:   'success',
                duration: 2000
              })
            },
            'fail': function (res)   {
            }
          })
        }
      },
      fail: function(){
   
          }
    })
  }

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程