前提条件

1、有一个微信开放平台 https://open.weixin.qq.com/

2、有一个微信公众平台 https://mp.weixin.qq.com  并且开通微信支付

3、有一个微信小程序 https://developers.weixin.qq.com/miniprogram/dev/quickstart/basic/release.html 登陆地址同 2 微信公众平台

申请过程就不详细说了,准备好各种企业的资质证书,运营执照,企业版 需要对公账户打款验证

小程序要绑定到公众号,公众号和小程序都要绑定到开放平台

说一下为什么要有这三个平台账号,原生平台app 拉起微信小程序,授权登陆以后取得登录码,授权登录官方文档 https://developers.weixin.qq.com/miniprogram/dev/api/wx.login.html

把这个登录码发送到后端,后端通过这个登录码+小程序的appid + secret 拿到用户的unionid(小程序 和 公众号 都要绑定了开放平台才会有unionid,同一开放平台下的小程序和公众号unionid相同)

获取unionid官方文档 https://developers.weixin.qq.com/miniprogram/dev/api/code2Session.html

通过这个unionid来获取到玩家在公众号的openid,微信支付发送红包到玩家账号上就是通过这个公众号的openid

后端一定要配置一个https的服务器 不然发微信红包的时候 只会收到微信服务器返回 302 not fond

Node 环境https的配置 https://blog.csdn.net/wufaliang003/article/details/77478720

下面直接上代码了

辅助函数部分

let crypto = require("crypto");

exports.MgetMD5 = function(str){
let hash = crypto.createHash('md5');
let md5Value = hash.update(str).digest("hex");
return md5Value.toUpperCase()
} exports.MgetSHA256 = function(str,key){
let hmac = crypto.createHmac('sha256',key);
let shaValue = hmac.update(str).digest("hex");
return shaValue.toUpperCase();
} let charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklnmopqrstuvwxyz0123456789";
//返回随机字符串
exports.MgetRandomStr = function(length){
if (length){
length = Math.round(length);
}
else{
length = Math.round(Math.random()*20 + 12)
}
let range = charSet.length;
let result = '';
let position = 0;
for(let i = 0; i < length; i++)
{ position = Math.floor(Math.random()*range);
result += charSet[position];
}
return result;
} //返回随机数字字符串
exports.MgetRandomNumber = function(length){
let numbers = '0123456789';
length = length ? length : 10;
let range = numbers.length;
let result = '';
let position = 0;
for(let i = 0; i < length; i++)
{ position = Math.floor(Math.random()*range);
result += numbers[position];
}
return result;
} //返回给定宽度的数字字符串
exports.MgetFixedNumber = function(number,width){
width = width ? width : 2;
let fixedNumber = number.toString();
for(; fixedNumber.length < width ; ){
fixedNumber = "0" + fixedNumber;
}
return fixedNumber;
} //返回 对象属性排序后的所有键和值拼接在在一起的字符串
exports.MgetSortedParameter = function(parameterObject){
let attributes = [];
parameterObject = parameterObject ? parameterObject:{};
for(let attr in parameterObject){
attributes.push(attr);
} attributes.sort();
let paramStr = "";
attributes.forEach(element=>{
paramStr += element + "=" + parameterObject[element] + "&"
}); return paramStr;
}

发送红包部分

