NodeJS微信支付

来源:互联网 发布:网络监控摄像机维修 编辑:程序博客网 时间:2024/05/16 17:45

NodeJS微信支付分可以为三个部分:

一、前端获取code获取用户Oppenid

二、拿到当前用户支付的请求参数

三、支付成功后的跳转

先说第一步骤吧

1)通过js脚本请求请求微信后台并返回code(JS跳转获取回调当前URL)

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=' + encodeURIComponent(URL) + '&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect
参数说明:

1:appid为公众号的ID

2:encodeURIComponent(URL)为加密当前你在微信后台JS_API配置的安全域名

3.  response_type=code,这个没什么好说的就是固定的 response_type=code,详细说明可以查看微信官网的说明

4.  scope=snsapi_base,固定这样写就好,详细说明可以查看微信官网的说明

5.  state=STATE 固定这样写就好,详细说明可以查看微信官网的说明

6.  wechat_redirect 固定这样写就好,详细说明可以查看微信官网的说明

2)通过code获取当前用户信息access_token

方法如下:

$.ajax({    url: '/astokenOpid',    dataType: 'json',    type: 'post',    ContentType: "application/json",    data: {        CODES: wxcodes    },    success: function(data) {        localStorage.setItem('userData', JSON.stringify(data));    },});
参数说明:

1、/astokenOpid 为当前node后台服务中的一个方法(后面会贴出来)

2、wxcodex 为当前上一步微信返回的code

3、success中的fun为当前返回用户

/astokenOpid方法如下(node后台方法)

