十 Node.js实现微信小程序支付功能

  • 一 开发前提
  • 二 支付流程介绍
  • 三 上代码
    • 1.小程序端发起后台请求,完成统一下单
      • 1.1 小程序端发起后台请求
      • 1.2 Node.js后台接收请求,完成统一下单(重点)
      • 1.3 获取统一下单的返回数据,拉起微信支付
  • 四 感悟

一 开发前提

1.一个注册好,并且通过微信认证的,主体信息不能是个人的小程序
主体信息为个人的小程序是没有微信支付功能的,并且也无法获取用户手机号码
2.一个注册好并且通过微信认证的商户号
3.商户号与小程序绑定
4.这篇文章是以旧版微信支付为例开发微信支付。文档地址:旧版微信支付文档

二 支付流程介绍

1.由小程序端发起后台请求,后台根据传回的参数请求微信同一下单接口,将拿到的参数返回给小程序端,再由小程序拉起微信支付,支付完成以后,在回调函数中执行对应的更新操作。

三 上代码

1.小程序端发起后台请求,完成统一下单

1.1 小程序端发起后台请求

// request是我自己封装的wx.request方法,方便调用。
// wechatapp/wechatpay是我的接口地址,以post方式访问
// data 是参数对象
request('wechatapp/wechatpay', data).then(res => {let result = res.data//result 是后台返回的数据,我的封装格式如下:// {//     flag:Boolean,       //用于判断请求结果是否正常//     state:Int,          //状态码,用于确定请求状态是否正常//     data:Array|Object,  //返回的数据,根据情况返回数组或者对象,增删改操作不返回data//     message:String,     //增删改的操作完成提示//     error:String        //增删改的错误提示// }if (result.flag) {let obj = result.data//这里得到微信统一下单的数据 //拉起小程序微信支付,此处粘贴1.3节点的代码//**************************************}})

1.2 Node.js后台接收请求,完成统一下单(重点)

//此处是Node.js后台的router,与1.1步骤中的访问API一致
wechatapp.post('/wechatpay', (req, res) => {let b = req.body//PayOrder方法中封装了完成微信统一下单的全部重要内容// req.ip 是当前访问该接口的ip地址,返回一个IPv6格式的地址// b.openid 是当前请求访问该接口的唯一码,该接口需要在小程序中完成登录才能获得,然后传回后台common2.PayOrder(b, b.openid, req.ip, result => {res.send(result)})
})

下面是PayOrder方法的完整内容
需要引入的第三方module:
1.request 用于访问第三方接口 npm i request
2. md5 用于完成MD5加密 npm i md5
3. xml-js 用于接口回调后格式化xml数据 npm i xml-js

PayOrder(b, openid, currip, cb) {let nonceStr = common.CreateCode('', 20) //随机字符串let out_trade_no = common.CreateCode('WPAY', 20) //支付订单号//第一次签名let body = this.WePaySign(b, openid, nonceStr, out_trade_no, currip)//此处的this.BaseURL=‘https://api.mch.weixin.qq.com/pay/unifiedorder’//这是微信旧版统一下单接口request({ url: this.BaseURL, method: "POST", body }, (err, response, result) => {if (!err && response.statusCode == 200) {//将返回的数据格式化为JSON,再由JSON格式化为JS对象//此处的convert是引入xml-js的别名var result1 = convert.xml2json(result, { compact: true, spaces: 4 });let obj = JSON.parse(result1)let xmlobj = obj.xml//根据文档,通过下面两个值得结果判断是否完成微信统一下单if (xmlobj.return_code._cdata == "SUCCESS" && xmlobj.result_code._cdata == "SUCCESS") {//prepay_id  该参数为统一下单接口返回的关键参数,我们就是要用它完成微信支付let prepay_id = xmlobj.prepay_id._cdata/*以下代码用于在微信小程序中拉起微信支付时使用根据接口要求,需要完成二次签名*/let appid = xmlobj.appid._cdata//获取时间戳let timeStamp = parseInt((new Date().getTime() / 1000)) + ''let stringA = `appId=${appid}`stringA += `&nonceStr=${nonceStr.toUpperCase()}`stringA += `&package=${'prepay_id=' + prepay_id}`stringA += `&signType=MD5`stringA += `&timeStamp=${timeStamp}`stringA += '&key=' + common.mch_secret//第二次签名let key = md5(stringA).toUpperCase()let data = {key,prepay_id,nonceStr,appid,timeStamp,out_trade_no,package: 'prepay_id=' + prepay_id}cb({ state: 200, flag: true, data })}} else {cb({ state: 200, flag: false, message: err })}});},/*** 微信支付下单签名*/WePaySign(b, openid, nonce_str, out_trade_no, currip) {//需要将参数封装成XML格式let total_fee = b.total * 100   //支付金额,以分为单位//拼接签名字符串// 此处的body是商品说明,在微信支付完成界面显示// notify_url 返回通知URL// mch_id 商户号let stringA = `appid=${common.appid}&body=微信统一下单测试  &mch_id=${common.mch_id}&nonce_str=${nonce_str}&notify_url=${common.notify_url}&openid=${openid}&out_trade_no=${out_trade_no}&spbill_create_ip=${currip}&total_fee=${total_fee}&trade_type=JSAPI`//mch_secret 商户秘钥stringA += `&key=${common.mch_secret}`//生成秘钥let key = MD5(stringA).toUpperCase()let formData = "<xml>"formData += "<appid>" + common.appid + "</appid>"// formData += "<body>" + JSON.stringify(b) + "</body>"formData += "<body>微信统一下单测试</body>"formData += "<mch_id>" + common.mch_id + "</mch_id>"formData += "<nonce_str>" + nonce_str + "</nonce_str>"formData += "<notify_url>" + common.notify_url + "</notify_url>"formData += "<openid>" + openid + "</openid>"formData += "<out_trade_no>" + out_trade_no + "</out_trade_no>"formData += "<sign>" + key + "</sign>"formData += "<spbill_create_ip>" + currip + "</spbill_create_ip>"formData += "<total_fee>" + total_fee + "</total_fee>"formData += "<trade_type>JSAPI</trade_type>"formData += "</xml>"return formData
}

1.3 获取统一下单的返回数据,拉起微信支付

下面是小程序拉起微信支付的代码,具体的格式请大家参考文档
将下面的的代码粘贴到1.1节点的标识处,也可以单独封装一个方法

wx.requestPayment({appId: obj.appId,timeStamp: obj.timeStamp,nonceStr: obj.nonceStr,package: obj.package,signType: 'MD5',paySign: obj.key,success(e) {//用户支付成功时更新数据库订单信息data = { total, openid: app.globalData.userInfo.openid, orderStr, out_trade_no: obj.out_trade_no }self.UpDateOrder(data)},fail(err) {console.log('取消支付');self.onLoad()}, complete(res) {}

四 感悟

第一次做微信支付,遇到的坑比较多,不过最多的还是签名那一块,两次签名折腾了好久,下面附上微信官方提供的签名校验工具地址
签名校验工具
1.第一大坑:一定要注意去空格去回车,否则与官方签名不一致,会导致签名失败。
2.第二大坑:统一下单接口和拉起微信支付时所用的随机码必须是同一个,同一个。否则统一下单接口之后拉起微信支付会提示签名失败,这一点文档中没说明,本人也是折腾了好一会儿才发现这个坑。
3.另外线上的小程序IP地址需要https域名,下一节为大家讲述怎么白嫖SSL证书及怎么为Node.js安装SSL证书

十 Node.js实现微信小程序支付功能相关推荐

  1. node.js基于微信小程序的外卖订餐系统 uniapp 小程序

    美食是人类永恒的话题,无论是在古代还是现代人们对美食都有一种非常的热爱在里面,但是随着时代的发展,人们可能没有更多的时间去研究美食,很多时候人们在下班或者放学之后更希望通过网络来进行订餐,为此我开发了 ...

  2. 视频教程-10分钟实现微信小程序支付功能-微信开发

    10分钟实现微信小程序支付功能 码农一枚,非著名全栈开发人员.分享自己的一些经验,学习心得,希望后来人少走弯路,少填坑. 多年全栈开发经验,擅长小程序,java,安卓,web前端开发. 邱石 ¥19. ...

  3. 10行代码实现微信小程序支付功能,使用小程序云开发实现小程序支付功能(含源码

    前面给大家讲过一个借助小程序云开发实现微信支付的,但是那个操作稍微有点繁琐,并且还会经常出现问题,今天就给大家讲一个简单的,并且借助官方支付api实现小程序支付功能. 传送门 借助小程序云开发实现小程 ...

  4. SpringBoot对接微信小程序支付功能开发(一,下单功能)

    1,接入前准备: 接入模式选择直连模式: 申请小程序,得到APPID,并开通微信支付: 申请微信商户号,得到mchid,并绑定APPID: 配置商户API key,下载并配置商户证书,根据微信官方文档 ...

  5. 微信小程序php后台支付,微信小程序 支付功能实现PHP实例详解

    微信小程序 支付功能实现PHP实例详解 前端代码: wx.request({ url: 'https://www.yourhost.com/weixin/WeiActivity/payJoinfee' ...

  6. python个人微信支付接口_Python实现微信小程序支付功能

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 2.获取openid( ...

  7. python微信小程序抢购_Python实现微信小程序支付功能!Python确实强的一批!

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 2.获取openid( ...

  8. 微信小程序支付功能用服务器吗,微信小程序 支付功能 服务器端(TP5.1)实现...

    首先下载微信支付SDK ,将整个目录的文件放在 /application/extend/WxPay 目录下 在使用SDK之前我们需要对 WxPay.Config.php 进行配置 namespace ...

  9. 基于springboot微信小程序支付功能实现

    基于springboot微信小程序支付功能实现 简单的封装微信小程序支付功能,支付工具类所依赖的fastjson.lombok.wagegger, 1.添加maven依赖: 版本号可根据自己项目的实际 ...

最新文章

  1. OpenCV+python:读取图片和视频详细信息
  2. 线程调度、公平锁和非公平锁、乐观锁和悲观锁、锁优化、重入锁
  3. STM32基于AD5663的UV灯电压控制
  4. zero ecilpse下载_推荐10个免费图片下载网站,助你摆脱找图烦恼!建议收藏
  5. Oracle表重命名后索引、约束、权限、同义词的影响
  6. 通过反编译让SpecFlow支持多层属性值的验证
  7. SpringCloud——服务网关
  8. 'scipy._lib.messagestream' 以及 'scipy.interpolate.interpnd.array' 解决办法
  9. Java内存溢出的情况
  10. [BUG] CS0234: 命名空间“System.Web.Mvc”中不存在类型或命名空间名称“Ajax”(是否缺少程序集引用?)...
  11. android日志统计管理,时间日志app下载-时间日志(时间统计管理)下载v1.1.1 安卓版-西西软件下载...
  12. 打造自己的Android源码学习环境之六:运行Android模拟器
  13. ContentProvider
  14. EHub_tx1_tx2_E100 测试VisionWorks跑自带的demo
  15. LeetCode.714.买卖股票的最佳时机含手续费
  16. PT_常见的连续型分布/均匀分布/指数分布/柯西分布/正态分布
  17. 【信息安全-科软课程】Lab2环境变量和Set-UID程序实验
  18. 基于QT搭建的网易云音乐
  19. 轻松实现富文本编辑器
  20. [数据结构]二叉树的结构及实现

热门文章

  1. 数据恢复大师免费安装教程
  2. 参考Box2d算法实现的一个平衡球游戏
  3. 计算机鼠标不动了,鼠标不动了怎么办,教您鼠标不动了怎么办
  4. nba2k18服务器暂时不可用,NBA2K18连不上服务器解决方法 连接不上服务器咋办_3DM单机...
  5. Linux开发工具vim篇
  6. 微信小程序上传组件(可同时长传图片+视频)
  7. python+selenium小结5:获取浏览器版本号,当前URL,当前页面title
  8. 禁用ios浏览器页面上下滚动回弹效果
  9. 1.网页源码中找到我们需要获取
  10. 计算机英语情景对话二人组,英语小对话二人组日常情景对话(2)