优雅的处理微信支付异步回调

优雅的处理微信支付异步回调

处理背景

1.由于使用的是v2版本的微信支付,微信支付响应是xml字符串,所以处理需要对此响应进行解析成java对象

1.在业务中把微信支付进行了统一封装,如调用微信支付会在系统业务级别对操作记录进行处理,如记录业务类型,支付状态,订单号,支付结果等,导致会在支付后接收微信支付通知响应时候,需要对响应信息对微信支付操作进行回写记录等等,

初始版本的微信回调实现处理


  /**
     * 微信支付回调处理
     *
     * @param xmlData 微信回调数据
     * @return 微信响应信息 xml字符串
     */
    public String handleNotifyResult(String xmlData) {
        log.info("微信支付回调原始信息:" + xmlData);
        WxPayOrderNotifyResult wxPayOrderNotifyResult = null;
        try {
            //解析xml串成java对象
            wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            
​
            ..
            ..
            ..
            业务场景处理
            
            
            //保存系统级别微信支付单记录
            updatePayOrder(wxPayOrderNotifyResult);
        } catch (WxPayException e) {
            log.error("微信支付回调异常", e);
            return  WxPayNotifyResponse.fail();
        }
​
        return  WxPayNotifyResponse.success();
    }
复制代码

此种处理回调没有问题,但是如果场景过多,如商城订单支付,会员开通支付,续费支付等等业务场景,都需复写上述操作,

把会变化之处独立出来,把不需要变化的抽离出来,各是各,分开写

由上分析可看出这是一个典型的环绕处理,而环绕操作就是不需要变化的部分,每个支付的场景就是变化之处,可以采用切面来完成,处理方式,初步考虑基于注解来处理业务处理前置操作和后置操作,但思考过后发现缺失灵活性,于是决定采用策略模式通过接口来解决此问题

改动

1.上述代码把xml字符串单独抽离出来,已类变量方式存在,定义构建方法赋值xml字符串
public class WxNotify {
     /**
     * 微信回调数据
     */
    private String xmlData;
​
​
    /**
     * 构建微信支付回调 支付成功方法
     *
     * @param xmlData         响应xml数据
     */
   public WxNotify build(String xmlData) {
        this.xmlData = xmlData;
        return this;
    }
    
   
    public String handleNotifyResult() {
        log.info("微信支付回调原始信息:" + xmlData);
        WxPayOrderNotifyResult wxPayOrderNotifyResult = null;
        try {
            //解析xml串成java对象
            wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            
​
            ..
            ..
            ..
            业务场景处理
            
            
            //保存系统级别微信支付单记录
            updatePayOrder(wxPayOrderNotifyResult);
        } catch (WxPayException e) {
            log.error("微信支付回调异常", e);
            return  WxPayNotifyResponse.fail();
        }
​
        return  WxPayNotifyResponse.success();
    }
}
复制代码
2.定义微信回调处理接口
 
/**
 * 微信支付回调处理
 *
 * @author chenyanpeng
 * @Date: 2021/7/30 16:42
 */
public interface NotifyHandleResponse {
    /**
     * 微信支付成功
     *
     * @param wxPayOrderNotifyResult 解析结果
     * @param bllCode 业务编码
     * @return 微信服务器记录的订单回调信息
     */
    String success(WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode);
​
​
    /**
     * 回调支付失败
     *
     * @param wxPayOrderNotifyResult 解析结果
     * @param bllCode 业务编码
     * @return 微信服务器记录的订单回调信息
     */
    String fail(WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode);
​
​
    /**
     * 微信回调过程处理异常
     *
     * @param e 异常信息
     * @param bllCode 业务编码
     * @return 微信服务器记录的订单回调信息
     */
    String error(Exception e,WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode);
}
​
复制代码
3 定义处理处理结果接口,赋值xml同时在赋值接口信息,然后面向接口开发,不是面向实现类
@Component
public class WxNotify {
    
    
     /**
     * 微信回调数据
     */
    private String xmlData;
    
    
     /**
     * 通知处理响应
     */
    private NotifyHandleResponse notifyHandleResponse;
​
​
    
