nodejs实现微信支付


JSSDK

1、H5支付和jssdk微信支付的区别
H5支付:只能在微信外部的浏览器进行支付
jssdk支付:在微信里面完成的支付

2、什么是JSSDK?
可以让微信里面的web页面有能力调用原生的api功能,这就叫jssdk(能力有限,相比微信小程序调用原生的api的能力差一些)
通过使用微信JS-SDK,网页开发者可以借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

3、获取 appid appsecret 和商户号 商户key
在这里插入图片描述
微信公众号里面获取appid appsecret (找到:基本配置)

  • appid:直接获取
  • appsecret 点击重置会生成一串数字字母组合的字符串 (保存)

商户ID和商户Key如何获取:

  • 商户ID:申请完成支付以后 邮件里面可以看到 或者点击 微信支付里面可以看到
  • 商户key:需要登录商户平台 账户中心->api安全->设置密钥 (32位密码 自己随便写 注意设置完成保存)

商户ID:
在这里插入图片描述

商户key:微信商户平台:https://pay.weixin.qq.com
在这里插入图片描述
扫码登录时(选择对应商户号)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
秘钥是随便填写的

配置jssdk

官网:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
1、配置微信JSSDK支付之前的准备工作**重要:
(一)公众号里面的配置
1、配置JS安全域名: 公众号设置->功能设置->JS接口安全域名 xxxx.com
2、支付需要配置支付域名:公众号设置->功能设置->网页授权域名 (
支付的时候配置的)
3、配置IP白名单:基本配置->IP白名单
(二)商户平台里面配置支付目录:

  • 商户平台>产品中心>开发配置->配置公众号支付授权目录 (* 支付的时候配置的)

① 配置JS安全域名:

注意:JS接口安全域名是前端部署服务器后的链接,而不是你node部署的服务器
在这里插入图片描述
点击下载文件:把文件复制到服务器项目的目录里面
在这里插入图片描述

在这里插入图片描述

做支付必须得配置它,只配置jssdk的话可以不用配置它

②配置IP白名单
在这里插入图片描述
想在哪里调用微信jssdk的参数,就在哪设置,比如要在118.123.14.36这台服务器里面配置,就输入服务器的ip地址
在这里插入图片描述
③商户平台里面配置支付目录
在这里插入图片描述
比如:
http://a.xxx.com/index.html http://a.xxx.com/
http://a.xxx.com/pay/index.html http://a.xxx.com/pay/

使用jssdk

①引入js
在这里插入图片描述
②wx.ready里面放置对应的代码,wx.getNetworkType是获取网络
在这里插入图片描述
③配置config
在这里插入图片描述
获取签名:

第一步:获取access_token
文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183
通过下面地址获取

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx7bf3787c783116e4&secret=cca407db4d8459c907d2c59274ca6d17
// 在浏览器数据获取到的结果

{"access_token":"10__sxf1kkKOcmLVcU3kNdQg3fsBeZ1522zvacAZ1dcqRc6Cot-Y-V1Pdn3keTXmV-SwDOZ5nSa3Tcpvk0nXbVZUT8l15T0aJBX_C2WesrsZapaBK9tQ0_cnrBmExIVZZiADAEII","expires_in":7200}

哪里加入白名单,就在哪里获取
在这里插入图片描述
第二步:根据access_token获取ticket

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=10__sxf1kkKOcmLVcU3kNdQg3fsBeZ1522zvacAZ1dcqRc6Cot-Y-V1Pdn3keTXmV-SwDOZ5nSa3Tcpvk0nXbVZUT8l15T0aJBX_C2WesrsZapaBK9tQ0_cnrBmExIVZZiADAEII&type=jsapi
// 在浏览器数据获取到的结果
		{"errcode":0,"errmsg":"ok","ticket":"HoagFKDcsGMVCIY2vOjf9g2_I8_P118MfAFHMc-AncAVkaHekeNmVlA2LK4JEznnejfTxR2EnyrGCeFwFEmHpQ","expires_in":7200}

第三步:根据ticket获取签名

 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

用工具获取,url是要调用jssdk的地址
在这里插入图片描述
点击生成签名,获取到了签名

signature : 62d5ba349c3559869981be73f28ce575c3947af8

使用官方JS-SDK的流程::

1.必须配置js接口的安全域名  找到公众号里面的设置->公众号设置->JS接口安全域名->功能设置->JS接口安全域名
2、点开下面地址配置安全域名:
		https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
