1、最近需要做微信支付、看了微信官方的文档需要他们的sdk、里面东西很多看起来也很复杂、网上有很多但是都不能完全跑通、结合网上的东西自己整合了一套完全可以跑通的
2、核心文件、WxPayConfig里面存放微信配置信息
public class WxPayConfig {
//小程序appid
public static final String appid = "";
//微信支付的商户id
public static final String mch_id = "";
//微信支付的商户密钥
public static final String key = "";
//微信小程序秘钥
public static final String secret = "";
//支付成功后的服务器回调url
public static final String notify_url = "http://localhost:8090/weixin/wxNotify";
//签名方式
public static final String SIGNTYPE = "MD5";
//交易类型
public static final String TRADETYPE = "JSAPI";
//微信统一下单接口地址
public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
}
3、WxPayUtil 这是微信支付最核心的文件、加密、xml转map等方法
package com.qqph.financial_center.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qqph.financial_center.config.WxPayConfig;
import org.apache.commons.codec.digest.DigestUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.springframework.util.StringUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author renShuai
* @create 2020/3/31
**/
public class WxPayUtil {
/**
* 签名字符串
*
* @param text 需要签名的字符串
* @param key 秘钥
* @param input_charset 字符集编码
* @return 签名结果
*/
public static String sign(String text, String key, String input_charset) {
text = text + "&key=" + key;
return DigestUtils.md5Hex(getContentBytes(text, input_charset));
}
/**
* @param content
* @param charset
* @return
*/
public static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不多,目前指定的编码集是:" + charset);
}
}
/**
* 生成随机数 codeLength(位数)
*
* @param codeLength
* @return
*/
public static String createCode(int codeLength) {
String code = "";
for (int i = 0; i < codeLength; i++) {
code += (int) (Math.random() * 9);
}
return code;
}
private static boolean isValidChar(Character ch) {
if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
return true;
if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f))
return true;// 简体中文汉字编码
return false;
}
/**
* 除去数组中空值或者签名参数
*
* @param sArray 签名参数组
* @return
*/
public static Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
return result;
}
/**
* 将数组所有元素排序、并按照“参数=参数值”的模式用“&”字符拼接字符串
*
* @param params
* @return
*/
public static String createLinkString(Map<String, String> params) {
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
String prestr = "";
for (int i = 0; i < keys.size(); i++)