本支付系统提供企业支付与个人支付的单通道支付和混合支付方案。
二、模块结构
1. 总体架构设计
模块划分,从上至下,各层通信。
2. 分层意义
为了项目的可扩展性和可维护性。进一步的追求高可用、高并发的支持。
3. 分层说明
- 终端显示层,包括各个终端的收银台页面,审批页面,审批短信等。开放接口层,为直接暴露给外部的 https口,与 service 层直接通信,主要用于与外部系统集成服务。
- Web 层,用于处理对显示层的数据渲染,对顶层操作的转发控制。这层的原则是”轻”,避免逻辑处理,可以允许少量的校验,与 service 层保持一对一关系。
- Service 层,负责对支付流程的抽象,支付安全的前置校验,支付过程的处理等。
- Manager 层,可以对 Service 层通用的逻辑的下沉,多个 Dao 层仓库的组合。
- Proxy层,通过代理层引用外部接口,避免外部接口的变化影响主流程。代理层可以直接与 Service 或 Manager层通信。
- Dao 层,原则上不进行逻辑处理,与数据库表一一对应。
- 在实现一个新功能时,应充分考虑代码在项目中结构位置。
三、表结构设计
1. 支付计划
- 一个支付计划由一个或多个业务订单组成
- 一次成功的支付可以有一个或多个支付行项目
- 支付计划不支持修改。订单的二次支付,重新生成一个新的支付计划
2. 退款计划
- 一个业务系统的退单对应一个退款计划
- 退单退款时,根据正向订单来校验订单是否有可退的金额
- 一个退款计划可以有一个或多个退款行项目
- 退款任务分为 待客服审批 或 待确认定时任务 的退款任务两种
3. 企业账户
- 企业账户的 可用额度为 授信额度 +企业余额
- 支付计划的支付行项目与企业账户的交易流水一一对应
4. 个人账户与现付
- 个人账户的金额来源于现付(支付宝+微信)的金额
- 个人账户 与 个人账户行项目为 1对多关系
- 个人账户在途物质为订单使用个人账户的临时金额记录
四、支付
1. 收银台时序图
2. 现付流程图
- 现付付款在整个支付系统的流向图
- 业务系统出票失败或者拒单退款后,客户现付付款的钱,转入个人余额,记录一笔个人账户行项目
- 客户使用个人账户付款,扣去个人余额,记录在途物资
- 个人账户退款,增加个人账户余额,更新账户行项目
- 定时任务,把个人账户行项目对应的金额,原路返回
3. 构建支付对象
- 订单是否能支付
- 操作人是否合法
- 因公与因私订单不能合并支付
- 二次支付的订单不能与非二次支付的订单一起支付
- 是否显示个人账户,个人账户金额大于0则显示
- 是否显示公司账户
- 管控规则不允许使用企业支付
- 违规信息不允许使用企业支付
- 差旅类型不唯一不允许使用企业支付
- 有出租车订单收银台不显示企业支付
- 因私订单,不显示企业支付
- 成本中心不唯一,不显示企业支付
- 企业账户不可用,不能使用企业账户支付
- 是否显示 公司账户支付 - 全额支付
- 选择了差标自付的违规原因,则不能显示公司账户支付-全额支付,其他情况显示
- 是否显示 公司账户支付 - 差标支付
- 乘客管控规则中有能使用差标支付的,且有订单金额大于差标金额的订单,则显示。其他情况不显示
- 企业支付相关校验点
- 是否有能使用的沿用授权订单
- 此次支付是否需要审批
- 此次支付是否需要确认差旅事由
- 此吃支付是否需要确认输入密码
4. 支付系统关键词
-
二次支付
业务系统订单可以在支付系统发起多笔成功的支付,故订单和支付计划为 1 对 多关系。
-
沿用授权
授权过的订单在出票失败后,支付系统会生成一笔待沿用授权的订单授权记录,待客户重新下单过后,系统校验两笔订单金额差异,日期差异,地点差异。如果符合条件,新订单则可以使用老订单的授权。
-
超标自付
超标自付,既差标内的金额使用公司账户支付,超出差标的金额,使用个人支付。
-
支付审批
公司支付订单,可能需要审批,外部系统(工作流/集成)决定支付下一步状态。
-
支付集成
集成支付审批工作流,推送支付信息给外部系统。
5. 支付底层实现
(1) 操作器uml
- Operation 操作器,定义一个操作器的基本 init(), execute(), rollback() 方法。
-
PayOperation 支付操作器,继承自Operation,添加支付操作的相关行为,prePay(), doPay(), postPay()。
-
OperationExecutor 操作执行器工具类,用来运行操作器的相关方法。
-
AbstractPay,抽象支付操作类,实现PayOperation,实现基本的操作器的相关行为,例如:支付初始化,初始化日志锁,异常账户回滚实现等。
-
MixedPayOperation 真正支付操作实现类,继承 AbstractPay,实现 PayOperation的 prePay ,doPay,postPay 方法。
(2) 支付过程
1
|
/**
|
(3) 实现操作器示例
- 实现一个支付操作类 TestPayOperation,继承抽象支付类(AbstractPay),实现 prePay ,doPay,postPay方法
1
|
public class TestPayOperation extends AbstractPay<PaymentInfo>{
|
- 通过操作执行器(OperationExecutor)调用 TestPayOperation:
1
|
|
(4) 数据加密
#####(5) redis分布式锁
#####(6) mysql 乐观锁
五、退款
1. 退款底层实现
#####(1) 退款过程
1
|
public abstract class AbstractRefund{
|