3、获取测试的appid  appsecret
		开发者工具->公众平台测试账户
	获取正式的appid  appsecret
		基本配置->公众号开发信息
4、下载官方的JS-SDK 实例包
	下载地址: 最下面https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
	配置appid  appsecret
5、jsApiList: []   加入权限
6、wx.ready(function () {})里面 使用对应的实例

nodejs

用到了wechat-api这个包生成签名
1.安装wechat-api
 cnpm install wechat-api --save

2、引入var API = require('wechat-api');  

3、实例化配置
var api = new API(config.wxappid,config.wxappsecret) ;

4、生成config的参数
        var param = {  
                debug: false,  
                jsApiList: ['checkJsApi',              
                        'chooseImage',            
                        'getNetworkType',
                        'openLocation',
                        'getLocation',             
                        'scanQRCode'
                ],  
                url: req.body.url  
        };  
        api.getJsConfig(param, function(err,result){  
                res.send(result);  
        }); 

手机端的调试工具:

  <script src="http://wechatfe.github.io/vconsole/lib/vconsole.min.js?v=3.2.0"></script>
<script>  
  //手机端的调试工具
   var vConsole = new VConsole();
</script>  

微信支付

在这里插入图片描述
准备工作:配置微信JSSDK支付之前的准备工作***重要(文章最上面以提)
微信支付的三大步骤:
1、获取用户openID:
①在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID,对于不同公众号,同一用户的openid不同id
②用户同意授权,获取code https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx4518345b2ab754e1&redirect_uri=http://www.jxy-edu.com/result.jsp&response_type=code&scope=snsapi_userinfo#wechat_redirect
2、通过获取的code,返回当前关注者在当前服务号唯一的openId https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx4518345b2ab754e1&secret=4aaf7d8e73e06714212c48cc35dd1fd8&code=0215wGRM0gyO872TmNRM0F8IRM05wGRk&grant_type=authorization_code
3、获取prepay_id 和 paySign

微信支付文档:
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
	
获取code和openid文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

理解:
①拿到 code,②通过nodejs后台a.sayid760.com/getOpenid 方法去获取openid ③通过ajax请求wechat(生成jssdk配置)④点击支付,调用下单接口(把参数传给后台)(请求支付的时候向 微信官方 调用下单接口,微信给返回 预付信息 )(后端返回jssdk签名字段)

示例链接: (复制进草料生成二维码)

// 获取openid ( 即 accessToke ) 可以保存到localStorage      
		https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx616683031bf5c67d&redirect_uri=http://a.sayid760.com&response_type=code&scope=snsapi_userinfo#wechat_redirect


// 或者
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7bf3787c783116e4&redirect_uri=http://a.sayid760.com?cid=123&name=zhangsan&response_type=code&scope=snsapi_base#wechat_redirect
				

例子

基础例子

扫描二维码

// index.html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>  
		<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
		<script src="https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js"></script>
		</script>

		<script type="text/javascript">
		 //手机端的调试工具
		 var vConsole = new VConsole();
		 $(function(){  
			wx.config({    //ctrl+shift+f格式化代码
				debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
				appId: 'wx616683031bf5c67d', // 必填,公众号的唯一标识
				timestamp:1 , // 必填,生成签名的时间戳
				nonceStr: '1', // 必填,生成签名的随机串
				signature: '772d88d69b90dfcca7d4c1dde2d28eb52cea95d9', // 必填,签名      ***
				jsApiList: ['getNetworkType','scanQRCode'] // 必填,需要使用的JS接口列表   注意配置权限
			});		
			
			wx.ready(function(){
			    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
				  wx.getNetworkType({
					success: function (res) {
						var networkType = res.networkType; // 返回网络类型2g,3g,4g,wifi
						console.log(networkType);
					}
				  });
				  
				  document.querySelector('#scanQRCode').onclick=function(){
				  	
				  	  wx.scanQRCode({
						needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
						scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有
						success: function (res) {
							var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
							alert(result);
						},
						error:function(res){
							alert(result)
						}
					 });
				  	
				  }
				  
			});
			wx.error(function(res){
			    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
			});
		 })
		</script>
	</head>

	<body>
		<button id="scanQRCode">
			扫一扫
		</button>
	</body>
</html>

微信支付例子

|- module
| |- config.js
| |- wechatPay.js
|- views
| |- index.ejs
|- app.js

