博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nodejs实现微信小程序支付功能及相关问题总结
阅读量:7069 次
发布时间:2019-06-28

本文共 2901 字,大约阅读时间需要 9 分钟。

最近使用nodejs作为服务器,搭建了一个微信小程序。其中的微信支付功能是比较复杂的一部分。不过只要我们能掌握微信支付的工作流程,那实现这个功能也不会很难的。下面分享此次微信支付的实现经历。  

开发文档学习

借图一用,个人认为这张图包含了微信支付的架构理念

商户系统和微信支付系统主要交互:

实现流程: 

=> 获取微信用户的openid (小程序端获取传到后台)

=> 预下单获取prepay_id ,sign签名(后台根据相关参数进行签名)

=> 小程序端发送支付请求(根据后台返回的prepay_id和sign)

2.实现代码

  1. 小程序获取openid

//小程序端wx.login({  success(res) {    if (res.code) {      // 发起网络请求      wx.request({        url: 'https://test.com/onLogin',        data: {          code: res.code        },        success:function(res){          let openId = res.data.openid//获取后台返回的openid        }      })    } else {      console.log('登录失败!' + res.errMsg)    }  }})//nodejs端 var request = require('request') const JSCODE = ''(前端传过来的值) let wxUrl = "https://api.weixin.qq.com/sns/jscode2session"//小程序appid,secret等信息存在后台的配置文件中var url = wxUrl + 'appid=' + Config.wxLogin.appid + '&secret=' + Config.wxLogin.secretvar js_code = req.query.js_codeurl = url + '&js_code=' + js_code + '&grant_type=authorization_code'request(url, function (error, response, body) {    if (error) {        var results = Util.formatErrorRes(error);        res.json(results);        return    }    var results = Util.formatRes(body);    res.json(results);})复制代码

2. 后台根据相关参数获取prepay_id,sign签名

   =>后端格式化参数(根据小程序的需要)

   =>后台带参数请求微信统一下单地址(其中notify_url后端接受支付结果的接口地址)

   =>请求成功解析小程序返回的xml格式数据(引入npm包xmlreader,主要获取prepay_id)

   =>根据返回的值进行二次签名生成签名字符串(与prepay_id一起返回给前端)

   =>前端根据返回的签名和prepay_id进行支付请求

   =>微信支付成功,微信服务器将支付结果发到之前设置的notify_url

   =>根据微信后台返回的结果,更新用户信息

    注:此部分代码较多,近期会整理下放在GitHub,如果哪位道友着急需要可在下方评论中说明

3.问题总结

  1. 支付签名错误 (主要看第二条)

微信官方回答1) 使用微信的在线签名工具检查签名是否和程序生成的一致    https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1    签名工具用谷歌打开。选择MD5,XML,然后把请求参数xml放进去,就能校验签名。2)如果和微信的在线签名工具一致,说明程序没有错误,确定是API密钥错误   (被别人改动或者记错了)在商户平台的账户信息中更改API密钥(账户设置-安全设置-API安全),   15分钟后生效   2.1)统一下单用的是A商户号,也必须是A商户号登陆商户平台设置key才对。   2.2)要注意统一下单请求参数中total_fee参数的类型是int类型。3) 如果和微信的在线签名工具不一致,说明程序有错误,    常见的错误可能是:    3.1) 编码问题,确保所有的都是utf-8的. 如果有中文, 可以先把中文改成英文重新签名,    看是否签名错误,如果英文不会错中文才会错,基本肯定是编码问题    3.2:)消息中字段大小写和文档中完全一致复制代码

  按照上述需求进行配置就可以解决支付签名错误的问题了。 

 2.express微信支付回调值req.body为空{}

     支付返回的格式是xml,查找到原因是express4.x里将body-parser分离出来,变成像其他中间件的使用方式,

所以我们需要在app.js中增加中间件

var bodyParser = require("body-parser");require("body-parser-xml")(bodyParser);// 解析支付回调的xml数据app.use(bodyParser.xml({    limit: "1MB",   // Reject payload bigger than 1 MB    xmlParseOptions: {        normalize: true,        normalizeTags: true,         explicitArray: false    },    verify: function(req, res, buf, encoding) {        if(buf && buf.length) {            // Store the raw XML            req.rawBody = buf.toString(encoding || "utf8");        }    }}));复制代码

3.二次签名报缺少参数或参数错误

  参数的格式必须严格按照文档要求,参数需要用使用驼峰(之前用下划线app_id这种类型一      直报参数错误...)

var ret = {    appId: appid,    package:'prepay_id='+prepayid,    nonceStr: noncestr,    signType:'MD5',    timeStamp: timestamp,};复制代码

5.没有支付权限

 检查该小程序账号是否已经获取了支付资格。

转载于:https://juejin.im/post/5c6bd54ff265da2dce1f395d

你可能感兴趣的文章
android去除标题栏和状态栏
查看>>
[转]利用 NPOI 變更字體尺寸及樣式
查看>>
eval解析JSON字符串的一个小问题
查看>>
jquery简单原则器(匹配除了指定选择器之外的元素 selector 表示选择器)
查看>>
update使用inner join
查看>>
Vue2.x中的父子组件相互通信
查看>>
多种替身邮方法总结!
查看>>
沟通比文档更有力
查看>>
Ural_1073. Square Country(DP)
查看>>
asp.net的10个提升性能或扩展性的秘密(二)
查看>>
[转载]我的WCF之旅(3):在WCF中实现双工通信
查看>>
Jquery中替换节点的方法replaceWith()和replaceAll()
查看>>
谈谈android模拟器和真机的差别
查看>>
upx最新壳脱壳测试
查看>>
[原创]手写一个PE文件
查看>>
安装php xdebug扩展
查看>>
junit junit4
查看>>
HUT-XXXX 数字游戏 求解区间的最值
查看>>
关于MAX部分快捷键失效的问题分析
查看>>
Qt学习之路_14(简易音乐播放器)
查看>>