您的位置:首页 > 移动开发 > 微信开发

使用微信公众号进行发红包

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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: