小程序微信支付工具类(新手无需看懂,CV就行)
package myst.yynz.back.util;
import org.apache.commons.codec.digest.DigestUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SignatureException;
import java.util.*;
public class PayUtil {
public static String sign(String text, String key, String input_charset) {
text = text + "&key="+key;
return DigestUtils.md5Hex(getContentBytes(text, input_charset));
}
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);
}
}
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(char 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;
}
public static Map paraFilter(Map <String,String> sArray) {
Map 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;
}
public static String createLinkString(Map <String,String> params) {
List <String> keys = new ArrayList <String> (params.keySet());
Collections.sort(keys);
String preStr = "";
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
if (i == keys.size() - 1) {
preStr = preStr + key + "=" + value;
} else {
preStr = preStr + key + "=" + value + "&";
}
}
return preStr;
}
public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
StringBuffer buffer=null;
try{
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(requestMethod);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();
if(null !=outputStr){
OutputStream os=conn.getOutputStream();
os.write(outputStr.getBytes("utf-8"));
os.close();
}
InputStream is = conn.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
buffer = new StringBuffer();
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line);
}
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
public static String urlEncodeUTF8(String source){
String result=source;
try {
result=java.net.URLEncoder.encode(source, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
public static InputStream String2Inputstream(String strxml) throws IOException {
return new ByteArrayInputStream(strxml.getBytes("UTF-8"));
}
public static Map doXMLParse(String strxml) throws Exception {
Map<String, String> map = new HashMap<String, String>();
if(null == strxml || "".equals(strxml)) {
return null;
}
InputStream in = String2Inputstream(strxml);
SAXReader read = new SAXReader();
Document doc = read.read(in);
Element root = doc.getRootElement();
@SuppressWarnings("unchecked")
List<Element> list = root.elements();
for (Element element : list) {
map.put(element.getName(), element.getText());
}
in.close();
return map;
}
public static String GetMapToXML(Map<String,String> param){
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
for (Map.Entry<String,String> entry : param.entrySet()) {
sb.append("<"+ entry.getKey() +">");
sb.append(entry.getValue());
sb.append("</"+ entry.getKey() +">");
}
sb.append("</xml>");
return sb.toString();
}
}
常量类(主要存放微信小程序的相关参数)
package myst.yynz.back.util;
public class Constants {
public static final String MCH_ID = "**********";
public static final String key = "**********";
public static final String appID = "**********";
public static final String secret = "";
public static final String REFUND_PATH = "https://api.mch.weixin.qq.com/secapi/pay/refund";
public static final String CERT_PATH = "/Users/cheyuhang/Desktop/********";
public static final String CODE_SUCCESS = "000";
public static final String CODE_ERROR = "999";
public static final String MSG_NULL = "无效的订单";
public static final String MSG_01 = "签名错误";
public static final String REFUND_SUCCESS = "退款成功!";
}
具体业务逻辑实现
package myst.yynz.back.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import myst.yynz.back.bean.Msg;
import myst.yynz.back.log.Operation;
import myst.yynz.back.util.Constants;
import myst.yynz.back.util.PayUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
@Controller
@Api(tags = "微信支付退款")
@RequestMapping(value = "/pay")
public class WxPayController {
private static final Logger LOGGER = Logger.getLogger(WxPayController.class);
private int socketTimeout = 10000;
private int connectTimeout = 30000;
private static RequestConfig requestConfig;
private static CloseableHttpClient httpClient;
@ApiOperation(value = "查看所有商品评价进行分页展示")
@CrossOrigin(allowCredentials = "true")
@GetMapping(value="/refund")
@Operation
@ResponseBody
public Msg refund() throws Exception {
Map<String, String> data = new HashMap<>();
String nonce_str = getRandomStringByLength(32);
data.put("appid", Constants.appID);
data.put("mch_id", Constants.MCH_ID);
data.put("nonce_str", nonce_str);
data.put("sign_type", "MD5");
data.put("out_trade_no","SHOPZDJ1626244934861ogym" );
data.put("out_refund_no", getRandomStringByLength(20));
Math.round(0.01 * 100);
data.put("total_fee",String.valueOf(Math.round(0.01 * 100)));
data.put("refund_fee", String.valueOf(Math.round(0.01 * 100)));
String preStr = PayUtil.createLinkString(data);
String mySign = PayUtil.sign(preStr, Constants.key, "utf-8").toUpperCase();
data.put("sign",mySign);
String xmlStr = postData(Constants.REFUND_PATH, PayUtil.GetMapToXML(data));
System.out.println(xmlStr);
Map notifyMap = PayUtil.doXMLParse(xmlStr);
return Msg.success().add("data",notifyMap);
}
private String getRandomStringByLength(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
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();
}
private static void initCert() throws Exception {
String key = Constants.MCH_ID;
String path = Constants.CERT_PATH;
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File(path));
try {
keyStore.load(instream, key.toCharArray());
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
public String postData(String url, String xmlObj) {
try {
initCert();
} catch (Exception e) {
e.printStackTrace();
}
String result = null;
HttpPost httpPost = new HttpPost(url);
StringEntity postEntity = new StringEntity(xmlObj, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
requestConfig = RequestConfig.custom()
.setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout)
.build();
httpPost.setConfig(requestConfig);
try {
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
try {
result = EntityUtils.toString(entity, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
}
} finally {
httpPost.abort();
}
return result;
}
}