<dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency>
private YJResult wxpay(String orderNo, Integer totalAmount, String remark) { log.info("微信支付配置数据:" + JSONObject.toJSONString(wxPayConfig)); Map<String, String> data = getWXPayConfig(); data.put("body", remark); data.put("out_trade_no", orderNo); data.put("total_fee", totalAmount + ""); data.put("notify_url", wechatPay); try { String signStr = CommonUtil.getSignStr(data)+"key="+wxPayConfig.getAppKey(); log.info("微信支付签名:" + signStr); String sign = WXPayUtil.MD5(signStr); log.info("微信支付签名:" + sign); data.put("sign", sign); String requestXml = WXPayUtil.mapToXml(data); System.out.println("sendXml:" + requestXml); String post = CommonUtil.httpsRequest(WXPayConstants.UNIFIEDORDER_URL, "POST", requestXml); log.info("微信支付返回参数:" + post); Map<String, String> resp = WXPayUtil.xmlToMap(post); if (resp.get("return_code").equals("FAIL")) { return YJResult.error(1005, resp.get("return_msg")); } resp.put("package","prepay_id="+resp.get("prepay_id")); log.info("微信支付结果:" + resp); return YJResult.success(resp); } catch (Exception e) { e.printStackTrace(); } return YJResult.error(1005, "微信支付失败"); } public Map<String, String> getWXPayConfig(){ Map<String, String> map = new TreeMap<>(); map.put("appid",wxPayConfig.getAppID()); map.put("mch_id",wxPayConfig.getMchID()); map.put("nonce_str",WXPayUtil.generateNonceStr()); map.put("spbill_create_ip",wxPayConfig.getSpbillCreateIp()); map.put("trade_type","APP"); return map; }
import com.alibaba.druid.util.StringUtils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.util.*; /** * //TODO * @author wdz * @date 2019/8/6 11:39 */ public class CommonUtil { // 随机字符串生成 public static String getRandomString(int length) { // length表示生成字符串的长度 String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } // 请求xml组装 public static String getRequestXml(String parameters) { StringBuffer sb = new StringBuffer(); sb.append("<xml>"); String[] split = parameters.split("&"); for (int i = 0; i < split.length; i++) { String s = split[i]; if (!StringUtils.isEmpty(s)){ String[] split1 = s.split("="); String key = split1[0]; String value = split1[1]; if ("key".equals(key)){ continue; } if ("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key) || "sign".equalsIgnoreCase(key)) { sb.append("<" + key + ">" + "<![CDATA[" + value + "]]></" + key + ">"); } else { sb.append("<" + key + ">" + value + "</" + key + ">"); } } } sb.append("</xml>"); return sb.toString(); } // 生成签名 public static String createSign(String characterEncoding,Map<String, String> parameters,String key) { StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet(); 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=" + key); System.out.println(sb.toString()); String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); return sign; } public static String createSigns(String characterEncoding,Map<String,String> parameters,String key){ StringBuffer sb = new StringBuffer(); //所有参与传参的参数按照accsii排序(升序) Set es = parameters.entrySet(); 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)) { sb.append(k + "=" + v + "&"); } } sb=sb.append("key="+key); System.out.println("sb字符串:"+sb.toString()); System.out.println("sbkey字符串:"+sb.toString()); //MD5加密,结果转换为大写字符 String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase(); System.out.println("MD5加密值:"+sign); return sb.toString()+"sign="+sign; } /** * 生成签名 * @param map * @return */ public static String getSignStr(Map<String, String> map) { String result = ""; try { 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()); } }); // 构造签名键值对的格式 StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> item : infoIds) { if (item.getKey() != null || item.getKey() != "") { String k = item.getKey(); String val = item.getValue(); if (!(val == "" || val == null)) { sb.append(k + "=" + val + "&"); } } } result = sb.toString(); System.out.println("ASLL排序:"+result); } catch (Exception e) { return null; } return result; } public static String md5Str(String str){ //进行MD5加密 String result = getMD5Value(str); return result; } /** * Description:MD5工具生成token * @param value * @return */ public static String getMD5Value(String value){ try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); byte[] md5ValueByteArray = messageDigest.digest(value.getBytes()); BigInteger bigInteger = new BigInteger(1 , md5ValueByteArray); return bigInteger.toString(16).toUpperCase(); } catch (Exception e) { throw new RuntimeException(e); } } /** * 验证回调签名 * @return */ public static boolean isTenpaySign(Map<String, String> map,String key) throws UnsupportedEncodingException { String charset = "utf-8"; String signFromAPIResponse = map.get("sign"); if (signFromAPIResponse == null || signFromAPIResponse.equals("")) { System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!"); return false; } System.out.println("服务器回包里面的签名是:" + signFromAPIResponse); // 过滤空 设置 TreeMap SortedMap<String, String> packageParams = new TreeMap<>(); for (String parameter : map.keySet()) { String parameterValue = map.get(parameter); String v = ""; if (null != parameterValue) { v = parameterValue.trim(); } packageParams.put(parameter, v); } 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 (!"sign".equals(k) && null != v && !"".equals(v)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + key); // 将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较 // 算出签名 String resultSign = ""; String tobesign = sb.toString(); if (null == charset || "".equals(charset)) { resultSign = MD5Util.MD5Encode(tobesign, charset) .toUpperCase(); } else { resultSign = MD5Util.MD5Encode(tobesign, charset) .toUpperCase(); } String tenpaySign = ((String) packageParams.get("sign")).toUpperCase(); return tenpaySign.equals(resultSign); } // 请求方法 public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) { try { URL url = new URL(requestUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求方式(GET/POST) conn.setRequestMethod(requestMethod); conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); // 当outputStr不为null时向输出流写数据 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意编码格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader( inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); return buffer.toString(); } catch (ConnectException ce) { System.out.println("连接超时:{}" + ce); } catch (Exception e) { System.out.println("https请求异常:{}" + e); } return null; } }