Элегантная обработка асинхронных обратных вызовов платежей WeChat

WeChat
Элегантная обработка асинхронных обратных вызовов платежей WeChat

Элегантная обработка асинхронных обратных вызовов платежей WeChat

фон ручки

1. Поскольку используется версия платежа WeChat версии 2, платежный ответ WeChat представляет собой строку xml, поэтому обработка должна преобразовать этот ответ в объект Java.

1. Платеж WeChat единообразно инкапсулирован в бизнесе.Например, вызов платежа WeChat будет обрабатывать записи операций на системном бизнес-уровне, такие как запись типа бизнеса, статус платежа, номер заказа, результат платежа и т. д., которые будут привести к получению WeChat после оплаты.Когда уведомление об оплате отвечает, необходимо записать ответную информацию на платежную операцию WeChat и т. д.,

Первоначальная версия обработки реализации обратного вызова WeChat


  /**
     * 微信支付回调处理
     *
     * @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. Определите интерфейс обработки обратного вызова WECHAT
 
/**
 * 微信支付回调处理
 *
 * @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();
    }
    
    
}

преимущество

С тех пор по сравнению с предыдущим

Система более устойчива,

Абоненс должен обратить внимание только на вызов самому бизнесу и не нужно обращать внимание на другие

Улучшена чистота кода, а обслуживание на более позднем этапе также стало более удобным.