现在很多游戏在初上线时都会有红包活动来吸引用户,笔者的几个游戏项目也是如此,游戏红包机制一般是用户在游戏内完成某些指标,便可以领取红包,红包累计到一定金额时,便可以以微信公众号的形式发给玩家对应的微信。


今天笔者主要将的是最后一步,发红包。

 

发红包之前需要有对应的微信支付账号,而且开通了现金红包功能,
主要是两步:

1、构建xml参数:

//构建xml
let fnCreateXml = function (json) {
    let _xml = '';
    for (let key in json) {

        _xml += '<' + key + '>' + json[key] + '</' + key + '>';
    }
    return _xml;
};

//生成url串用于微信md5校验
let fnCreateUrlParam = function (json) {
    let _str = '';
    let _arr = [];
    for (let key in json) {

        _arr.push(key + '=' + json[key]);

    }
    return _arr.join('&');
};

//生成微信红包数据
let fnGetWeixinBonus = function (option) {
    let total_amount = option.total_amount || 10, 	//红包总金额
        re_openid = option.re_openid, 				//红包发送的目标用户
        total_num = option.total_num || 1; 			//红包个数
    let now = new Date();
    let showName = wxConfig.showName;				//红包名字
    let clientIp = wxConfig.clientIp;				//客户端IP
    let wishing = wxConfig.wishing;					//红包上显示的祝福语
    let mch_id = wxConfig.mch_id;					//商户ID
    let wxappid = wxConfig.wxappid,					//微信支付APPID
        wxkey = wxConfig.wxkey;						//公众号secret
    let date_time = now.getFullYear() + '' + (now.getMonth() + 1) + '' + now.getDate();
    let date_no = (now.getTime() + '').substr(-8); //生成8为日期数据,精确到毫秒
    let random_no = Math.floor(Math.random() * 99);
    if (random_no < 10) { //生成位数为2的随机码
        random_no = '0' + random_no;
    }
    let muc_id = mch_id;
    let xmlTemplate = '<xml>{content}</xml>';
    let contentJson = {};
    contentJson.act_name = showName;
    contentJson.client_ip = clientIp;
    contentJson.mch_billno = muc_id + date_time + date_no + random_no; //订单号为 mch_id + yyyymmdd+10位一天内不能重复的数字; //+201502041234567893';
    contentJson.mch_id = muc_id;

    contentJson.nick_name = showName;
    contentJson.nonce_str = Math.random().toString(36).substr(2, 15);
    contentJson.re_openid = re_openid;
    contentJson.remark = wishing;
    contentJson.send_name = showName;
    contentJson.total_amount = total_amount;
    contentJson.total_num = total_num;
    contentJson.wishing = wishing;
    contentJson.wxappid = wxappid;
    contentJson.key = wxkey;
    let contentStr = fnCreateUrlParam(contentJson);
    let crypto = require('crypto');
    contentJson.sign = crypto.createHash('md5').update(contentStr, 'utf8').digest('hex').toUpperCase();
    delete contentJson.key;
    let xmlData = fnCreateXml(contentJson);
    let sendData = '<xml>' + xmlData + '</xml>'; //_xmlTemplate.replace(/{content}/)
    return sendData;
};

2、然后就是调用微信接口发送红包

function sendRedPacket(total_amount, re_openid) {
    return new Promise((resolve, reject) => {
        let host = 'api.mch.weixin.qq.com';
        let path = '/mmpaymkttransfers/sendredpack';
        let total_num = 1;

        let opt = {
            host: host,
            port: '443',
            method: 'POST',
            path: path,
            key: fs.readFileSync('./config/apiclient_key.pem'), //将微信生成的证书放入 cert目录
            cert: fs.readFileSync('./config/apiclient_cert.pem')
        };
        let body = '';
        opt.agent = new https.Agent(opt);

        var req = https.request(opt, function (res) {
            res.on('data', function (d) {
                body += d;
            }).on('end', function () {
                let parser = new xml2js.Parser({trim: true, explicitArray: false, explicitRoot: false});//解析签名结果xml转json
                parser.parseString(body, function (err, result) {
                    if (result["result_code"] === "SUCCESS") {
                        resolve({"code": result["result_code"], "mch_billno": result["mch_billno"]});
                    } else {
                        console.log(result["return_msg"]);

                        resolve({"code": result["result_code"]});
                    }
                });
            });

        }).on('error', function (e) {
            console.log("Got error: " + e.message);
        });

        let option = {total_amount, re_openid, total_num};
        let sendData = fnGetWeixinBonus(option);
        req.write(sendData);
        req.end();
    });
}

以上代码就可以实现发送红包到微信的功能,笔者亲测有效。

至于微信接口的详细信息,大家可以查看微信文档

https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3