主类
public class WechatPay {
@Value("${wechat.appid}")
private String appid;
@Value("${wechat.appsecret}")
private String appsecret;
@Value("${wechat.merchid}")
private String merchid;
@Value("${wechat.paysecret}")
private String paysecret;
@Value("${wechat.notifyurl}")
private String notifyurl;
public Map<String, String> pay(String openid, String ordersn, BigDecimal totalFee, String body, String ip)
{
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
Map<String, String> payData = new HashMap<String, String>();
String nonceStr = ToolUtils.getRandomStr();
payData.put("appid", appid);
payData.put("mch_id", merchid);
payData.put("nonce_str", nonceStr);
payData.put("body", body);
payData.put("out_trade_no", ordersn);
payData.put("total_fee", totalFee.toBigInteger().toString()); // 单位分
payData.put("spbill_create_ip", ip);
payData.put("notify_url", notifyurl);
payData.put("trade_type", "JSAPI");
payData.put("openid", openid);
// 把所有元素,按照参数=参数值并用&拼接成url参数模式
String param = ToolUtils.createLink(payData);
//System.out.println(param);
//生成签名
String signature = ToolUtils.makeSign(param, paysecret);
payData.put("sign", signature);
//System.out.println(signature);
//将类型为map的参数转换为xml
String xml = formatXml(payData);
System.out.println(xml);
// 发送请求
Map<String, String> res = HttpTools.doHttpPost(url, xml);
if (null != res && res.get("return_code").equals("SUCCESS")) {
Map<String, String> responseData = new HashMap<String, String>();
responseData.put("appId", appid);
responseData.put("nonceStr", res.get("nonce_str"));
responseData.put("package", "prepay_id=" + res.get("prepay_id"));
responseData.put("signType", "MD5");
String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
responseData.put("timeStamp", timeStamp);
String responseDataParam = ToolUtils.createLink(responseData);
String paysign = ToolUtils.makeSign(responseDataParam, paysecret);
responseData.put("paysign", paysign);
return responseData;
}
return null;
}
private String formatXml(Map<String, String> payData) {
String format = "<xml>\n" + "<appid><![CDATA[%1$s]]></appid>\n"
+ "<mch_id><![CDATA[%2$s]]></mch_id>\n"
+ "<body>%3$s</body>\n"
+ "<nonce_str><![CDATA[%4$s]]></nonce_str>\n"
+ "<notify_url>%5$s</notify_url>\n"
+ "<openid>%6$s</openid>\n"
+ "<out_trade_no>%7$s</out_trade_no>\n"
+ "<spbill_create_ip>%8$s</spbill_create_ip>\n"
+ "<total_fee>%9$s</total_fee>\n"
+ "<trade_type>%10$s</trade_type>\n"
+ "<sign><![CDATA[%11$s]]></sign>\n"
+ "</xml>";
return String.format(
format,
payData.get("appid"),
payData.get("mch_id"),
payData.get("body"),
payData.get("nonce_str"),
payData.get("notify_url"),
payData.get("openid"),
payData.get("out_trade_no"),
payData.get("spbill_create_ip"),
payData.get("total_fee"),
payData.get("trade_type"),
payData.get("sign")
);
}
}
这里注意
1:小程序支付package格式是 package: prepay_id=xxxxxxxxx
2: 小程序sign签名是
paySign = MD5(appId=wxd678efh567hg6787&nonceStr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&package=prepay_id=wx2017033010242291fcfe0db70013231072&signType=MD5&timeStamp=1490840662&key=qazwsxedcrfvtgbyhnujmikolp111111) = 22D9B4E54AB1950F51E0649E8810ACD6
辅助类
public static String createLink(Map<String, String> payData)
{
List<String> keys = new ArrayList<String>(payData.keySet());
Collections.sort(keys);
StringBuffer param = new StringBuffer();
for (int i = 0; i< keys.size(); i++) {
String key = keys.get(i);
String value = payData.get(key);
if (i == keys.size() - 1) {
param.append(key).append("=").append(value);
} else {
param.append(key).append("=").append(value).append("&");
}
}
return param.toString();
}
public static Map<String, String> parseXml(String strxml)
{
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(strxml);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
NodeList children = root.getChildNodes();
Map<String, String> res = new HashMap<String, String>();
for (int i = 0; i < children.getLength(); i++) {
System.out.println(children.item(i).getNodeName());
res.put(children.item(i).getNodeName(), children.item(i).getFirstChild().getNodeValue());
}
return res;
} catch (IOException | SAXException | ParserConfigurationException e) {
e.printStackTrace();
return null;
}
}
public static String makeSign(String param, String paysecret)
{
param = param.concat("&key=").concat(paysecret);
return DigestUtils.md5DigestAsHex(param.getBytes()).toUpperCase();
//return ToolUtils.md5(param).toUpperCase();
}
http类
public class HttpTools {
public static JSONObject doHttpGet(String url) {
try {
URL urlObj = new URL(url);
HttpURLConnection connection = (HttpURLConnection)urlObj.openConnection();
connection.setRequestMethod("GET");
Integer resultCode = connection.getResponseCode();
if (resultCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer response = new StringBuffer();
String inputLine;
while((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
return new JSONObject(response.toString());
}
return null;
} catch(MalformedURLException ex) {
return null;
} catch(IOException ex) {
return null;
} catch (JSONException e) {
return null;
}
}
public static JSONObject doHttpPost(String url, Map<String, String> params) {
try {
URL urlObj = new URL(url);
HttpURLConnection connection = (HttpURLConnection)urlObj.openConnection();
connection.setRequestMethod("POST");
if (null != params) {
StringBuffer param = new StringBuffer();
Set<String> keySet = params.keySet();
for(String key : keySet) {
param.append(key).append("=").append(params.get(key)).append("&");
}
String finalParam = param.substring(0, param.length() - 1);
OutputStream outputStream = connection.getOutputStream();
outputStream.write(finalParam.getBytes("utf-8"));
outputStream.flush();
outputStream.close();
}
Integer resultCode = connection.getResponseCode();
if (resultCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
StringBuffer response = new StringBuffer();
String inputLine;
while((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
return new JSONObject(response.toString());
}
return null;
} catch(MalformedURLException ex) {
return null;
} catch(IOException ex) {
return null;
} catch (JSONException e) {
return null;
}
}
public static Map<String, String> doHttpPost(String url, String params) {
try {
URL urlObj = new URL(url);
HttpURLConnection connection = (HttpURLConnection)urlObj.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
if (null != params) {
OutputStream outputStream = connection.getOutputStream();
outputStream.write(params.getBytes("utf-8"));
outputStream.flush();
outputStream.close();
}
Integer resultCode = connection.getResponseCode();
if (resultCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
StringBuffer response = new StringBuffer();
String inputLine;
while((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
System.out.println(response);
Map<String, String> res = ToolUtils.parseXml(response.toString());
return res;
}
return null;
} catch(MalformedURLException ex) {
return null;
} catch(IOException ex) {
return null;
}
}
}