直接上代碼- -
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 是發放公衆号的