微信小程序 + nodeJs(loopback) 实现支付
实现小程序的支付,首先需要去微信官网先了解一下微信小程序支付相关接口文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1
微信支付首先需要调用微信的统一下单接口,返回微信支付接口需要数据。具体参数参考:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
在后端服务中,提供一个小程序前端调用的订单接口,生成预定单并访问微信统一下单接口返回微信接口数据,具体服务端代码如下:
module.exports = (req, res) => {
// TODO replace the codes bellow and add your own codes here
const wx_app_id = server.get('wx-app-id');
let pay_info = {
[wx_app_id]: { // 定义能支付的商户,可能存在多个
mch_id: server.get('wx-mch-id'),
pay_key: server.get('wx-pay-key')
}
}if(!(req.body.appid in pay_info)) {
res.send({
successed: false,
message: '商户不支持支付',
datalist: '暂不支持支付的appid'
});
return
}
let sendtowx = {
appid: req.body.appid,
mch_id: pay_info[req.body.appid].mch_id,
nonce_str: moment().valueOf(),
body: req.body.body,
// detail: req.body.detail,
// attach: req.body.attach,
out_trade_no: getOrderNo(), //订单在同一商家不能重复
total_fee: req.body.total_fee,
spbill_create_ip: req.headers['x-real-ip'] || req.headers['x-forwarded-for'] || req.connection.remoteAddress,
notify_url: req.body.notify_url, // 订单支付反馈通知接口,一般做修改订单完成状态用,微信支付成功后会在后台调用
trade_type: 'JSAPI',
openid: req.body.openid
}
sendtowx.sign = wx_sign(sendtowx, pay_info[req.body.appid].pay_key); //生成MD5加密字符,传入字段不能有undefined。否则会报签名错误 let request_str = '<xml>'
for (let item in sendtowx) {
request_str = request_str + '<' + item + '>'
request_str = request_str + sendtowx[item]
request_str = request_str + '</' + item + '>'
}
request_str = request_str + '</xml>'
console.log('request_str:', request_str);
const AppOrder = server.models.AppOrder;
AppOrder.findOrCreate({where:req.body.where},{ // 首先创建系统订单,此时状态为待支付
status:"0",
pay_price: sendtowx.total_fee/100,
order_no: sendtowx.out_trade_no
}, function(err, data, created) {
console.log(data,created,'s;s/');
if (err) {
console.log(err);
} else if(created){
console.log("创建预付订单成功",data);
request.post( // 调用微信支付统一下单接口,返回微信预订单数据
{
url : 'https://api.mch.weixin.qq.com/pay/unifiedorder',
// headers: {
// 'Content-Type':'text/xml; charset=utf-8',
// 'Content-Length': data.length
// },
body: request_str,
rejectUnauthorized: false
}, function(err, httpResponse, body){
// 请求完成之后的回调函数
console.log(body)
parseString(body, {explicitArray:false}, function (err, result) {
let res_body = { }
if(result.xml.return_code == 'SUCCESS') {
res_body.successed = true
res_body.message = 'ok'
let temp = {
appId: result.xml.appid,
timeStamp: moment().format('X'),
nonceStr: moment().format('x'),
package: 'prepay_id='+result.xml.prepay_id,
signType: "MD5"
}
temp.paySign = wx_sign(temp, pay_info[result.xml.appid].pay_key)
result.xml = temp
}
else {
res_body.successed = false
res_body.message = '支付失败'
}
if(res_body.message) {
res_body.datalist = result.xml
res.send(res_body);
}
});
})
}
else {
res.send({
code: "applied",
successed: false,
message: '不能重复提交订单!'
});
}
}); }
经常遇到的问题是会报签名错误问题,排查方法:
1.排查微信支付申请的pay-key是否正确,或写成了appid、app-key;
2.排查在上传MD5签名时是否传入了undefined的字段;
3.如果都没问题,建议在微信商户管理后面中重新设置pay-key。
统一下单结束后,小程序前端调用统一下单接口,开始微信支付:
payNow: function (e) {
let that = this;
let data = {
openid: app.globalData.openId,
appid: app.globalData.app_id,
body: this.data.applyGame.name + "测试",
// attach: this.data.applyGame.id,//附加信息,暂时不添加
total_fee: 1,
notify_url: app.globalData.appUrl + 'sdk/wxpayvnotify', // 微信支付成功反馈通知接口
where:{ // 不能重复提交订单条件
status: orderStatus.pay,
}
};
pay(data, (res) => {
if (res.statusCode == 200) {
if (res.data.successed == true) {
let backobj = res.data.datalist; let timestamp = backobj.timeStamp;
let nonceStr = backobj.nonceStr;
let prepay_id = backobj.package;
let signType = backobj.signType;
let paySign = backobj.paySign;
wx.requestPayment({
'timeStamp': timestamp,
'nonceStr': nonceStr,
'package': prepay_id,
'signType': signType,
'paySign': paySign,
'notify_url': app.globalData.appUrl + 'sdk/wxpayverify',
success: function (res) {
wx.navigateTo({
url: "/pages/my-game/index",
})
wx.switchTab({
url: '/pages/my-game/index',
})
},
fail: function (res) {
console.log(res,'支付失败');
wx.showToast({
title: '支付失败!',
icon: 'none',
})
// wx.navigateTo({
// url: "../pay/payfail/payfail",
// })
},
})
} else {
if (res.data.code === 'applied'){
wx.showToast({
title: '已经报名',
icon: 'none',
})
}else{
wx.showToast({
title: res.data.message,
icon: 'none',
})
} }
}else{
wx.showToast({
title: '支付失败!',
icon: 'none',
})
}
})
}
支付完成。
微信小程序 + nodeJs(loopback) 实现支付的更多相关文章
- day87_11_7微信小程序之登录,支付(获取ip,requests使用),授权
一.登录接口. 官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 在登录接口 ...
- 微信小程序对接通联支付
1.首先拿到通联支付开发API:https://aipboss.allinpay.com/know/devhelp/main.php?pid=15#mid=92 2.如果注册通联或者企业认证工作请到: ...
- 让你的微信小程序具有在线支付功能
前言 最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过 ...
- 微信小程序在线支付功能使用总结
最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过程如出 ...
- 微信小程序常见问题集合(长期更新)
最新更新: 新手跳坑系列:推荐阅读:<二十四>request:fail错误(含https解决方案)(真机预览问题 跳坑指南<七十>如何让微信小程序服务类目审核通过 跳坑六十九: ...
- 两百条微信小程序跳坑指南(不定时更新)
微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...
- WordPress版微信小程序开发系列(二):安装使用问答
自WordPress版微信小程序发布开源以来,受关注的程度超过我原来的想象.这套程序主要面对的用户是wordpress网站的站长,如果wordpress站想在微信的生态圈得到推广,小程序成为一种重要的 ...
- nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId
nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId 前言: 我准备用nodejs+koa+uniapp实现一款餐饮点单小程序,以及nodejs+koa+vue实现后端管理 ...
- 微信小程序-登陆、支付、模板消息
wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要 ...
随机推荐
- 前端面试题整理—Webpack篇
1.什么是webpack,与grunt和gulp有啥不同 webpack是一个模块打包工具,在webpack里面一切皆模块 通过loader转换文件,通过plugin注入钩子,最后输出有多个模块组合成 ...
- Knockoutjs 响应式计算研究
reactive programming https://en.wikipedia.org/wiki/Reactive_programming In computing, reactive progr ...
- JSP+MySQL验证登录的实现方式
用IDEA连接MySQL验证登录实现方式核心部分代码 用setString的方法对从数据库中的提取的信息经行比对: try { Class.forName("com.mysql.jdbc.D ...
- idea工具的快捷方式
用idea默认的快捷键 Ctrl+~,快速切换方案(界面外观.代码风格.快捷键映射等菜单) Shift+Enter,向下插入新行 Ctrl+F,查找文本 Ctrl+R,替换文本 Ctrl+I,实现方法 ...
- python 去除html 超链接href 如何实现?
今天持久男 在抓取数据的时候发现很多内容都加了锚文本, 这怎么办呢? 没办法只能通过工具解决 我是这样解决的: 例如: soup = BeautifulSoup('<p>Hello < ...
- *42. Trapping Rain Water 接雨水
1. 原始题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这 ...
- virtualenv安装及使用
环境 Windows 10 python 3.6.7 安装 virtualenv用于创建虚拟环境,用于隔离不同的python版本的运行,是容器类软件.这里在Windows下通过pip安装: pip i ...
- Android运行时权限
Android 6.0加入了运行时权限这一概念.对于危险权限,应用必须在使用的时候进行申请.可以使用命令行查看危险权限:adb shell pm list permissions -d -g CALE ...
- 高德JSAPI获取当前所在位置的经度纬度
这是在浏览器中的效果: 控制台打印出来的就是经度纬度的值 代码如下: <!doctype html> <html> <head> <meta charset= ...
- datatable 给某一列添加title属性
简单描述:采用datatable拼接的表格,没有title属性,嗯就是这个情况,直接上代码 代码: //js代码$("#toAdd").click("click" ...