NodeJS微信支付

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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值