Maison  >  Article  >  Applet WeChat  >  Partagez l'exemple de tutoriel de code de la fonction de paiement du mini programme

Partagez l'exemple de tutoriel de code de la fonction de paiement du mini programme

零下一度
零下一度original
2017-05-26 09:45:322563parcourir

Le paiement pour le mini-programme WeChat est similaire au paiement pour le compte officiel WeChat. En comparaison, il est plus simple que le paiement pour le compte officiel. Il suffit d'appeler l'interface de commande unifiée de WeChat pour obtenir le prepay_id, et nous pouvons ensuite le faire. appelez le paiement WeChat.

Aujourd'hui nous allons encapsuler l'interface de paiement d'un nœud généraliste ! ! !

Nous devons d'abord connaître quelques informations pour appeler l'interface de commande unifiée

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, &#39;61.50.221.43&#39;, total_fee, &#39;JSAPI&#39;) + "</sign>"  
    formData += "</xml>"  
    var self = this
    request({  
      url: url,  
      method: &#39;POST&#39;,  
      body: formData  
    }, function(err, response, body) {  
      if (!err && response.statusCode == 200) {  
        var prepay_id = self.getXMLNodeValue(&#39;prepay_id&#39;, body.toString("utf-8")) 
        var tmp = prepay_id.split(&#39;[&#39;)  
        var tmp1 = tmp[2].split(&#39;]&#39;)  
        //签名  
        var _paySignjs = self.paysignjs(appid, nonce_str, &#39;prepay_id=&#39; + tmp1[0], &#39;MD5&#39;, 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

Il s'agit du code d'une interface de commande unifiée. Nous avons besoin de l'identifiant du compte public de l'applet appid, du compte marchand mch_id. id, Le seul paramètre de l'applet openid est clémot de passe pour le paiement. Les paramètres restants sont les informations de commande et le prix. Je exige entrez dans le module q et utilisez la promesse. de personne à personne et peut être ajusté selon vos propres besoins. Nous devons demander l'interface api.mch.weixin.qq.com/pay/unifiedorder

Remarque : les données de formulaire que nous transmettons ici sont un fichier XML au lieu de json

Ensuite, nous avons besoin d'une méthode de signature. Ici, nous devons encapsuler deux méthodes. L'une est utilisée par la méthode de signature pour appeler l'interface de commande unifiée, et l'autre est utilisée pour appeler le paiement par applet

signe de l'interface de commande unifiée. :

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 + &#39;&key=&#39; + key  
    var crypto = require(&#39;crypto&#39;)  
    var sign = crypto.createHash(&#39;md5&#39;).update(string, &#39;utf8&#39;).digest(&#39;hex&#39;)  
    return sign.toUpperCase() 

支付sign:
var ret = {  
        appId: appid,  
        nonceStr: nonceStr,  
        package: package,  
        signType: signType,  
        timeStamp: timeStamp  
    }  
    var string = this.raw(ret)  
    string = string + &#39;&key=&#39; + key  
    var sign = crypto.createHash(&#39;md5&#39;).update(string, &#39;utf8&#39;).digest(&#39;hex&#39;)  
    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 = &#39;&#39;  
    for (var k in newArgs) {  
        string += &#39;&&#39; + k + &#39;=&#39; + 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("")  
    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 = &#39;davdian&#39; + 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, &#39;61.50.221.43&#39;, total_fee, &#39;JSAPI&#39;) + "</sign>"  
    formData += "</xml>"  
    var self = this
    request({  
      url: url,  
      method: &#39;POST&#39;,  
      body: formData  
    }, function(err, response, body) {  
      if (!err && response.statusCode == 200) {  
        var prepay_id = self.getXMLNodeValue(&#39;prepay_id&#39;, body.toString("utf-8")) 
        var tmp = prepay_id.split(&#39;[&#39;)  
        var tmp1 = tmp[2].split(&#39;]&#39;)  
        //签名  
        var _paySignjs = self.paysignjs(appid, nonce_str, &#39;prepay_id=&#39; + tmp1[0], &#39;MD5&#39;, 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(&#39;data--->&#39;, data, 123123)
        res.json(data)
      })  
  },

Ensuite, il suffit d'appeler cette interface dans le mini programme, et nous obtiendrons tous les informations de paiement, puis déposez-les. Payez simplement via WeChat.

Voici quelques pièges du paiement par mini-programme :

1. L'interface de commande unifiée est en XML (ce n'est pas seulement pour les mini-programmes, mais aussi pour les comptes officiels), et la valeur de retour est de également au format XML et doit être obtenu par vous-même prepay_id,

2. L'algorithme de signature doit apporter la clé, et enfin elle doit être convertie en une valeur plus grande

3. L'algorithme de signature du paiement WeChat doit également apporter l'appid (ce n'est pas scientifique, un gouffre profond)

4 L'algorithme de signature ne doit pas utiliser la clé d'épissage json

[Recommandations associées]

1.

Développement de l'accès au paiement WeChat au mini-programme WeChat

2.

Explication détaillée de l'exemple de mise en œuvre du saut de point d'ancrage au sol dans le développement du mini-programme

3.

Analyse du code pour implémenter la fonction de paiement en ligne du mini programme WeChat

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn