摘要:本文将带你了解微信应用开发之支付统一下单,希望本文对大家学微信有所帮助。
本文将带你了解微信应用开发之支付统一下单,希望本文对大家学微信有所帮助。
在做小程序支付希望你已经熟读微信的文档微信支付-小程序-手机端和微信支付-小程序-后台。且你已经有了
AppID: "wx****************", // 小程序ID
Secret: "********************************", // 小程序Secret
Mch_id: "**********", // 商户号
Mch_key: "********************", // 商户key1234
关于上面的这4个数据的获取,请自行在自己的账号中获取和设置。且你已经有了用户的openid。《微信小程序开发(四)获取用户openid》。
小程序接口
wx.requestPayment({
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success':function(res){
},
'fail':function(res){
}
})
小程序接口就暴露这一个方法。这个方法有4个参数是需要后台去获取的。
其实大部分工作都是后台的事情。
后端实现
后端主要是统一下单的这个接口https://api.mch.weixin.qq.com/pay/unifiedorder。
这里主要就是几个签名算法:
统一下单签名
// 生成签名
function paysignjsapi(appid,body,mch_id,nonce_str,notify_url,openid,out_trade_no,spbill_create_ip,total_fee) {
var ret = {
appid: appid,
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: 'JSAPI'
};
var str = raw(ret);
str = str + '&key='+key;
var md5Str = cryptoMO.createHash('md5').update(str).digest('hex');
md5Str = md5Str.toUpperCase();
return md5Str;
};
function raw(args) {
var keys = Object.keys(args);
keys = keys.sort();
var newArgs = {};
keys.forEach(function(key) {
newArgs[key.toLowerCase()] = args[key];
});
var str = '';
for(var k in newArgs) {
str += '&' + k + '=' + newArgs[k];
}
str = str.substr(1);
return str;
};
小程序paySign
function paysignjs(appid, nonceStr, package, signType, timeStamp) {
var ret = {
appId: appid,
nonceStr: nonceStr,
package: package,
signType: signType,
timeStamp: timeStamp
};
var str = raw1(ret);
str = str + '&key='+key;
return cryptoMO.createHash('md5').update(str).digest('hex');
};
function raw1(args) {
var keys = Object.keys(args);
keys = keys.sort()
var newArgs = {};
keys.forEach(function(key) {
newArgs[key] = args[key];
});
var str = '';
for(var k in newArgs) {
str += '&' + k + '=' + newArgs[k];
}
str = str.substr(1);
return str;
};
统一下单后端实现
var wxConfig = require('../wx_pay/wx_x_config');
var cryptoMO = require('crypto'); // MD5算法
var parseString = require('xml2js').parseString; // xml转js对象
var key = wxConfig.Mch_key;
/*
* 根据openid 发起微信支付
*/
router.all('/api/wxpay/unifiedorder', function(req, res, next) {
var param = req.query || req.params;
var openid = param.openid;
var spbill_create_ip = req.ip.replace(/::ffff:/, ''); // 获取客户端ip
var body = '测试支付'; // 商品描述
var notify_url = 'https://www.hgdqdev.cn/api/wxpay' // 支付成功的回调地址 可访问 不带参数
var nonce_str = getNonceStr(); // 随机字符串
var out_trade_no = wxConfig.getWxPayOrdrID(); // 商户订单号
var total_fee = '1'; // 订单价格 单位是 分
var timestamp = Math.round(new Date().getTime()/1000); // 当前时间
var bodyData = '
bodyData += '
bodyData += '' + body + ''; // 商品描述
bodyData += '
bodyData += '
bodyData += '
bodyData += '
bodyData += '
bodyData += '
bodyData += '
bodyData += '
// 签名
var sign = paysignjsapi(
wxConfig.AppID,
body,
wxConfig.Mch_id,
nonce_str,
notify_url,
openid,
out_trade_no,
spbill_create_ip,
total_fee
);
bodyData += '
bodyData += '
// 微信小程序统一下单接口
var urlStr = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
request({
url: urlStr,
method: 'POST',
body: bodyData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var returnValue = {};
parseString(body, function (err, result) {
if (result.xml.return_code[0] == 'SUCCESS') {
returnValue.msg = '操作成功';
returnValue.status = '100';
returnValue.out_trade_no = out_trade_no; // 商户订单号
// 小程序 客户端支付需要 nonceStr,timestamp,package,paySign 这四个参数
returnValue.nonceStr = result.xml.nonce_str[0]; // 随机字符串
returnValue.timestamp = timestamp.toString(); // 时间戳
returnValue.package = 'prepay_id=' + result.xml.prepay_id[0]; // 统一下单接口返回的 prepay_id 参数值
returnValue.paySign = paysignjs(wxConfig.AppID, returnValue.nonceStr, returnValue.package, 'MD5',timestamp); // 签名
res.end(JSON.stringify(returnValue));
} else{
returnValue.msg = result.xml.return_msg[0];
returnValue.status = '102';
res.end(JSON.stringify(returnValue));
}
});
}
})
});
wxConfig代码:
/* 微信参数AppID 和 Secret */
var wxConfig = {
AppID: "wx****************", // 小程序ID
Secret: "********************************", // 小程序Secret
Mch_id: "**********", // 商户号
Mch_key: "********************", // 商户key
// 生成商户订单号
getWxPayOrdrID: function(){
var myDate = new Date();
var year = myDate.getFullYear();
var mouth = myDate.getMonth() + 1;
var day = myDate.getDate();
var hour = myDate.getHours();
var minute = myDate.getMinutes();
var second = myDate.getSeconds();
var msecond = myDate.getMilliseconds(); //获取当前毫秒数(0-999)
if(mouth < 10){ /*月份小于10 就在前面加个0*/
mouth = String(String(0) + String(mouth));
}
if(day < 10){ /*日期小于10 就在前面加个0*/
day = String(String(0) + String(day));
}
if(hour < 10){ /*时小于10 就在前面加个0*/
hour = String(String(0) + String(hour));
}
if(minute < 10){ /*分小于10 就在前面加个0*/
minute = String(String(0) + String(minute));
}
if(second < 10){ /*秒小于10 就在前面加个0*/
second = String(String(0) + String(second));
}
if (msecond < 10) {
msecond = String(String(00) + String(second));
} else if(msecond >= 10 && msecond < 100){
msecond = String(String(0) + String(second));
}
var currentDate = String(year) + String(mouth) + String(day) + String(hour) + String(minute) + String(second) + String(msecond);
return currentDate;
}
};
module.exports = wxConfig;
实例
// 支付按钮点击事件
payTap: function(){
var self = this;
wx.request({
url: 'https://www.hgdqdev.cn/api/wxpay/unifiedorder',
data: {
openid: self.data.openid // 这里正常项目不会只有openid一个参数
},
success: function(res){
if(res.data.status == 100){
var payModel = res.data;
wx.requestPayment({
'timeStamp': payModel.timestamp,
'nonceStr': payModel.nonceStr,
'package': payModel.package,
'signType': 'MD5',
'paySign': payModel.paySign,
'success': function (res) {
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
})
},
'fail': function (res) {
}
})
}
},
fail: function(){
}
})
}
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之微信频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号