//  views/index.ejs
<!doctype html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">  
    <title>微信测试页面</title>  
    <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>  
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>  
    <script src="https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js"></script>

    <script>  
    $(function(){  
        var vConsole = new VConsole();

        function getQueryString(name) {  
          var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");  
          var r = window.location.search.substr(1).match(reg);  
          if (r != null) return decodeURI(r[2]);  
          return null;  
        }  

        //1、获取code
        var code=getQueryString('code');      /*获取code*/
        $(function(){  
            // 2、获取openid
             $.get('http://a.sayid760.com/getOpenId?code='+code,function(response){
                 console.log('1111111')
                 console.log(response)
                  var openid=response.openid;
                  wxInit(openid)
              })
        })  
        
        function wxInit(openid){
             var param = {'cmd':'get_js_config','url':location.href};  
            //发送请求获取wx_js_config  
            $.ajax({  
                    url: 'http://a.sayid760.com/wechat',    //获取config
                    type: 'POST',  
                    data: param,  
                    datatype: 'json',  
                    success: function (data) {  
                        wx.config(data);  
                        wx.ready(function(){  
                            document.getElementById('btn3').onclick = function() {
                                wx.scanQRCode({
                                    needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                                    scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
                                    success: function(res) {
                                        var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                                        alert(result);
                                    },fail:function(err){
                                        
                                        alert(JSON.stringify(err))
                                    }
                                });
                            }                            


                            // 监听支付
                            document.querySelector('#onPay').onclick = function () {
                                    //根据openid获取支付参数
                                    $.get('http://a.sayid760.com/order/?openid='+openid,function(response){
                                        console.log('==============response===========');
                                            console.log(response);
                                            wx.chooseWXPay({                                                                                
                                                "timestamp":response.timeStamp,   // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
                                                "nonceStr":response.nonceStr,
                                                "package":response.package,
                                                "signType":response.signType,
                                                "paySign":response.paySign,
                                                success: function (res) {
                                                // 支付成功后的回调函数
                                                    alert(JSON.stringify(res));
                                                }
                                            });
                                            //js支付的安全域名配置错误  choosewxpay:fail (具体什么错误不提示)
                                            //出现 choosewxpay:fail错误以后   用ios手机调试  这时候会告诉你具体错误
                                    })                              
                            };
                                            
                                
                                                
                        });  
                        wx.error(function(res){  
                            alert(JSON.stringify(res));  
                            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。  
                        });  
                    }  
                })  
        }
    })
    </script>  
</head>  
<body>  
    <button id="btn3">扫一扫</button>
    <button id="onPay">支付</button>
</body>  
</html>  
// app.js


/*
用到了wechat-api这个包生成签名


1.安装wechat-api
 cnpm install wechat-api --save


2、引入var API = require('wechat-api');  


3、实例化配置

var api = new API(config.wxappid,config.wxappsecret) ;


4、生成config的参数

        var param = {  
                debug: false,    调试模式
                jsApiList: ['checkJsApi',              
                        'chooseImage',            
                        'getNetworkType',
                        'openLocation',
                        'getLocation',             
                        'scanQRCode'
                ],  
                url: req.body.url  
        };  
       
        api.getJsConfig(param, function(err,result){  
                
                res.send(result);  
        }); 

*/


var config = require('./module/config');  
var API = require('wechat-api');  

//引入统一下单的api
var wechatPay = require('./module/wechatPay');  


var express = require('express');  
var bodyParser = require('body-parser');  
var xmlparser = require('express-xml-bodyparser');



var request = require('request');

var api = new API(config.wxappid,config.wxappsecret)  
var app = new express();

//xmlparser
app.use(xmlparser());


app.use(express.static('./public'));
//使用中间件body-parser获取post参数  
app.use(bodyParser.urlencoded({extended: false}));  
app.use(bodyParser.json());  

app.set('view engine','ejs');


  
app.post('/wechat',function (req, res, next) {  
        //使用wechat-api获取JSconfig  
        var param = {  
                debug: false,  
                jsApiList: ['checkJsApi',
                'onMenuShareTimeline',
                'onMenuShareAppMessage',
                'onMenuShareQQ',
                'onMenuShareWeibo',
                'onMenuShareQZone',
                'hideMenuItems',
                'showMenuItems',
                'hideAllNonBaseMenuItem',
                'showAllNonBaseMenuItem',
                'translateVoice',
                'startRecord',
                'stopRecord',
                'onVoiceRecordEnd',
                'playVoice',
                'onVoicePlayEnd',
                'pauseVoice',
                'stopVoice',
                'uploadVoice',
                'downloadVoice',
                'chooseImage',
                'previewImage',
                'uploadImage',
                'downloadImage',
                'getNetworkType',
                'openLocation',
                'getLocation',
                'hideOptionMenu',
                'showOptionMenu',
                'closeWindow',
                'scanQRCode',
                'chooseWXPay',
                'openProductSpecificView',
                'addCard',
                'chooseCard',
                'openCard'],  
                url: req.body.url  
        };  
        /*api.getTicket(function(err,result){ 
                console.log(err); 
                console.log(result); 
        });*/  
        api.getJsConfig(param, function(err,result){  
                // console.log(err)
                // console.log(result)
                res.send(result);  
        });  
        // console.log('执行');
})  


