使用微信公众号进行发红包
2016-12-17 17:03
148 查看
package com.tintop.customer.dxaction;
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.math.BigDecimal;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
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.beanutils.BeanUtils;
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 com.bsd.directext.annotations.ExtRemoteClass;
import com.bsd.directext.annotations.ExtRemoteMethod;
import com.tintop.customer.entity.ConsumerDetails;
import com.tintop.customer.entity.RedPack;
import com.tintop.customer.entity.WxAccount;
import com.tintop.customer.entity.WxPublicAccount;
import com.tintop.customer.util.MD5Util;
import com.tintop.frame.util.AppContext;
/**
* 微信公众红包功能
* com.tintop.customer.entity.RedPack's DxAction
*/
@ExtRemoteClass(bean="fbtagRedPackDxAction",name="FbtagRedPackDxAction")
public class RedPackDxAction extends com.tintop.customer.util.CustGeneralDxAction{
//普通红包URL
private static final String PTHB_URL="https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
//微信公众号
private WxPublicAccount publicAccount;
//微信号
private WxAccount wxAccount;
//可以传入要发人的微信号,公司微信号,订单号
@ExtRemoteMethod
public String SendRedPack(String wxAccount){
String respXml = "";
SortedMap<String, Object> map = new TreeMap<String, Object>();
try {
map.put("act_name", "任务红包");//活动名称
map.put("wxappid", 这里填微信公众号);
map.put("mch_billno", 这里填订单号);//订单编号
map.put("mch_id", publicAccount.getMchId());
map.put("nonce_str", buildRandom());
//TODO
map.put("re_openid", 这里填微信关注用户的openId);//微信用户 openId
map.put("wishing", "恭喜发财");
map.put("send_name", "泰博科技");//商户名称
map.put("total_amount", 100);//红包金额,以分为单位,>100,<20000
map.put("total_num", 1);//红包个数
map.put("client_ip", "127.0.0.1");
map.put("sign", createSign(map));//签名
respXml = doSendRedPack(createXML(map));
} catch (Exception e) {
e.printStackTrace();
}
map.put("wxAccount",wxAccount);
map.put("lendType", 1);
//发送成功保存红包订单
if(isSend(respXml)){
saveRedPack(map);
return "发送红包成功";
}
return "发送红包失败";
}
/**
* 封装请求参数 XML
*/
public static String createXML(Map<String, Object> map){
String xml = "<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;
}
/**
* 验证红包是否发送成功
* @param respXml
* @return
*/
public boolean isSend(String respXml){
//返回结果成功
return respXml.contains("<result_code><![CDATA[SUCCESS]]></result_code>");
}
/**
* 保存红包
* @param map
*/
public void saveRedPack(SortedMap<String, Object> map){
RedPack r = new RedPack();
try {
BeanUtils.populate(r, map);
}catch (Exception e) {
e.printStackTrace();
}
daoFac.getRedPackDao().merge(r);
}
/**
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 sign
*/
public String createSign(SortedMap<String, Object> map) {
StringBuffer sb = new StringBuffer();
Set es = map.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + publicAccount.getApiKey());
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
/**
* 发送红包
*/
public String doSendRedPack(String data) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(publicAccount.getKeyStoreFile()));//P12文件目录
try {
keyStore.load(instream, publicAccount.getMchId().toCharArray());//这里写密码..默认是你的MCHID
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, publicAccount.getMchId().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();
try {
HttpPost httpost = new HttpPost(PTHB_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(),"UTF-8");
// 微信返回的报文时GBK,直接使用httpcore解析乱码
// String jsonStr = EntityUtils.toString(response.getEntity(),"UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 解析response数据
* @param entity
* @param defaultCharset
* @return
* @throws Exception
* @throws IOException
*/
public 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();
}
}
/**
* 随机16为数值
*/
public String buildRandom() {
String currTime = getCurrTime();
String strTime = currTime.substring(8, currTime.length());
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < 4; i++) {
num = num * 10;
}
return (int) ((random * num)) + strTime;
}
/**
* 获取当前时间 yyyyMMddHHmmss
* @return String
*/
public String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
/**
* 创建订单编号
*
* @return
*/
public String getOrderNo() {
String order = publicAccount.getMchId()
+ new SimpleDateFormat("yyyyMMdd").format(new Date());
Random r = new Random();
for (int i = 0; i < 10; i++) {
order += r.nextInt(9);
}
return order;
}
}
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.math.BigDecimal;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
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.beanutils.BeanUtils;
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 com.bsd.directext.annotations.ExtRemoteClass;
import com.bsd.directext.annotations.ExtRemoteMethod;
import com.tintop.customer.entity.ConsumerDetails;
import com.tintop.customer.entity.RedPack;
import com.tintop.customer.entity.WxAccount;
import com.tintop.customer.entity.WxPublicAccount;
import com.tintop.customer.util.MD5Util;
import com.tintop.frame.util.AppContext;
/**
* 微信公众红包功能
* com.tintop.customer.entity.RedPack's DxAction
*/
@ExtRemoteClass(bean="fbtagRedPackDxAction",name="FbtagRedPackDxAction")
public class RedPackDxAction extends com.tintop.customer.util.CustGeneralDxAction{
//普通红包URL
private static final String PTHB_URL="https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
//微信公众号
private WxPublicAccount publicAccount;
//微信号
private WxAccount wxAccount;
//可以传入要发人的微信号,公司微信号,订单号
@ExtRemoteMethod
public String SendRedPack(String wxAccount){
String respXml = "";
SortedMap<String, Object> map = new TreeMap<String, Object>();
try {
map.put("act_name", "任务红包");//活动名称
map.put("wxappid", 这里填微信公众号);
map.put("mch_billno", 这里填订单号);//订单编号
map.put("mch_id", publicAccount.getMchId());
map.put("nonce_str", buildRandom());
//TODO
map.put("re_openid", 这里填微信关注用户的openId);//微信用户 openId
map.put("wishing", "恭喜发财");
map.put("send_name", "泰博科技");//商户名称
map.put("total_amount", 100);//红包金额,以分为单位,>100,<20000
map.put("total_num", 1);//红包个数
map.put("client_ip", "127.0.0.1");
map.put("sign", createSign(map));//签名
respXml = doSendRedPack(createXML(map));
} catch (Exception e) {
e.printStackTrace();
}
map.put("wxAccount",wxAccount);
map.put("lendType", 1);
//发送成功保存红包订单
if(isSend(respXml)){
saveRedPack(map);
return "发送红包成功";
}
return "发送红包失败";
}
/**
* 封装请求参数 XML
*/
public static String createXML(Map<String, Object> map){
String xml = "<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;
}
/**
* 验证红包是否发送成功
* @param respXml
* @return
*/
public boolean isSend(String respXml){
//返回结果成功
return respXml.contains("<result_code><![CDATA[SUCCESS]]></result_code>");
}
/**
* 保存红包
* @param map
*/
public void saveRedPack(SortedMap<String, Object> map){
RedPack r = new RedPack();
try {
BeanUtils.populate(r, map);
}catch (Exception e) {
e.printStackTrace();
}
daoFac.getRedPackDao().merge(r);
}
/**
* 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 sign
*/
public String createSign(SortedMap<String, Object> map) {
StringBuffer sb = new StringBuffer();
Set es = map.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + publicAccount.getApiKey());
String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
return sign;
}
/**
* 发送红包
*/
public String doSendRedPack(String data) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(publicAccount.getKeyStoreFile()));//P12文件目录
try {
keyStore.load(instream, publicAccount.getMchId().toCharArray());//这里写密码..默认是你的MCHID
} finally {
instream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, publicAccount.getMchId().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();
try {
HttpPost httpost = new HttpPost(PTHB_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(),"UTF-8");
// 微信返回的报文时GBK,直接使用httpcore解析乱码
// String jsonStr = EntityUtils.toString(response.getEntity(),"UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
/**
* 解析response数据
* @param entity
* @param defaultCharset
* @return
* @throws Exception
* @throws IOException
*/
public 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();
}
}
/**
* 随机16为数值
*/
public String buildRandom() {
String currTime = getCurrTime();
String strTime = currTime.substring(8, currTime.length());
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < 4; i++) {
num = num * 10;
}
return (int) ((random * num)) + strTime;
}
/**
* 获取当前时间 yyyyMMddHHmmss
* @return String
*/
public String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
/**
* 创建订单编号
*
* @return
*/
public String getOrderNo() {
String order = publicAccount.getMchId()
+ new SimpleDateFormat("yyyyMMdd").format(new Date());
Random r = new Random();
for (int i = 0; i < 10; i++) {
order += r.nextInt(9);
}
return order;
}
}
相关文章推荐
- 使用WebController爬虫框架进行微信公众号文章爬取并持久化
- 使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发
- 使用ping++进行微信公众号支付
- 5.使用 公众平台测试账号 进行开发(微信公众号开发实战)
- 论如何使用Python进行微信公众号的开发
- 使用Django进行微信公众号开发
- 使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发
- 5.使用 公众平台测试账号 进行开发(微信公众号开发实战)
- 使用ngrok在本地进行微信公众号调试
- 使用Lccwin32进行MySQL开发。
- 使用ASP+jmail进行邮件群发
- vs.net web项目使用visual source safe进行源代码管理
- 水晶报表使用经验谈1--建立水晶报表第一步及编译最易出现错误的解决方法及报表转换成pdf文档进行打印方法
- 使用IntraWeb进行Web编程(二)
- [导入]使用正则表达式进行xml数据验证
- 使用正则表达式进行数据有效性校验的TextBox控件
- 使用Server.Transfer对URL进行隐藏以及其他
- 用VC++进行MapX二次开发::之二------使用MapX的基石
- 使用ASP和Word进行服务器端拼写检查
- 使用CsUnit进行单元测试(一)