文档章节

代码设计之多渠道支付

zgw06629
 zgw06629
发布于 2015/04/29 19:17
字数 673
阅读 102
收藏 0
点赞 0
评论 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
粉丝 15
博文 54
码字总数 30471
作品 0
海淀
程序员
支付系统设计

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

daydaygo ⋅ 2017/11/21 ⋅ 0

支付渠道那些事

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

信志 ⋅ 2016/09/14 ⋅ 0

支付流程的坑点

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

信志 ⋅ 2016/08/22 ⋅ 0

支付系统0X00: 支付系统预研

date: 2017-11-19 17:12:16 title: 支付系统0X00: 支付系统预研 最近在写支付系统, 之前公司写了一版, 量级比较小, 纯同步, 应用层就简单的 api + task, 项目结构也简单: lib: 用来存放项目核...

daydaygo ⋅ 2017/11/21 ⋅ 0

如何做一个对账系统

在互联网行业中只要涉及到支付,必然就会有对账的需求,几乎所有互联网公司的业务中多多少少的都会涉及到支付,大一点的公司甚至都标配有了自己的第三方支付公司,因此对账具有普遍性。对账系...

纯洁的虫纸 ⋅ 2017/07/20 ⋅ 0

让比特币交易更快更便宜,基于“闪电网络”的电子商务网站将问世

  2014 年,约瑟夫·朴恩(Joseph Poon)和萨帝厄斯·追亚(Thaddeus Dryja)还是旧金山比萨茶会上闲逛的“比特币迷”工程师。他们的讨论常涉及比特币的核心问题,那就是:如何让比特币更有...

DeepTech深科技 ⋅ 01/25 ⋅ 0

手游渠道 SDK 统一接入框架--TypeSDK

TypeSDK是一个开源的统一手游渠道SDK接入框架,拥有80个海内外渠道,具备简单接入、快速出包、运营工具、分权限管理、产品数据打点等功能。实施周版本更新制度,确保每个每个使用者直接下载就...

TypeSDK ⋅ 2016/11/10 ⋅ 0

诚招兼职程序员,月薪可达3k-8k,特招matlab、Java

我们希望成为程序员的“Uber”团队!增值程序员业余时间! 主要承接国内外学生课程设计相关内容,海量稳定优质的订单,强大的线下渠道团队推广 如果您是学生,可以在学习的同时还能获得不菲的...

老铁够稳 ⋅ 2017/03/18 ⋅ 0

诚招兼职程序员,月薪可达3k-8k,特招matlab、Java

我们希望成为程序员的“Uber”团队!增值程序员业余时间! 主要承接国内外学生课程设计相关内容,海量稳定优质的订单,强大的线下渠道团队推广 如果您是学生,可以在学习的同时还能获得不菲的...

老铁够稳 ⋅ 2017/03/18 ⋅ 0

国内首款开源的互联网支付系统roncoo-pay

roncoo-pay是国内首款开源的互联网支付系统,其核心目标是汇聚所有主流支付渠道,打造一款轻量、便捷、易用,且集支付、资金对账、资金清结算于一体的支付系统,满足互联网业务系统的收款和业...

liwei2000 ⋅ 2017/07/31 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何使用serverchan微信推送告警

之前实现推送告警信息到微信的方法有如下几种: 1、通过企业公众号实现----收费: 2、通过QQ邮箱,在微信平台上开启收到邮件进行提醒; 3、第三方告警平台API,一般也是收费的; 不过最近看文...

问题终结者 ⋅ 30分钟前 ⋅ 0

TCP的RPC

RPC就是远程方法调用(Remote Process Call ),包含了客户端和服务端,涉及了对象的序列化传输。 1.服务端启动,注册远程调用的类2.客户端发送请求信息包含类、方法、参数的一些信息、序列化传...

Cobbage ⋅ 50分钟前 ⋅ 0

IOS-UI UI初步代码布局添加事件

ISO开发界面,UI是必须学习的一部分,其实很早之前想学来了,一直没有沉下心来学习。看到IOS的代码风格和布局就别扭的不行,跟java代码和android布局比较显得不是那么方便,所以一直到现在。...

京一 ⋅ 今天 ⋅ 0

浅谈OpenDaylight的二次开发

OpenDaylight作为一款开源SDN网络控制器,依托于强大的社区支持以及功能特性,成为了目前主流的SDN网络控制器开发平台。在比较稳定的OpenDaylight Helium版本中,已经为开发者提供了大量的网...

wangxuwei ⋅ 今天 ⋅ 0

API 开发中可选择传递 token 接口遇到的一个坑

在做 API 开发时,不可避免会涉及到登录验证,我使用的是jwt-auth 在登录中会经常遇到一个token过期的问题,在config/jwt.php默认设置中,这个过期时间是一个小时,不过为了安全也可以设置更...

等月人 ⋅ 今天 ⋅ 0

Java NIO之文件处理

程序要操作本地操作系统的一个文件,可以分为以下三个部分: 对文件位置的操作 对文件的操作 对文件内容的操作 其中,对文件内容的操作在 Java NIO之Channel 中已经有了介绍,通过FileChann...

士别三日 ⋅ 今天 ⋅ 0

Maven的pom.xml配置文件详解

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.......

小海bug ⋅ 今天 ⋅ 0

解决httpclient超时设置不生效的问题

最近公司有项目需要通过http调用第三方服务,且第三方服务偶有超时,故需要设置一定的超时时间防止不响应的情况出现。 初始设置如下: [java] view plain copy //超时设置 RequestConfig re...

Mr_Tea伯奕 ⋅ 今天 ⋅ 0

过滤器Filter和拦截器HandlerInterceptor

过滤器 依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要...

hutaishi ⋅ 今天 ⋅ 0

Redis入门详解(转)

Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis应用场景 Redis总结 Redis简介: Redi...

xiaoyaoyoufang ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部