Paiement du programme WeChat Mini Exemples simples et précautions

高洛峰
Libérer: 2017-01-10 09:59:12
original
2433 Les gens l'ont consulté

Paiement du programme WeChat Mini

Le paiement dans le programme WeChat Mini est similaire au paiement dans le compte officiel WeChat. En comparaison, il est plus simple que le paiement dans le compte officiel. Il suffit d'appeler l'interface de commande unifiée de WeChat pour l'obtenir. Après prepay_id, nous pouvons appeler 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
Copier après la connexion

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 le mot de passe pour le paiement par clé. Les paramètres restants sont les informations de commande et le prix. J'ai besoin d'entrer dans le module q pour utiliser la promesse. Cela varie d'une personne à l'autre et peut être défini en fonction de vos propres besoins. . Nous devons demander l'interface https://api.mch.weixin.qq.com/pay/unifiedorder

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

Ensuite, nous méthode de signature nécessaire, ici nous devons encapsuler deux méthodes, l'une est la méthode de signature utilisée pour appeler l'interface de commande unifiée, l'autre est utilisée pour appeler le mini programme de paiement

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()
Copier après la connexion

Signe de paiement :

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()
Copier après la connexion

Notez que lors du cryptage, nous obtenons une chaîne au lieu d'un json, nous devons donc convertir le json en un chaîne, le code est le suivant :

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
Copier après la connexion

L'interface de commande unifiée renvoie du XML avec prepay_id, nous avons donc besoin d'une méthode pour l'analyser. Le code est le suivant :

var tmp = xml.split("<" + node_name + ">")
  var _tmp = tmp[1].split("</" + node_name + ">")
  return _tmp[0]
Copier après la connexion

Enfin, il suffit de les connecter ensemble pour obtenir tous les paramètres requis pour le paiement WeChat. Le code est le suivant :

//微信小程序支付封装,暂支持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 = &#39;&#39;
  for (var k in newArgs) {
    string += &#39;&&#39; + k + &#39;=&#39; + 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 + &#39;&key=&#39; + key
  var sign = crypto.createHash(&#39;md5&#39;).update(string, &#39;utf8&#39;).digest(&#39;hex&#39;)
  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 = ""
  formData += "" + appid + "" //appid
  formData += "" + attach + "" //附加数据
  formData += "" + body + ""
  formData += "" + mch_id + "" //商户号
  formData += "" + nonce_str + "" //随机字符串,不长于32位。
  formData += "" + notify_url + ""
  formData += "" + openid + ""
  formData += "" + bookingNo + ""
  formData += "61.50.221.43"
  formData += "" + total_fee + ""
  formData += "JSAPI"
  formData += "" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + ""
  formData += ""
  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
 }
}
Copier après la connexion

<🎜. >

Après cela, nous encapsulons l'interface de commande :

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)
   })
 },
Copier après la connexion

Ensuite, il suffit d'appeler cette interface dans le mini programme, et nous obtiendrons tout le paiement Informations, puis nous pouvons payer 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 json pour épisser la clé

Merci d'avoir lu, J'espère que cela pourra aider tout le monde, merci pour votre soutien à ce site !

Pour plus d'exemples simples de paiement par applet WeChat et d'articles sur les précautions, veuillez faire attention au site Web PHP chinois !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal