-
Notifications
You must be signed in to change notification settings - Fork 919
公共模块_支付消息回调路由
egan edited this page Jul 5, 2019
·
2 revisions
预先设置好拦截器处理器
PayService service = ....;
//增加支付回调消息拦截器
payService.addPayMessageInterceptor(new AliPayMessageInterceptor());
//设置回调消息处理
payService.setPayMessageHandler(spring.getBean(AliPayMessageHandler.class));
支付回调时调用回调方法
/**
* 支付回调地址
*
* @param request 请求
*
* @return 返回对应的响应码
*
* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)}
*
* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler}
*
*/
HttpServletRequest request
//业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler()
response.getWriter().write(service.payBack(request.getParameterMap(), request.getInputStream()).toMessage());
.
** 在一个多种支付类型,多种支付账户中,或者某些特殊的支付消息中,针对的类型比较多并需要对不同的业务做出处理方案。**
这里如果使用逻辑判断来实现的话会比较繁琐而且也比较难维护,这里我们使用PayMessageRouter
来对支付消息进行路由处理对应的业务。
1. payType 支付类型
2. transactionType 交易类型
3. msgType 消息类型
4. subject 简介,主题
5. key 在支付消息中对应键的名字
6. rValue 与key进行对应的value的值(正则匹配模式)
在整个项目中 PayMessageRouter 应该是单例
PayService service = ....;
router = new PayMessageRouter(service);
router
.rule()
.msgType(MsgType.text.name()) //消息类型
.payType("aliPay") //用于标识支付服务商,比如 支付宝:aliPay,微信:wxPay这里开发者自行定义
.transactionType("APP")//交易类型,有关回调的可在这处理
.handler(handler) //处理器
.end()
.rule()
.msgType(MsgType.text.name()) //消息类型
.payType("wxPay") //支付账户事件类型
.key2RValue("subject",".*充100送20.+") //根据订单标题 正则表达式匹配
.interceptor(interceptor) //拦截器
.handler(handler) //处理器
.end()
;
// 将PayMessage交给消息路由器
HttpServletRequest request = ...;
//支付账户配置
PayConfigStorage storage = service.getPayConfigStorage();
//获取支付方返回的对应参数
Map<String, Object> params = service.getParameter2Map(request.getParameterMap(), request.getInputStream());
PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
PayOutMessage outMessage = router.route(message);
- 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
- 规则的结束必须用Rule.end()或者Rule.next(),否则不会生效
public interface PayMessageHandler {
/**
* @param payMessage 支付消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param payService 支付服务
* @return xml,text格式的消息,如果在异步规则里处理的话,可以返回null
*/
PayOutMessage handle(PayMessage payMessage,
Map<String, Object> context,
PayService payService
) throws PayErrorException;
}
public interface PayMessageInterceptor {
/**
* 拦截微信消息
*
* @param payMessage 支付消息
* @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个
* @param payService 支付服务
* @return true代表OK,false代表不OK
*/
boolean intercept(PayMessage payMessage,
Map<String, Object> context,
PayService payService
) throws PayErrorException;
}