简易版订单系统

前言

  • 从事订单支付系统的设计研发已经接近俩年了,一直想好好把其中一些思考沉淀下来。一是回顾之前的设计,看看迭代过程中的一些思路是否合理,如果给自己从头再来的机会(不用考虑苦逼的兼容脏数据等等问题)能否设计得更好?二来自己一直想培养写博客的习惯,却从15年一直到现在都没有养成,希望从现在开始能坚持下来一步一步写下去(无论技术还是感悟),此系列文章算是个开头,希望这个开头不太难

订单系统的思考

订单系统的定位

  • 作为底层支撑系统是一个承上启下的位置,上游对接商品用户等业务系统,下游对接支付系统。由业务系统发起下单,下单成功之后再交由支付系统去支付。订单系统只提供底层支持,由商品业务系统控制流程。但当有多种业务系统时,代码非常容易冗余不容易维护,迭代成本往往也很高。
    old

  • 订单作为中心系统,控制订单流程,网关直接到订单系统,订单系统在下单之前,下单之后分别调用业务系统完成订单风控,以及订单通知,下单成功之后,后续支付流程完成交由支付系统来控制,订单和支付各自职能划分清楚.
    new

订单系统核心功能 (个人认为)

  1. 记录交易快照(留下凭证既订单记录)
  2. 订单状态流转(完成交易闭环,支付,退款,取消等等)

订单系统设计

订单设计(极简版本)

new

  • 这是一个最基础的订单系统设计这里大致讲解每部分的作用
  1. 统一风控主要做统一的下单前置校验(例如前端参数以及金额相关校验)
  2. 统一金额处理可以处理优惠券分配,服务费,积分分配等等金额统一相关的部分
  3. 配置该业务订单是否需要业务系统前置校验,三方校验,后置通知等等
  4. 创建无效订单可以为后续提供幂等处理(订单号),以及减少失败后置处理
  5. 订单后置处理如需要应该异步化完全和下单流程分割开来
  6. 业务系统部分例如前置冻结库存,成功之后扣除库存通知用户等等

状态设计

  • 设计一个好的订单系统,前提肯定是要对状态归类,以及设计一套合适并且易于扩展迭代的订单状态,状态机的部分我们留到下篇文章单独讲解,此处我们先简要介绍几种常用订单状态
  1. 无效状态
  2. 初始状态
  3. 支付成功状态
  4. 交易完成状态
  5. 退款中状态
  6. 退款状态
  7. 异常关闭状态
  • 每种大业务类型的订单除了以上列出的主要状态外,肯定还会有各自的一系列子状态需要定义,一般各自的订单子状态不一致。此处定义枚举建议间隔(例如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代替,例如存入商品信息,收货地址等等.

总结

  • 一个微型订单系统甚至只要一张订单表+状态机就能够搭建(订单状态机
  • 任何一个复杂的订单系统也是由微型订单系统扩展而来,搭建订单系统的时候,前期功能可以简单,但架构一定要分明,方便后续扩展。一个成熟的订单系统肯定都是由业务的不断演进不断迭代才越来越优秀。
  • 订单系统的一大难点在于操作的原子性,属于与用户交易打交道的第一道关口,任何异常以及细节都需要仔细考虑(订单异常情况处理)