//构造订单号
function getOrderID(){
let currentDate = new Date();
let year = currentDate.getFullYear(); let month = currentDate.getMonth()
month = month >= 9 ? month + 1 : '0'+(month + 1); let day = currentDate.getDate()
day = mutils.MgetFixedNumber(day); //mch_id 是微信支付分配的商户号
let orderid = mch_id + year + month + day + mutils.MgetRandomNumber(); return orderid;
} //发红包
function makeHongBao(openid,res){
//设置参数模型
let ParamModel = {};
ParamModel["nonce_str"] = mutils.MgetRandomStr();//随机字符串,不长于32位
ParamModel["wxappid"] = gzh_appid;//公众账号appid
ParamModel["mch_id"] = mch_id;//商户号 微信支付分配的商户号 申请中
ParamModel["mch_billno"] = getOrderID();//商户订单号 字母加数字构成 长度最多28位且必须唯一
ParamModel["send_name"] = "商户名称";//商户名称 红包发送者名称
ParamModel["re_openid"] = "otWaQ0ztsh9p6X4ZQVMzNa17sTpQ"//公众号下 用户openid
ParamModel["total_amount"] = 100;//付款金额,单位分
ParamModel["total_num"] = 1;//红包发放总个数
ParamModel["wishing"] = "感谢您使用XXX,祝您旗开得胜!";//红包祝福语 最大长度128位
ParamModel["client_ip"] = "125.120.226.214";//调用接口的机器Ip地址
ParamModel["act_name"] = "分享送红包";//活动名称
ParamModel["remark"] = "分享越多送得越多";//备注信息
ParamModel["scene_id"] = "PRODUCT_5";// 非必须 PRODUCT_6 渠道分润 红包金额大于200或者小于1元时必传 PRODUCT_1
//ParamModel["notify_way"] ="JSAPI";//通知用户形式 ------------- 小程序红包参数?
//ParamModel["risk_info"] = "posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26deviceid%3dIOS";//活动信息 非必须
let attrStr = mutils.MgetSortedParameter(ParamModel);
attrStr += "key=" + mch_key//key为商户平台设置的密钥key
ParamModel["sign"] = mutils.MgetMD5(attrStr); //构造POST参数xml
let contents = '<xml>';
for( let attr in ParamModel){
contents += makeXMLNode(attr,ParamModel[attr],false);
}
contents += '</xml>';
//配置请求选项
let options = {
host:'api.mch.weixin.qq.com',
port:443,
path:'/mmpaymkttransfers/sendredpack',
key:fs.readFileSync(__dirname + '/cert/apiclient_key.pem'),
cert:fs.readFileSync(__dirname + '/cert/apiclient_cert.pem'),
method:'POST'
} options.agent = new https.Agent(options);
//发送Post请求
var request = https.request(options, function(response){
response.setEncoding('utf8');
response.on('data',function(data){
console.log("data:",data);
res.end("wait to do !");
});
}); request.write(contents);
request.end();
request.on('error',function(err){
console.log(err)
})
}
function makeXMLNode(nodeName,Value,bCTata){
if (bCTata){
return '<' + nodeName + '><![CDATA[' + Value + ']]></' + nodeName + '>'
} return '<' + nodeName + '>' + Value + '</' + nodeName + '>'
}

如何获取到公众号的openid

1、后台通过公众号的的appid 和 secret(需要自己设置) 获取到access_token 官方文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

2、批量获取到关注公众号的的用户信息 注意一次最多获取一百条  官方文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839

3、把前面提到的unionid 拿来依次和用户信息里面的unionid比对 如果相同说明找到正确的用户了就取它的openid ,就可以根据这个openid发红包了

写得感觉有点乱,主要是参考思路,过程比较坑 + 各种扫二维码 输验证码

node 服务器如果是在外网有固定ip地址,listen函数就不要填ip地址了,不然会报错

