前提条件

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. BZOJ4598: [Sdoi2016]模式字符串(点分治 hash)

    题意 题目链接 Sol 直接考虑点分治+hash匹配 设\(up[i]\)表示\(dep \% M = i\)的从下往上恰好与前\(i\)位匹配的个数 \(down\)表示\(dep \% M = i ...

  2. 洛谷P2792 [JSOI2008]小店购物(最小树形图)

    题意 题目链接 Sol 一开始的思路:新建一个虚点向每个点连边,再加上题面中给出的边,边权均为大小*需要购买的数量 然后发现死活都过不去 看了题解才发现题目中有个细节--买了\(A\)就可以买\(B\ ...

  3. MPU/SoC/Application Processor/Embedded OS

    Everything has its principles and mechanisms which are designed by its creator and followed by its u ...

  4. Python爬虫教程-02-使用urlopen

    Spider-02-使用urlopen 做一个最简单的python爬虫,使用爬虫爬取:智联招聘某招聘信息的DOM urllib 包含模块 - urllib.request:打开和读取urls - ur ...

  5. MVC框架以及实例(补充)

    此文是MVC框架以及实例(http://www.cnblogs.com/justmaomao/p/6739065.html)的补充部分 以下简单介绍简单登录的相关内容 1)在login.jsp中待提交 ...

  6. [转]实现Hive数据同步更新的shell脚本

    引言: 上一篇文章<Sqoop1.4.4 实现将 Oracle10g 中的增量数据导入 Hive0.13.1 ,并更新Hive中的主表>http://www.linuxidc.com/Li ...

  7. asp.net 服务器控件的 ID,ClientID,UniqueID 的区别

    1.简述 ID是设计的时候自己所指定的ID,是我们分配给服务器控件的编程标识符,我们常常使用this.controlid来寻找控件,那么这个controlid就是这里所说的ID. ClientID是由 ...

  8. eclipse直接使用tomcat安装程序的webapp目录调试

    感谢此文:http://blog.csdn.net/soszou/article/details/23673133 本文很多技术及操作来源于此文 需求:因为微信方面的开发调试.为了测试方便,直接构建了 ...

  9. 第三课 java编程入门

    java特点: 1.面对象性 2.可移植性/跨平台性 java组成: jdk(java工具开发工具包) /       \              \ jre       指令集合   api和常用 ...

  10. ZT pthread_detach

    pthread_detach 创 建一个线程默认的状态是joinable, 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收(退出 ...