nodejs+koa2实现微信小程序签名和请求支付(二)

废话不多说直接上代码:

const getTradeNo = function() {
    let date = new Date();
    let arr = [
        date.getFullYear(),
        ((date.getMonth() + 1)>=10?(date.getMonth() + 1):'0'+(date.getMonth() + 1)),
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds(),
        Math.floor(Math.random() * 100000)
    ]
    let orderNo = arr.join('');
    if (orderNo.length < 22) {
        let len = 22 - orderNo.length;
        orderNo = orderNo + Math.floor(Math.random() * len * 10).toString();
    }
    return orderNo;
}

生成随机字符串

 // 随机字符
const getNonceStr = function() {
    let str = "";
    let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    for (let i = 0; i< 32; i++) {
        str += possible.charAt(Math.floor(Math.random() * possible.length))
    }
    return str;
};

微信支付预签名

// 微信支付预签名
const getPrePaySign = function(appid, mchId, notifyUrl, productIntro, nonceStr, openId, tradeNo, ip, price, trade_type, apiKey) {
    let ret = {
        appid: appid,
        attach: tradeNo,
        body: productIntro,
        mch_id: mchId,
        nonce_str: nonceStr,
        notify_url: notifyUrl,
        openid: openId,
        out_trade_no: tradeNo,
        spbill_create_ip: ip,
        total_fee: price,
        trade_type: 'JSAPI'
    };
    
    let stringSignTemp = raw(ret, apiKey);
    let sign = md5(stringSignTemp).toUpperCase();
    return sign;
}

使用axios向微信发送支付请求

productIntro: 支付的产品信息,自定义就好

appid: 小程序appid

mchId::微信支付的商户号

apiKey::商户号的apikey

notifyUrl: 支付结果的通知地址,用来微信支付服务器向我们通知支付结果

const util = require('util')
const axios = require('axios')
const parser = require('fast-xml-parser');
let J2XParse = parser.j2xParser;
const { 
    generateToken,
    getNonceStr,
    getPrePaySign,
    getTradeNo
} = require('../../../core/util')
const { V_User} = require('../../models/violin/v_user')
const { Order } = require('../../models/violin/v_order')
const j2xParser = new J2XParse();
class WXPlay {
    // 支付
    static async requestWXPay(wxInfo) {
        let tradeNo = getTradeNo();
        let nonceStr = getNonceStr();
        let productIntro = wxInfo.productIntro;
        let appid = global.config.violinWx.appid;
        let mchId = global.config.violinWx.mchId;
        let notifyUrl = global.config.violinWx.notifyUrl;
        let apiKey = global.config.violinWx.payApiKey;
        let signStr = getPrePaySign(appid, mchId, notifyUrl, productIntro, nonceStr, wxInfo.openId, tradeNo, wxInfo.ip, wxInfo.payAmount, 'JSAPI', apiKey);
        let xmlData = { 
            xml: {
                appid: global.config.violinWx.appid,
                attach: tradeNo,
                body: productIntro,
                mch_id: global.config.violinWx.mchId,
                nonce_str: nonceStr,
                notify_url: global.config.violinWx.notifyUrl,
                openid: wxInfo.openId,
                out_trade_no: tradeNo,
                spbill_create_ip: wxInfo.ip,
                total_fee: wxInfo.payAmount,
                trade_type: 'JSAPI',
                sign: signStr
            }
        }
        let sendData = j2xParser.parse(xmlData);
        let wxUrl = global.config.violinWx.payUrl
        const result = await axios({
            method: 'POST',
            url: wxUrl,
            headers: {
                'Content-Type': 'text/xml'
            },
            data: sendData
        });
        if (result.err) {
            return err;
        }
        if (result.data && parser.validate(result.data)) {
            let jsonObj = parser.parse(result.data);
            if (jsonObj.xml.return_code === 'SUCCESS' && jsonObj.xml.result_code === 'SUCCESS') {
                let order = {
                    appid: global.config.violinWx.appid,
                    orderNo: tradeNo,
                    orderName: wxInfo.productIntro,
                    orderType: wxInfo.orderType,
                    userId: wxInfo.userId,
                    mch_id: global.config.violinWx.mchId,
                    payAmount: wxInfo.money,
                    orderStatus: 0,
                    prepay_id: jsonObj.xml.prepay_id,
                    entriesId: wxInfo.entriesId
                }
                await Order.addOrder(order);
            }
                
            return jsonObj;
        }
        return result;
    }
}

module.exports = {
    WXPlay
}

谢谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪山上的小灰熊

谢谢支持哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值