zoukankan      html  css  js  c++  java
  • 微信小程序篇(微信小程序的支付)

    微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可。

    今天我们来封装一般node的支付接口!!!

    首先调用统一下单接口我们需要知道一些信息

    var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()
        var deferred = Q.defer()  
        var appid = config.appId  
        var nonce_str = this.createNonceStr()  
        var timeStamp = this.createTimeStamp()  
        var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"  
        var formData = "<xml>"  
        formData += "<appid>" + appid + "</appid>" //appid  
        formData += "<attach>" + attach + "</attach>" //附加数据  
        formData += "<body>" + body + "</body>"  
        formData += "<mch_id>" + mch_id + "</mch_id>" //商户号  
        formData += "<nonce_str>" + nonce_str + "</nonce_str>" //随机字符串,不长于32位。  
        formData += "<notify_url>" + notify_url + "</notify_url>"  
        formData += "<openid>" + openid + "</openid>"  
        formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"  
        formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"  
        formData += "<total_fee>" + total_fee + "</total_fee>"  
        formData += "<trade_type>JSAPI</trade_type>"  
        formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"  
        formData += "</xml>"  
        var self = this
        request({  
          url: url,  
          method: 'POST',  
          body: formData  
        }, function(err, response, body) {  
          if (!err && response.statusCode == 200) {  
            var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")) 
            var tmp = prepay_id.split('[')  
            var tmp1 = tmp[2].split(']')  
            //签名  
            var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)  
            var args = {  
              appId: appid,  
              timeStamp: timeStamp,  
              nonceStr: nonce_str,  
              signType: "MD5",  
              package: tmp1[0],  
              paySign: _paySignjs  
            }
            deferred.resolve(args)  
          } else {  
            console.log(body)  
          } 
        })  
        return deferred.promise  

    这个是一个统一下单接口的代码,我们需要appid小程序公众号id,mch_id商户号id,openid小程序的唯一标实,key支付用的密码,剩下的参数都是订单的信息和价格之类的,本人require进q模块使用promise,这个因人而异,可以根据自己需要来。我们需要请求https://api.mch.weixin.qq.com/pay/unifiedorder接口

    注意:这里我们传递的formdata是一个xml而不是json

    然后我们需要签名方法,这里我们需要封装两个方法,一个是签名方法调用统一下单接口会用到,另一个是调用小程序支付用到

    统一下单接口sign:

    var ret = {  
          appid: appid,  
          attach: attach,  
          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: trade_type  
        }  
        var string = this.raw(ret)  
        string = string + '&key=' + key  
        var crypto = require('crypto')  
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  
        return sign.toUpperCase() 

    支付sign:

    var ret = {  
            appId: appid,  
            nonceStr: nonceStr,  
            package: package,  
            signType: signType,  
            timeStamp: timeStamp  
        }  
        var string = this.raw(ret)  
        string = string + '&key=' + key  
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  
        return sign.toUpperCase()  

    注意加密的时候我们获取的是string而不是一个json,所以我们需要吧json转换成string,代码如下:

    var keys = Object.keys(args)  
        keys = keys.sort()  
        var newArgs = {}  
        keys.forEach(function(key) {  
            newArgs[key] = args[key]  
        })  
        var string = ''  
        for (var k in newArgs) {  
            string += '&' + k + '=' + newArgs[k]  
        }  
        string = string.substr(1)  
        return string  

    统一下单接口返回的是带有prepay_id的xml,所以我们需要一个方法进行解析,代码如下:

    var tmp = xml.split("<" + node_name + ">")  
        var _tmp = tmp[1].split("</" + node_name + ">")  
        return _tmp[0]  

    最后我们只需要把这些连接到一起就是可以获取所有微信支付所需参数,代码如下:

    //微信小程序支付封装,暂支持md5加密,不支持sha1
    /**
    ***create order by jianchep 2016/11/22     
     **/
    var config = require('../config/weapp.js')
    var Q = require("q")  
    var request = require("request")  
    var crypto = require('crypto')  
    var ejs = require('ejs')
    var fs = require('fs')  
    var key = config.key
    module.exports = {
      // 获取prepay_id
      getXMLNodeValue: function(node_name, xml) {  
        var tmp = xml.split("<" + node_name + ">")  
        var _tmp = tmp[1].split("</" + node_name + ">")  
        return _tmp[0]  
      },
      // object-->string
      raw: function(args) {  
        var keys = Object.keys(args)  
        keys = keys.sort()  
        var newArgs = {}  
        keys.forEach(function(key) {  
            newArgs[key] = args[key]  
        })  
        var string = ''  
        for (var k in newArgs) {  
            string += '&' + k + '=' + newArgs[k]  
        }  
        string = string.substr(1)  
        return string  
      },  
        // 随机字符串产生函数  
      createNonceStr: function() {  
          return Math.random().toString(36).substr(2, 15)  
      },  
      // 时间戳产生函数  
      createTimeStamp: function() {  
          return parseInt(new Date().getTime() / 1000) + ''  
      },
      // 支付md5加密获取sign
      paysignjs: function(appid, nonceStr, package, signType, timeStamp) {  
        var ret = {  
            appId: appid,  
            nonceStr: nonceStr,  
            package: package,  
            signType: signType,  
            timeStamp: timeStamp  
        }  
        var string = this.raw(ret)  
        string = string + '&key=' + key  
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  
        return sign.toUpperCase()  
      },
      // 统一下单接口加密获取sign
      paysignjsapi: function(appid, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) {  
        var ret = {  
          appid: appid,  
          attach: attach,  
          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: trade_type  
        }  
        var string = this.raw(ret)  
        string = string + '&key=' + key  
        var crypto = require('crypto')  
        var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')  
        return sign.toUpperCase()  
      },
      // 下单接口
      order: function(attach, body, mch_id, openid, total_fee, notify_url) {
        var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()
        var deferred = Q.defer()  
        var appid = config.appId  
        var nonce_str = this.createNonceStr()  
        var timeStamp = this.createTimeStamp()  
        var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"  
        var formData = "<xml>"  
        formData += "<appid>" + appid + "</appid>" //appid  
        formData += "<attach>" + attach + "</attach>" //附加数据  
        formData += "<body>" + body + "</body>"  
        formData += "<mch_id>" + mch_id + "</mch_id>" //商户号  
        formData += "<nonce_str>" + nonce_str + "</nonce_str>" //随机字符串,不长于32位。  
        formData += "<notify_url>" + notify_url + "</notify_url>"  
        formData += "<openid>" + openid + "</openid>"  
        formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"  
        formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"  
        formData += "<total_fee>" + total_fee + "</total_fee>"  
        formData += "<trade_type>JSAPI</trade_type>"  
        formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"  
        formData += "</xml>"  
        var self = this
        request({  
          url: url,  
          method: 'POST',  
          body: formData  
        }, function(err, response, body) {  
          if (!err && response.statusCode == 200) {  
            var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")) 
            var tmp = prepay_id.split('[')  
            var tmp1 = tmp[2].split(']')  
            //签名  
            var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)  
            var args = {  
              appId: appid,  
              timeStamp: timeStamp,  
              nonceStr: nonce_str,  
              signType: "MD5",  
              package: tmp1[0],  
              paySign: _paySignjs  
            }
            deferred.resolve(args)  
          } else {  
            console.log(body)  
          } 
        })  
        return deferred.promise  
      }
    }

    之后我们封装下单接口:

    unifiedorder: function (req, res) {
        var body = "测试支付"  
        var openid = "openid"
        var total_fee = 1
        var notify_url = "http://localhost/notify"
        var mch_id = config.shopId
        var attach = "测试"  
        wxpay.order(attach, body, mch_id, openid, total_fee, notify_url)
          .then(function(data){  
            console.log('data--->', data, 123123)
            res.json(data)
          })  
      },

    然后我们只需要在小程序里面调用这个接口,就会获取到所有的支付需要信息,再掉微信支付即可。

    这里说几个小程序支付的坑:

    1.统一下单接口是xml(这个不只是小程序,公众号也是),返回值也是xml格式需要自己获取prepay_id,

    2.签名算法要带上key,最后要转换成大些

    3.微信支付的sign算法也要带上appid(这个不科学,深坑)

    4.签名算法一定不要用json拼接key

  • 相关阅读:
    预备作业02-162315马军
    预备作业01-162315马军
    # 2017-2018-1 20155224 《信息安全系统设计基础》第四周学习总结
    # 2017-2018-1 20155224 《信息安全系统设计基础》第3周学习总结
    # 第二周课堂实践以及MyOD
    # 2017-2018-1 20155224 《信息安全系统设计基础》第1周学习总结
    # 20155224 2016-2017-2《Java程序设计》课程总结
    # 20155224 实验五 Java网络编程及安全
    # 20155224 课堂实践 MyOD
    # 20155224 实验四 Android程序设计
  • 原文地址:https://www.cnblogs.com/jcscript/p/6126722.html
Copyright © 2011-2022 走看看