热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

nodejs微信公众号支付开发

这篇文章主要为大家详细介绍了nodejs微信公众号支付开发,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
odeJs 微信公众号功能开发,移动端 H5页面调用微信的支付功能。这几天根据公司的需要使用 node 和 h5页面调用微信的支付功能完成支付需求。现在把开发过程重新捋一遍,以帮助更多的开发者顺利的完成微信支付功能的开发。(微信暂时还没有提供 node 的支付功能)

一.请求CODE

请求 code 的目的就是获取用户的 openid(用户相对于当前公众号的唯一标识) 和access_token,请求的API:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
此 api 需要注意几个参数:

1. appid公众号的 appid,可以在公众号中看到
2. redirect_uri 自定义的微信回调地址, 微信会在你请求完上面的地址后跳转到你定义的redirect_uri的地址, 带着 code,此处的 redirect_url 需要 **url_encode** *php*, 如果你的程序是 node 则需要使用 **encodeURLComponent(url)**编码
3. response_type=code,这个没什么好说的就是固定的 response_type=code,详细说明可以查看微信官网的说明
4. scope=snsapi_userinfo,固定这样写就好,详细说明可以查看微信官网的说明
5. state=STATE 固定这样写就好,详细说明可以查看微信官网的说明
6. wechat_redirect 固定这样写就好,详细说明可以查看微信官网的说明
ps:官网链接:

二.通过code获取access_token,openid

第一步已经获取到了 code 的值了, 那么接下来就需要通过 code 来获取 access_token,openid的值了,请求的 api
API https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
此处api 的参数说明:

1. appid 微信公众号 id,微信公众号后台获取
2. secret 微信公众号的密钥, 微信公众号后台获取
3. code, 第一步获取用到的 code
4. grant_type=authorization_code 固定就好

三.通过access_token调用接口

access_token 可以做后续的功能, 可以参考官方的例子:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316518&lang=zh_CN

四.网页端调起支付API

看见这个是不是感觉快完事儿了, 只要网页端调用微信支付功能就完事儿了?no,还差点
在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。
注意:WeixinJSBridge内置对象在其他浏览器中无效。
示例代码如下:

function onBridgeReady(){
 WeixinJSBridge.invoke(
 'getBrandWCPayRequest', {
  "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入 
  "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数 
  "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串 
  "package" : "prepay_id=u802345jgfjsdfgsdg888", 
  "signType" : "MD5",  //微信签名方式: 
  "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
 },
 function(res){ 
  if(res.err_msg == "get_brand_wcpay_request:ok" ) {} // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。 
 }
 ); 
}
if (typeof WeixinJSBridge == "undefined"){
 if( document.addEventListener ){
 document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
 }else if (document.attachEvent){
 document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
 document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
 }
}else{
 onBridgeReady();
}

看到上面的代码, 那么想调用微信的支付功能需要传递参数,

{
 "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入 
 "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数 
 "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串 
 "package" : "prepay_id=u802345jgfjsdfgsdg888", 
 "signType" : "MD5",  //微信签名方式: 
 "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
}

参数说明:

1. appId //公众号名称,由商户传入
2. timeStamp //时间戳,自1970年以来的秒数 此处需要特别的注意一下,需要是字符串的时间戳格式, 意思就是必须就“” 引号
3. nonceStr //随机串 32位的, 随后会提供方法
4. signType // 微信签名方式: MD5
5. paySign //微信签名, 随后说
6. **package** //这个最重要, 充哪里获取到的呢? 接下来说。
ps: 官网接口说明
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

五.获取package, 从微信的 统一下单 接口获取prepay_id

官方 api:
https://api.mch.weixin.qq.com/pay/unifiedorder

请求参数一堆, 但是有一些不是必须的,下面是必须参数

{
 appid : APPID,
 attach : ATTACH,
 body : BODY,
 mch_id : MCH_ID,
 nonce_str: NONCE_STR,
 notify_url : NOTIFY_URL,// 微信付款后的回调地址
 openid : OPENID,
 out_trade_no : OUT_TRADE_NO ,//new Date().getTime(), //订单号
 spbill_create_ip : SPBILL_CREATE_IP , //客户端的 ip
 total_fee : TOTAL_FEE, //商品的价格, 此处需要注意的是这个价格是以分算的, 那么一般是元, 你需要转换为 RMB 的元
 trade_type : 'JSAPI',
}

微信的统一下单接口要求传递的是 xml 的数据, 而且数据还需要签名, 那么首先吧数据签名。
签名规则可以参考微信给出的签名规则(签名方法一会给出)
微信官方签名规则:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

生成签名后需要吧数据组装为xml 的格式:

var body = ' ' +
 ''+config.wxappid+' ' +
 ''+obj.attach+' ' +
 ''+obj.body+' ' +
 ''+config.mch_id+' ' +
 ''+obj.nonce_str+' ' +
 ''+obj.notify_url+'' +
 ''+obj.openid+' ' +
 ''+obj.out_trade_no+''+
 ''+obj.spbill_create_ip+' ' +
 ''+obj.total_fee+' ' +
 ''+obj.trade_type+' ' +
 ''+obj.sign+' ' + // 此处必带签名, 否者微信在验证数据的时候是不通过的
 '';