//获取openid返回客户端
app.get('/getOpenId',function(req, res){

        var code=req.query.code;

        var pay=new wechatPay();
        //openid

        pay.getAccessToken(code,function(err,data){
                console.log(data);
                res.json(data);
        })

})
 
app.get('/',function (req, res) {  
        //使用wechat-api获取JSconfig  
        



                //使用wechat-api获取JSconfig             
                res.render('index');   
               
})  


app.get('/order',function (req, res) {  
                //使用wechat-api获取JSconfig  

                //使用wechat-api获取JSconfig 
                var openid=req.query.openid;
                
                
                var pay=new wechatPay();
                pay.createOrder({
                        openid:openid,
                        notify_url : 'http://a.sayid760.com/notifyUrl', //微信支付完成后的回调
                        out_trade_no : new Date().getTime(), //订单号
                        attach : '名称',
                        body : '购买信息',
                        total_fee : '1', // 此处的额度为分
                        spbill_create_ip : req.connection.remoteAddress.replace(/::ffff:/, ''),
                }, function (error, responseData) {                
                        if(error){
                                console.log(error);
                        }
                        res.json(responseData);        /*签名字段*/
                });          
       
})  


app.post('/notifyUrl',function (req, res) {  
        //使用wechat-api获取JSconfig  

        //接受xml
        
        var pay=new wechatPay();
        
        
        var notifyObj=req.body.xml;

        var signObj={};

        for(var attr in notifyObj){
            if(attr !='sign'){
                signObj[attr]=notifyObj[attr][0]
            }
        }


        console.log(pay.getSign(signObj));
        console.log('--------------------------');

        console.log(req.body.xml.sign[0]);

})  

app.listen(8002,function(){  
    console.log('port 8003 is running!');  
});  
// module/config.js
var config={
    mch_id: '1535063641',
    wxappid: "wx616683031bf5c67d",
    wxappsecret:'f506525621307c15c0df13c94363a848',
    wxpaykey: 'c23fdgas768fdhASdsad121hgkf684gd'
}

module.exports=config;

// module/wechatPay.js

var url = require('url');
var queryString = require('querystring');
var crypto = require('crypto');
var request = require('request');
var xml2jsparseString = require('xml2js').parseString;
// 引入项目的配置信息
var config = require('./config.js');

// wechat 支付类 (使用 es6 的语法)
class WechatPay {    /**
     * 构造函数
     * @param params 传递进来的方法
     */
    constructor(){
        // this.userInfo = userInfo;

        // console.log(this.userInfo);
    }

    /**
     * 获取微信统一下单参数
     */
    getUnifiedorderXmlParams(obj){
        var body = '<xml> ' +
            '<appid>'+config.wxappid+'</appid> ' +
            '<attach>'+obj.attach+'</attach> ' +
            '<body>'+obj.body+'</body> ' +
            '<mch_id>'+config.mch_id+'</mch_id> ' +
            '<nonce_str>'+obj.nonce_str+'</nonce_str> ' +
            '<notify_url>'+obj.notify_url+'</notify_url>' +
            '<openid>'+obj.openid+'</openid> ' +
            '<out_trade_no>'+obj.out_trade_no+'</out_trade_no>'+
            '<spbill_create_ip>'+obj.spbill_create_ip+'</spbill_create_ip> ' +
            '<total_fee>'+obj.total_fee+'</total_fee> ' +
            '<trade_type>'+obj.trade_type+'</trade_type> ' +
            '<sign>'+obj.sign+'</sign> ' +
            '</xml>';
        return body;
    }

