Skip to content

公共模块_支付消息回调路由

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);


  1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
  2. 规则的结束必须用Rule.end()或者Rule.next(),否则不会生效

PayMessageHandler

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;

}

PayMessageInterceptor

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;

}