组件化开发——支付中心

最近在对项目中支付模块的重构,经过三个月的努力,让项目的支付焕然一新。过程是艰辛的,结果是完美的,哈哈。接下来分享一下在重构支付整个流程设计和实现。

为什么要独立模块?随时公司业务不断的发展,项目需要对接不同的支付方式和支付渠道,随着时间的推移,对接的支付方式不断增加,同时支付模块的代码量不断的增加, 很多相同的代码。更严重的是每新增一种支付方式或者支付渠道,工作量也随之在增加。同时业务需求也在变化,老的支付模块就不能适应需求, 即使通过改造去适应都需要花费很多时间。最后经过小组开会讨论,准备对支付中心进行重构,要求不同的支付方式必须独立成模块,能独立运行,不同的支付方式可以随机组合。讨论了一周,也确定了重构的方案。接下来就是开始动手干。

设计思路:创建一个支付中心, 所有终端发起支付,必须先经过支付中心, 支付中心接收到支付请求后, 对发起支付前的基本参数进行检查, 参数检查通过后, 根据不同的支付方式,使用arouter进行路由分发到对应的支付sdk, 具体的支付sdk负责执行支付操作。支付的结果通过回调的方式返还给发起支付的终端。 支付中心提供一个默认的(包含所有的支付方式)支付路由分发器。当然接入支付中心的终端,可以通过配置文件实现自己的支付路由分发。

具体实现

通之前集成的支付方式不难发现,不同的支付方式之间,支付参数和支付成功返回的数据差别不大或者说基本相同。所以首先我们需要对支付请求参数和支付返回的数据进行封装

/**
 * 支付必须的参数
 */
public class PayCenterPayParams implements Serializable {
    /**
     * 支付来源类型
     */
    @PaySourceType.IntDef
    private int paySourceType = PaySourceType.DEFAULT;
    /**
     * 支付方式
     */
    @PaySupportType.IntDef
    private int payType;
    /**
     * 支付、退款、刷新
     * 默认是支付
     */
    @PayIntention.IntDef
    private int payIntention = PayIntention.PAY;
    /**
     * 业务模块与支付模块协商【实际支付信息都存在这个json数据中】
     */
    private String parameterJson;
    /**
     * 是否是重试
     */
    private boolean isRetry;
}

//-----------------------------------------------------------------------------
/**
 * 支付结果
 */
public class PayResults {

    @PaySourceType.IntDef
    private int paySourceType;
    /**
     * 业务模块与支付模块协商【实际返回的支付数据】
     */
    private String resultJson;
    private boolean needPrint;
    /**
     * 记录服务器返回的失败原因
     */
    private String reasonStr;
    /**
     * 是否是重试
     */
    private boolean isRetry;
    /**
     * 分步支付时,各模块已经支付的金额,用于回调时来判断是否支付完成,
     * 若为null,则认为支付完成
     */
    private BigDecimal payedAmount;
}

从代码中可以看出, 支付请求和支付结果中的实际参数我们使用String类型的json字符串代表,通过json字符串在不同模块之间进行传输。至于json字符串包含什么数据, 这个只需要和服务器端约定好即可。

接下来需要为支付结果定义一个回调接口,将支付的结果返回给调用者

/**
 * 支付通用回调
 */
public interface PayCallBack {
    /**
     * 支付结果回调
     * @param code {@link PayCenterConstants}
     * @param results {@link PayResults}
     */
    void onPayCallBack(@PayCenterConstants.PayIntDef int code, PayResults results);
}

约定好支付请求和支付结果数据,接下来我们需要定义支付的公共接口。所有的支付方式都需要实现该公共接口中的方法。接口定义了支付所需要的行为,当然我们肯定也会为该公共接口提供默认的实现或者抽象类, 进步进行封装。

/**
 * 支持中心提供的方法,包括发起读取支付范本,调取支付面板,具体支付实现由各模块自己实现
 * 流程为:
 * 1.各业务模块向支付中心发起读取支付范本的请求,支付中心回传结果;
</>
 * 2.业务模块可向支付中心请求调起支付面板,也可自己实现
</>
 * 3.业务模块向支付中心指定支付方式并发起支付
 * 4.对开发票及抹零操作由各模块自己实现
 */
public interface IPayCenter extends IProvider {

    /**
     * 发起支付
     *
     * @param activity    调起的页面
     * @param payParams   支付参数
     * @param payCallBack 支付回调
     */
    void pay(Activity activity, PayCenterPayParams payParams, PayCallBack payCallBack);

    /**
     * 添加支付代理操作,用于在{@link IPayCenter#pay(Activity, PayCenterPayParams, PayCallBack)}执行前和执行后的操作
     *
     * @param proxy 代理器{@link IProxy}
     */
    void setPayProxy(IPayProxy proxy);

    /**
     * 添加的除支付外的其他操作,用于业务与底层的交互
     *
     * @param context         调起者
     * @param operateParams   {@link PayCenterPayParams}参数封装
     * @param operateCallback {@link OperateCallBack}
     */
    void operate(Context context, PayCenterPayParams operateParams, OperateCallBack operateCallback);


    /**
     * 做一些销毁操作
     */
    void destroy();

    interface IPayProxy extends IProxy {
    }
}

定义一个抽象的类, 对公共接口进行实现,将接口定义的行为隐藏起来。不同的支付方式只需要实现该抽象类中的抽象方法即可

