分享小程序支付功能的实例代码教程
微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可。
今天我们来封装一般node的支付接口!!!
首先调用统一下单接口我们需要知道一些信息var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()var deferred = Q.defer()var appid = config.appIdvar 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>" //appidformData += "<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 = thisrequest({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,这个因人而异,可以根据自己需要来。我们需要请求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=' + keyvar 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=' + keyvar 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.keymodule.exports = {// 获取prepay_idgetXMLNodeValue: function(node_name, xml) {var tmp = xml.split("<" + node_name + ">")var _tmp = tmp[1].split("</" + node_name + ">")return _tmp[0]},// object-->stringraw: 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加密获取signpaysignjs: 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=' + keyvar sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')return sign.toUpperCase()},// 统一下单接口加密获取signpaysignjsapi: 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=' + keyvar 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.appIdvar 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>" //appidformData += "<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 = thisrequest({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 = 1var notify_url = "http://localhost/notify"var mch_id = config.shopIdvar 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
【相关推荐】
1. 微信小程序微信支付接入开发
2. 小程序开发之实现楼层锚点跳跃实例详解
3. 实现微信小程序的在线支付功能代码解析以上就是分享小程序支付功能的实例代码教程的详细内容,更多请关注小潘博客其它相关文章!