文档章节

代码设计之多渠道支付

zgw06629
 zgw06629
发布于 2015/04/29 19:17
字数 673
阅读 113
收藏 0

支付网关中需要接入多个支付渠道,如cybs、fortumo、amx,其中cybs为信用卡支付,其他两个为运营商支付。

不管使用那种支付渠道,支付流程都是类似的。显而易见可以使用模板方法。首先定义一个模板类,支付流程中各支付渠道通用的方法放在模板类中,特异于各个支付渠道的方法作为抽象方法,由子类实现。

如下图所示:

其中AbstractPaymentService为模板类,其他三个为各支付渠道实现子类。

模板类--AbstractPaymentService伪代码如下所示:

protected final Logger logger = LoggerFactory.getLogger(AbstractPaymentService.class);
 
public PayResultDTO pay(PayOrderDTO dto){
    logger.info("Entering pay, and the dto is {}", dto);
    //将DTO转为Entity(数据库实体)
    PayOrder payOrder = convertDTOToEntity(dto);
    //落地支付单
    insertPayOrder(payOrder);
    //去支付 抽象方法 由各个支付渠道自己去实现
    return doPay(dto);
}
protected abstract PayResultDTO doPay(PayOrderDTO dto) ;
private void insertPayOrder(PayOrder payOrder) {
    // do something here...
}
private PayOrder convertDTOToEntity(PayOrderDTO dto) {
    //do something here...
    return null;
}

Cybs支付渠道实现子类–CybsPaymentService伪代码如下:

@Override
 protected PayResultDTO doPay(PayOrderDTO dto) {
     //使用cybs 第一次支付需要特殊处理
     if(dto.isFirstPay())
         return doFirstPay();
     else
         return doNormalPay();
 }
 private PayResultDTO doNormalPay() {
     //do smething here...
     return result;
 }
 private PayResultDTO doFirstPay() {
     //do smething here...
     return result;
 }

其他两个支付渠道实现类类似,只要实现doPay方法即可。比如Amx以HttpClient方式调用Amx Server的Http接口发起支付并同步等待返回。

若这时需要接入一个新的支付渠道,如Paypal,只需定义一个PaypalPaymentService继承模板类–AbstractPaymentService,同时实现doPay方法即可。

接着再定义一个支付门面类,方便客户端(交易系统)调用支付方法,即客户端无需关心是哪种支付渠道,只须调用pay方法即可。支付门面代码如下所示:

@Service
public class PaymentFacadeService {
    @Autowired
    private CybsPaymentService cybsPaymentService;
    @Autowired
    private FortumoPaymentService fortumoPaymentService;
    @Autowired
    private AmxPaymentService amxPaymentService;
 
    public PayResultDTO pay(PayOrderDTO dto) {
        String payChannel = dto.getPayChannel();
        if (payChannel.equalsIgnoreCase("cybs"))
            return cybsPaymentService.pay(dto);
        else if (payChannel.equalsIgnoreCase("fortumo"))
            return fortumoPaymentService.pay(dto);
        else if (payChannel.equalsIgnoreCase("amx"))
            return amxPaymentService.pay(dto);
        return null;
    }
}

门面类应该有更优雅的实现方式,即不用在门面类的成员变量中全部罗列出所有的支付渠道的实现类。

这时客户端调用支付方法伪代码示例为:

@Autowired
private PaymentFacadeService paymentServcie;
 
public MyResultDTO pay(...){
    //构造payOrderDTO
    PayOrderDTO dto = new PayOrderDTO();
    //填充属性 
    //...
    PayResultDTO resultDTO = paymentServcie.pay(dto);
    //do something with resultDTO
    return myResult;
}

支付门面设计方案二:

public class PaymentFacadeService2 {
    private Map<String,AbstractPaymentService> channelServiceMap;
     
