<!-- 微信支付 --> <dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>0.0.3</version> </dependency> <!-- google二維碼工具 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.1.0</version> </dependency>
2. 實現SDK微信配置類,建立商戶本身的配置類java
public class WxPayConfig implements WXPayConfig{ private byte[] certData; //初始化退款、撤銷時的商戶證書 public WxPayConfig() throws Exception { String certPath = "D://第三方開放平臺/wx_apiclient_cert.p12"; File file = new File(certPath); InputStream certStream = new FileInputStream(file); this.certData = new byte[(int) file.length()]; certStream.read(this.certData); certStream.close(); } public String getAppID() { return ""; } /** 微信支付商戶號 */ public String getMchID() { return ""; } public String getKey() { return ""; } public int getHttpConnectTimeoutMs() { return 8000; } public int getHttpReadTimeoutMs() { return 10000; } @Override public InputStream getCertStream() { ByteArrayInputStream certBis; certBis = new ByteArrayInputStream(this.certData); return certBis; } }
private WxPayConfig config; private WXPay wxpay; public WxPayController() { try { //初始化微信支付客戶端 config = new WxPayConfig(); wxpay = new WXPay(config); } catch (Exception e) { e.printStackTrace(); } }
3.2 建立預支付接口,生成支付二維碼(能夠在頁面添加img標籤,讓它的url指向這裏就能直接在頁面特定區域顯示二維碼了)git
/** * 預支付接口,生成支付二維碼 * @param order * @return * @throws Exception */ @RequestMapping("/wxpay/pay") public void pay(HttpServletResponse response) throws Exception { //TODO:這裏執行商戶系統建立新的訂單操做 WxPayOrder order = new WxPayOrder(); order.setOut_trade_no(System.currentTimeMillis() + ""); wxPayService.createOrder(order); //設置請求參數 Map<String, String> data = new HashMap<String, String>(); data.put("body", "微信支付測試"); data.put("out_trade_no", order.getOut_trade_no()); data.put("device_info", ""); data.put("fee_type", "CNY"); data.put("total_fee", "1"); data.put("spbill_create_ip", "192.168.0.119"); data.put("notify_url", notify_url); data.put("trade_type", "NATIVE"); // 此處指定爲掃碼支付 data.put("product_id", "12"); try { //發起支付 Map<String, String> resp = wxpay.unifiedOrder(data); //獲取二維碼URL String code_url = resp.get("code_url"); //根據url生成二維碼 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); // 設置二維碼參數 Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); BitMatrix bitMatrix = multiFormatWriter.encode(code_url, BarcodeFormat.QR_CODE, 300, 300, hints); //返回二維碼 MatrixToImageWriter.writeToStream(bitMatrix, "jpg", response.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } }
3.3 建立支付結果回調接口(回調的URL必須公網能夠訪問,測試時能夠使用花生殼等工具映射一個公網地址github
/** * 支付結果回調 * @return * @throws Exception */ @PostMapping("/wxpay/notify_url") public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception { // 讀取回調內容 InputStream inputStream; StringBuffer sb = new StringBuffer(); inputStream = request.getInputStream(); String s; BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); while ((s = in.readLine()) != null) { sb.append(s); } in.close(); inputStream.close(); // 支付結果通知的xml格式數據 String notifyData = sb.toString(); // 轉換成map Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData); //支付確認內容 String resXml = ""; //驗證簽名 if (wxpay.isPayResultNotifySignatureValid(notifyMap)) { // 簽名正確 WxPayOrder order = wxPayService.getOrder(notifyMap.get("out_trade_no")); if(order != null) { if("SUCCESS".equals(notifyMap.get("result_code"))) { //交易成功 // TODO:更新訂單 System.out.println("訂單" + notifyMap.get("out_trade_no") + "微信支付成功"); } else { //交易失敗 System.out.println("訂單" + notifyMap.get("out_trade_no") + "微信支付失敗"); } } // 注意特殊狀況:訂單已經退款,但收到了支付結果成功的通知,不該把商戶側訂單狀態從退款改爲支付成功 //設置成功確認內容 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; } else { // 簽名錯誤,若是數據裏沒有sign字段,也認爲是簽名錯誤 //設置失敗確認內容 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg></return_msg>" + "</xml> "; System.out.println("訂單" + notifyMap.get("out_trade_no") + "微信支付失敗"); } //發送通知 response.getWriter().println(resXml); }
3.4 建立申請退款接口(這裏必定要注意先要下載並配置證書,不然會報錯;證書下載請參考官方文檔,證書配置見商戶微信配置類)api
/** * 微信申請退款接口 * @param out_trade_no 訂單號 * @throws Exception */ @RequestMapping("/wxpay/refund") public void refund(String out_trade_no) throws Exception { //設置請求參數 HashMap<String, String> data = new HashMap<String, String>(); data.put("out_trade_no", out_trade_no); data.put("out_refund_no", out_trade_no); data.put("total_fee", "1"); data.put("refund_fee", "1"); data.put("refund_fee_type", "CNY"); data.put("op_user_id", config.getMchID()); try { //調用sdk發起退款 Map<String, String> result = wxpay.refund(data); if("SUCCESS".equals(result.get("result_code"))) { //TODO:更新訂單 System.out.println("訂單" + out_trade_no + "微信退款成功"); } } catch (Exception e) { e.printStackTrace(); } }