【html
前言:之前寫過一個獲取微信二維碼支付的接口,發現最近公司新開的項目會常常用到,如今我又翻出代碼看了一遍,以爲仍是把整個代碼流程記下來的好java
】算法
借鑑博客:服務器
他這篇博客寫得不錯,挺全的:https://www.cnblogs.com/xu-xiang/p/5797575.html微信
先聲明:微信支付接口官方文檔仍是要看的,多看幾遍所須要的參數,支付流程,再看一下別人博客的支付代碼基本就明白了整個流程。session
APP_ID (微信支付 公衆號ID )併發
MCH_ID (商戶號ID)
API_KEY (微信商戶平臺key密鑰)
NOTIFY_URL (掃碼支付成功後,微信要回調你服務器的接口地址)
UFDODER_URL (微信官方獲取支付二維碼的接口地址)app
上代碼圖:dom
HttpUtil03.java 發送get,post請求的工具類jsp
PayCommonUtil.java 請求微信接口時須要sign簽名參數,裏面有生成簽名算法的方法
PayConfigUtil.java 配置參數文件,放一些公衆號ID、商戶號ID、key、微信接口路徑呀什麼的配置參數
WXGetScanCodePayUtil.java 處理髮送參數,併發送參數獲取二維碼code的工具
WXScanCodePayTest.java main方法,編訂單死數據,測試接口的
XMLUtil4jdom.java 因爲微信獲取支付二維碼code的接口所須要的參數是xml格式的,因此專門搞個工具類來把map轉xml,或者把xml轉String
上圖:
3.一、我在WXScanCodePayTest.java這個類的main方法中測試運行整個請求處理接口流程,微信支付二維碼接口須要一些訂單商品參數,目前只是測試玩玩,因此寫死
String orderId = "201805150001"; String order_price = "100";//100分,其實這裏是10塊錢 // 微信支付URL須要傳入的金額單位是分,此處將訂單金額轉換成'分'單位 BigDecimal fen = new BigDecimal(order_price); fen = fen.setScale(0, BigDecimal.ROUND_HALF_UP); order_price = fen.toString(); // 微信支付顯示標題 String body = "給老子100萬"; // 微信支交易訂單號,不能重複 String out_trade_no = "" + System.currentTimeMillis(); // 組裝參數 Map<String, Object> param = new HashMap<String, Object>(); param.put("order_price", order_price); param.put("body", body);//商品描述 param.put("out_trade_no", out_trade_no);//微信支付交易訂單號,本身生成 param.put("attach", orderId);//訂單id param.put("time_expire", DateUtil.getOrderExpireTime(1*60*1000L));//設置二維碼失效時間:1分鐘 // 生成微信支付二維碼連接 Map<String, String> result = WXGetScanCodePayUtil.doUnifiedOrder(param, null); if ("FAIL".equals(result.get("return_code"))){ log.error("生成二維碼錯誤: " + result.get("return_msg")); // request.getSession().setAttribute("create_wx_qrcode_error_msg", result.get("return_msg")); // session.setAttribute("create_wx_qrcode_error_msg", result.get("return_msg")); } else { String urlCode = result.get("code_url"); System.out.println("生成的二維碼鏈接:" + urlCode); // BufferedImage bufferedImage = MatrixToImage.encodeQrcode(urlCode, 250, 250); // ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
如下代碼是用在controller測試代碼裏的,用生成二維碼圖片的工具生成一個二維碼圖片,以流的形式返回給jsp頁面的<img src="獲取二維碼圖片流的controller接口地址">標籤,之前測試玩的,我就不弄了
// 生成微信二維碼,輸出到response流中 // String icon = UserController.class.getClassLoader().getResource("coffee_icon.png").getPath(); //二維碼繪圖工具 // BufferedImage bufferedImage = MatrixToImageWriterWithLogo.genBarcode(urlCode, 512, 512, icon); // 二維碼的內容,寬,高,二維碼中心的圖片地址 // ImageIO.write(bufferedImage, "jpg", response.getOutputStream()); }
3.二、在WXGetScanCodePayUtil.doUnifiedOrder(param, null);方法裏處理要傳的參數,並處理髮送(使用HttpUtil03.java工具)post請求給微信支付二維碼接口
/** * * @Description:調用微信支付接口返回URL * @author:zrt * @param param 訂單價格,訂單顯示內容,訂單號 * @param request * @return * @throws Exception * @version:2018年5月15日下午12:02:06 */ @SuppressWarnings("unchecked") public static Map<String, String> doUnifiedOrder(Map<String, Object> param, HttpServletRequest request) throws Exception { String appid = PayConfigUtil.APP_ID; // appid String mch_id = PayConfigUtil.MCH_ID; // 商戶號 String key = PayConfigUtil.API_KEY; // key String trade_type = "NATIVE"; // String spbill_create_ip = PayCommonUtil.getIpAddress(request); // 獲取發起電腦 ip String spbill_create_ip = "192.168.2.59"; String notify_url = PayConfigUtil.NOTIFY_URL; // 回調接口 String currTime = PayCommonUtil.getCurrTime(); String strTime = currTime.substring(8, currTime.length()); String strRandom = PayCommonUtil.buildRandom(4) + ""; String nonce_str = strTime + strRandom; // 隨機字符串 String order_price = (String) param.get("order_price"); // 價格 注意:價格的單位是分 String body = (String) param.get("body"); // 商品名稱 String out_trade_no = (String) param.get("out_trade_no"); // 訂單號 String attach = (String) param.get("attach"); // 附加參數,這裏傳的是咱們的訂單號orderId String time_expire = (String) param.get("time_expire");//設置二維碼失效時間 SortedMap<String,String> packageParams = new TreeMap<String,String>(); packageParams.put("appid", appid); packageParams.put("mch_id", mch_id); packageParams.put("nonce_str", nonce_str); packageParams.put("body", body); packageParams.put("out_trade_no", out_trade_no); packageParams.put("total_fee", order_price); packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("notify_url", notify_url); packageParams.put("trade_type", trade_type); packageParams.put("attach", attach); packageParams.put("time_expire", time_expire); // 簽名 String sign = PayCommonUtil.createSign("UTF-8", packageParams, key); packageParams.put("sign", sign); // 微信支付接口傳輸數據使用xml方式進行的,此處將參數裝換爲xml // map --> xml String requestXML = PayCommonUtil.getRequestXml(packageParams); System.out.println("---------- Request XML: " + requestXML); //設置請求頭 Map<String, String> headers = new HashMap<String, String>(); headers.put("content-type", "text/html; charset=UTF-8"); // String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML); HttpEntity httpEntity = HttpUtil03.sendHttpsPost(UFDODER_URL, headers, requestXML, true); BufferedReader reader = new BufferedReader(new InputStreamReader(httpEntity.getContent(), "UTF-8")); StringBuilder resXml = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { resXml.append(line); resXml.append("\r\n"); } System.out.println("---------- Response XML: " + resXml.toString()); // xml --> map return XMLUtil4jdom.doXMLParse(resXml.toString()); }
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
整個獲取微信支付二維碼的處理流程就是這樣
上最後效果圖:不要問爲何生成的支付二維碼是紅色的,我用生成二維碼圖片的插件本身調顏色大小時瞎調的,懶得改了