node接入微信支付v2

首先要去获取接入支付的商户号以及各种信息

这是自己第一次接入微信支付,xml2js插件主要用于解析xml文本,以及将自己的信息转换为微信支付所需要的xml字符串类型。

在接入v2支付过程中比较简单,建议还是写法以面向对象编程为主,方便后期添加其他的支付方式,native支付接入我主要是适用于网站上使用,在此做个备忘录,避免下次写忘记。

const xml2js = require("xml2js");
const axios = require("axios");
const crypto = require("crypto");


// 订单号生成函数
function randomNumber(length = 32) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let noceStr = '', maxPos = chars.length;
    while (length--) noceStr += chars[Math.random() * maxPos | 0];
    return noceStr;
}

// 加密签名
function createSignV2(info, key) {
    const hash = crypto.createHash("md5");
    let stringA = "";
    let keys = Object.keys(info);
    keys.sort();
    for (let item of keys) {
        stringA += `${item}=${info[item]}&`;
    }
    let stringSignTemp = `${stringA}key=${key}`;
    return hash.update(stringSignTemp).digest("hex");
}

/**
 * 购买下单
 * @param {*} money 购买金额
 * @returns 下单结果
 */
async function wxpay(money) {
    let orderInfo = {
        // 商户号ID
        mch_id: "162xxxxxxx",
        // 公共账号ID
        appid: "wx0xxxxxxxxxxx",
        // 商品描述
        body: "我是在购买名叫xx的商品",
        // 支付通知地址  post 接口 在线能访问的
        notify_url: "https://www.osdaklshad.cn",
        // 支付类型
        trade_type: "NATIVE",
        // 随机字符串 支付必传
        nonce_str: randomNumber(),
        // 订单号
        out_trade_no: randomNumber(),
        // 金额  以分为单位
        total_fee: Number(money) * 100
    };
    // 签名密钥
    orderInfo.sign = createSignV2(orderInfo, "2962bxxxxxxxxxxxxxxxxxxxxxxxxa4f")
    let builder = new xml2js.Builder();
    let xmlData = builder.buildObject(orderInfo);
    try {
        const wx_pay = await axios
            .post("https://api.mch.weixin.qq.com/pay/unifiedorder", {
                xmlData,
                headers: { "Content-Type": "application/xml" },
            });
        var parser = new xml2js.Parser({ explicitArray: false });
        const wx_result = await parser.parseStringPromise(wx_pay.data);
        wx_result.xml.out_trade_no = orderInfo.out_trade_no;
        wx_result.xml.total_fee = orderInfo.total_fee;
        return wx_result.xml;
    } catch (err) {
        console.log('支付报错:', err)
    }
}

/**
 * 取消订单
 * @param {*} goods 订单号
 * @returns 
 */
async function closeGood(goods) {
    let closeInfo = {
        // 商户号ID
        mch_id: "162xxxxxxx",
        // 公共账号ID
        appid: "wx08ae8bxxxxxxxxx",
        out_trade_no: goods,
        nonce_str: randomNumber(),
    }
    closeInfo.sign = createSignV2(closeInfo, "2962b0e189xxxxxxxxxxxxxxxxx")
    let builder = new xml2js.Builder();
    let xmlData = builder.buildObject(closeInfo);
    try {
        const wx_close = await axios
            .post("https://api.mch.weixin.qq.com/pay/closeorder", {
                xmlData,
                headers: { "Content-Type": "application/xml" },
            });
        var parser = new xml2js.Parser({ explicitArray: false });
        const wx_result = await parser.parseStringPromise(wx_close.data);
        console.log('取消:', wx_result.xml)
        return wx_result.xml;
    } catch (err) {
        console.log('支付报错:', err)
    }

}

/**
 * 订单状态查询
 * @param {*} goods 订单号 
 * @returns 
 */
async function queryGood(goods) {
    let queryInfo = {
        // 商户号ID
        mch_id: "162xxxxxxxx2",
        // 公共账号ID
        appid: "wx08axxxxxxx",
        out_trade_no: goods,
        nonce_str: randomNumber(),
    }
    queryInfo.sign = createSignV2(queryInfo, "2962b0e1xxxxxxxxxxxxxxxxx")
    let builder = new xml2js.Builder();
    let xmlData = builder.buildObject(queryInfo);
    try {
        const wx_query = await axios
            .post("https://api.mch.weixin.qq.com/pay/orderquery", {
                xmlData,
                headers: { "Content-Type": "application/xml" },
            });
        var parser = new xml2js.Parser({ explicitArray: false });
        const wx_result = await parser.parseStringPromise(wx_query.data);
        console.log('查询值:', wx_result.xml)
        return wx_result.xml;
    } catch (err) {
        console.log('支付报错:', err)
    }

}
module.exports = {
    wxpay,
    closeGood,
    queryGood
};

ps:切记回调地址是在线能访问的https或http 的post接口,才能回调成功。

我这里只写了几种实用的方法

你可能感兴趣的:(微信)