    /**
     * 构建微信支付回调 支付成功方法
     *
     * @param xmlData         响应xml数据
     * @param notifyInterface 通知处理接口
     */
    public WxNotify build(String xmlData, NotifyHandleResponse notifyHandleResponse) {
        this.notifyHandleResponse = notifyHandleResponse;
        this.xmlData = xmlData;
        return this;
    }
    
   
    public String handleNotifyResult() {
        log.debug("微信支付回调原始信息:" + xmlData);
        WxPayOrderNotifyResult wxPayOrderNotifyResult = null;
        try {
            //解析xml串成java对象
            wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            //响应结果
            String message = null;
            //支付结果处理
            if (isOk(wxPayOrderNotifyResult)) {
                 //调用支付成功方法
                 message = WxPayNotifyResponse.success(
                     notifyHandleResponse.success(wxPayOrderNotifyResult, wxPayOrderNotifyResult.getOutTradeNo())
                 );
                //此处织入支付成功后置操作
                updatePayOrder(wxPayOrderNotifyResult);
            }else{
                 //调用支付失败方法
                message =  WxPayNotifyResponse.fail(
                        notifyHandleResponse.fail(wxPayOrderNotifyResult, wxPayOrderNotifyResult.getOutTradeNo())
                 )
                 //此处织入支付成功后置操作
                 ·····
            }
            return message;
        } catch (WxPayException e) {
            log.error("微信支付回调异常", e);
            //调用程序异常处理方法
            return  WxPayNotifyResponse.fail(
                notifyHandleResponse.error(e,wxPayOrderNotifyResult,wxPayOrderNotifyResult.getOutTradeNo())
            );   
        }
    }
    
    
    
    /**
     * 是否支付成功
     *
     * @param wxPayOrderNotifyResult 微信支付结果
     * @return true成功
     */
    private boolean isOk(WxPayOrderNotifyResult wxPayOrderNotifyResult) {
        return
                "SUCCESS".equals(wxPayOrderNotifyResult.getResultCode()) && "SUCCESS".equals(wxPayOrderNotifyResult.getResultCode());
    }
}
复制代码
4调用
@RequestMapping("/wxPay")
public class WxNotifyContrller {
    
    
    //自己实现的接口处理类,该类实现定义处理接口
    @Autowired
    private DefaultNotifyResponseImpl notifyHandleResponse;
    
    
    
    
    /**
     * 默认支付回调通知处理 demo3
     *
     * @param xmlData 响应数据
     * @return 返回给wx服务器的数据, 会显示在查询微信订单中的信息中
     */
    @GetMapping(value = "/notify/demo1")
    public String handleNotify(@RequestBody(required = false) String xmlData) {
        return wxNotify.build(xmlData, notifyHandleResponse).handleNotifyResponse();
    }
    
    
    
    
    
    /**
     * 默认支付回调通知处理 demo2
     *
     * @param xmlData 响应数据
     * @return 返回给wx服务器的数据, 会显示在查询微信订单中的信息中
     */
    @GetMapping(value = "/notify/demo2")
    public String demo2(@RequestBody(required = false) String xmlData) {
        return wxNotify.build(xmlData, new NotifyHandleResponse() {
            @Override
            public String success(WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode) {
                //业务处理
                .....
                
                return "支付成功(。。。)";
            }
            @Override
            public String fail(WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode) {
                //业务处理
                
                .....
                return "支付失败(。。。)";
            }
            @Override
            public String error(Exception e,WxPayOrderNotifyResult wxPayOrderNotifyResult,String bllCode) {
                //业务处理
                
                .....
                return "支付异常(。。。)";
            }
        }).handleNotifyResponse();
    }
    
    
}
复制代码

优点

自此完成,相对之前

系统更有弹性,

调用者只需关注调用业务本身,无需关注其他

代码整洁度提高,在后期维护也更方便

猜你喜欢

转载自juejin.im/post/6991752096823377933