基于nodejs实现微信支付功能


Posted in NodeJs onDecember 20, 2017

本文实例为大家分享了nodejs实现微信支付的具体代码,供大家参考,具体内容如下

通过nodejs使用微信支付最重要的就是微信的签名,在这里md5后的字符必须转化为大写

一、回复微信通知消息模版

message.ejs

<xml> 
  <return_code><![CDATA[<%-return_code%>]]></return_code> 
  <return_msg><![CDATA[<%=return_msg%>]]></return_msg> 
</xml>

二、微信支付model文件代码

wxpay.js

var config = require('../config'); //配置文件 appid 等信息 
var Q = require("q"); 
var request = require("request"); 
var crypto = require('crypto'); 
var ejs = require('ejs'); 
var fs = require('fs'); 
var key = "此处为申请微信支付的API密码"; 
var messageTpl = fs.readFileSync(__dirname + '/message.ejs', 'utf-8'); 
 
var WxPay = { 
  getXMLNodeValue: function(node_name, xml) { 
    var tmp = xml.split("<" + node_name + ">"); 
    var _tmp = tmp[1].split("</" + node_name + ">"); 
    return _tmp[0]; 
  }, 
 
  raw: function(args) { 
    var keys = Object.keys(args); 
    keys = keys.sort() 
    var newArgs = {}; 
    keys.forEach(function(key) { 
      newArgs[key] = args[key]; 
    }); 
    var string = ''; 
    for (var k in newArgs) { 
      string += '&' + k + '=' + newArgs[k]; 
    } 
    string = string.substr(1); 
    return string; 
  }, 
 
  paysignjs: function(appid, nonceStr, package, signType, timeStamp) { 
    var ret = { 
      appId: appid, 
      nonceStr: nonceStr, 
      package: package, 
      signType: signType, 
      timeStamp: timeStamp 
    }; 
    var string = this.raw(ret); 
    string = string + '&key=' + key; 
    var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); 
    return sign.toUpperCase(); 
  }, 
 
  paysignjsapi: function(appid, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) { 
    var ret = { 
      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, 
      spbill_create_ip: spbill_create_ip, 
      total_fee: total_fee, 
      trade_type: trade_type 
    }; 
    var string = this.raw(ret); 
    string = string + '&key=' + key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 
    var crypto = require('crypto'); 
    var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); 
    return sign.toUpperCase(); 
  }, 
 
  // 随机字符串产生函数 
  createNonceStr: function() { 
    return Math.random().toString(36).substr(2, 15); 
  }, 
 
  // 时间戳产生函数 
  createTimeStamp: function() { 
    return parseInt(new Date().getTime() / 1000) + ''; 
  },
// 此处的attach不能为空值 否则微信提示签名错误 
  order: function(attach, body, mch_id, openid, bookingNo, total_fee, notify_url) { 
    var deferred = Q.defer(); 
    var appid = config.member_config.appid; 
    var nonce_str = this.createNonceStr(); 
    var timeStamp = this.createTimeStamp(); 
    var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 
    var formData = "<xml>"; 
    formData += "<appid>" + appid + "</appid>"; //appid 
    formData += "<attach>" + attach + "</attach>"; //附加数据 
    formData += "<body>" + body + "</body>"; 
    formData += "<mch_id>" + mch_id + "</mch_id>"; //商户号 
    formData += "<nonce_str>" + nonce_str + "</nonce_str>"; //随机字符串,不长于32位。 
    formData += "<notify_url>" + notify_url + "</notify_url>"; 
    formData += "<openid>" + openid + "</openid>"; 
    formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"; 
    formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"; 
    formData += "<total_fee>" + total_fee + "</total_fee>"; 
    formData += "<trade_type>JSAPI</trade_type>"; 
    formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"; 
    formData += "</xml>"; 
    var self = this; 
    request({ 
      url: url, 
      method: 'POST', 
      body: formData 
    }, function(err, response, body) { 
      if (!err && response.statusCode == 200) { 
        console.log(body); 
        var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8")); 
        var tmp = prepay_id.split('['); 
        var tmp1 = tmp[2].split(']'); 
        //签名 
        var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp); 
        var args = { 
          appId: appid, 
          timeStamp: timeStamp, 
          nonceStr: nonce_str, 
          signType: "MD5", 
          package: tmp1[0], 
          paySign: _paySignjs 
        }; 
        deferred.resolve(args); 
      } else { 
        console.log(body); 
      } 
    }); 
    return deferred.promise; 
  }, 
 
  //支付回调通知 
  notify: function(obj) { 
    var output = ""; 
    if (obj.return_code == "SUCCESS") { 
      var reply = { 
        return_code: "SUCCESS", 
        return_msg: "OK" 
      }; 
 
    } else { 
      var reply = { 
        return_code: "FAIL", 
        return_msg: "FAIL" 
      }; 
    } 
 
    output = ejs.render(messageTpl, reply); 
    return output; 
  }, 
}; 
module.exports = WxPay;

