微信小程序 支付
微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取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
感谢阅读,希望能帮助到大家,谢谢大家对本站 的支持!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。