现在小程序越来越流行起来,微信小程序的开发也在不断的完善,现在我们就来讲讲微信小程序如何接入微信支付。
我们在微信官方的开发文档中可以查到微信小程序的支付接口wx.requestPayment(Object object),在里面可以查到必填的参数和格式等。
实例代码:
wx.requestPayment({
timeStamp: '', // 时间戳,从 1970 年 1 月 1 日 00:00:00 至今的秒数,即当前的时间
nonceStr: '', // 随机字符串,长度为32个字符以下
package: '', // 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=***
signType: 'MD5',
paySign: '', // 签名,具体签名方案参见 小程序支付接口文档
success(res) { }, // 接口调用成功的回调函数
fail(res) { } // 接口调用失败的回调函数
})
object.signType 的合法值----MD5或者HMAC-SHA256
当然这些参数都是需要自己后端(node)处理后得到参数,传回微信小程序的。
发起微信支付。了解更多信息,请查看微信支付接口文档;
商户系统(node后端)和微信支付系统主要交互:
主要是签名生成算法,算法实例如下面的node代码实例中的函数getSign(signParams)
node后端示例代码:
/*
* @Author: zhangyong
* @Date: 2018-04-17
* @Descrition : wechat 微信支付功能
*/
var queryString = require('querystring');
var crypto = require('crypto');
var request = require('request');
var uuid = require('uuid');
var sql = require('./assets/sql/sql')
var xml2jsparseString = require('xml2js').parseString;
// 引入项目的配置信息
const CONFIG = require('../config')
var config = CONFIG.app_info;
// wechat 支付类 (使用 es6 的语法)
class WechatAppletPay {
/**
* 构造函数
* @param params 传递进来的方法
*/
constructor( userInfo ){
this.userInfo = userInfo;
this.order_id = "";
}
/**
* 获取微信统一下单参数
*/
getUnifiedorderXmlParams(obj){
var body = ' ' +
'' +config.wxappid+' ' +
''+obj.body+' ' +
'' +config.mch_id+' ' +
'' +obj.nonce_str+' ' +
'' +obj.notify_url+'' +
'' +obj.openid+' ' +
'' +obj.out_trade_no+''+
'' +obj.spbill_create_ip+' ' +
'' +obj.total_fee+' ' +
'' +obj.trade_type+' ' +
'' +obj.sign+' ' +
'';
return body;
}
/**
* 获取微信统一下单的接口数据
*/
getPrepayId(obj){
var that = this;
// 生成统一下单接口参数
var UnifiedorderParams = {
appid : config.wxappid,
body : obj.bookid,
mch_id : config.mch_id,
nonce_str: this.createNonceStr(),
notify_url : obj.notify_url,// 微信付款后的回调地址
openid : this.userInfo.openid,
out_trade_no : uuid.v4().replace(/-/g,''),//new Date().getTime(), //订单号
spbill_create_ip : obj.spbill_create_ip,
total_fee : obj.total_fee,
trade_type : 'JSAPI'
};
that.order_id = UnifiedorderParams.out_trade_no;
// 返回 promise 对象
return new Promise(function (resolve, reject) {
// 获取 sign 参数
UnifiedorderParams.sign = that.getSign(UnifiedorderParams);
var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
request.post({url : url, body:JSON.stringify(that.getUnifiedorderXmlParams(UnifiedorderParams))}, function (error, response, body) {
var prepay_id = '';
if (!error && response.statusCode == 200) {
// 微信返回的数据为 xml 格式, 需要装换为 json 数据, 便于使用
xml2jsparseString(body, {async:true}, function (error, result) {
prepay_id = result.xml.prepay_id[0];
// 放回数组的第一个元素
resolve(prepay_id);
});
} else {
reject(body);
}
});
})
}
/**
* 获取微信支付的签名
* @param payParams
*/
getSign(signParams){
// 按参数名ASCII码从小到大排序
var keys = Object.keys(signParams);
keys = keys.sort();
var newArgs = {};
keys.forEach(function (val, key) {
if (signParams[val]){
newArgs[val] = signParams[val];
}
})
// 拼接API密钥
var string = queryString.stringify(newArgs)+'&key='+config.wxpaykey;
// 生成签名
return crypto.createHash('md5').update(queryString.unescape(string), 'utf8').digest("hex").toUpperCase();
}
/**
* 微信支付的所有参数
* @param req 请求的资源, 获取必要的数据
*/
getBrandWCPayParams( obj, callback ){
var that = this;
var prepay_id_promise = that.getPrepayId(obj);
prepay_id_promise.then(function (prepay_id) {
var prepay_id = prepay_id;
var wcPayParams = {
"appId" : config.wxappid, // 微信小程序的APPID
"timeStamp" : parseInt(new Date().getTime() / 1000).toString(), //时间戳,自1970年以来的秒数
"nonceStr" : that.createNonceStr(), // 随机串
// 通过统一下单接口获取
"package" : "prepay_id="+prepay_id,
"signType" : "MD5", // 微信签名方式:
};
wcPayParams.paySign = that.getSign(wcPayParams); //微信支付签名
wcPayParams.order_id = that.order_id; //微信支订单号
callback(wcPayParams);
},function (error) {
callback(error);
});
}
/**
* 获取随机的NonceStr
*/
createNonceStr() {
return Math.random().toString(36).substr(2, 15);
};
}
module.exports = WechatAppletPay;
调用WechatAppletPay方法
var WechatAppletPay= new WechatAppletPay(userInfo);
WechatAppletPay.getBrandWCPayParams(req.body, function (data) {
console.log(data);
})