三、在express router中调用wxpay

//微信支付demo 
router.get('/order', function(req, res, next){ 
  var attach = "1276687601"; 
  var body = "测试支付"; 
  var mch_id = "1111111"; //商户ID 
  var openid = "111111"; 
  var bookingNo = "201501806125346"; //订单号 
  var total_fee = 10; 
  var notify_url = "http://localhost/wxpay/notify"; //通知地址 
  wxpay.order(attach, body, mch_id, openid, bookingNo, total_fee, notify_url).then(function(data){ 
    res.render('wxpay', {args: data}); 
  }); 
});
//微信回调通知 采用数据流形式读取微信返回的xml数据 此处不在累赘 
router.post('/notify', function(req, res, next){ 
 
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
nodejs中实现路由功能
Dec 29 NodeJs
NodeJs基本语法和类型
Feb 13 NodeJs
Nodejs关于gzip/deflate压缩详解
Mar 04 NodeJs
实例详解Nodejs 保存 payload 发送过来的文件
Jan 14 NodeJs
Nodejs如何复制文件
Mar 09 NodeJs
nodejs 的 session 简单使用
Jun 06 NodeJs
nodejs个人博客开发第六步 数据分页
Apr 12 NodeJs
详解如何在NodeJS项目中优雅的使用ES6
Apr 22 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
详解使用PM2管理nodejs进程
Oct 24 NodeJs
基于nodejs实现微信支付功能
Dec 20 NodeJs
nodejs利用readline提示输入内容实例代码
Jul 15 NodeJs
nodeJS微信分享
Dec 20 #NodeJs
NodeJS爬虫实例之糗事百科
Dec 14 #NodeJs
nodejs实现爬取网站图片功能
Dec 14 #NodeJs
NodeJs form-data格式传输文件的方法
Dec 13 #NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 #NodeJs
nodejs实现大文件(在线视频)的读取
Oct 16 #NodeJs
nodejs发送http请求时遇到404长时间未响应的解决方法
Dec 10 #NodeJs
You might like
排序算法之PHP版快速排序、冒泡排序
2014/04/09 PHP
ThinkPHP的MVC开发机制实例解析
2014/08/23 PHP
PHP实现对站点内容外部链接的过滤方法
2014/09/10 PHP
PHP实现Session入库/存入redis的方法
2017/05/04 PHP
浅谈PHP中的Trait使用方法
2019/03/22 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
js类中获取外部函数名的方法
2007/08/19 Javascript
用dom+xhtml+css制作的一个相册效果代码打包下载
2008/01/24 Javascript
Jquery Ajax.ashx 高效分页实现代码
2009/10/20 Javascript
javascript JSON操作入门实例
2010/04/16 Javascript
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
使用JS画图之点、线、面
2015/01/12 Javascript
招聘网站基于jQuery实现自动刷新简历
2015/05/10 Javascript
js+css实现有立体感的按钮式文字竖排菜单效果
2015/09/01 Javascript
使用Function.apply()的参数数组化来提高 JavaScript程序性能的技巧
2015/12/23 Javascript
基于JavaScript实现简单的随机抽奖小程序
2016/01/05 Javascript
JS实现根据用户输入分钟进行倒计时功能
2016/11/14 Javascript
谈谈JS中常遇到的浏览器兼容问题和解决方法
2016/12/17 Javascript
JS实现AES加密并与PHP互通的方法分析
2017/04/19 Javascript
Nuxt.js踩坑总结分享
2018/01/18 Javascript
通过vue-cli3构建一个SSR应用程序的方法
2018/09/13 Javascript
vue文件运行的方法教学
2019/02/12 Javascript
vuex vue简单使用知识点总结
2019/08/29 Javascript
VSCode 配置uni-app的方法
2020/07/11 Javascript
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
python实现合并两个数组的方法
2015/05/16 Python
python中Apriori算法实现讲解
2017/12/10 Python
python贪吃蛇游戏代码
2020/04/18 Python
Django admin model 汉化显示文字的实现方法
2019/08/12 Python
python中os包的用法
2020/06/01 Python
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
Ellesse英国官网:意大利高级运动品牌
2019/07/23 全球购物
橄榄树药房:OLIVEDA
2019/09/01 全球购物
大学拉赞助协议书范文
2014/09/26 职场文书
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android