前提条件

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. 教程:让你的表单升级到CSS3和HTML5客户端验证

    今天我们一起来看看如何创建一个实用并且功能强大的表单,表单使用如今最热门的技术HTML5和css3来创建,并且可以通过HTML5进行客户端验证. 查看预览下载附件 第一步:策划表单功能 首先,我们得为 ...

  2. SQL server查找指定表的所有索引

    WITH tmp AS ( SELECT indexname = a.name , tablename = c.name , indexcolumns = d.name , a.indid FROM ...

  3. Two references point to the same heap memory

    Phone类 package com.itheima_03; /* * 手机类 */ public class Phone { String brand; int price; String colo ...

  4. 应用程序和Activity

    Android 应用程序的组成部分 Android应用程序由各个组件组成,并使用Manifest绑定到一起,Manifest描述了每一个组件和它们之间的交互方式,还用于指定权限,硬件,平台以及应用程序 ...

  5. 基于Vue的WebApp项目开发(五)

    实现图片分享列表 步骤一:新增图片列表文件photolist.vue <template> <div id="tml"> 图片分享页面 </div&g ...

  6. d3js shape深入理解

    本文将视图了解d3js提供的帮助我们创建矢量图形的helper函数,比如下面的: http://d3indepth.com/shapes/ lines curves pie chart segment ...

  7. js实现查找字符串出现最多的字符和次数

    代码如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset=" ...

  8. DDD(领域驱动设计)总结

    基本概念: 领域驱动设计(简称 ddd)概念来源于2004年著名建模专家eric evans发表的他最具影响力的书籍:<domain-driven design –tackling comple ...

  9. ScriptManager的使用方法 .(转)

    从这一节开始我将和大家一起学习ASP.NET AJAX的服务器端控件的用法.首先,安装ASPAJAXExtSetup.msi,可以到微软官方网站上去下载.安装之后当你新建项目的时候会多出一个ASP.N ...

  10. December 22nd 2016 Week 52nd Thursday

    The best hearts are always the bravest. 心灵最高尚的人,往往也是最勇敢的人. Keep conscience clear, don't let too many ...