package com.hzbuvi.pay.wechat.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzbuvi.pay.wechat.utils.HttpRequest;
import com.hzbuvi.pay.wechat.utils.PayCommonUtil;
import com.hzbuvi.pay.wechat.utils.WechatUtils;
import com.hzbuvi.pay.wechat.utils.XmlUtils;
import com.hzbuvi.util.basic.ValueUtil;
import com.hzbuvi.util.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* Created by SJQ on 2017/2/17.
*/
@RestController
@RequestMapping("/wechat")
public class WechatPay
{
private static final Logger log = LoggerFactory.getLogger(WechatPay.class);
private static String APPID = "wx29983132bd04dca9";
private static String MCHID= "1435678702";
private static String KEY= "eidiwoeid483";
private static String BODY= "order pay";
private static String out_trade_no= DateUtil.toString(new Date(),"yyyyMMddHHmmss");
private static String product_id= DateUtil.toString(new Date(),"yyyyMMddHHmmss")+1;
private static String notify_url= "http://88.88.88.211:8095/backUrl/wechatPay";
@RequestMapping(value = "/pay",method = RequestMethod.GET)
public String pay(@RequestParam Map<String,String> params){
JSONObject retJson = new JSONObject();
try {
String jsonStr = ValueUtil.toJson(params);
JSONObject requestObj = JSON.parseObject(jsonStr);
String order_price = "1";
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid", APPID);
packageParams.put("mch_id", MCHID);
packageParams.put("nonce_str", WechatUtils.getNonce_str());
packageParams.put("body",new String(BODY.getBytes("utf-8")) );
packageParams.put("trade_type", "NATIVE");
packageParams.put("spbill_create_ip", "123.12.12.123");
packageParams.put("notify_url", notify_url);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("total_fee", order_price);
packageParams.put("product_id", product_id);
Calendar nowTime = Calendar.getInstance();
packageParams.put("time_start", DateUtil.toString(
nowTime.getTime(), "yyyyMMddHHmmss"));
String sign = PayCommonUtil.createSign("UTF-8", packageParams, KEY);
packageParams.put("sign", sign);
String requestXML = PayCommonUtil.getRequestXml(packageParams);
log.info("支付请求:" + requestXML);
long startTime=System.currentTimeMillis();
String resXml = HttpRequest.post(
"https://api.mch.weixin.qq.com/pay/unifiedorder",
requestXML);
log.info("请求结果:" + resXml);
long endTime=System.currentTimeMillis();
Integer execute_time = (int) ((endTime-startTime)/1000);
SortedMap map = XmlUtils.parseXmlStr(resXml);
Boolean validateCallback = PayCommonUtil.isTenpaySign("utf-8",map,KEY);
log.info("验证返回签名结果:" + validateCallback);
if (!validateCallback){
return ValueUtil.toError("999","回掉签名验证失败");
}
JSONObject reportParams = new JSONObject();
reportParams.put("url", "https://api.mch.weixin.qq.com/pay/unifiedorder");
reportParams.put("execute_time", execute_time);
reportParams.put("return_code", map.get("return_code").toString());
reportParams.put("return_msg", map.get("return_msg").toString());
reportParams.put("result_code", map.get("result_code").toString());
if (map.get("err_code") != null) {
reportParams.put("err_code", map.get("err_code").toString());
reportParams.put("err_code_des", map.get("err_code_des").toString());
}
reportParams.put("out_trade_no", out_trade_no);
if (map.get("return_code").toString().equals("SUCCESS") && map.get("result_code").toString().equals("SUCCESS")) {
String urlCode = (String) map.get("code_url");
retJson.put("code", 0);
retJson.put("message", "下单成功.");
retJson.put("data", urlCode);
} else {
retJson.put("code", 1);
retJson.put("message", map.get("err_code_des").toString());
retJson.put("data", "");
}
return retJson.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.hzbuvi.pay.wechat.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.ProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by SJQ on 2017/2/17.
*/
public class PayCommonUtil {
public static Logger log = LoggerFactory.getLogger(PayCommonUtil.class);
/**
* 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
* @return boolean
*/
public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
String v = (String)entry.getValue();
if(!"sign".equals(k) && null != v && !"".equals(v)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
String mysign = MD5.MD5Encode(sb.toString()).toLowerCase();
String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();
return tenpaySign.equals(mysign);
}
/**
* @author
* @date 2016-4-22
* @Description:sign签名
* @param characterEncoding
* 编码格式
* @params parameters
* 请求参数
* @return
*/
public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
StringBuffer sb = new StringBuffer();
Set es = packageParams.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = "";
try {
v = (String) entry.getValue();
} catch (Exception e) {
v = entry.getValue() + "";
}
if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + API_KEY);
System.out.println("ASCII字典序排序::::"+sb.toString());
String sign = MD5.MD5Encode(sb.toString()).toUpperCase();
return sign;
}
/**
* @author
* @date 2016-4-22
* @Description:将请求参数转换为xml格式的string
* @param parameters
* 请求参数
* @return
*/
public static String getRequestXml(SortedMap<Object, Object> parameters) {
StringBuffer sb = new StringBuffer();
sb.append("<xml>");
Set es = parameters.entrySet();
Iterator it = es.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String k = (String) entry.getKey();
String v = "";
try {
v = (String) entry.getValue();
} catch (Exception e) {
v = entry.getValue() + "";
}
if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
} else {
sb.append("<" + k + ">" + v + "</" + k + ">");
}
}
sb.append("</xml>");
return sb.toString();
}
/**
* 取出一个指定长度大小的随机正整数.
*
* @param length
* int 设定所取出随机数的长度。length小于11
* @return int 返回生成的随机数。
*/
public static int buildRandom(int length) {
int num = 1;
double random = Math.random();
if (random < 0.1) {
random = random + 0.1;
}
for (int i = 0; i < length; i++) {
num = num * 10;
}
return (int) ((random * num));
}
/**
* 获取当前时间 yyyyMMddHHmmss
*
* @return String
*/
public static String getCurrTime() {
Date now = new Date();
SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String s = outFormat.format(now);
return s;
}
public static JSONObject httpsRequestToJsonObject(String requestUrl,
String requestMethod, String outputStr) {
JSONObject jsonObject = null;
try {
StringBuffer buffer = httpsRequest(requestUrl, requestMethod,
outputStr);
jsonObject = JSON.parseObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:" + ce.getMessage());
} catch (Exception e) {
log.error("https请求异常:" + e.getMessage());
}
return jsonObject;
}
private static StringBuffer httpsRequest(String requestUrl,
String requestMethod, String output)
throws NoSuchAlgorithmException, NoSuchProviderException,
KeyManagementException, MalformedURLException, IOException,
ProtocolException, UnsupportedEncodingException {
URL url = new URL(requestUrl);
HttpsURLConnection connection = (HttpsURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod(requestMethod);
if (null != output) {
OutputStream outputStream = connection.getOutputStream();
outputStream.write(output.getBytes("UTF-8"));
outputStream.close();
}
InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
connection.disconnect();
return buffer;
}
}
package com.hzbuvi.pay.wechat.utils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.util.*;
import static javax.swing.text.html.HTML.Tag.BODY;
import static javax.swing.text.html.HTML.Tag.HEAD;
/**
* Created by SJQ on 2017/2/17.
*/
public class XmlUtils {
/**
* 解析XML字符串
*
* @param xml
* @return
* @throws
*/
public static SortedMap<String,Object> parseXmlStr(String xml){
SortedMap<String,Object> map = new TreeMap<String, Object>();
try {
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
Iterator<Element> it = root.elementIterator();
while (it.hasNext()) {
Element element = it.next();
map.put(element.getName(), element.getTextTrim());
}
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
}
package com.hzbuvi.pay.wechat.utils;
import java.security.MessageDigest;
/**
* User: rizenguo
* Date: 2014/10/23
* Time: 15:43
*/
public class MD5 {
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "a", "b", "c", "d", "e", "f"};
/**
* 转换字节数组为16进制字串
* @param b 字节数组
* @return 16进制字串
*/
public static String byteArrayToHexString(byte[] digest) {
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
int val = ((int) digest[i]) & 0xff;
if (val < 16)
hexValue.append("0");
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
/**
* 转换byte到16进制
* @param b 要转换的byte
* @return 16进制格式
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0) {
n = 256 + n;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* MD5编码
* @param origin 原始字符串
* @return 经过MD5加密之后的结果
*/
public static String MD5Encode(String origin) {
String resultString = null;
try {
resultString = origin;
MessageDigest md = MessageDigest.getInstance("MD5");
resultString = byteArrayToHexString(md.digest(resultString.getBytes("utf-8")));
} catch (Exception e) {
e.printStackTrace();
}
return resultString;
}
}
package com.hzbuvi.pay.wechat.utils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
/**
* Created by SJQ on 2017/2/17.
*/
public class HttpRequest {
public static String post(String url,String pama) throws IOException{
URL postUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
connection.setDoOutput(true);
connection.setConnectTimeout(10000);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.connect();
DataOutputStream out = new DataOutputStream(connection
.getOutputStream());
out.writeBytes(pama);
out.flush();
out.close();
int status = connection.getResponseCode();
if(status==200){
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
String line;
StringBuffer sb = new StringBuffer("");
while ((line = reader.readLine()) != null){
line = new String(line);
sb.append(line);
}
reader.close();
connection.disconnect();
if(sb.toString().length()>0){
return sb.toString();
}
return String.valueOf(status);
}
return String.valueOf(status);
}
}