/**
 * 支付基础操作
 */
public abstract class BasePayProvider implements IPayCenter {
    protected PayCallBack payCallBack;
    protected PayCenterPayParams payParams;

    @Override
    public void pay(Activity activity, PayCenterPayParams payParams, PayCallBack payCallBack) {
        this.payParams = payParams;
        this.payCallBack = payCallBack;
        checkPayParams();
        pay(activity, payParams);
    }

    @Override
    public void init(Context context) {
        //TODO:若需要初始化操作,子类重写即可
    }

    @Override
    public void operate(
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
第1章 登录验证模块 1 1.1 开发站点前的配置 1 1.1.1 创建Web站点 1 1.1.2 使用站点安全工具配置身份验证模式 2 1.1.3 配置站点的数据存储方式 4 1.1.4 定制自己的数据存储方式 4 1.2 最普通的登录方式 6 1.2.1 用户注册功能 6 1.2.2 用户的登录功能 7 1.2.3 修改密码功能 8 1.2.4 在登录页面中添加注册导航功能 8 1.2.5 显示登录用户名和用户状态功能 8 1.2.6 根据用户登录身份显示不同效果页功能 9 1.3 基于角色的登录方式 10 1.3.1 在应用程序中启用角色 10 1.3.2 创建角色 10 1.3.3 创建角色访问规则 11 1.3.4 赋予用户角色权限 11 1.3.5 验证角色的登录 12 1.4 匿名用户的授权管理 12 1.5 小结 13 第2章 缓存管理模块 14 2.1 数据库缓存依赖的优点 14 2.2 开始使用缓存 15 2.2.1 开启应用程序的缓存功能 15 2.2.2 配置缓存依赖的数据库 15 2.2.3 为SQL Server启用缓存通知 16 2.3 控件级数据缓存功能 16 2.3.1 添加时间戳和数据 16 2.3.2 观察缓存数据的变 18 2.4 页面级数据缓存依赖功能 18 2.4.1 配置页面的缓存属性 18 2.4.2 完善模块中两个功能的导航 19 2.5 小结 20 第3章 个性设置模块 21 3.1 简单类型的个性设置功能 21 3.1.1 设置个性的项目 21 3.1.2 配置个性信息 22 3.1.3 个性用户登录站点 22 3.1.4 保存个性设置 22 3.1.5 显示个性设置 23 3.2 复杂类型的个性设置功能 23 3.2.1 设计复杂个性的项目 24 3.2.2 配置复杂项目 25 3.2.3 保存复杂项目的设置 25 3.2.4 获取复杂项目的设置并显示 26 3.3 匿名用户的个性设置功能 27 3.3.1 启用匿名用户的个人配置属性 28 3.3.2 设计匿名用户的登录功能 28 3.3.3 将匿名用户的个性设置移植到已验证用户 30 3.4 完善系统对3个功能的导航 31 3.5 小结 31 第4章 投票模块 32 4.1 一个简单的投票系统 32 4.1.1 设计投票功能的数据存储方式 32 4.1.2 投票项目管理功能 33 4.1.3 投票功能 37 4.1.4 图形显示投票结果功能 38 4.2 防止重复投票技术 40 4.2.1 利用Session对象 40 4.2.2 利用Cookies对象 41 4.2.3 验证IP和登录时间 41 4.2.4 小范围调查 42 4.3 一个完整的投票系统 42 4.3.1 投票系统的功能模块 42 4.3.2 投票系统的数据库架构 43 4.3.3 数据库中数据之间的关系 43 4.3.4 投票主题管理 44 4.3.5 投票项目管理 52 4.3.6 投票功能管理 54 4.3.7 投票系统后台权限管理 59 4.4 小结 60 第5章 RSS模块 61 5.1 RSS的定义 61 5.2 RSS的作用 61 5.3 RSS的订阅原理 62 5.3.1 RSS的工作原理 62 5.3.2 RSS订阅工具的使用 63 5.4 在网站内加入RSS功能 65 5.4.1 使用Microsoft提供的RSS工具包 65 5.4.2 一个简单的RSS阅读器 66 5.4.3 一个复杂的RSS阅读器 67 5.4.4 让站点提供订阅功能 69 5.5 小结 70 第6章 在线编辑模块 71 6.1 在线编辑的原理 71 6.2 编辑器的界面 71 6.3 一个简单的在线编辑器 72 6.3.1 在线编辑窗口的界面设计 72 6.3.2 在线编辑的功能实现 73 6.3.3 在线编辑的运行效果 74 6.4 多功能在线编辑器的介绍 74 6.4.1 FreeTextBox编辑器 74 6.4.2 FCKEditor在线编辑器 76 6.5 小结 79 第7章 在线支付模块 80 7.1 在线支付介绍 80 7.1.1 在线支付的安全保障 80 7.1.2 在线支付的优点 80 7.2 在线支付的流程 81 7.3 使用支付宝实现在线支付 81 7.3.1 支付宝接口概述 81 7.3.2 支付宝接口服务下载 81 7.4 使用支付宝实现在线支付的实例 82 7.4.1 在项目中加入支付宝程序 82 7.4.2 设计订单提交功能 82 7.4.3 获取支付成功后的返回信息 84 7.4.4 设置支付过程中的通知 88 7.4.5 实现订单到支付宝的提交 90 7.5 小结 92 第8章 电子邮件模块 93

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值