request.get({        url: 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRECT&code=' + req.body.CODES + '&grant_type=authorization_code',        form: {}    }, function(error, response, body) {        console.log(body);        if (!error && response.statusCode == 200) {            var userdata = JSON.parse(body);            res.json(userdata);        }    });

3)调取微信原生进行公众号支付

案例如下

/**     * 微信支付     */    wxpay(wxcodes) {        let _this = this;        $.ajax({            url: '/wxpay',            dataType: 'json',            type: 'post',            ContentType: "application/json",            data: {                CODES: wxcodes,                token: '', // access_token                opid: '', // oppenid                retoken: '', // refresh_token                scope: '',// scope                expin: '',// expires_in                bodyDetail: '',// 支付详情                bodyTitle: '',// 支付标题                Totla_fees:  // 支付金额 注:微信支付单位为整形最小值为1   以分为单位            },            success: function(data) {                wxdata.appId = data.appId;                wxdata.timeStamp = data.timeStamp;                wxdata.nonceStr = data.nonceStr;                wxdata.package = data.package;                wxdata.signType = data.signType;                wxdata.paySign = data.paySign;                if (typeof WeixinJSBridge == "undefined") {                    if (document.addEventListener) {                        document.addEventListener('WeixinJSBridgeReady', _this.onBridgeReady(data.orderNum), false);                    } else if (document.attachEvent) {                        document.attachEvent('WeixinJSBridgeReady', _this.onBridgeReady(data.orderNum));                        document.attachEvent('onWeixinJSBridgeReady', _this.onBridgeReady(data.orderNum));                    }                } else { _this.onBridgeReady(data.orderNum); }            },        });    };
参数注解:

1、wxdata为全局公用对象;

2、/wxpay 为后台路由接受控制器 支付的func;

3、data参数为当前上一步后台获取oppenid用户信息和当前需要支付的订单金额、详细及标题;

4)支付过程及其成功后回调的页面

/**     * 调取原生支付     */    onBridgeReady(oderNumber) {        let _this = this;        WeixinJSBridge.invoke(            'getBrandWCPayRequest', {                "appId": wxdata.appId,                "timeStamp": wxdata.timeStamp,                "nonceStr": wxdata.nonceStr,                "package": wxdata.package,                "signType": wxdata.signType,                "paySign": wxdata.paySign            },            function(res) {                if (res.err_msg == "get_brand_wcpay_request:ok") {                    prompt.tipMsgBox('支付成功');                } else if (res.err_msg == "get_brand_wcpay_request:cancel") {                    prompt.tipMsgBox('支付已取消');                } else if (res.err_msg == "get_brand_wcpay_request:fail") {                    prompt.tipMsgBox('支付失败:网络错误,稍后重试');                }            }        );    };
微信支付返回状态码

5)下面的都是node后台版本微信支付签名加支付的代码

路由模块支付

/** * 获取wxpay */router.post('/wxpay', function(req, res, next) {    let reqs= req.body; // 页面点击支付跳转过来的方法参数    let ress = res;    var ip = req.headers['x-real-ip'] ? req.headers['x-real-ip'] : req.ip.replace(/::ffff:/, ''); //获取当前用户的ID    wxpay.prototype.getAccessToken(reqs.reqTotla, reqs.CODES, ip, reqs.token, reqs.opid, reqs.retoken, reqs.scope, reqs.expin, function(data, orderNumber) {        data.orderNum = orderNumber        ress.json(data);    }, reqs.bodyDetail, reqs.bodyTitle);});


支付的方法脚本

var url = require('url');var queryString = require('querystring');var crypto = require('crypto');var request = require('request');var xml2jsparseString = require('xml2js').parseString;var http = require('http');var querystring = require('querystring');var md5 = require('md5');var cookParser = require('cookie-parser');var session = require('express-session');var express = require('express');var app = express();var times = new Date().getTime();var nonce = Math.random();let ordernumbers = '';var addData = {    'signature': '', // 签名    'userid': session('id') || '', // 用户ID    'timestamp': times, // 时间戳      'nonce': nonce // 随机数  }function signature(uid, utoken) {    let id = uid || '';    let token = utoken || '';    var strins = times + '' + nonce + '' + id.toString().toUpperCase() + '' + token.toString().toUpperCase()    var arrayList = strins.split('')    var sortList = arrayList.sort(function(a, b) { return a.localeCompare(b) })    var sortString = sortList.join('')    var md5String = md5(sortString).toString().toUpperCase();    return md5String}// 引入项目的配置信息// var config = require('../config/index.js');var obj = {    appid: '',// APPID     attach: '', // 可为空attach    body: '',    mch_id: '1327276501', // mch_id 详见微信公众号     nonce_str: '',    notify_url: '/success', // 微信付款后的回调地址    openid: '',    out_trade_no: '', // new Date().getTime(), //订单号    spbill_create_ip: '', //客户端的ip    total_fee: '', //商品的价格, 此处需要注意的是这个价格是以分算的, 那么一般是元, 你需要转换为 RMB 的元 Y    trade_type: 'JSAPI',}config = {    wxappid: '',// APPID详见微信公众号    mch_id: '', // mch_id 详见公众号    wxpaykey: '',// 微信的支付key    wxappsecret: '', // 微信secret     WxSSLCERT_PATH: '',// 微信sslcert_path 可为空    WxNOTIFY_URL: '/success', // 成功后回调页面    WxNOTIFY_ERROR_URL: '/error',// 失败后回调页面    WxLOG_LEVENL: '3', // 详见公众号日志模式 Log_levenl    WxToken: ''// 详见公众号token};// 支付需要用到的参数var userInfo = {    access_token: '',    expires_in: '',    refresh_token: '',    openid: '',    scope: '',};class WechatPay {    /**     * 获取微信统一下单参数     */    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;    } 
    /**     * 随机数     */
    createNonceStr() {        return Math.random().toString(36).substr(2, 15);    };    /**     * 获取微信的 AccessToken     */    getAccessToken(total, code, ip, token, opid, retoken, scope, expin, callback, bodyDetail, bodyTitle) {        var that = this;        total = parseFloat(total) * 100;        obj.spbill_create_ip = ip;        obj.total_fee = total;        obj.body = bodyDetail;        obj.attach = bodyTitle;        request.get({            url: "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + config.wxappid + "&secret=" + config.wxappsecret + "&code=" + code + "&grant_type=authorization_code",            form: {}        }, function(error, response, body) {            if (!error && response.statusCode == 200) {                userInfo.access_token = token;                userInfo.expires_in = expin;                userInfo.refresh_token = retoken;                userInfo.openid = opid;                userInfo.scope = scope;                obj.openid = opid;                // 拼接微信的支付的参数                that.getBrandWCPayParams(function(error, responseData, orderNumber) {                    console.log(orderNumber);                    callback && callback(responseData, orderNumber);                });            }        });    };
}
module.exports =WechatPay;



原创粉丝点击