利用JUC,带你看看不一样的微信支付回调的处理!!!

countDownLatch及ScheduledThreadPoolExecutor在微信支付里的应用

前言

最近做微信支付,考虑到安全问题,公司线上支付的服务器不能开端口给微信进行调用。
所以之前的项目里都是微信下单后,跳转一个中间页面,调用后台进行查看是否支付成功。
但是这样出现用户明明支付了订单,还是待付款的订单。原因有长时间不输密码了,断网了等等因素引起的。当用户量上去后,这种频率出现的概率就会变大。

countDownLatch和ScheduledThreadPoolExecutor结合处理

微信查询处理的代码优化后:

public HashMap<String, String> wxOrderQuery(OnlinePayRecord onlinePayRecord, HashMap<String, String> params) {
        HashMap<String, String> returnMap = new HashMap<>();
        CountDownLatch countDownLatch = new CountDownLatch(1);
        long starttime = System.currentTimeMillis();
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
        try {
            scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
                long nowtime = System.currentTimeMillis();
                WXOrderQueryRsp wxOrderQueryRsp = null;
                try {
                    //请求微信订单查询
                    wxOrderQueryRsp = wxService.orderQuery(onlinePayRecord, params);
                    if ("SUCCESS".equals(wxOrderQueryRsp.getTrade_state())) {
                        logger.info("调取微信订单查询接口结束,支付成功");
                        onlinePayRecord.setTransactionId(wxOrderQueryRsp.getTransaction_id());
                        onlinePayRecord.setTimeEnd(wxOrderQueryRsp.getTime_end());
                        onlinePayRecord.setTradeState("PAYSUC");
                        onlinePayRecord.setTradeStateDesc("支付成功");
                        returnMap.put("tradeState", "PAYSUC");
                        returnMap.put("tradeStateDesc", "支付成功");
                        returnMap.put("timeEnd",onlinePayRecord.getTimeEnd());
                        scheduledThreadPoolExecutor.shutdown();
                        countDownLatch.countDown();
                    } else {
                        while ((nowtime - starttime) > 300000) {
                            onlinePayRecord.setTradeState(wxOrderQueryRsp.getTrade_state());
                            onlinePayRecord.setTradeStateDesc(wxOrderQueryRsp.getTrade_state_desc());
                            returnMap.put("tradeState", wxOrderQueryRsp.getTrade_state());
                            returnMap.put("tradeStateDesc", wxOrderQueryRsp.getTrade_state_desc());
                            countDownLatch.countDown();
                            scheduledThreadPoolExecutor.shutdown();
                        }
                    }
                    returnMap.put("payType", onlinePayRecord.getPayType());
                    returnMap.put("outTradeNo", wxOrderQueryRsp.getOut_trade_no());
                    returnMap.put("transactionId", wxOrderQueryRsp.getTransaction_id());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, 1, 1, TimeUnit.SECONDS);

        } catch (Exception e) {
            e.printStackTrace();
            logger.info("请求异常");
            returnMap.put("tradeState", "ERROR");
            returnMap.put("tradeStateDesc", "请求异常");
            returnMap.put("payType", onlinePayRecord.getPayType());
            returnMap.put("outTradeNo", onlinePayRecord.getOutTradeNo());
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return returnMap;
    }

不了解ScheduledThreadPoolExecutor,和countDownLatch的看我之前的几篇博客。
利用ScheduledThreadPoolExecutor定时线程池,进行轮询。并且加入countDownLatch.await()等待特性,countDownLatch当减到0时,await方法就可以过去,否则一直阻塞在那里。
但是不能一直阻塞,退出阻塞的条件就是支付成功,或者5分钟以后依然未支付。此处的时间看具体需求。

给大家个小例子

@RestController
public class IndexController {
    @Autowired
    private EmployeesDao employeesDao;
    @RequestMapping("/updateage")
    public String processUserData() throws InterruptedException {
        Employees emp=new Employees();
        emp.setId(4);
        emp.setAge(23);
        emp.setPosition("pos");
        emp.setName("Jordan");
        employeesDao.save(emp);
        return null;
    }
    @RequestMapping("/frontReg")
    public Map frontReg()  {
       Map map= weixinpay(4);
       return map;
    }
    public  Map weixinpay(int wwz311) {
        System.out.println("调用");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1);
        long starttime = System.currentTimeMillis();
        Map map=new HashMap();
        scheduledThreadPoolExecutor.scheduleWithFixedDelay(() -> {
            Employees emp=employeesDao.findAll().get(0);
            System.out.println(emp.getAge());
            if(emp.getAge()==23){
            //当年龄是23时中断线程,同时
            //countDownLatch-1
                map.put("flag","修改Jordan震年龄成功:"+emp.getAge());
                scheduledThreadPoolExecutor.shutdown();
                countDownLatch.countDown();
            }else{
                long nowtime = System.currentTimeMillis();
                while ((nowtime - starttime) > 20000) {
                    map.put("flag","修改Jordan年龄失败:"+emp.getAge());
                    countDownLatch.countDown();
                    scheduledThreadPoolExecutor.shutdown();
                }
            }
            map.put("data","success");
        }, 0, 1, TimeUnit.SECONDS);
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return map;
    }
}

dao层就不给大家了,JPA基本方法,表就一条数据:

Employees 表
在这里插入图片描述

当我访问http://localhost:8761/frontReg,如图:

在这里插入图片描述
当我访问http://localhost:8761/frontReg,同时过俩秒访问http://localhost:8761/udateage,如图:

在这里插入图片描述
这其实就是模拟了上边的微信回调的demo

总结

优化后微信回调,用来解决当不能让微信进行回调系统接口时,我们可以在微信下单的方法后,起个线程,进行异步处理。轮询微信查询订单状态,超时判定为未支付。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值