https://www.cnblogs.com/gopark/p/9394951.html,這篇文章寫的已經很詳細了。
下面寫一下自己的思路:
1.首先下載demo,地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
2.demo中很多方法對於公眾號支付用不到,不需要全都看
3.主要是獲取11個參數,放到Map中,用demo里提供WXPayUtil.mapToXml方法轉為XML格式,通過post方法請求微信端的統一下單接口,后台收到微信傳過來的XML字符串,通過WXPayUtil.xmlToMap方法轉為Map,根據key值,獲取prepay_id(預支付ID),再把需要的6個參數放到Map中,發送給前台,前台根據prepay_id,喚起微信支付,完成付款。
4.11個參數跟6個參數在controller里面都有寫,重點的是:openid
5.查看訂單,取消訂單等其他功能,后續接觸到再進行更新
下面放上自己寫的controller
1 package com.github.wxpay.controller; 2 3 import com.github.wxpay.sdk.WXPayConstants; 4 import com.github.wxpay.sdk.WXPayUtil; 5 import com.github.wxpay.util.Constant; 6 import com.github.wxpay.util.HttpRequestUtil; 7 import com.github.wxpay.util.OrderUtil; 8 import org.springframework.web.bind.annotation.RequestMethod; 9 import org.springframework.web.bind.annotation.ResponseBody; 10 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpSession; 13 import java.util.HashMap; 14 import java.util.Map; 15 import org.springframework.web.bind.annotation.RequestMapping; 16 import com.github.wxpay.sdk.WXPayConstants.SignType; 17 18 public class WxPayController { 19 20 /** 21 * 22 * @Description 微信瀏覽器內微信支付/公眾號支付(JSAPI) 23 */ 24 @RequestMapping(value = "/orders",method = RequestMethod.GET) 25 @ResponseBody 26 public Map orders(HttpServletRequest request){ 27 try { 28 Map<String, String> paramMap = new HashMap<String, String>(); 29 HttpSession session = request.getSession(); 30 String wxopenid = session.getAttribute("openid") == null ? null : session.getAttribute("openid").toString(); 31 //在商戶平台的賬戶中心下:需要用戶自行下載證書及安裝 32 String key = Constant.signCustomerKey; 33 String ip = request.getHeader("x-forwarded-for"); 34 35 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 36 ip = request.getHeader("Proxy-Client-IP"); 37 } 38 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 39 ip = request.getHeader("WL-Proxy-Client-IP"); 40 } 41 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 42 ip = request.getRemoteAddr(); 43 } 44 if (ip.indexOf(",") != -1) { 45 String[] ips = ip.split(","); 46 ip = ips[0].trim(); 47 } 48 paramMap.put("appid", Constant.APPIDS[0]); 49 paramMap.put("mch_id", ""); 50 paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); 51 paramMap.put("body", "測試訂單XX礦泉水"); 52 paramMap.put("openid", wxopenid); 53 paramMap.put("out_trade_no", OrderUtil.orderNumber()); 54 paramMap.put("spbill_create_ip", ip); 55 paramMap.put("total_fee", "0.01"); 56 paramMap.put("notify_url", "http://127.0.0.1:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp");// 此路徑是微信服務器調用支付結果通知路徑 57 paramMap.put("trade_type", "JSAPI"); 58 String sign = WXPayUtil.generateSignature(paramMap,key,SignType.MD5); 59 paramMap.put("sign", sign); 60 61 // 將所有參數(map)轉xml格式 62 String mapToXml = WXPayUtil.mapToXml(paramMap); 63 System.out.println(mapToXml); 64 // 統一下單 https://api.mch.weixin.qq.com/pay/unifiedorder 65 String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 66 // 發送post請求"統一下單接口"返回預支付id:prepay_id 67 String xmlStr = HttpRequestUtil.sendPost(unifiedorder_url,mapToXml); 68 69 Map<String,String> XmlToMap = WXPayUtil.xmlToMap(xmlStr); 70 // 以下內容是返回前端頁面的json數據 71 String prepay_id = ""; // 預支付ID 72 if (xmlStr.indexOf("SUCCESS") != -1) { 73 Map<String, String> map = WXPayUtil.xmlToMap(xmlStr); 74 prepay_id = map.get("prepay_id"); 75 } 76 Map<String, String> payMap = new HashMap<String, String>(); 77 XmlToMap.put("appId", Constant.APPIDS[0]); 78 XmlToMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+""); 79 XmlToMap.put("nonceStr", WXPayUtil.generateNonceStr()); 80 XmlToMap.put("signType", "MD5"); 81 XmlToMap.put("package", "prepay_id=" + prepay_id); 82 String paySign = WXPayUtil.generateSignature(payMap, key); 83 payMap.put("paySign", paySign); 84 return XmlToMap; 85 }catch (Exception e){ 86 e.printStackTrace(); 87 } 88 return null; 89 } 90 } 91
httpRequest工具:
1 package com.github.wxpay.util; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.PrintWriter; 7 import java.net.URLConnection; 8 import java.util.List; 9 import java.net.URL; 10 import java.util.Map; 11 12 public class HttpRequestUtil { 13 /** 14 * 向指定URL發送GET方法的請求 15 * 16 * @param url 17 * 發送請求的URL 18 * @param param 19 * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 20 * @return URL 所代表遠程資源的響應結果 21 */ 22 public static String sendGet(String url, String param) { 23 String result = ""; 24 BufferedReader in = null; 25 try { 26 String urlNameString = url + "?" + param; 27 URL realUrl = new URL(urlNameString); 28 // 打開和URL之間的連接 29 URLConnection connection = realUrl.openConnection(); 30 // 設置通用的請求屬性 31 connection.setRequestProperty("accept", "*/*"); 32 connection.setRequestProperty("connection", "Keep-Alive"); 33 connection.setRequestProperty("user-agent", 34 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 35 // 建立實際的連接 36 connection.connect(); 37 // 獲取所有響應頭字段 38 Map<String, List<String>> map = connection.getHeaderFields(); 39 // 遍歷所有的響應頭字段 40 for (String key : map.keySet()) { 41 System.out.println(key + "--->" + map.get(key)); 42 } 43 // 定義 BufferedReader輸入流來讀取URL的響應 44 in = new BufferedReader(new InputStreamReader( 45 connection.getInputStream())); 46 String line; 47 while ((line = in.readLine()) != null) { 48 result += line; 49 } 50 } catch (Exception e) { 51 System.out.println("發送GET請求出現異常!" + e); 52 e.printStackTrace(); 53 } 54 // 使用finally塊來關閉輸入流 55 finally { 56 try { 57 if (in != null) { 58 in.close(); 59 } 60 } catch (Exception e2) { 61 e2.printStackTrace(); 62 } 63 } 64 return result; 65 } 66 67 /** 68 * 向指定 URL 發送POST方法的請求 69 * 70 * @param url 71 * 發送請求的 URL 72 * @param param 73 * 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。 74 * @return 所代表遠程資源的響應結果 75 */ 76 public static String sendPost(String url, String param) { 77 PrintWriter out = null; 78 BufferedReader in = null; 79 String result = ""; 80 try { 81 URL realUrl = new URL(url); 82 // 打開和URL之間的連接 83 URLConnection conn = realUrl.openConnection(); 84 // 設置通用的請求屬性 85 conn.setRequestProperty("accept", "*/*"); 86 conn.setRequestProperty("connection", "Keep-Alive"); 87 conn.setRequestProperty("user-agent", 88 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 89 // 發送POST請求必須設置如下兩行 90 conn.setDoOutput(true); 91 conn.setDoInput(true); 92 // 獲取URLConnection對象對應的輸出流 93 out = new PrintWriter(conn.getOutputStream()); 94 // 發送請求參數 95 out.print(param); 96 // flush輸出流的緩沖 97 out.flush(); 98 // 定義BufferedReader輸入流來讀取URL的響應 99 in = new BufferedReader( 100 new InputStreamReader(conn.getInputStream())); 101 String line; 102 while ((line = in.readLine()) != null) { 103 result += line; 104 } 105 } catch (Exception e) { 106 System.out.println("發送 POST 請求出現異常!"+e); 107 e.printStackTrace(); 108 } 109 //使用finally塊來關閉輸出流、輸入流 110 finally{ 111 try{ 112 if(out!=null){ 113 out.close(); 114 } 115 if(in!=null){ 116 in.close(); 117 } 118 } 119 catch(IOException ex){ 120 ex.printStackTrace(); 121 } 122 } 123 return result; 124 } 125 }
隨機數工具:
package com.github.wxpay.util; import com.github.wxpay.sdk.WXPayUtil; public class OrderUtil { public static String orderNumber(){ int r1 = (int)(Math.random()*10); int r2 = (int)(Math.random()*10); long now = WXPayUtil.getCurrentTimestampMs(); String paymentID = String.valueOf(r1)+String.valueOf(r2)+String.valueOf(now); return paymentID; } }