在我們對接微信支付的時候可能會出現用戶支付了,但我們系統業務支付狀態並沒有改變的情況,這是因為微信推送支付數據流的時候是后台通知交互時,
如果微信收到商戶的應答不符合規范或超時,微信會判定本次通知失敗,重新發送通知,直到成功為止(在通知一直不成功的情況下,微信總共會發起10次通知,
通知頻率為15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 總計 24h4m),但微信不保證通知最終一定能成功。
所以這里就需要我們自己主動去查詢:接口詳細說明地址(http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2)
1 //創建一個定時器主動查詢訂單支付狀態 2 Timer timer = new Timer(); 3 timer.schedule(new TimerTask() { 4 5 //最大重試次數 6 int MAX_RETRY = 5; 7 8 @Override 9 public void run() { 10 11 MAX_RETRY--; 12 13 //檢查訂單系統 14 WxpOrderDTO wxpOrderDTO = 15 wxpOrderMapper.selectWxpOrder(orderNo); 16 17 if (wxpOrderDTO.getStatus().equals("1")) { 18 19 //取消定時器(訂單支付成功) 20 timer.cancel(); 21 22 } else { 23 24 //查詢訂單狀態 25 WxMpPayResult payResult = wxMpService.getJSSDKPayResult(null, orderNo); 26 if (payResult.getReturn_code().equals("SUCCESS")) { 27 28 //已經支付,更新訂單狀態 29 if (payResult.getResult_code().equals("SUCCESS")) { 30 wxpOrderMapper.updateOrderStatus(orderNo); 31 } 32 33 } 34 35 } 36 37 if (MAX_RETRY == 0) { 38 39 //取消定時器(用戶取消支付) 40 timer.cancel(); 41 42 } 43 44 45 } 46 47 }, 2000, 5000);
/** * 該接口提供所有微信支付訂單的查詢,當支付通知處理異常戒丟失的情冴,商戶可以通過該接口查詢訂單支付狀態。 * 詳見http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2 * @param transactionId * @param outTradeNo */ WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo);
1 @Override 2 public WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo) { 3 String nonce_str = System.currentTimeMillis() + ""; 4 5 SortedMap<String, String> packageParams = new TreeMap<String, String>(); 6 packageParams.put("appid", wxMpConfigStorage.getAppId()); 7 packageParams.put("mch_id", wxMpConfigStorage.getPartnerId()); 8 if (transactionId != null && !"".equals(transactionId.trim())) 9 packageParams.put("transaction_id", transactionId); 10 else if (outTradeNo != null && !"".equals(outTradeNo.trim())) 11 packageParams.put("out_trade_no", outTradeNo); 12 else 13 throw new IllegalArgumentException("Either 'transactionId' or 'outTradeNo' must be given."); 14 packageParams.put("nonce_str", nonce_str); 15 packageParams.put("sign", WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey())); 16 17 StringBuilder request = new StringBuilder("<xml>"); 18 for (Entry<String, String> para : packageParams.entrySet()) { 19 request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey())); 20 } 21 request.append("</xml>"); 22 23 HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/orderquery"); 24 if (httpProxy != null) { 25 RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); 26 httpPost.setConfig(config); 27 } 28 29 StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8); 30 httpPost.setEntity(entity); 31 try { 32 CloseableHttpResponse response = httpClient.execute(httpPost); 33 String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); 34 XStream xstream = XStreamInitializer.getInstance(); 35 xstream.alias("xml", WxMpPayResult.class); 36 WxMpPayResult wxMpPayResult = (WxMpPayResult) xstream.fromXML(responseContent); 37 return wxMpPayResult; 38 } catch (IOException e) { 39 throw new RuntimeException("Failed to query order due to IO exception.", e); 40 } 41 }
哈哈,具體要根據自己的業務來做啊,這里提供一個思路,O(∩_∩)O哈哈~
