WeChat ミニ プログラムでの支払いは WeChat 公式アカウントでの支払いに似ていますが、WeChat の統合注文インターフェイスを呼び出して prepay_id を取得し、WeChat 支払いを呼び出すだけで済みます。
今日は、一般的なノードの支払いインターフェイスをカプセル化します。 ! !
まず、統合注文インターフェイスを呼び出すための情報を知る必要があります
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 アプレットの一意の識別子が必要です。 キー支払い用のパスワード、および残りのパラメータは注文情報と価格ですrequireqモジュールを入力し、promiseを使用します。これは人によって異なり、自分のニーズに応じて設定できます。 api.mch.weixin.qq.com/pay/unifiedorder インターフェースをリクエストする必要があります
注: ここで渡すフォームデータは json ではなく xml です
次に、署名メソッドが必要です。ここでカプセル化する必要があります。 2 つのメソッド、1 つは統合注文インターフェイスを呼び出す署名メソッドによって使用され、もう 1 つはミニ プログラムで支払いのための統合注文インターフェイスを呼び出すために使用されます
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) }) },
その後、呼び出す必要があるだけですこのインターフェイスをミニ プログラムに組み込むと、必要な支払い情報がすべて取得され、WeChat 経由で支払いが行われます。
ミニ プログラムの支払いの落とし穴は次のとおりです:
1. 統一された注文インターフェイスは XML であり (これはミニ プログラムだけでなく、公式アカウントでも同様です)、戻り値も XML 形式である必要があります。 prepay_id を自分で取得します
2. 署名アルゴリズム キーを持ってきて、最後にそれをより大きなものに変換する必要があります
3. WeChat 支払いの署名アルゴリズムも appid を持ってくる必要があります (これは非科学的で、深い落とし穴です) )
4. 署名アルゴリズムはキーの結合に json を使用してはなりません
【関連する推奨事項】
1. WeChat ミニプログラム用の WeChat 支払いアクセスの開発
2.フロアアンカーポイントの実装の詳細な説明ミニプログラム開発のジャンプ例
3. WeChatミニプログラムのオンライン決済機能を実現するコードの分析
以上がミニプログラム決済機能のサンプルコードチュートリアルを共有しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。