前言
- 从事订单支付系统的设计研发已经接近俩年了,一直想好好把其中一些思考沉淀下来。一是回顾之前的设计,看看迭代过程中的一些思路是否合理,如果给自己从头再来的机会(不用考虑苦逼的兼容脏数据等等问题)能否设计得更好?二来自己一直想培养写博客的习惯,却从15年一直到现在都没有养成,希望从现在开始能坚持下来一步一步写下去(无论技术还是感悟),此系列文章算是个开头,希望这个开头不太难
订单系统的思考
订单系统的定位
作为底层支撑系统是一个承上启下的位置,上游对接商品用户等业务系统,下游对接支付系统。由业务系统发起下单,下单成功之后再交由支付系统去支付。订单系统只提供底层支持,由商品业务系统控制流程。但当有多种业务系统时,代码非常容易冗余不容易维护,迭代成本往往也很高。
订单作为中心系统,控制订单流程,网关直接到订单系统,订单系统在下单之前,下单之后分别调用业务系统完成订单风控,以及订单通知,下单成功之后,后续支付流程完成交由支付系统来控制,订单和支付各自职能划分清楚.
订单系统核心功能 (个人认为)
- 记录交易快照(留下凭证既订单记录)
- 订单状态流转(完成交易闭环,支付,退款,取消等等)
订单系统设计
订单设计(极简版本)
- 这是一个最基础的订单系统设计这里大致讲解每部分的作用
- 统一风控主要做统一的下单前置校验(例如前端参数以及金额相关校验)
- 统一金额处理可以处理优惠券分配,服务费,积分分配等等金额统一相关的部分
- 配置该业务订单是否需要业务系统前置校验,三方校验,后置通知等等
- 创建无效订单可以为后续提供幂等处理(订单号),以及减少失败后置处理
- 订单后置处理如需要应该异步化完全和下单流程分割开来
- 业务系统部分例如前置冻结库存,成功之后扣除库存通知用户等等
状态设计
- 设计一个好的订单系统,前提肯定是要对状态归类,以及设计一套合适并且易于扩展迭代的订单状态,状态机的部分我们留到下篇文章单独讲解,此处我们先简要介绍几种常用订单状态
- 无效状态
- 初始状态
- 支付成功状态
- 交易完成状态
- 退款中状态
- 退款状态
- 异常关闭状态
- 每种大业务类型的订单除了以上列出的主要状态外,肯定还会有各自的一系列子状态需要定义,一般各自的订单子状态不一致。此处定义枚举建议间隔(例如0初始状态,3支付中)方便后续扩展。
订单表设计
- 极简订单表结构
字段名 | 类型 | 备注 |
---|---|---|
id | bigint | 自增主键id |
order_id | varchar | 订单id内置部分订单信息(唯一键) |
parent_order_id | varchar | 父订单id |
top_order_id | varchar | 顶级订单id |
third_order_id | varchar | 外部订单号 |
order_price | bigint | 单位分,订单金额 |
order_status | int | 订单状态 |
order_sub_status | int | 订单子状态 |
biz_type | int | 业务类型 |
sub_biz_type | int | 业务子类型 |
version | bigint | 版本号(乐观锁用到) |
extend | text | 存入业务相关信息 |
refund_price | bigint | 退款金额 |
- 以上省略创建时间,更新时间,创建者id,姓名,更新者id,姓名等建表常规字段
- 订单金额相关 肯定不止订单金额,退款金额俩部分。这里只考虑最简单的其它例如优惠金额,支付时间,结算时间等等省略
- 业务相关信息后续分表会讲到,这里先直接一个extend代替,例如存入商品信息,收货地址等等.