前提条件

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. 20个网页设计师应该学习的CSS3经典教程实例

    CSS3技术离我们越近,我们也应该学习一些简单的CSS3技术了,而学习最基本的方法就是模仿,以及观看大师作品的案例.收集了20个基础教程,均是涉及到css3应用范围,值得你和我一起共同学习. Smoo ...

  2. django开发博客(1) 入门

    现在正式开始博客开发 1.安装django1.4 如果你使用的是fedoraDVD版,安装时选择了web开发组建,这一步可以省略,因为它自带django环境 django下载地址 https://ww ...

  3. Eclipse 分屏显示同一个代码文件

    描述: 今天在使用Eclipse开发的时候不知按错哪个键,出现编辑框分屏显示同一个代码,由于之前没有使用过这一功能,所以就去查了一下,原来是Eclipse的分屏功能. 快捷键: 方式一:Window ...

  4. TF-IDF与余弦相似性的应用:找出相似文章

    "找出相似文章"的一种算法: 利用TF-IDF算法,找出两篇文章的关键词. 每篇文章若干个关键词的相对词频. 生成两篇文章各自的词频向量. 计算两个向量的余弦相似度,值越大就表示越 ...

  5. MySQL 8.0复制性能的提升(翻译)

    What’s New With MySQL Replication in MySQL 8.0 MySQL复制从问世到现在已经经历了多个年头,它的稳定性和可靠性也在稳步的提高.这是一个不停进化的过程,由 ...

  6. 购买 In-app Billing 商品

    购买 In-app Billing 商品 一旦你的应用连接上了 Google Play,你就可以初始化内购商品的购买请求了.Google Play 提供了结算接口,可以让用户进入使用他们的支付方式,所 ...

  7. Python学习---DjangoForm的总结大全

    DjangoForm基础知识总结 1.Form是什么东西? 用于验证用户请求数据合法性的一个组件 2. Django的Form的实现步骤: a. 创建一个验证用户请求的模板 from django i ...

  8. Linux下的Mysql的双向同步

    在主从复制的基础上实现双向同步 [更多参考] https://www.cnblogs.com/shuidao/p/3551238.html http://blog.csdn.net/i_bruce/a ...

  9. 添加PHP扩展模块

    php安装好后,可能在初次安装时,会有些模块会有遗漏,但是我们又不想重新编译php,因为耗时是比较长的.我们可不可以在不重新编译安装php的情况下,来为php单独添加某一个模块呢?查找资料,发现还是有 ...

  10. August 15th 2017 Week 33rd Tuesday

    Would rather have done a regret, do not miss the regret. 宁愿做过了后悔,也不要错过了后悔. Yesterday, I read several ...