微信红包JAVA代码整理

一、红包接口调用服务类:

package cn.com.wechat.act.core.service;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;


import javax.net.ssl.SSLContext;


import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.Args;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;


import cn.com.wechat.act.util.PropertiesUtil;
import cn.com.wechat.act.util.RedMd5;
import cn.com.wechat.act.util.RoundUtil;


/**
 * @ClassName: WxRedPacketService 
 * @Description: 微信红包服务类
 * @author bob_zhang
 * @date 2016-1-14 上午10:41:43
 */


@Service
public class WxRedPacketService {

private Logger logger = Logger.getLogger(WxRedPacketService.class);

/**微信商户号 */
private static String mch_id = PropertiesUtil.getRedpacketProperties("mch_id");
/**微信红包接口地址 */
private static String sendPacketUrl = PropertiesUtil.getRedpacketProperties("sendPacketUrl");
/**服务号appid */
private static String appid = PropertiesUtil.getRedpacketProperties("appid");
/**提供方名称 */
private static String nickName = PropertiesUtil.getRedpacketProperties("nickName");
/**发红包者名称 */
private static String sendName = PropertiesUtil.getRedpacketProperties("sendName");
/**接口调用方IP */
private static String clientIp = PropertiesUtil.getRedpacketProperties("clientIp");
/**商户密钥 */
private static String partnerkey = PropertiesUtil.getRedpacketProperties("partnerkey");
/**加密字符编码,我用的UTF-8 */
private static String charset = PropertiesUtil.getRedpacketProperties("charset");
/**证书文件目录 */
private static String cerfile = PropertiesUtil.getRedpacketProperties("cerfile");


/**
* @Title: sendRedPacket 
* @Description: 发送红包方法
* @param @param openId 微信用户openid
* @param @param money 红包金额
* @param @return 设定文件 
* @return int 返回类型 
* @throws
*/
public int sendRedPacket(String openId,String money,String actName,String wishing,String remark) {

//商户订单号
String orderNNo = getOrderNo();
//红包参数
Map<String, String> paramMap = getParamMap(orderNNo,openId,money,actName,wishing,remark);
//发送的报文参数
String xml = createXML(paramMap);
logger.info("红包发送报文:" + xml);

try {
String resXml = doSend(sendPacketUrl,xml);
logger.info("红包发送返回报文:" + resXml);
//红包发送成功,状态判断
if(resXml.indexOf("SUCCESS")>-1) {
return 1;
} else if(resXml.indexOf("NO_AUTH")>-1) {
//发放失败,此请求可能存在风险,已被微信拦截
return 2;
} else if(resXml.indexOf("SENDNUM_LIMIT")>-1) {
//该用户今日领取红包个数超过限制
return 3;
} else if(resXml.indexOf("MONEY_LIMIT")>-1) {
//红包金额发放限制
return 4;
} else if(resXml.indexOf("SEND_FAILED")>-1) {
//红包发放失败,请更换单号再重试
return 5;
} else if(resXml.indexOf("SYSTEMERROR")>-1) {
//请求已受理,请稍后使用原单号查询发放结果
return 6;
} else if(resXml.indexOf("NOTENOUGH")>-1) {
//帐号余额不足,请到商户平台充值后再重试
return 7;
} else {
//其它错误
return 8;
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}

/**
* @Title: getOrderNo 
* @Description: 生成商户订单号
* @param @return 设定文件 
* @return String 返回类型 
* @throws
*/
private static String getOrderNo() {
String order = mch_id + new SimpleDateFormat("yyyyMMddss").format(new Date());
Random r = new Random();
for (int i = 0; i < 2; i++) {
order += r.nextInt(9000) + 1000;
}
return order;
}

/**
* @Title: getParamMap 
* @Description: 红包参数拼接及签名生成 
* @param @param orderNNo 红包订单号
* @param @param openId 微信openid
* @param @param money 红包金额
* @param @param actName 活动名称
* @param @param wishing 红包祝福语
* @param @param remark 备注
* @param @return 设定文件 
* @return Map<String,String> 返回类型 
* @throws
*/
private static Map<String,String> getParamMap(String orderNNo,String openId,String money,String actName,String wishing,String remark) {
Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("nonce_str", RoundUtil.getUUID());//随机字符串
paramMap.put("mch_billno", orderNNo);//商户订单
paramMap.put("mch_id", mch_id);//商户号
paramMap.put("wxappid", appid);//商户appid
paramMap.put("nick_name", nickName);//提供方名称
paramMap.put("send_name", sendName);//发红包者名称
paramMap.put("re_openid", openId);//用户openid
paramMap.put("total_amount", money);//付款金额
paramMap.put("total_num", "1");//红包发送总人数
paramMap.put("wishing", wishing);//红包祝福语
paramMap.put("client_ip", clientIp);//接口调用机器IP地址
paramMap.put("act_name", actName);//活动名称
paramMap.put("remark", remark);//备注
paramMap.put("sign", redSignal(paramMap));//签名
return paramMap;
}

private static String createXML(Map<String, String> map){
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml>";
Set<String> set = map.keySet();
Iterator<String> i = set.iterator();
while(i.hasNext()){
String str = i.next();
xml+="<"+str+">"+"<![CDATA["+map.get(str)+"]]>"+"</"+str+">";
}
xml+="</xml>";
return xml;
}

/**
* @Title: redSignal 
* @Description: 发送红包签名生成
* @param @param params
* @param @return 设定文件 
* @return String 返回类型 
* @throws
*/
private static String redSignal(Map<String, String> params) {
SortedMap<String, String> packageParams = new TreeMap<String, String>();
for (Map.Entry<String, String> m : params.entrySet()) {
packageParams.put(m.getKey(), m.getValue().toString());
}
StringBuffer sb = new StringBuffer();
Set<?> es = packageParams.entrySet();
Iterator<?> it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = (String) entry.getValue();
if (!StringUtils.isEmpty(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + partnerkey);
String sign = RedMd5.MD5Encode(sb.toString(), charset).toUpperCase();
return sign;
}


public static String doSend(String url, String data) throws Exception {
KeyStore keyStore  = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(cerfile));//P12文件目录
        try {
            keyStore.load(instream, mch_id.toCharArray());//这里写密码..默认是你的MCHID
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, mch_id.toCharArray())//这里也是写密码的
                .build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
        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"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                String jsonStr = toStringInfo(response.getEntity(),charset);
                
                EntityUtils.consume(entity);
               return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
}

/**
* @Title: toStringInfo 
* @Description: 返回对象转换XML
* @param @param entity
* @param @param defaultCharset
* @param @return
* @param @throws Exception
* @param @throws IOException 设定文件 
* @return String 返回类型 
* @throws
*/
private static String toStringInfo(HttpEntity entity, String defaultCharset) throws Exception, IOException{
final InputStream instream = entity.getContent();
   if (instream == null) {
       return null;
   }
   try {
    Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
               "HTTP entity too large to be buffered in memory");
       int i = (int)entity.getContentLength();
       if (i < 0) {
           i = 4096;
       }
       Charset charset = null;
       
       if (charset == null) {
           charset = Charset.forName(defaultCharset);
       }
       if (charset == null) {       
          charset = HTTP.DEF_CONTENT_CHARSET;
       }
       final Reader reader = new InputStreamReader(instream, charset);
       final CharArrayBuffer buffer = new CharArrayBuffer(i);
       final char[] tmp = new char[1024];
       int l;
       while((l = reader.read(tmp)) != -1) {
           buffer.append(tmp, 0, l);
       }
       return buffer.toString();
   } finally {
       instream.close();
   }
}

}


二、MD5加密类:

package cn.com.wechat.act.util;


import java.security.MessageDigest;


public class RedMd5 {

private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));