    public PayResultDTO pay(PayOrderDTO dto) {
        String payChannel = dto.getPayChannel();
         
        return channelServiceMap.get(payChannel).pay(dto);
    }
    public void setChannelServiceMap(Map<String, AbstractPaymentService> serviceMap) {
        this.channelServiceMap = serviceMap;
    }
     
}

spring 配置:

<bean id="paymentFacadeService2"
        class="com.tcl.gateway.service.refactoring.PaymentFacadeService2">
        <property name="channelServiceMap">
            <map>
                <entry key="cybs">
                    <bean class="com.tcl.gateway.service.refactoring.CybsPaymentService"></bean>
                </entry>
                <entry key="fortumo">
                    <bean class="com.tcl.gateway.service.refactoring.FortumoPaymentService"></bean>
                </entry>
                <entry key="amx">
                    <bean class="com.tcl.gateway.service.refactoring.AmxPaymentService"></bean>
                </entry>
            </map>
        </property>
    </bean>


© 著作权归作者所有

共有 人打赏支持
zgw06629
粉丝 16
博文 54
码字总数 30471
作品 0
海淀
程序员
支付系统设计

date:2017-04-01 巨人的肩膀 In me the tiger sniffs the rose. —— 英国诗人西格夫里·萨松代表作《于我,过去,现在以及未来 》 凤凰牌老熊 - 支付老兵的 blog 龙果开源支付系统 Ping++...

daydaygo
2017/11/21
0
0
【支付系统设计从0到1】深度解析支付宝产品架构

支付宝作为最老牌的支付机构,其支付系统的架构和使用的技术是很值得我们在设计与实现支付系统时作为参考的,这篇文章为大家深度解析支付宝的产品架构。 系统架构概况 支付宝的系统采用的是一...

金融民工小曾
08/26
0
0
【支付系统设计从0到1】支付系统流程和典型架构设计

支付业务的核心流程 1.支付应用根据用户选择的支付工具来调用对应的支付产品来执行支付。 2.支付产品通过支付网关根据支付工具、渠道费率、接口稳定性等因素选择合适的支付渠道来落地支付。 ...

金融民工小曾
08/25
0
0
支付渠道那些事

年初开始对公司的支付系统进行微服务架构改造。 之前有一系列文章介绍了改造的背景。 为什么要重构到微服务 重构中的天时地利任何 重构的准备工作 从这一篇开始,进入重构工作的正题了。 在支...

信志
2016/09/14
130
0
支付流程的坑点

支付流程中的猜的几个坑。 1.熟读支付渠道的的文档 2.支付金额的传递到底是元还是分(支付宝和微信貌似是分,银联貌似元) 3.同一订单重复提交数据或者是重复请求,在微信获取时已经申请预付...

信志
2016/08/22
385
0

没有更多内容

加载失败,请刷新页面

加载更多

WinDbg

参考来自:http://www.cnit.net.cn/?id=225 SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols ctrl + d to open dump_file Microsoft (R) Windows Debugger Version 6.12.0002.633......

xueyuse0012
43分钟前
2
0
OSChina 周五乱弹 —— 想不想把92年的萝莉退货

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @罗马的王:分享松澤由美的单曲《地球ぎ》 很久没看圣斗士星矢了 《地球ぎ》- 松澤由美 手机党少年们想听歌,请使劲儿戳(这里) @开源中国首...

小小编辑
今天
11
1
springBoot条件配置

本篇介绍下,如何通过springboot的条件配置,控制Bean的创建 介绍下开发环境 JDK版本1.8 springboot版本是1.5.2 开发工具为 intellij idea(2018.2) 开发环境为 15款MacBook Pro 前言 很多时候,...

贺小五
今天
1
0
javascript source map 的使用

之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大...

粒子数反转
昨天
1
0
谈谈如何学Linux和它在如今社会的影响

昨天,还在农耕脑力社会,今天已经人工智能技术、大数据、信息技术的科技社会了,高速开展并迅速浸透到当今科技社会的各个方面,Linux日益成为人们信息时代的到来,更加考验我们对信息的处理程...

linux-tao
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部