package com.stylefeng.guns.core.util;
|
|
import ch.qos.logback.core.encoder.Encoder;
|
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.lang.StringUtils;
|
|
import javax.crypto.Mac;
|
import javax.crypto.spec.SecretKeySpec;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.PrintWriter;
|
import java.io.UnsupportedEncodingException;
|
import java.util.*;
|
|
|
public class NotifyDemo {
|
/**
|
* md5秘钥
|
*/
|
static final String md5key = "impARTxrQcfwmRijpDNCw6hPxaWCddKEpYxjaKXDhCaTCXJ6";
|
|
|
/**
|
* 支付通知模块,用于:在支付成功后 接受银商平台发送的支付结果通知
|
*/
|
// @RequestMapping(value = "/notify.do", method = RequestMethod.POST)
|
public String getNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
|
/*接收参数*/
|
Map<String, String> params = getRequestParams(request);
|
System.out.println("params:" + params);
|
String sign = params.get("sign");
|
System.out.println(sign);
|
|
/*验签*/
|
//对通知内容生成sign
|
String strSign = makeSign(md5key, params);
|
//System.out.println("strSign="+strSign);
|
//判断签名是否相等
|
if (sign.equals(strSign)) {
|
// 收到通知后记得返回SUCCESS
|
System.out.println("验签通过");
|
PrintWriter writer = response.getWriter();
|
writer.print("SUCCESS");
|
writer.flush();
|
} else {
|
System.out.println("验签未通过");
|
}
|
|
//更新商户系统的订单
|
|
//跳转支付完成页面
|
return "/WEB-INF/views/jsp/payResult.jsp";
|
}
|
|
|
// 获取HttpServletRequest里面的参数
|
public static Map<String, String> getRequestParams(HttpServletRequest request) {
|
Map<String, String[]> params = request.getParameterMap();
|
Map<String, String> params2 = new HashMap<>();
|
for (String key : params.keySet()) {
|
String[] values = params.get(key);
|
if (values.length > 0) {
|
params2.put(key, request.getParameter(key));
|
}
|
}
|
return params2;
|
}
|
|
|
public static String makeSign(String md5Key, Map<String, String> params) {
|
|
String preStr = buildSignString(params); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
|
String text = preStr + md5Key;
|
System.out.println("待签名字符串:" + text);
|
return DigestUtils.sha256Hex(getContentBytes(text)).toUpperCase();
|
}
|
|
/**
|
* 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
|
*
|
* @param data 待签名数据
|
* @param key API密钥
|
* @param signType 签名方式
|
* @return 签名
|
*/
|
public static String generateSignature(final Map<String, String> data, String key, String signType) throws Exception {
|
Set<String> keySet = data.keySet();
|
String[] keyArray = keySet.toArray(new String[keySet.size()]);
|
Arrays.sort(keyArray);
|
StringBuilder sb = new StringBuilder();
|
for (String k : keyArray) {
|
if (k.equals("sign")) {
|
continue;
|
}
|
if (data.get(k).trim().length() > 0) {
|
// 参数值为空,则不参与签名
|
sb.append(k).append("=").append(data.get(k).trim()).append("&");
|
}
|
}
|
sb.append("key=").append(key);
|
if ("HMAC-SHA256".equals(signType)) {
|
return HMACSHA256(sb.toString(), key);
|
} else {
|
throw new Exception(String.format("Invalid sign_type: %s", signType));
|
}
|
}
|
|
/**
|
* 生成 HMACSHA256
|
*
|
* @param data 待处理数据
|
* @param key 密钥
|
* @return 加密结果
|
* @throws Exception
|
*/
|
public static String HMACSHA256(String data, String key) throws Exception {
|
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
|
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
|
sha256_HMAC.init(secret_key);
|
byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
|
StringBuilder sb = new StringBuilder();
|
for (byte item : array) {
|
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
|
}
|
return sb.toString().toUpperCase();
|
}
|
|
// 构建签名字符串
|
public static String buildSignString(Map<String, String> params) {
|
|
// params.put("Zm","test_test");
|
|
if (params == null || params.size() == 0) {
|
return "";
|
}
|
|
List<String> keys = new ArrayList<>(params.size());
|
|
for (String key : params.keySet()) {
|
if ("sign".equals(key))
|
continue;
|
if (StringUtils.isEmpty(params.get(key)))
|
continue;
|
keys.add(key);
|
}
|
//System.out.println(listToString(keys));
|
|
Collections.sort(keys);
|
|
StringBuilder buf = new StringBuilder();
|
|
for (int i = 0; i < keys.size(); i++) {
|
String key = keys.get(i);
|
String value = params.get(key);
|
|
if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
|
buf.append(key + "=" + value);
|
} else {
|
buf.append(key + "=" + value + "&");
|
}
|
}
|
|
return buf.toString();
|
}
|
|
// 根据编码类型获得签名内容byte[]
|
public static byte[] getContentBytes(String content) {
|
try {
|
return content.getBytes("UTF-8");
|
} catch (UnsupportedEncodingException e) {
|
throw new RuntimeException("签名过程中出现错误");
|
}
|
}
|
}
|