1、接口文档
https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5
2、证书下载及证书安装
首先,商户调用微信红包接口时,服务器会进行证书验证,所以要在商户平台下载证书。在管理后台的“账户信息”里找到“安全设置”就可以下载了证书了。
商户平台:https://pay.weixin.qq.com

我们把下载好的证书解压放到目录D:/certs下。SSL接口中使用到这些证书。

接着就是向帐号中充值,因为发放现金红包将扣除商户的可用余额,所以需要预先充值,确保可用余额充足。进入“资金管理”菜单找到“现金管理”,在此进行充值,保证帐号有余额可以进行红包发放。

3、业务代码
3.1红包实体类
package com.benben.timetable.wechat.entity;
/**
* 现金红包
*
* @ClassName: SendRedPack
* @Description: TODO
* @author 潘广伟(笨笨)
* @date 2015年12月11日
*
*/
public class SendRedPack {
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;
private String act_name;
private String remark;
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 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 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;
}
}
再次吐槽微信的xml格式。下划线啊!!!
3.2、生成红包数据签名
public String createSendRedPackOrderSign(SendRedPack redPack){
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(payKey)
return DigestUtils.md5Hex(sign.toString()).toUpperCase()
}
签名算法请参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
之前微信支付也用到相同的签名方式:http://blog.csdn.net/jrainbow/article/details/49904065
3.3、SSL接口
private String ssl(String url,String data){
StringBuffer message = new StringBuffer()
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12")
FileInputStream instream = new FileInputStream(new File("D:/certs/apiclient_cert.p12"))
keyStore.load(instream, mchId.toCharArray())
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, mchId.toCharArray())
.build()
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER)
CloseableHttpClient httpclient = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build()
HttpPost httpost = new HttpPost(url)
httpost.addHeader("Connection", "keep-alive")
httpost.addHeader("Accept", "*/*")
httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
httpost.addHeader("Host", "api.mch.weixin.qq.com")
httpost.addHeader("X-Requested-With", "XMLHttpRequest")
httpost.addHeader("Cache-Control", "max-age=0")
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ")
httpost.setEntity(new StringEntity(data, "UTF-8"))
System.out.println("executing request" + httpost.getRequestLine())
CloseableHttpResponse response = httpclient.execute(httpost)
try {
HttpEntity entity = response.getEntity()
System.out.println("----------------------------------------")
System.out.println(response.getStatusLine())
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength())
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"))
String text
while ((text = bufferedReader.readLine()) != null) {
message.append(text)
}
}
EntityUtils.consume(entity)
} catch (IOException e) {
e.printStackTrace()
} finally {
response.close()
}
} catch (Exception e1) {
e1.printStackTrace()
}
return message.toString()
}
注意:微信本身提供的demo中的ssl程序是不正确的。
3.4 发送红包
/**
* 现金红包
* @Title: bindDevice
* @return String
* @throws
*/
public Map<String, String> sendRedPack(SendRedPack redPack) throws Exception{
String sign = createSendRedPackOrderSign(redPack);
redPack.setSign(sign);
xmlUtil.xstream().alias("xml", redPack.getClass());
String xml = xmlUtil.xstream().toXML(redPack);
String response = ssl(sendEedPackUrl,xml);
Map<String, String> responseMap = xmlUtil.parseXml(response);
return responseMap;
}
|