基于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 相关文章推荐
PHPStorm 2020.1 调试 Nodejs的多种方法详解
Sep 17 NodeJs
轻松创建nodejs服务器(10):处理POST请求
Dec 18 NodeJs
PHP和NodeJs开发的应用如何共用Session
Apr 16 NodeJs
nodejs实现获取某宝商品分类
May 28 NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 NodeJs
nodejs服务搭建教程 nodejs访问本地站点文件
Apr 07 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
解决Nodejs全局安装模块后找不到命令的问题
May 15 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
Feb 06 NodeJs
nodejs处理tcp连接的核心流程
Feb 26 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
Win9x/ME下Apache+PHP安装配置
2006/10/09 PHP
PHP5+UTF8多文件上传类
2008/10/17 PHP
php判断并删除空目录及空子目录的方法
2015/02/11 PHP
PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
2020/08/03 PHP
filemanage功能中用到的common.js
2007/04/08 Javascript
用javascript做拖动布局的思路
2008/05/31 Javascript
jquery 双色表格实现代码
2009/12/08 Javascript
jQuery 核心函数以及jQuery对象
2010/03/23 Javascript
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
15款jQuery分布引导插件分享
2015/02/04 Javascript
JQuery实现的按钮倒计时效果
2015/12/23 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
ES6中的箭头函数实例详解
2017/04/06 Javascript
js 毫秒转天时分秒的实例
2017/11/17 Javascript
vant(ZanUi)结合async-validator实现表单验证的方法
2018/12/06 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
2019/04/29 Javascript
实现高性能javascript的注意事项
2019/05/27 Javascript
js prototype和__proto__的关系是什么
2019/08/23 Javascript
详解elementUI中input框无法输入的问题
2020/04/27 Javascript
[51:50]完美世界DOTA2联赛 Magma vs GXR 第一场 11.07
2020/11/10 DOTA
Python实用日期时间处理方法汇总
2015/05/09 Python
python中getaddrinfo()基本用法实例分析
2015/06/28 Python
python利用正则表达式排除集合中字符的功能示例
2017/10/10 Python
Python字典的概念及常见应用实例详解
2019/10/30 Python
Python PIL库图片灰化处理
2020/04/07 Python
Python 爬虫的原理
2020/07/30 Python
夏威夷灵感服装及配饰:Reyn Spooner
2018/09/18 全球购物
大二自我鉴定
2014/01/31 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
铅球加油稿100字
2014/09/26 职场文书
群众路线教育实践活动总结
2014/10/30 职场文书
教师工作决心书
2015/02/04 职场文书
爱护公物主题班会
2015/08/17 职场文书
银行柜员工作心得体会
2016/01/23 职场文书
新手入门Jvm-- JVM对象创建与内存分配机制
2021/06/18 Java/Android
SQL实现LeetCode(180.连续的数字)
2021/08/04 MySQL