接下来就是请求 api 获取prepay_id的值了, 将上面得到的 xml 数据请求下面的 api 发送给微信, 微信验证数据没问题后会放回你想要的值。
api : https://api.mch.weixin.qq.com/pay/unifiedorder

六. 获取到了prepay_id是不是就可以在 h5 段直接调用微信的支付了么? 答案是还不可以。

获取到了prepay_id那么现在h5 呼起微信的支付功能的参数是这样的:

{
 "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入 
 "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数 
 "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串 
 "package" : "prepay_id=u802345jgfjsdfgsdg888", 
 "signType" : "MD5",  //微信签名方式:
}

有了这样的参数, 那么你还需要吧所有参与的参数做签名。签名规跟上面的一样,生成了签名后需要吧签名的参数 paySign 赋给h5 呼起微信的支付功能的参数(也就是微信的签名不参与签名的生成)
最后的参数是这样子的:

{
 "appId" : "wx2421b1c4370ec43b", //公众号名称,由商户传入 
 "timeStamp":" 1395712654",  //时间戳,自1970年以来的秒数 
 "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串 
 "package" : "prepay_id=u802345jgfjsdfgsdg888", 
 "signType" : "MD5",  //微信签名方式:
 "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名
}

如果你的各个环节都没有问题, 那么得到了这样参数后你就可以正常的调用起微信的支付功能, 跟原生的功能是没有任何的差别的,(估计你现在的心里也特高兴吧, 没有 app 竟然可以使用 app 的功能,就是这么的神奇)。

七.支付完成的回调

微信支付完了后会在 h5 页面的微信支付的回调函数里面放回值,
res.err_msg == "get_brand_wcpay_request:ok" ,这样就是成功了, 但是不是就完事儿了呢 ? 也不是,为什么呢? 微信真的收到钱了么? 收到的钱是不是你传递给微信的值呢 ?你还需要将支付的结果写数据库什么的,这些都是未知。还记的在统一下单接口中有个必须参数就是 notify_url : NOTIFY_URL,// 微信付款后的回调地址 这个地址是用户传递给微信的, 微信在收到用户的付款后会以 post 的方式请求这个接口,微信会传递用户付款的信息过来, 不过是 xml 格式的。
类系这样的 xml 格式:


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 1
 
 

根据自己的业务逻辑解析这个 xml 格式的数据就好了。
注意:这里你在获取到数据后微信需要得到你的回应, 如果你一直不回应微信, 微信会请求你好几次, 这样估计你的逻辑会有问题吧,所以你需要给微信返回 xml 的格式的 回应。


 
 

小坑:node ,express 框架开发, 如果你在微信的支付成功后的回调中没有获取到任何 xml 的值, 那么你需要安装一组件:body-parser-xml, 你可以使用 npm install body-parser-xml --save 安装, 在 app.js 里面require('body-parser-xml')(bodyParser);,使用中间件的方式

// 解决微信支付通知回调数据
app.use(bodyParser.xml({
 limit: '2MB', // Reject payload bigger than 1 MB
 xmlParseOptions: {
 normalize: true, // Trim whitespace inside text nodes
 normalizeTags: true, // Transform tags to lowercase
 explicitArray: false // Only put nodes in array if >1
 }
}));

这样你就可以正常的获取到微信的 xml 数据了。

使用方法:

pay.getAccessToken({
 notify_url : 'http://demo.com/', //微信支付完成后的回调
 out_trade_no : new Date().getTime(), //订单号
 attach : '名称',
 body : '购买信息',
 total_fee : '1', // 此处的额度为分
 spbill_create_ip : req.connection.remoteAddress,
 }, function (error, responseData) {
 res.render('payment', {
  title : '微信支付',
  wxPayParams : JSON.stringify(responseData),
  //userInfo : userInfo
 });
 });

就到这里吧, 感觉也差不多了。如有不对的地方还请指正。

更多nodejs微信公众号支付开发相关文章请关注PHP中文网!

推荐阅读
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • 手把手教你使用GraphPad Prism和Excel绘制回归分析结果的森林图
    本文介绍了使用GraphPad Prism和Excel绘制回归分析结果的森林图的方法。通过展示森林图,可以更加直观地将回归分析结果可视化。GraphPad Prism是一款专门为医学专业人士设计的绘图软件,同时也兼顾统计分析的功能,操作便捷,可以帮助科研人员轻松绘制出高质量的专业图形。文章以一篇发表在JACC杂志上的研究为例,利用其中的多因素回归分析结果来绘制森林图。通过本文的指导,读者可以学会如何使用GraphPad Prism和Excel绘制回归分析结果的森林图。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
author-avatar
浮尘所惑的猫猫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有