小程序发微信红包后端Nodejs实现的更多相关文章

  1. 微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的

    最近公司在开发一个小程序红包系统,客户抢到红包需要提现.也就是通过小程序来给用户发红包. 小程序如何来发红包呢?于是我想到两个方法. 之前公众号开发一直用了的.一个是红包接口,一个是企业支付接口.一开 ...

  2. 微信小程序发红包

    背景: 近期一个朋友公司要做活动,活动放在小程序上.小程序开发倒是不难,不过要使用小程序给微信用户发红包,这个就有点麻烦 确定模式: 小程序目前没有发红包接口,要实现的话,只能是模拟红包,即小程序上做 ...

  3. 微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的

    微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的   最近公司在开发一个小程序红包系统,客户抢到红包需要提现.也就是通过小程序来给用户发红包. 小程序如何来发红包呢?于是我想 ...

  4. 微信小程序结合微信公众号进行消息发送

    微信小程序结合微信公众号进行消息发送 由于小程序的模板消息已经废弃了,官方让使用订阅消息功能.而订阅消息的使用限制比较大,用户必须得订阅.需要获取用户同意接收消息的权限.用户必须得和小程序有交互的时候 ...

  5. 开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试

    在我们开发开发H5程序或者小程序的时候,有时候需要基于内置浏览器或者微信开发者工具进行测试,这个时候可以采用默认的localhost进行访问后端接口,一般来说没什么问题,如果我们需要通过USB基座方式 ...

  6. 微信小程序(微信应用号)开发ide安装解决方法

    这两天整个技术圈都炸锅了,微信小程序(微信应用号)发布内测,首批200家收到邀请,但是没受邀请的同学,也不用担心,下面介绍一下解决方法. 首先需要下载ide,昨天只需要下载0.9版本的编辑器并替换文件 ...

  7. 微信小程序(原名微信应用号)开发工具0.9版安装教程

    微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...

  8. [小程序开发] 微信小程序内嵌网页web-view开发教程

    为了便于开发者灵活配置小程序,微信小程序开放了内嵌网页能力.这意味着小程序的内容不再局限于pages和large,我们可以借助内嵌网页丰富小程序的内容.下面附上详细的开发教程(含视频操作以及注意事项) ...

  9. 微信小程序之微信登陆 —— 微信小程序教程系列(20)

    简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实这个Hello World项目,就有一个简化版的微信登陆.只不过是,还没有写入到咱们自 ...

随机推荐

  1. sublime3下载安装及常用插件、浏览器预览设置

    之前与学习前端有关的软件都安装在了实验室电脑上,最近由于要放寒假(也许我寒假回去会学习呢),于是得在笔记本电脑上重新安装一遍.几个软件各种出错,花了一下午才安装好,必须记录下来啊! 这篇文章主要介绍s ...

  2. MyEclipse去除网上复制下来的代码带有的行号(使用正则表达式)

    一.正则表达式去除代码行号 作为开发人员,我们经常从网上复制一些代码,有些时候复制的代码前面是带有行号,如: MyEclipse本身自带有查找替换功能,并且支持正则表达式替换,使用正则替换就可以很容易 ...

  3. Html5 填表 表单(二) input type 各种输入, 各种用户选择,上传等等泛输入用户交互

    <input>        无限制输入     type    限制输入 type = 如下类型     type 后还可以跟一些属性: 如<input type=text max ...

  4. SP从32位系统到64位系统的迁移方法

    前提:目标系统为64位1.在32位系统下正常安装SP,获取SP运行时必须的文件2.将[浪潮集团金融事业部]目录拷贝到目标系统的[C:\Program Files]目录3.进入目标系统的[浪潮集团金融事 ...

  5. Android链接蓝牙电子称

    蓝牙一直是我内心屏蔽的一个模块哈哈哈哈!然而今天我不得不正视它了,我百度了看了好多因为需要设备匹配所以设备不在没办法测试,几天之后设备到了.因为没有接触过,看到返回的打印出来的菱形方块就以为是错了.于 ...

  6. TCP状态统计 - 脚本命令

    一.netstat命令说明 netstat常见参数 -a (all)显示所有选项,默认不显示LISTEN相关 -t (tcp)仅显示tcp相关选项 -u (udp)仅显示udp相关选项 -n 拒绝显示 ...

  7. MFC连接Mysql数据库执行查询和插入

    配置环境: include:mysql.h文件 lib:libmysql.lib文件 dll::libmysql.dll文件 连接代码: MYSQL m_sqlCon; MYSQL_RES *m_re ...

  8. 企业级Nginx增加日志选项

    日志介绍 目的:将用户的访问信息记录到指定的文件中由ngx_http_log_module模块负责 访问日志参数: access_log:指定日志文件的路径和使用何种日志格式记录日志 log_form ...

  9. [BZOJ 4036][HAOI2015]按位或

    4036: [HAOI2015]按位或 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 746  Solved: 4 ...

  10. js图形库

    SVG.js viz.js graphviz的js实现版 raphael d3 (http://d3js.org/) JavaScript InfoVis Toolkit Flotr2 and Env ...