Элегантная обработка асинхронных обратных вызовов платежей 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();
}
}
преимущество
С тех пор по сравнению с предыдущим
Система более устойчива,
Абоненс должен обратить внимание только на вызов самому бизнесу и не нужно обращать внимание на другие
Улучшена чистота кода, а обслуживание на более позднем этапе также стало более удобным.