主要代碼以下:java
GlobalConfig.javaweb
1 public class GlobalConfig { 2 3 public GlobalConfig() { 4 } 5 6 public static final String APPID = ""; 7 public static final String APPSECRET = ""; // appsecret 8 public static final String MCH_ID = ""; // 商業號 9 public static final String KEY = ""; // key 10 public static final String URL = ""; //回調地址 11 12 public static final String TRADE_TYPE = "NATIVE"; 13 }
微信支付服務器簽名支付請求請求類 RequestHandler.javaspring
1 public class RequestHandler { 2 /** Token獲取網關地址地址 */ 3 private String tokenUrl; 4 /** 預支付網關url地址 */ 5 private String gateUrl; 6 /** 查詢支付通知網關URL */ 7 private String notifyUrl; 8 /** 商戶參數 */ 9 private String appid; 10 private String appkey; 11 private String partnerkey; 12 private String appsecret; 13 private String key; 14 /** 請求的參數 */ 15 private SortedMap parameters; 16 /** Token */ 17 private String Token; 18 private String charset; 19 /** debug信息 */ 20 private String debugInfo; 21 private String last_errcode; 22 23 private HttpServletRequest request; 24 25 private HttpServletResponse response; 26 27 /** 28 * 初始構造函數。 29 * 30 * @return 31 */ 32 public RequestHandler(HttpServletRequest request, HttpServletResponse response) { 33 this.last_errcode = "0"; 34 this.request = request; 35 this.response = response; 36 // this.charset = "GBK"; 37 this.charset = "UTF-8"; 38 this.parameters = new TreeMap(); 39 // 驗證notify支付訂單網關 40 notifyUrl = "http://gw.tenpay.com/gateway/simpleverifynotifyid.xml"; 41 42 } 43 44 /** 45 * 初始化函數。 46 */ 47 public void init(String app_id, String app_secret, String partner_key) { 48 this.last_errcode = "0"; 49 this.Token = "token_"; 50 this.debugInfo = ""; 51 this.appid = app_id; 52 this.partnerkey = partner_key; 53 this.appsecret = app_secret; 54 this.key = partner_key; 55 } 56 57 public void init() { 58 } 59 60 /** 61 * 獲取最後錯誤號 62 */ 63 public String getLasterrCode() { 64 return last_errcode; 65 } 66 67 /** 68 * 獲取入口地址,不包含參數值 69 */ 70 public String getGateUrl() { 71 return gateUrl; 72 } 73 74 /** 75 * 獲取參數值 76 * 77 * @param parameter 78 * 參數名稱 79 * @return String 80 */ 81 public String getParameter(String parameter) { 82 String s = (String) this.parameters.get(parameter); 83 return (null == s) ? "" : s; 84 } 85 86 // 設置密鑰 87 88 public void setKey(String key) { 89 this.partnerkey = key; 90 } 91 92 // 設置微信密鑰 93 public void setAppKey(String key) { 94 this.appkey = key; 95 } 96 97 // 特殊字符處理 98 public String UrlEncode(String src) throws UnsupportedEncodingException { 99 return URLEncoder.encode(src, this.charset).replace("+", "%20"); 100 } 101 102 // 獲取package的簽名包 103 public String genPackage(SortedMap<String, String> packageParams) throws UnsupportedEncodingException { 104 String sign = createSign(packageParams); 105 106 StringBuffer sb = new StringBuffer(); 107 Set es = packageParams.entrySet(); 108 Iterator it = es.iterator(); 109 while (it.hasNext()) { 110 Map.Entry entry = (Map.Entry) it.next(); 111 String k = (String) entry.getKey(); 112 String v = (String) entry.getValue(); 113 sb.append(k + "=" + UrlEncode(v) + "&"); 114 } 115 116 // 去掉最後一個& 117 String packageValue = sb.append("sign=" + sign).toString(); 118 // System.out.println("UrlEncode後 packageValue=" + packageValue); 119 return packageValue; 120 } 121 122 /** 123 * 建立md5摘要,規則是:按參數名稱a-z排序,遇到空值的參數不參加簽名。 124 */ 125 public String createSign(SortedMap<String, String> packageParams) { 126 StringBuffer sb = new StringBuffer(); 127 Set es = packageParams.entrySet(); 128 Iterator it = es.iterator(); 129 while (it.hasNext()) { 130 Map.Entry entry = (Map.Entry) it.next(); 131 String k = (String) entry.getKey(); 132 String v = (String) entry.getValue(); 133 if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { 134 sb.append(k + "=" + v + "&"); 135 } 136 } 137 sb.append("key=" + this.getKey()); 138 // System.out.println("md5 sb:" + sb); 139 String sign = MD5Util.MD5Encode(sb.toString(), this.charset).toUpperCase(); 140 // System.out.println("packge簽名:" + sign); 141 return sign; 142 143 } 144 145 /** 146 * 建立package簽名 147 */ 148 public boolean createMd5Sign(String signParams) { 149 StringBuffer sb = new StringBuffer(); 150 Set es = this.parameters.entrySet(); 151 Iterator it = es.iterator(); 152 while (it.hasNext()) { 153 Map.Entry entry = (Map.Entry) it.next(); 154 String k = (String) entry.getKey(); 155 String v = (String) entry.getValue(); 156 if (!"sign".equals(k) && null != v && !"".equals(v)) { 157 sb.append(k + "=" + v + "&"); 158 } 159 } 160 161 // 算出摘要 162 String enc = TenpayUtil.getCharacterEncoding(this.request, this.response); 163 String sign = MD5Util.MD5Encode(sb.toString(), enc).toLowerCase(); 164 165 String tenpaySign = this.getParameter("sign").toLowerCase(); 166 167 // debug信息 168 this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:" + tenpaySign); 169 170 return tenpaySign.equals(sign); 171 } 172 173 // 輸出XML 174 public String parseXML() { 175 StringBuffer sb = new StringBuffer(); 176 sb.append("<xml>"); 177 Set es = this.parameters.entrySet(); 178 Iterator it = es.iterator(); 179 while (it.hasNext()) { 180 Map.Entry entry = (Map.Entry) it.next(); 181 String k = (String) entry.getKey(); 182 String v = (String) entry.getValue(); 183 if (null != v && !"".equals(v) && !"appkey".equals(k)) { 184 185 sb.append("<" + k + ">" + getParameter(k) + "</" + k + ">\n"); 186 } 187 } 188 sb.append("</xml>"); 189 return sb.toString(); 190 } 191 192 /** 193 * 設置debug信息 194 */ 195 protected void setDebugInfo(String debugInfo) { 196 this.debugInfo = debugInfo; 197 } 198 199 public void setPartnerkey(String partnerkey) { 200 this.partnerkey = partnerkey; 201 } 202 203 public String getDebugInfo() { 204 return debugInfo; 205 } 206 207 public String getKey() { 208 return key; 209 }
處理類繼承此類 ResponseHandler.javaapache
1 import java.io.BufferedReader; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.PrintWriter; 6 import java.io.UnsupportedEncodingException; 7 import java.util.HashMap; 8 import java.util.Iterator; 9 import java.util.Map; 10 import java.util.Set; 11 import java.util.SortedMap; 12 import java.util.TreeMap; 13 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 17 import org.jdom.JDOMException; 18 19 import com.wjf.dxsv.pay.wechatpay.util.MD5Util; 20 import com.wjf.dxsv.pay.wechatpay.util.TenpayUtil; 21 import com.wjf.dxsv.pay.wechatpay.util.XMLUtil; 22 23 /** 24 * 應答處理類 應答處理類繼承此類,重寫isTenpaySign方法便可。 25 * 26 * @author miklchen 27 * 28 */ 29 public class ResponseHandler { 30 31 /** 密鑰 */ 32 private String key; 33 34 /** 應答的參數 */ 35 private SortedMap parameters; 36 37 /** debug信息 */ 38 private String debugInfo; 39 40 private HttpServletRequest request; 41 42 private HttpServletResponse response; 43 44 private String uriEncoding; 45 46 /** 47 * 構造函數 48 * 49 * @param request 50 * @param response 51 */ 52 public ResponseHandler(HttpServletRequest request, HttpServletResponse response) throws IOException, JDOMException { 53 this.request = request; 54 this.response = response; 55 56 this.key = ""; 57 this.parameters = new TreeMap(); 58 this.debugInfo = ""; 59 60 this.uriEncoding = ""; 61 62 // Map m = this.request.getParameterMap(); 63 InputStream inputStream; 64 StringBuffer sb = new StringBuffer(); 65 inputStream = request.getInputStream(); 66 String s; 67 BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 68 while ((s = in.readLine()) != null) { 69 sb.append(s); 70 } 71 in.close(); 72 inputStream.close(); 73 74 Map<String, String> m = new HashMap<String, String>(); 75 m = XMLUtil.doXMLParse(sb.toString()); 76 77 Iterator it = m.keySet().iterator(); 78 while (it.hasNext()) { 79 String k = (String) it.next(); 80 String v = m.get(k); 81 this.setParameter(k, v); 82 } 83 84 } 85 86 /** 87 * 獲取密鑰 88 */ 89 public String getKey() { 90 return key; 91 } 92 93 /** 94 * 設置密鑰 95 */ 96 public void setKey(String key) { 97 this.key = key; 98 } 99 100 /** 101 * 獲取參數值 102 * 103 * @param parameter 104 * 參數名稱 105 * @return String 106 */ 107 public String getParameter(String parameter) { 108 String s = (String) this.parameters.get(parameter); 109 return (null == s) ? "" : s; 110 } 111 112 /** 113 * 設置參數值 114 * 115 * @param parameter 116 * 參數名稱 117 * @param parameterValue 118 * 參數值 119 */ 120 public void setParameter(String parameter, String parameterValue) { 121 String v = ""; 122 if (null != parameterValue) { 123 v = parameterValue.trim(); 124 } 125 this.parameters.put(parameter, v); 126 } 127 128 /** 129 * 返回全部的參數 130 * 131 * @return SortedMap 132 */ 133 public SortedMap getAllParameters() { 134 return this.parameters; 135 } 136 137 /** 138 * 是否簽名正確,規則是:按參數名稱a-z排序,遇到空值的參數不參加簽名。 139 * 140 * @return boolean 141 */ 142 public boolean isTenpaySign() { 143 StringBuffer sb = new StringBuffer(); 144 Set es = this.parameters.entrySet(); 145 Iterator it = es.iterator(); 146 while (it.hasNext()) { 147 Map.Entry entry = (Map.Entry) it.next(); 148 String k = (String) entry.getKey(); 149 String v = (String) entry.getValue(); 150 if (!"sign".equals(k) && null != v && !"".equals(v)) { 151 sb.append(k + "=" + v + "&"); 152 } 153 } 154 155 sb.append("key=" + this.getKey()); 156 157 // 算出摘要 158 String enc = TenpayUtil.getCharacterEncoding(this.request, this.response); 159 String sign = MD5Util.MD5Encode(sb.toString(), enc).toLowerCase(); 160 161 String tenpaySign = this.getParameter("sign").toLowerCase(); 162 163 // debug信息 164 this.setDebugInfo(sb.toString() + " => sign:" + sign + " tenpaySign:" + tenpaySign); 165 166 System.out.println(tenpaySign + " " + sign); 167 return tenpaySign.equals(sign); 168 } 169 170 /** 171 * 返回處理結果給財付通服務器。 172 * 173 * @param msg: 174 * Success or fail。 175 * @throws IOException 176 */ 177 public void sendToCFT(String msg) throws IOException { 178 String strHtml = msg; 179 PrintWriter out = this.getHttpServletResponse().getWriter(); 180 out.println(strHtml); 181 out.flush(); 182 out.close(); 183 } 184 185 /** 186 * 獲取uri編碼 187 * 188 * @return String 189 */ 190 public String getUriEncoding() { 191 return uriEncoding; 192 } 193 194 /** 195 * 設置uri編碼 196 * 197 * @param uriEncoding 198 * @throws UnsupportedEncodingException 199 */ 200 public void setUriEncoding(String uriEncoding) throws UnsupportedEncodingException { 201 if (!"".equals(uriEncoding.trim())) { 202 this.uriEncoding = uriEncoding; 203 204 // 編碼轉換 205 String enc = TenpayUtil.getCharacterEncoding(request, response); 206 Iterator it = this.parameters.keySet().iterator(); 207 while (it.hasNext()) { 208 String k = (String) it.next(); 209 String v = this.getParameter(k); 210 v = new String(v.getBytes(uriEncoding.trim()), enc); 211 this.setParameter(k, v); 212 } 213 } 214 } 215 216 /** 217 * 獲取debug信息 218 */ 219 public String getDebugInfo() { 220 return debugInfo; 221 } 222 223 /** 224 * 設置debug信息 225 */ 226 protected void setDebugInfo(String debugInfo) { 227 this.debugInfo = debugInfo; 228 } 229 230 protected HttpServletRequest getHttpServletRequest() { 231 return this.request; 232 } 233 234 protected HttpServletResponse getHttpServletResponse() { 235 return this.response; 236 } 237 238 }
處理事物 WechatPayService.javajson
1 import java.io.FileInputStream; 2 import java.io.IOException; 3 import java.security.*; 4 import java.security.cert.CertificateException; 5 import java.util.*; 6 7 import org.apache.http.client.ClientProtocolException; 8 import org.apache.http.client.methods.CloseableHttpResponse; 9 import org.apache.http.client.methods.HttpPost; 10 import org.apache.http.client.params.ClientPNames; 11 import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 12 import org.apache.http.conn.ssl.SSLContexts; 13 import org.apache.http.entity.StringEntity; 14 import org.apache.http.impl.client.CloseableHttpClient; 15 import org.apache.http.impl.client.DefaultHttpClient; 16 import org.apache.http.impl.client.HttpClientBuilder; 17 import org.apache.http.impl.client.HttpClients; 18 import org.apache.http.util.EntityUtils; 19 import org.jdom.JDOMException; 20 21 import com.wjf.dxsv.pay.wechatpay.util.MD5Util; 22 import com.wjf.dxsv.pay.wechatpay.util.XMLUtil; 23 24 import javax.net.ssl.SSLContext; 25 26 public class WechatPayService { 27 28 public static String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 29 public static String url2 = "https://api.mch.weixin.qq.com/secapi/pay/refund"; 30 31 private HttpClientBuilder httpClientBuilder; 32 @SuppressWarnings("unused") 33 private CloseableHttpClient httpClient; 34 private String responseMessage; 35 36 public WechatPayService() { 37 httpClientBuilder = HttpClientBuilder.create(); 38 httpClient = httpClientBuilder.build(); 39 } 40 41 public String getUrlCode(SortedMap<String, String> packageParams) 42 throws ClientProtocolException, IOException, JDOMException { 43 String sign = createSign(packageParams); 44 String xml = "<xml>" + "<appid>" + packageParams.get("appid") + "</appid>" + "<mch_id>" 45 + packageParams.get("mch_id") + "</mch_id>" + "<nonce_str>" + packageParams.get("nonce_str") 46 + "</nonce_str>" + "<sign>" + sign + "</sign>" + "<body><![CDATA[" + packageParams.get("body") 47 + "]]></body>" + "<out_trade_no>" + packageParams.get("out_trade_no") + "</out_trade_no>" 48 + "<total_fee>" + packageParams.get("total_fee") + "</total_fee>" + "<spbill_create_ip>" 49 + packageParams.get("spbill_create_ip") + "</spbill_create_ip>" + "<notify_url>" 50 + packageParams.get("notify_url") + "</notify_url>" + "<trade_type>" + packageParams.get("trade_type") 51 + "</trade_type>" + "</xml>"; 52 53 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); 54 CloseableHttpClient httpClient = httpClientBuilder.build(); 55 HttpPost httpPost = new HttpPost(url); 56 httpPost.setEntity(new StringEntity(xml, "UTF-8")); 57 CloseableHttpResponse response = httpClient.execute(httpPost); 58 responseMessage = EntityUtils.toString(response.getEntity(), "UTF-8"); 59 Map<?, ?> map = XMLUtil.doXMLParse(responseMessage); 60 String codeUrl = map.get("code_url").toString(); 61 response.close(); 62 httpClient.close(); 63 return codeUrl; 64 } 65 66 public Map<String, Object> forRefund(SortedMap<String, String> packageParams) throws KeyStoreException, IOException, 67 UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, CertificateException { 68 String sign = createSign(packageParams); 69 String xml = "<xml>" + "<appid><![CDATA[" + packageParams.get("appid") + "]]></appid>" + "<mch_id><![CDATA[" 70 + packageParams.get("mch_id") + "]]></mch_id>" + "<nonce_str><![CDATA[" + packageParams.get("nonce_str") 71 + "]]></nonce_str>" + "<out_trade_no><![CDATA[" + packageParams.get("out_trade_no") 72 + "]]></out_trade_no>" + "<out_refund_no><![CDATA[" + packageParams.get("out_refund_no") 73 + "]]></out_refund_no>" + "<total_fee><![CDATA[" + packageParams.get("total_fee") + "]]></total_fee>" 74 + "<refund_fee><![CDATA[" + packageParams.get("refund_fee") + "]]></refund_fee>" 75 + "<op_user_id><![CDATA[" + packageParams.get("mch_id") + "]]></op_user_id>" + "<sign>" + sign 76 + "</sign>" + "</xml>"; 77 Map doXMLtoMap = new HashMap(); 78 KeyStore keyStore = KeyStore.getInstance("PKCS12"); 79 String P12_PASSWORD = GlobalConfig.MCH_ID; 80 FileInputStream inputStream = new FileInputStream(System.getProperty("user.dir") + "//src//resources//cert//apiclient_cert.p12"); 81 try { 82 keyStore.load(inputStream, P12_PASSWORD.toCharArray()); 83 } catch (IOException e) { 84 e.printStackTrace(); 85 } catch (NoSuchAlgorithmException e) { 86 e.printStackTrace(); 87 } catch (CertificateException e) { 88 e.printStackTrace(); 89 } finally { 90 inputStream.close(); 91 } 92 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, P12_PASSWORD.toCharArray()).build(); 93 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 94 DefaultHttpClient client = new DefaultHttpClient(); 95 client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); 96 CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); 97 HttpPost httpPost = new HttpPost(url2); 98 99 try { 100 httpPost.setEntity(new StringEntity(xml, "UTF-8")); 101 CloseableHttpResponse response = httpClient.execute(httpPost); 102 System.out.println(response.getEntity()); 103 String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); 104 if (jsonStr.indexOf("FAIL") >= 0) { 105 return null; 106 } 107 doXMLtoMap = XMLUtil.doXMLParse(jsonStr); 108 return doXMLtoMap; 109 } catch (Exception e) { 110 e.printStackTrace(); 111 } finally { 112 httpClient.close(); 113 } 114 return null; 115 } 116 117 public String getResponseMessage() { 118 return responseMessage; 119 } 120 121 /** 122 * 建立md5摘要,規則是:按參數名稱a-z排序,遇到空值的參數不參加簽名。 123 */ 124 public String createSign(SortedMap<String, String> packageParams) { 125 StringBuffer sb = new StringBuffer(); 126 Set es = packageParams.entrySet(); 127 Iterator it = es.iterator(); 128 while (it.hasNext()) { 129 Map.Entry entry = (Map.Entry) it.next(); 130 String k = (String) entry.getKey(); 131 String v = (String) entry.getValue(); 132 if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { 133 sb.append(k + "=" + v + "&"); 134 } 135 } 136 sb.append("key=" + GlobalConfig.KEY); 137 String sign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); 138 return sign; 139 } 140 }
WechatPayController.javaapi
1 import org.json.JSONException; 2 import org.json.JSONObject; 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Controller; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.ResponseBody; 7 8 import com.wjf.dxsv.pay.wechatpay.GlobalConfig; 9 import com.wjf.dxsv.pay.wechatpay.ResponseHandler; 10 import com.wjf.dxsv.pay.wechatpay.WechatPayService; 11 import com.wjf.dxsv.pay.wechatpay.util.QRCodeUtils; 12 import com.wjf.dxsv.pay.wechatpay.util.TenpayUtil; 13 import com.wjf.dxsv.proscenium.model.vrc.payitemOrderExtend; 14 import com.wjf.dxsv.proscenium.service.vsc.OrderService; 15 16 import javax.servlet.ServletOutputStream; 17 import javax.servlet.http.HttpServletRequest; 18 import javax.servlet.http.HttpServletResponse; 19 20 import java.io.BufferedOutputStream; 21 import java.io.IOException; 22 import java.security.KeyManagementException; 23 import java.security.KeyStoreException; 24 import java.security.NoSuchAlgorithmException; 25 import java.security.UnrecoverableKeyException; 26 import java.security.cert.CertificateException; 27 import java.util.Map; 28 import java.util.SortedMap; 29 import java.util.TreeMap; 30 31 @Controller 32 @RequestMapping("/weixin/") 33 public class WechatPayController { 34 @Autowired 35 private OrderService orderService; 36 37 public OrderService getOrderService() { 38 return orderService; 39 } 40 41 @RequestMapping("pay") 42 public void getCodeUrl(String orderid,HttpServletResponse response, HttpServletRequest request)throws Exception { 43 JSONObject zanObj = new JSONObject(); 44 String currTime = TenpayUtil.getCurrTime(); 45 String strTime = currTime.substring(8, currTime.length()); 46 String strRandom = TenpayUtil.buildRandom(4) + ""; 47 String nonce_str = strTime + strRandom; 48 49 payitemOrderExtend payitem = orderService.selectOrderIdpay(orderid); 50 51 //商品描述 52 String body = payitem.getTitle(); 53 //訂單號 54 String out_trade_no = payitem.getOrder_id(); 55 //價格 56 String order_price = payitem.getTotal_fee(); 57 58 String spbill_create_ip = request.getRemoteAddr(); 59 String notify_url = GlobalConfig.URL + "api/weixin/result"; 60 61 SortedMap<String, String> packageParams = new TreeMap<String, String>(); 62 packageParams.put("appid", GlobalConfig.APPID); 63 packageParams.put("mch_id", GlobalConfig.MCH_ID); 64 packageParams.put("nonce_str", nonce_str); 65 packageParams.put("body", body); 66 packageParams.put("out_trade_no", out_trade_no); 67 packageParams.put("total_fee", order_price); 68 packageParams.put("spbill_create_ip", "120.77.154.111");//ip地址 69 packageParams.put("notify_url", notify_url); 70 packageParams.put("trade_type", GlobalConfig.TRADE_TYPE); 71 72 WechatPayService wechatPayService = new WechatPayService(); 73 String code_url = wechatPayService.getUrlCode(packageParams); 74 75 System.out.println(code_url); 76 zanObj.put("status", code_url); 77 if (code_url.equals("")){ 78 System.err.println(wechatPayService.getResponseMessage()); 79 } 80 try { 81 response.getWriter().print(zanObj.toString()); 82 response.getWriter().flush(); 83 response.getWriter().close(); 84 } catch (JSONException e) { 85 e.printStackTrace(); 86 } catch (IOException e) { 87 e.printStackTrace(); 88 } 89 } 90 91 @RequestMapping("QRcode") 92 public void getQrCode(String code_url, HttpServletResponse response) throws Exception { 93 ServletOutputStream sos = response.getOutputStream(); 94 QRCodeUtils.encode(code_url, sos); 95 } 96 97 /** 98 * 微信回調接口 99 */ 100 @RequestMapping(value = "result") 101 public void wechatOrderBack(HttpServletRequest request, HttpServletResponse response) throws Exception { 102 System.out.println("ok!!!!!"); 103 // 建立支付應答對象 104 ResponseHandler resHandler = new ResponseHandler(request, response); 105 resHandler.setKey(GlobalConfig.KEY); 106 // 判斷簽名是否正確 107 if (resHandler.isTenpaySign()) { 108 String resXml = ""; 109 if ("SUCCESS".equals(resHandler.getParameter("result_code"))) { 110 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" 111 + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; 112 } else { 113 System.out.println("支付失敗,錯誤信息:" + resHandler.getParameter("err_code")); 114 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" 115 + "<return_msg><![CDATA[報文爲空]]></return_msg>" + "</xml> "; 116 } 117 BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); 118 out.write(resXml.getBytes()); 119 out.flush(); 120 out.close(); 121 } else { 122 System.out.println("通知簽名驗證失敗"); 123 } 124 } 125 126 /** 127 * 微信退款接口 128 */ 129 @RequestMapping(value = "refund") 130 public String wechatRefund(HttpServletResponse response, HttpServletRequest request) 131 throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, 132 IOException, CertificateException { 133 134 String currTime = TenpayUtil.getCurrTime(); 135 String strTime = currTime.substring(8, currTime.length()); 136 String strRandom = TenpayUtil.buildRandom(4) + ""; 137 String nonce_str = strTime + strRandom; 138 String out_trade_no = "1400755861"; 139 String order_price ="1"; 140 SortedMap<String, String> parameters = new TreeMap<String, String>(); 141 parameters.put("appid", GlobalConfig.APPID); 142 parameters.put("mch_id", GlobalConfig.MCH_ID); 143 parameters.put("nonce_str", nonce_str); 144 parameters.put("out_trade_no",out_trade_no); 145 parameters.put("out_refund_no", "4005522001201703274823948987"+strTime); 146 parameters.put("total_fee", order_price); 147 parameters.put("refund_fee", order_price); 148 parameters.put("op_user_id", GlobalConfig.MCH_ID); 149 WechatPayService wechatPayService = new WechatPayService(); 150 151 Map map = wechatPayService.forRefund(parameters); 152 if (map != null) { 153 String return_code = (String) map.get("return_code"); 154 String result_code = (String) map.get("result_code"); 155 if (return_code.equals("SUCCESS") && result_code.equals("SUCCESS")) { 156 // 退款成功 157 return "退款成功"; 158 } else { 159 return (String) map.get("err_code_des"); 160 } 161 } else { 162 return "未知的錯誤"; 163 } 164 } 165 }