实现小程序的支付,首先需要去微信官网先了解一下微信小程序支付相关接口文档: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',
})
}
})
}

支付完成。

console.log(e,'s//s/');
let that = this;
// if (!this.data.payNowBottonUse) {//防止按钮重复点击
// return;
// }
// this.setData({
// payNowBottonUse: false
// })
let data = {
openid: app.globalData.openId,
appid: app.globalData.app_id,
body: this.data.applyGame.name + "报名测试",
// body: "pppddpdp",
// detail: JSON.stringify(that.data.payOrdrInfoData.specific_project),//服务id
// attach: this.data.applyGame.id,//附加信息,暂时不添加
// //product_id: "002",//trade_type=NATIVE时(即扫码支付),此参数必传。
total_fee: ,
notify_url: app.globalData.appUrl + 'sdk/wxpayvnotify',
member_id: this.data.memberInfo.id,
user_id: app.globalData.userId,
game_id: this.data.applyGame.id,
where:{ // 不能重复提交订单条件
status: orderStatus.pay,
gameId: this.data.applyGame.id,
memberId: this.data.memberInfo.id
}
};
pay(data, (res) => {
if (res.statusCode == ) {
if (res.data.successed == true) {
let backobj = res.data.datalist;
console.log(backobj,'slslslslls');
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) 实现支付的更多相关文章

  1. day87_11_7微信小程序之登录,支付(获取ip,requests使用),授权

    一.登录接口. 官方文档https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 在登录接口 ...

  2. 微信小程序对接通联支付

    1.首先拿到通联支付开发API:https://aipboss.allinpay.com/know/devhelp/main.php?pid=15#mid=92 2.如果注册通联或者企业认证工作请到: ...

  3. 让你的微信小程序具有在线支付功能

    前言 最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过 ...

  4. 微信小程序在线支付功能使用总结

    最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过程如出 ...

  5. 微信小程序常见问题集合(长期更新)

    最新更新: 新手跳坑系列:推荐阅读:<二十四>request:fail错误(含https解决方案)(真机预览问题 跳坑指南<七十>如何让微信小程序服务类目审核通过 跳坑六十九: ...

  6. 两百条微信小程序跳坑指南(不定时更新)

    微信小程序联盟出品 跳坑textarea<二百二十三>不显示文本及textarea相关问题集合跳坑<二百一十三> background-image无法获取本地资源图片....跳 ...

  7. WordPress版微信小程序开发系列(二):安装使用问答

    自WordPress版微信小程序发布开源以来,受关注的程度超过我原来的想象.这套程序主要面对的用户是wordpress网站的站长,如果wordpress站想在微信的生态圈得到推广,小程序成为一种重要的 ...

  8. nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId

    nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId 前言: 我准备用nodejs+koa+uniapp实现一款餐饮点单小程序,以及nodejs+koa+vue实现后端管理 ...

  9. 微信小程序-登陆、支付、模板消息

    wx.login(OBJECT) 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key).用户数据的加解密通讯需要 ...

随机推荐

  1. java 打印空心菱形的两种实现

    第一种实现方式: //打印给定行数的空心菱形 public static void draw(int size){ if (size % 2 == 0) //如果是偶数行变为奇数 { size++; ...

  2. centos7安装与配置nginx1.11,开机启动

    1.官网下载安装包 http://nginx.org/en/download.html,选择适合Linux的版本,这里选择最新的版本,下载到本地后上传到服务器或者centos下直接wget命令下载. ...

  3. PHP中的数组

    一.数组的基础 php数组的分类 按照下标的不同,php分为关联数组与索引数组: 索引数组:下标从零依次增长(以前那种) 关联数组:下标为字符串格式,每个下标字符串与数组的值一一关联对应(有点儿像对象 ...

  4. 记一次解决netty半包问题的经历

    最近学习了netty,想写一个简单的rpc,结果发现发送消息时遇到难题了,网上搜了一下,这种情况是半包问题和粘包问题,主要是出现在并发高一些的时候. talk is cheap 客户端编码: prot ...

  5. java程序设计习题总结

    ---恢复内容开始--- main()方法的参数名可以改变:main()方法的参数个数不可以改变. 当一个程序没有main()方法是,是可以编译通过的,但是不能给运行,因为找不到一个主函数入口. 标识 ...

  6. important覆盖行内样式

    优先级,外部样式<内部样式<行内样式,后台富文本编辑器编辑的正文显示在前台时可用!important覆盖其行内样式 今天的问题,font-family:"思源黑体 CN!impo ...

  7. Deep Mutual Learning

    论文地址: https://arxiv.org/abs/1706.00384 论文简介 该论文探讨了一种与模型蒸馏(model distillation)相关却不同的模型---即相互学习(mutual ...

  8. 通过 iis或者本地IP 调试代码

    首先说下这个操作的意义,做微信开发每次需要将代码部署后才能调试.现在设置了Nginx服务器,生产环境可以指向正式服务器地址,调试时可以将Nginx指向自己的PC,但是vs调试启动的默认地址是[loca ...

  9. 全面剖析XMLHttpRequest对象

    XMLHttpRequest对象是当今所有AJAX和Web 2.0应用程序的技术基础.尽管软件经销商和开源社团现在都在提供各种AJAX框架以进一步简化XMLHttpRequest对象的使用:但是,我们 ...

  10. Java_面向对象

    目录 一.封装 二.继承 三.多态 四.重载与重写 五.接口与抽象类 六.继承与组合 七.初始化块 面向对象的三大特征:封装.继承.多态. 一.封装 是指将对象的状态信息都隐藏在对象内部,不允许外部程 ...