    /**
     * 获取微信统一下单的接口数据
     */
    getPrepayId(obj){
        var that = this;
        // 生成统一下单接口参数
        var UnifiedorderParams = {
            appid : config.wxappid,
            attach : obj.attach,
            body : obj.body,
            mch_id : config.mch_id,
            nonce_str: this.createNonceStr(),
            notify_url : obj.notify_url,// 微信付款后的回调地址
            openid : obj.openid,  //改
            out_trade_no : obj.out_trade_no,//new Date().getTime(), //订单号
            spbill_create_ip : obj.spbill_create_ip,
            total_fee : obj.total_fee,
            trade_type : 'JSAPI',
            // sign : getSign(),
        };
        // 返回 promise 对象
        return  new Promise(function (resolve, reject) {
            // 获取 sign 参数
            UnifiedorderParams.sign = that.getSign(UnifiedorderParams);
            var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
            request.post({url : url, body:JSON.stringify(that.getUnifiedorderXmlParams(UnifiedorderParams))}, function (error, response, body) {
                var prepay_id = '';
                if (!error && response.statusCode == 200) {
                    // 微信返回的数据为 xml 格式, 需要装换为 json 数据, 便于使用
                    xml2jsparseString(body, {async:true}, function (error, result) {
                        prepay_id = result.xml.prepay_id[0];
                        // 放回数组的第一个元素
                        resolve(prepay_id);
                    });
                } else {
                    reject(body);
                }
                
            });
        })
    }

    /**
     * 获取微信支付的签名
     * @param payParams
     */
    getSign(signParams){
        // 按 key 值的ascll 排序
        var keys = Object.keys(signParams);
        keys = keys.sort();
        var newArgs = {};
        keys.forEach(function (val, key) {
            if (signParams[val]){
                newArgs[val] = signParams[val];
            }
        })
        var string = queryString.stringify(newArgs)+'&key='+config.wxpaykey;
        // 生成签名
        return crypto.createHash('md5').update(queryString.unescape(string), 'utf8').digest("hex").toUpperCase();
    }

    /**
     * 微信支付的所有参数
     * @param req 请求的资源, 获取必要的数据
     * @returns {{appId: string, timeStamp: Number, nonceStr: *, package: string, signType: string, paySign: *}}
     */
    getBrandWCPayParams( obj, callback ){
        var that = this;
        var prepay_id_promise = that.getPrepayId(obj);
        prepay_id_promise.then(function (prepay_id) {
            var prepay_id = prepay_id;
            var wcPayParams = {
                "appId" : config.wxappid,     //公众号名称,由商户传入
                "timeStamp" : parseInt(new Date().getTime() / 1000).toString(),         //时间戳,自1970年以来的秒数
                "nonceStr" : that.createNonceStr(), //随机串
                // 通过统一下单接口获取
                "package" : "prepay_id="+prepay_id,
                "signType" : "MD5",         //微信签名方式:
            };
          
            wcPayParams.paySign = that.getSign(wcPayParams); //微信支付签名

            callback(null, wcPayParams);
        },function (error) {
            callback(error);
        });
    }

    /**
     * 获取随机的NonceStr
     */
    createNonceStr() {
        return Math.random().toString(36).substr(2, 15);
    };

    //获取微信的 AccessToken   openid

    getAccessToken(code, cb){
        var that = this;
        var getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+config.wxappid+"&secret="+config.wxappsecret+"&code="+code+"&grant_type=authorization_code";
        request.post({url : getAccessTokenUrl}, function (error, response, body) {
            if (!error && response.statusCode == 200){
                if (40029 == body.errcode) {
                    cb(error, body);
                } else {
                    body = JSON.parse(body);
                
                    cb(null, body);
                }
            } else {
                cb(error);
            }
        });
    }


    /**
     * 创建订单
     */
    createOrder(obj, cb){
        this.getBrandWCPayParams(obj, function (error, responseData) {
            if (error) {
                cb(error);
            } else {

                cb(null, responseData);
            }
        });
    }
}

module.exports = WechatPay;

入的坑

1、测试的时候经常404,打印错误信息提示没把ip输入白名单,明明刚才已经填好白名单,原因是笔记本电脑的ip地址(百度ip)自动改变了。
2、每次url变化之后都需要重新微信jssdk授权,虽然每次授权url除去#后都是一样的,但是必须这么做,微信的机制。
3、使用微信自定义分享功能的时候,当分享链接中存在中文的时候,一定要进行encodeURIComponent(),否则在安卓手机上能成功自定义分享,ios手机上则不能成功分享。查阅资料后得知是安卓手机会自动encodeURIComponent,而ios不会。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页