WeChat 미니 프로그램 결제
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 애플릿의 유일한 매개변수는 키 결제를 위한 비밀번호입니다. 나머지 매개변수는 주문 정보와 가격입니다. Promise를 사용하려면 q 모듈을 입력해야 합니다. 이는 사람마다 다르며 필요에 따라 설정할 수 있습니다. . https://api.mch.weixin.qq.com/pay/unifiedorder 인터페이스를 요청해야 합니다
참고: 여기서 전달하는 양식 데이터는 json 대신 xml입니다
그런 다음 서명 메서드가 필요합니다. 여기서는 두 가지 메서드를 캡슐화해야 합니다. 하나는 통합 주문 인터페이스를 호출하는 데 사용되는 서명 메서드이고, 다른 하나는 결제용 미니 프로그램
통합 주문 인터페이스 서명을 호출하는 데 사용됩니다.
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()
결제 기호:
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()
암호화할 때 json 대신 문자열을 얻으므로 json을 문자열의 경우 코드는 다음과 같습니다.
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]
마지막으로 WeChat 결제에 필요한 모든 매개변수를 얻으려면 이들을 연결하기만 하면 됩니다.
//微信小程序支付封装,暂支持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 = "" 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 } }" + 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 += "
그 후 주문 인터페이스를 캡슐화합니다.
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을 사용하여 키를 연결해서는 안 됩니다
읽어주셔서 감사합니다. 모든 사람에게 도움이 되기를 바랍니다. 이 사이트를 지원해 주셔서 감사합니다!
더 많은 WeChat 애플릿 결제 간단한 예시와 주의사항은 PHP 중국어 홈페이지를 참고해주세요!