java微信公众号支付开发之现金红包

2025-05-29 0 69

我们先来看看公众号发放现金红包的效果:

java微信公众号支付开发之现金红包

需要调用商户平台的接口,接口发放规则如下:

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>

接口需要调用商户平台的证书,证书需要去商户平台下载:

java微信公众号支付开发之现金红包

然后在接口中使用证书,首先我们新建一个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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 java微信公众号支付开发之现金红包 https://www.kuaiidc.com/111574.html

相关文章

发表评论
暂无评论