我们先来看看公众号发放现金红包的效果:
需要调用商户平台的接口,接口发放规则如下:
1.发送频率限制——默认1800/min
2.发送个数上限——按照默认1800/min算
3.金额上限——根据传入场景id不同默认上限不同,可以在商户平台产品设置进行设置和申请,最大不大于4999元/个
4.其他的“量”上的限制还有哪些?——用户当天的领取上限次数,默认是10
5.如果量上满足不了我们的需求,如何提高各个上限?——金额上限和用户当天领取次数上限可以在商户平台进行设置
注意-红包金额大于200时,请求参数scene_id必传,参数说明见下文。
注意2-根据监管要求,新申请商户号使用现金红包需要满足两个条件:1、入驻时间超过90天 2、连续正常交易30天。
请求url https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
是否需要证书 是(证书及使用说明详见商户证书)
请求方式 post
请求数据示例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<xml>
<sign><![cdata[e1ee61a91c8e90f299de6ae075d60a2d]]></sign>
<mch_billno><![cdata[0010010404201411170000046545]]></mch_billno>
<mch_id><![cdata[888]]></mch_id>
<wxappid><![cdata[wxcbda96de0b165486]]></wxappid>
<send_name><![cdata[send_name]]></send_name>
<re_openid><![cdata[onqojjmm1tad-3ropncn-yufa6ui]]></re_openid>
<total_amount><![cdata[200]]></total_amount>
<total_num><![cdata[1]]></total_num>
<wishing><![cdata[恭喜发财]]></wishing>
<client_ip><![cdata[127.0.0.1]]></client_ip>
<act_name><![cdata[新年红包]]></act_name>
<remark><![cdata[新年红包]]></remark>
<scene_id><![cdata[product_2]]></scene_id>
<consume_mch_id><![cdata[10000097]]></consume_mch_id>
<nonce_str><![cdata[50780e0cca98c8c8e814883e5caa672e]]></nonce_str>
<risk_info>posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26deviceid%3dios</risk_info>
</xml>
|
接口需要调用商户平台的证书,证书需要去商户平台下载:
然后在接口中使用证书,首先我们新建一个weixinssl 类
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
@component
public class weixinssl {
/**
* 证书类型
*/
@value("${werchant.storekey}")
private string storekey;
/**
* 文件路径
*/
@value("${werchant.sslfile}")
private string sslfile;
/**
* 商户号
*/
@value("${werchant.merchantnumber}")
private string merchantnumber;
public string getstorekey() {
return storekey;
}
public void setstorekey(string storekey) {
this.storekey = storekey;
}
public string getsslfile() {
return sslfile;
}
public void setsslfile(string sslfile) {
this.sslfile = sslfile;
}
public string getmerchantnumber() {
return merchantnumber;
}
public void setmerchantnumber(string merchantnumber) {
this.merchantnumber = merchantnumber;
}
}
|
封装httpclientssl 类实现 https 请求加证书:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
@component
public class httpclientssl {
@autowired
private weixinssl weixinssl;
// 请求超时时间(毫秒) 5秒
public static requestconfig requestconfig;
// 响应超时时间(毫秒) 60秒
public static int http_response_timeout = 60 * 1000;
// httpclient字符编码
public static string encoding = "utf-8";
public static requestconfig getrequestconfig() {
return requestconfig.custom().setconnecttimeout(5 * 1000)
.setconnectionrequesttimeout(http_response_timeout).build();
}
public static void setrequestconfig(requestconfig requestconfig) {
httpclientssl.requestconfig = requestconfig;
}
/**
* https请求伪造证书
* @return
*/
public closeablehttpclient defaultsslclient() {
sslcontext sslcontext = null;
try {
new sslcontextbuilder().loadtrustmaterial(null,new truststrategy(){
@override
public boolean istrusted(x509certificate[] chain, string authtype)
throws java.security.cert.certificateexception {
return false;
}
});
} catch (nosuchalgorithmexception | keystoreexception e) {
e.printstacktrace();
}
sslconnectionsocketfactory factory = new sslconnectionsocketfactory(sslcontext);
return httpclients.custom().setsslsocketfactory(factory).build();
}
/**
* https请求加证书
* @return
*/
public closeablehttpclient defaultsslclientfile() {
if (this.weixinssl == null){
return this.defaultsslclient();
}
fileinputstream inputstream = null;
keystore keystore = null;
try {
// ssl类型
keystore = keystore.getinstance(weixinssl.getstorekey());
// ssl文件
inputstream = new fileinputstream(weixinssl.getsslfile());
// 设置ssl密码
keystore.load(inputstream,weixinssl.getmerchantnumber().tochararray());
} catch (keystoreexception | nosuchalgorithmexception | certificateexception | ioexception e1) {
e1.printstacktrace();
} finally {
try {
inputstream.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
sslcontext sslcontext = null;
try {
sslcontext = sslcontexts.custom().loadkeymaterial(keystore,weixinssl.getmerchantnumber().tochararray()).build();
} catch (unrecoverablekeyexception | nosuchalgorithmexception | keystoreexception | keymanagementexception e) {
e.printstacktrace();
}
sslconnectionsocketfactory factory = new sslconnectionsocketfactory(sslcontext, new string[] { "tlsv1" }, null,
sslconnectionsocketfactory.browser_compatible_hostname_verifier);
return httpclients.custom().setsslsocketfactory(factory).build();
}
/**
* 封装发送请求的方法
* @throws unsupportedencodingexception
*/
public string send(string url, string data, closeablehttpclient closeablehttpclient)
throws unsupportedencodingexception {
closeablehttpclient client = closeablehttpclient;
httppost httppost = new httppost(urldecoder.decode(url, encoding));
httppost.addheader("connection", "keep-alive");
httppost.addheader("accept", "*/*");
httppost.addheader("content-type", "application/x-www-form-urlencoded; charset=utf-8");
httppost.addheader("host", "api.mch.weixin.qq.com");
httppost.addheader("x-requested-with", "xmlhttprequest");
httppost.addheader("cache-control", "max-age=0");
httppost.addheader("user-agent", "mozilla/4.0 (compatible; msie 8.0; windows nt 6.0) ");
httppost.setconfig(this.getrequestconfig());// 设置超时时间
closeablehttpresponse response = null;
// 参数放入
stringentity entity = new stringentity(data, encoding);
entity.setcontentencoding(encoding);
entity.setcontenttype("application/xml");
httppost.setentity(entity);
try {
response = client.execute(httppost);
if (response.getstatusline().getstatuscode() == 200) {
httpentity httpentity = (httpentity) response.getentity();
if (response != null) {
return entityutils.tostring(httpentity,encoding);
}
}
} catch (ioexception e) {
e.printstacktrace();
}
return null;
}
}
|
这样我们就封装了一个https请求加证书的实体类,接下来我们生成请求微信红包接口:
https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack 的参数签名:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/**
* 红包参数实体类
* @throws unsupportedencodingexception
*/
@component
public class sendredpack implements serializable{
/**
*
*/
private static final long serialversionuid = -1000489228099916099l;
private string nonce_str;// 随机字符串
private string sign;// 签名
private string mch_billno;// 商户订单号
private string mch_id;// 商户号
private string wxappid;// 公众账号
private string send_name;// 商户名称
private string re_openid;// 用户
private int total_amount;// 付款金额 单位:分
private int total_num;// 红包发放总人数
private string wishing;// 红包祝福语
private string client_ip;// ip地址
private string act_name;// 活动名称
private string remark;// 备注
public string getnonce_str() {
return nonce_str;
}
public void setnonce_str(string nonce_str) {
this.nonce_str = nonce_str;
}
public string getsign() {
return sign;
}
public void setsign(string sign) {
this.sign = sign;
}
public string getmch_billno() {
return mch_billno;
}
public void setmch_billno(string mch_billno) {
this.mch_billno = mch_billno;
}
public string getmch_id() {
return mch_id;
}
public void setmch_id(string mch_id) {
this.mch_id = mch_id;
}
public string getwxappid() {
return wxappid;
}
public void setwxappid(string wxappid) {
this.wxappid = wxappid;
}
public string getsend_name() {
return send_name;
}
public void setsend_name(string send_name) {
this.send_name = send_name;
}
public string getre_openid() {
return re_openid;
}
public void setre_openid(string re_openid) {
this.re_openid = re_openid;
}
public int gettotal_amount() {
return total_amount;
}
public void settotal_amount(int total_amount) {
this.total_amount = total_amount;
}
public int gettotal_num() {
return total_num;
}
public void settotal_num(int total_num) {
this.total_num = total_num;
}
public string getwishing() {
return wishing;
}
public void setwishing(string wishing) {
this.wishing = wishing;
}
public string getclient_ip() {
return client_ip;
}
public void setclient_ip(string client_ip) {
this.client_ip = client_ip;
}
public string getact_name() {
return act_name;
}
public void setact_name(string act_name) {
this.act_name = act_name;
}
public string getremark() {
return remark;
}
public void setremark(string remark) {
this.remark = remark;
}
}
|
接下来是发送红包的控制器:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/**
* 领红包控制器
* @author zengliang
*/
@controller
@requestmapping(value="/redenvelopesreceive")
public class redenvelopesreceivecontroller {
//微信唯一标识
@value("${weixin.appid}")
private string appid;
//微信开发者密码标识
@value("${weixin.appsecret}")
public string appsecret;
@autowired
private sendredpack sendredpack;
@autowired
private httpclientssl httpclientssl;
/**
* 发送xml参数
* @author zengliang
*/
@responsebody
@requestmapping(value="/sendxml")
public string sendxml(string openid,long redenvelopes_id
,string mch_billno){
redenvelopes redenve = redenvelopesservice.findone(redenvelopes_id);
xmlutil xmlutil= new xmlutil();
sendredpack.setact_name(redenve.getact_name());
sendredpack.setnonce_str(xmlutil.random());
sendredpack.setre_openid(openid);
sendredpack.setclient_ip(redenve.getclient_ip());
sendredpack.setmch_billno(mch_billno);
sendredpack.setmch_id(redenve.getmch_id());
string xx = redenve.getremark();
sendredpack.setremark(stringutils.isempty(xx) == false?xx:"空");
sendredpack.setsend_name(redenve.getsend_name());
sendredpack.settotal_amount(redenve.gettotal_amount());
sendredpack.settotal_num(redenve.gettotal_num());
sendredpack.setwishing(redenve.getwishing());
sendredpack.setwxappid(redenve.getwxappidxx());
//生成签名
string params = this.createsendredpackordersign(sendredpack,redenve.getstore_key());
sendredpack.setsign(params);
xmlutil.xstream().alias("xml",sendredpack.getclass());
//扩展xstream,使其支持cdata块
string requestxml = xmlutil.xstream().toxml(sendredpack);
string result;
try {
result = httpclientssl.send("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack",requestxml,httpclientssl.defaultsslclientfile());
system.out.println("成功返回值"+result);
return result;
} catch (unsupportedencodingexception e) {
e.printstacktrace();
}
return null;
}
/**
* 生成签名
* @param redpack
* @return
*/
public string createsendredpackordersign(sendredpack redpack,string storekey){
stringbuffer sign = new stringbuffer();
sign.append("act_name=").append(redpack.getact_name());
sign.append("&client_ip=").append(redpack.getclient_ip());
sign.append("&mch_billno=").append(redpack.getmch_billno());
sign.append("&mch_id=").append(redpack.getmch_id());
sign.append("&nonce_str=").append(redpack.getnonce_str());
sign.append("&re_openid=").append(redpack.getre_openid());
sign.append("&remark=").append(redpack.getremark());
sign.append("&send_name=").append(redpack.getsend_name());
sign.append("&total_amount=").append(redpack.gettotal_amount());
sign.append("&total_num=").append(redpack.gettotal_num());
sign.append("&wishing=").append(redpack.getwishing());
sign.append("&wxappid=").append(redpack.getwxappid());
sign.append("&key=").append(storekey);
return digestutils.md5hex(sign.tostring()).touppercase();
}
}
|
然后我们需要用一个解析xml的工具类实现解析微信返回的xml
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/**
* 解析xml工具类
* @author zengliang
*/
@component
public class xmlutil {
/**
* 解析微信返回的xml
* @param xml
* @return
* @throws exception
*/
@suppresswarnings("unchecked")
public map<string, string> parsexml(string xml)throws exception {
map<string,string> map = new hashmap<string,string>();
document doc = null;
try {
doc = documenthelper.parsetext(xml); // 将字符串转为xml
element rootelt = doc.getrootelement(); // 获取根节点
list<element> list = rootelt.elements();//获取根节点下所有节点
for (element element : list) { //遍历节点
map.put(element.getname(), element.gettext()); //节点的name为map的key,text为map的value
}
} catch (documentexception e) {
e.printstacktrace();
} catch (exception e) {
e.printstacktrace();
}
return map;
}
/**
* 扩展xstream,使其支持cdata块
*/
private xstream xstream = new xstream(new xppdriver(new nonamecoder()) {
@override
public hierarchicalstreamwriter createwriter(writer out) {
return new prettyprintwriter(out) {
// 对所有xml节点的转换都增加cdata标记
boolean cdata = true;
@override
@suppresswarnings("rawtypes")
public void startnode(string name, class clazz) {
super.startnode(name, clazz);
}
@override
public string encodenode(string name) {
return name;
}
@override
protected void writetext(quickwriter writer, string text) {
if (cdata) {
writer.write("<![cdata[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
private xstream inclueunderlinexstream = new xstream(new domdriver(null,new xmlfriendlynamecoder("_-", "_")));
public xstream getxstreaminclueunderline() {
return inclueunderlinexstream;
}
public xstream xstream() {
return xstream;
}
/**
* 生成随机数
* @return
*/
public string random(){
string random = uuid.randomuuid().tostring().replace("-", "");
return random;
}
}
|
然后我们调用 sendxml 方法公众号就能向用户发送红包了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。
原文链接:https://blog.csdn.net/u010088415/article/details/79942302
相关文章
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
- ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
- 个人服务器网站搭建:如何选择适合自己的建站程序或框架? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
2025-05-29 95
-
2025-06-04 94
-
2025-05-25 72
-
2025-05-25 97
-
2025-05-25 110



