package com.walker.pay.wechat.v2;
|
|
import com.walker.infrastructure.core.domx.JaxbDomParser;
|
import com.walker.infrastructure.utils.KeyValue;
|
import com.walker.infrastructure.utils.MD5;
|
import com.walker.infrastructure.utils.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.w3c.dom.Document;
|
import org.w3c.dom.Node;
|
|
import java.io.UnsupportedEncodingException;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Set;
|
|
public class SignUtils {
|
|
protected static final Logger logger = LoggerFactory.getLogger(SignUtils.class);
|
|
private static final JaxbDomParser domParser = new JaxbDomParser();
|
|
/**
|
* 返回xml字符串,该方法用来告诉微信,通知处理结果
|
* @param status 状态
|
* @param msg 描述
|
* @return
|
* @date 2023-02-17
|
*/
|
public static String toXmlNotifyStatus(String status, String msg){
|
List<KeyValue<String, String>> params = new ArrayList<>(2);
|
params.add(new KeyValue<>("return_code", status));
|
params.add(new KeyValue<>("return_msg", msg));
|
return toXml(params);
|
}
|
|
public static Map<String,String> decodeXml(String content) {
|
Map<String, String> xml = new HashMap<String, String>();
|
Document doc = domParser.getDocumentFromXml(content);
|
|
Node node = doc.getFirstChild(); // 获取根节点
|
for(Node childNode = node.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()){
|
if(childNode.getNodeType() == Node.ELEMENT_NODE){
|
xml.put(childNode.getNodeName(), childNode.getTextContent());
|
}
|
}
|
return xml;
|
}
|
|
public static String toXml(List<KeyValue<String, String>> params) {
|
StringBuilder sb = new StringBuilder();
|
sb.append("<xml>");
|
for (int i = 0; i < params.size(); i++) {
|
sb.append("<"+params.get(i).getKey()+">");
|
sb.append(params.get(i).getValue());
|
sb.append("</"+params.get(i).getKey()+">");
|
}
|
sb.append("</xml>");
|
return sb.toString();
|
}
|
|
/**
|
* 与genPackageSign方法唯一的区别就是,没有转成大写字母。不知道这帮微信咋弄文档
|
* @param params
|
* @param wxApiKey
|
* @return
|
*/
|
public static final String getAppSign(List<KeyValue<String, String>> params, String wxApiKey){
|
return getSign(params, wxApiKey, false);
|
}
|
|
public static final String getPackageSign(List<KeyValue<String, String>> params, String wxApiKey){
|
return getSign(params, wxApiKey, true);
|
}
|
|
public static final String getSign(List<KeyValue<String, String>> params, String wxApiKey, boolean upperCase){
|
StringBuilder sb = new StringBuilder();
|
for (int i = 0; i < params.size(); i++) {
|
sb.append(params.get(i).getKey());
|
sb.append(StringUtils.CHAR_EQUALS);
|
sb.append(params.get(i).getValue());
|
sb.append(StringUtils.CHAR_AND);
|
}
|
sb.append("key=");
|
sb.append(wxApiKey);
|
logger.debug("sign = {}", sb);
|
|
String packageSign;
|
try {
|
if(upperCase){
|
packageSign = MD5.getMessageDigest(sb.toString().getBytes(StringUtils.DEFAULT_CHARSET_UTF8)).toUpperCase();
|
} else {
|
packageSign = MD5.getMessageDigest(sb.toString().getBytes(StringUtils.DEFAULT_CHARSET_UTF8));
|
}
|
// logger.debug("摘要信息:" + packageSign);
|
// String result = new String(packageSign.toString().getBytes(), "utf-8");
|
// logger.debug("第二次转:" + result);
|
// return result;
|
return packageSign;
|
|
} catch (UnsupportedEncodingException e) {
|
e.printStackTrace();
|
throw new RuntimeException("签名不支持的字符集utf8");
|
}
|
}
|
|
/**
|
* 获取sign
|
* @param map 待签名数据
|
* @param signKey 微信签名key
|
* @return String
|
*/
|
public static String getSign(Map<String, String> map, String signKey) throws Exception{
|
// map排序
|
Set<String> keySet = map.keySet();
|
String[] keyArray = keySet.toArray(new String[keySet.size()]);
|
Arrays.sort(keyArray);
|
StringBuilder sb = new StringBuilder();
|
for (String k : keyArray) {
|
if (k.equals(MD5.NAME_SIGN_2)) {
|
continue;
|
}
|
if (StringUtils.isNotEmpty(map.get(k)) && map.get(k).trim().length() > 0) // 参数值为空,则不参与签名
|
sb.append(k).append(StringUtils.CHAR_EQUALS).append(map.get(k).trim()).append(StringUtils.CHAR_AND);
|
}
|
sb.append("key=").append(signKey);
|
// String sign = SecureUtil.md5(sb.toString()).toUpperCase();
|
String sign = MD5.getMessageDigest(sb.toString().getBytes(StringUtils.DEFAULT_CHARSET_UTF8)).toUpperCase();
|
// System.out.println("sign ========== " + sign);
|
return sign;
|
}
|
|
}
|