利用定时器的方式实现主动查询订单支付状态

时间:2022-09-18 23:29:25

在我们对接微信支付的时候可能会出现用户支付了,但我们系统业务支付状态并没有改变的情况,这是因为微信推送支付数据流的时候是后台通知交互时,

如果微信收到商户的应答不符合规范或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起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哈哈~