return resultSb.toString();
}


private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}


public static String MD5Encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}


private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };


}


三、随机数生成类(不重要)

package cn.com.wechat.act.util;


import java.util.UUID;




/**
 * @ClassName: RoundUtil 
 * @Description: 随机数生成工具类
 * @author bob_zhang
 * @date 2015-8-15 下午3:41:09
 */
public class RoundUtil {

/**
* @Title: getUUID 
* @Description: 获取UUID
* @param @return 设定文件 
* @return String 返回类型 
* @throws
*/
public static String getUUID() {
String uuid = UUID.randomUUID().toString(); 
uuid = uuid.substring(0,8)+uuid.substring(9,13)+uuid.substring(14,18)+uuid.substring(19,23)+uuid.substring(24); 
        return uuid;
}

/**
* @Title: getCode 
* @Description: 随机生成4位验证码
* @param @return 设定文件 
* @return String 返回类型 
* @throws
*/
public static String getCode() {
int i = (int) (Math.random() * 9000 + 1000);
return i + "";
}


}

另外还要导几个JAR包,这个可以在腾讯红包文档中获取到:

文档地址:https://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=4_3

第3点商户证书中第2小点使用商户证书,里面有个"请参考微信支付提供的Demo外链"的下载链接,下下来里面会有几个jar包,这个得导进去。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值