天天看點

微信開放平台-- 微信紅包發放

直接上代碼- -

public ResponseEntity sendRedEnvelopes(SendRedEnvelopesDto sendRedEnvelopesDto) {
        RedEnvelopesDto redEnvelopesDto=newRedEnvelopesDto(sendRedEnvelopesDto);
        Map<String,String> paramMap = null;
        try {
            paramMap = WeixinUtil.convertBeanToMap(redEnvelopesDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.ok().body(ServerResponse.buildByErrorMessage("錯誤的參數"));
        }
        paramMap.put("sign",WeixinUtil.getSign(paramMap,Configure.getValue("mec_key")));//簽名 ,預設sign_type是MD5
        String reqParm=WeixinUtil.arrayToXml(paramMap);
//        WxRedPackageBiz.class.getClassLoader().getResourceAsStream(L_STRING_FILE)
        String unifiedStr = WxstoreUtils.postSSL(WeixinUtil.SENDREDPACK, reqParm,Configure.getValue("mec_id"),Configure.getValue("mec_path"));
        // logger.debug("微信紅包傳回資料:"+unifiedStr);
        Map<String, String> preMap = WeixinUtil.xmltoMap(unifiedStr);
        RedEnvelopesInfoWithBLOBs redEnvelopesInfo=new RedEnvelopesInfoWithBLOBs();
        redEnvelopesInfo.setReqPram(reqParm);
        redEnvelopesInfo.setRespPram(unifiedStr);
         redEnvelopesInfo=redEnvelopesPram(redEnvelopesInfo,preMap,sendRedEnvelopesDto);
        Integer sign=redEnvelopesInfoService.insertSelective(redEnvelopesInfo);
        if(sign.intValue()==1){
            return ResponseEntity.ok().body(ServerResponse.buildBySuccess(preMap));
        }
        return ResponseEntity.ok().body(ServerResponse.buildByErrorMessage("失敗"));
    }
           
public RedEnvelopesDto newRedEnvelopesDto(SendRedEnvelopesDto sendRedEnvelopesDto) {
        RedEnvelopesDto redEnvelopesDto =new RedEnvelopesDto();
        redEnvelopesDto.setNonce_str(WeixinUtil.createNoncestr(32));
        redEnvelopesDto.setMch_billno(sendRedEnvelopesDto.getMchBillno());
        redEnvelopesDto.setMch_id(Configure.getValue("mec_id"));
        redEnvelopesDto.setWxappid(sendRedEnvelopesDto.getAppid());
        redEnvelopesDto.setSend_name("有車時代");
        redEnvelopesDto.setRe_openid(sendRedEnvelopesDto.getReOpenid());
        BigDecimal decimal=new BigDecimal(sendRedEnvelopesDto.getTotalMoney());
        BigDecimal totalMoeny = decimal.multiply(new BigDecimal(100));
        Integer  total= totalMoeny.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
        redEnvelopesDto.setTotal_amount(total);
        redEnvelopesDto.setTotal_num(1);
        redEnvelopesDto.setWishing("紅包兌換");
        redEnvelopesDto.setClient_ip(sendRedEnvelopesDto.getClientIp());
        redEnvelopesDto.setAct_name("紅包兌換");
        redEnvelopesDto.setRemark("紅包兌換");
        redEnvelopesDto.setScene_id("PRODUCT_2");
        //redEnvelopesDto.setRisk_info(map.get("riskInfo"));
        return redEnvelopesDto;
    }
           

微信相關配置

package com.yihulian.autoshop.third;

import com.yihulian.core.server.framework.utils.tools.MD5Util;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import javax.servlet.http.HttpServletRequest;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;


/**
 * 微信相關工具類
 * ClassName:WeixinUtil 
 * Date:     2017年10月24日 下午2:05:05 
 * @author   sqq 
 * @since    JDK 1.8 
 */
public class WeixinUtil {
	
	/** = */
	public static final String QSTRING_EQUAL = "=";

	/** & */
	public static final String QSTRING_SPLIT = "&";

	//編碼方式
	public static final String ENCODE = "UTF-8";

	//微信uri-請求預支付接口
	public static String UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	public static String SENDREDPACK = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";

	/**
	 * 對象轉換成map
	 * @param bean
	 * @return
	 * @throws IntrospectionException
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static Map<String, String> convertBeanToMap(Object bean) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		Class type = bean.getClass();
		Map<String, String> returnMap = new HashMap<String, String>();
		BeanInfo beanInfo = Introspector.getBeanInfo(type);
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (int i = 0; i < propertyDescriptors.length; i++) {
			PropertyDescriptor descriptor = propertyDescriptors[i];
			String propertyName = descriptor.getName();
			if (!propertyName.equals("class")) {
				Method readMethod = descriptor.getReadMethod();
				Object result = readMethod.invoke(bean, new Object[0]);
				if (result != null) {
					returnMap.put(propertyName, result.toString());
				} else {
					returnMap.put(propertyName, "");
				}
			}
		}
		Map<String,String> map=new TreeMap<String, String>();
		for (String key : returnMap.keySet()) {//
			//		System.out.println("-------------------------:" + key);
			//值為空不參加簽名
			if(returnMap.get(key)!=null && !"".equals(returnMap.get(key))){
				//			System.out.println("-------------------------1:" + key);
				map.put(key,returnMap.get(key));
			}
		}
		return map;
	}
	/**
	 * 	作用:産生随機字元串,不長于32位
	 */
	public static String createNoncestr(int length){
		
		String chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
		String str ="";
		Random rand = new Random();
		for (int i = 0; i < length; i++) {
			int index = rand.nextInt(chars.length());
			str += chars.substring(index, index + 1);
		} 
		return str;
	}
		
	/**
	 * 	把請求要素按照“參數=參數值”的模式用“&”字元拼接成字元串
     * @param para 請求要素
     * @param sort 是否需要根據key值作升序排列
     * @param encode 是否需要URL編碼
     * @return 拼接成的字元串
	 */
	public static String formatBizQueryParaMap(Map<String,String> para,boolean sort, boolean encode)
	{
		List<String> keys = new ArrayList<String>(para.keySet());
        
        if (sort)
        	Collections.sort(keys);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = para.get(key);
            
            if (encode) {
				try {
					value = URLEncoder.encode(value, ENCODE);
				} catch (UnsupportedEncodingException e) {
				}
            }
            
            if (i == keys.size() - 1) {//拼接時,不包括最後一個&字元
                sb.append(key).append(QSTRING_EQUAL).append(value);
            } else {
                sb.append(key).append(QSTRING_EQUAL).append(value).append(QSTRING_SPLIT);
            }
        }
        return sb.toString();
	}
	
//	/**
//	 * 	作用:生成簽名
//	 */
//	public static String getSign(Map<String,String> paramMap,String merchantkey)
//	{
//	//	System.out.println("------------------bef-----------");ofr
//		Map<String,String> map=new TreeMap<>();
//		for (String key : paramMap.keySet()) {//
//	//		System.out.println("-------------------------:" + key);
//			//值為空不參加簽名
//			if(paramMap.get(key)!=null && !"".equals(paramMap.get(key))){
//	//			System.out.println("-------------------------1:" + key);
//				map.put(paramMap.get(key),paramMap.get(key));
//			}
//		}
//        List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
//        // 對所有傳入參數按照字段名的 ASCII 碼從小到大排序(字典序)
//        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
//
//            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
//                return (o1.getKey()).toString().compareTo(o2.getKey());
//            }
//        });
//
//		String params = formatBizQueryParaMap(map, true, false);
//		//echo '【string1】'.$String.'</br>';
//		//簽名步驟二:在string後加入KEY
//		params = params + "&key=" + merchantkey;//
//		//echo "【string2】".$String."</br>";
//		//簽名步驟三:MD5加密并轉大寫
//		params = MD5Util.encodeByMD5(params);
//		//echo "【string3】 ".$String."</br>";
//		//簽名步驟四:所有字元轉為大寫
//		//echo "【result】 ".$result_."</br>";
//		return params;
//	}
    /**
     * 生成簽名
     * @param paramMap
     * @return
     */
    public static String getSign(Map<String, String> paramMap,String merchantkey) {

        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(paramMap.entrySet());
            // 對所有傳入參數按照字段名的 ASCII 碼從小到大排序(字典序)
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });

            // 構造簽名鍵值對的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (!(val == "" || val == null)) {
                        sb.append(key + "=" + val + "&");
                    }
                }

            }
			sb.append("key=" + merchantkey);
            result = sb.toString();
			//簽名步驟三:MD5加密并轉大寫
			result =encodeByMD5(result);
            //進行MD5加密
           // result = DigestUtils.md5Hex(result).toUpperCase();
        } catch (Exception e) {
            return null;
        }
        return result;
    }

	/**
	 * MD5加密(UTF-8編碼,32位,轉大寫)
	 * @param originstr
	 * @return
	 */
	public static String encodeByMD5(String originstr) {
		String result = "";
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			md5.update(originstr.getBytes("UTF-8"));
			byte b[] = md5.digest();
			int i;
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0) {
					i += 256;
				}
				if (i < 16) {
					buf.append("0");
				}
				buf.append(Integer.toHexString(i));
			}
			result = buf.toString().toUpperCase();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}
    /**
	 * 	作用:map轉xml
	 */
	public static String arrayToXml(Map<String,String> paramMap){
        String xml = "<xml>";
        for (String key : paramMap.keySet()) {//
			//值是否隻有字母和數字
//			if(paramMap.get(key).matches("^[\\da-zA-Z]*$")){
//				xml += "<" + key + ">" + paramMap.get(key) + "</" + key + ">";
//			}else{
				xml += "<" + key + "><![CDATA[" + paramMap.get(key) + "]]></" + key + ">";
				//xml += "<" + key + "><" + paramMap.get(key) + "></" + key + ">";
			//}
		}
        xml += "</xml>";
        return xml;
    }
	
	/**
	 * xml 轉  map
	 * @param xml
	 * @return
	 */
	public static Map<String,String> xmltoMap(String xml) {  
        try {  
            Map<String,String> map = new HashMap<String,String>();  
            Document document = DocumentHelper.parseText(xml);  
            Element nodeElement = document.getRootElement();  
            List node = nodeElement.elements();  
            for (Iterator it = node.iterator(); it.hasNext();) {
                Element elm = (Element) it.next();  
                String val = elm.getText();
                val = val.replace("<![CDATA[", "");
                val = val.replace("]]>", "");
                map.put(elm.getName(), val);  
                elm = null;  
            }  
            node = null;
            nodeElement = null;  
            document = null;  
            return map;  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }
	
	/**
	 * jsonStrToMap:(json轉map).
	 * @author sqq
	 * @param jsonStr
	 * @return
	 * @since JDK 1.8
	 */
	public static Map<String, Object> jsonStrToMap(String jsonStr){
        Map<String, Object> map = new HashMap<String, Object>();
        //最外層解析
        JSONObject json = JSONObject.fromObject(jsonStr);
        for(Object k : json.keySet()){
              Object v = json.get(k);
              //如果内層還是數組的話,繼續解析
              if(v instanceof JSONArray){
                    List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
                    Iterator<JSONObject> it = ((JSONArray)v).iterator();
                    while(it.hasNext()){
                      JSONObject json2 = it.next();
                      list.add(jsonStrToMap(json2.toString()));
                    }
                    map.put(k.toString(), list);
              } else {
                  map.put(k.toString(), v);
              }
        }
        return map;
    }
	/**
	 * 擷取ip位址
	 * getRemoteHost
	 * @author sqq
	 * @param request
	 * @return
	 * @since JDK 1.8
	 */
	public static String getRemoteHost(javax.servlet.http.HttpServletRequest request){
	    String ip = request.getHeader("x-forwarded-for");
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("WL-Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getRemoteAddr();
	    }
	    return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
	}
	
	/** 
	 * 擷取精确到秒的時間戳 
	 * @param date 
	 * @return 
	 */  
	public static int getTimestamp(Date date){  
	    if (null == date) {  
	        return 0;  
	    }  
	    String timestamp = String.valueOf(date.getTime()/1000);  
	    return Integer.valueOf(timestamp);  
	}
	
	/**
	 * 授權統一路徑拼湊
	 * @return
	 * @throws Exception
	 */
	public String doWeixinRedirectUrl(HttpServletRequest request) throws Exception{
		//特别注意:params分享會出現code過期參數  應去掉後作為回調位址
	//	String server_url_name = PropertiesUtil.getValue("SERVER_URL_NAME");//伺服器位址
		String returl = request.getScheme()+"://"+ request.getServerName() + request.getRequestURI(); 
		Map<String,String[]> paramMap = request.getParameterMap();
		String params = "";
		int next = 0;
		//過濾code、state
		for (String key : paramMap.keySet()) {
			String[] strs = paramMap.get(key);
			if(!key.equals("code") && !key.equals("state")){
				if(next == 0){
					params += "?";
				}else{
					params += "&";
				}
				params += key + "=" + strs[0];
				next ++;
			}
			
		}
		System.out.println("params:" + params);
		String dqurl = returl + params;
		
		dqurl = URLEncoder.encode(dqurl, "utf-8");
		String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+  "&redirect_uri="+ dqurl +"&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
		return url;
	}
}

           

至此  完了       公衆号要想發  紅包  需要公衆号上關聯商戶号

幾個特殊的字元串   mec_id  商戶号ID  mec_key  商戶号秘鑰   mec_path 商戶号中有個 apiclient_cert.p12檔案  這個檔案的路徑  我是直接引用網上的

微信開放平台-- 微信紅包發放

appid  是發放公衆号的   

繼續閱讀