订单系统初识
Posted by 付辉 on Friday, June 8, 2018 共1177字计划将订单系统做一下梳理,包括之前写的IAP
支付。其中一些细节,自己描述的也不是特别满意。后续慢慢的完善。
整个订单系统,概括的讲,其实就是创建订单
、支付订单
、交付权益
这三个过程。但里面涉及的东西,可能必我们想象的要多很多。
订单号
在调用支付时,一般都会要求创建订单号。该订单号是标识本地交易的凭证,必须做到系统唯一。
创建订单号也有很多学问。最差也得做到:首先,不重复;其次,别人不能通过订单号,推测出任何有意义的信息;再次,订单号长度一定要做好控制。
订单再支付
描述一个场景:用户下单之后,并没有立即支付,而是过了一段时间,重新支付之前下的订单。这种情况,如果涉及到扣减库存,还会设置订单的过期时间。
重新支付的时候可能会有点问题:很多支付接口,不允许使用同一个订单号支付两次,即使上一次没有支付成功。换句话说,当你想重新支付时,系统需要生成一个新的订单号。
这样会导致:用户仅仅成功购买了一个商品,后台却生成了数笔订单。后期的统计变得麻烦了不少。
我们的做法便是:在确认支付时,生成两个订单,一个父订单,一个子订单。父订单用来标识用户的购买行为,子订单用户跟第三方支付。
订单统一管理
对于业务简单的部门来说,订单号自己创建,自己管理完全足够了。
但公司想汇总各个部门的订单数据时会变得异常麻烦。所以需要统一的订单创建平台。该平台负责订单的创建、以及后续订单的状态管理。
整个系统也开始变得复杂起来了。订单创建、订单状态更新都需要通知“订单系统”。数据也开始出现不一致。
交付
在用户下单、支付成功之后,将购买的商品或权益给到用户。
实物商品
将用户的购买行为添加到他的购买记录等,让快递员将商品送到用户手中等。
虚拟商品
用户在王者荣耀上买了一套皮肤,这就属于购买虚拟商品。最终腾讯只需要给用户的数据库写一条权益记录就好,不存在发货的过程。
签收
拆单
用户可能一次性购买多个商品,但系统只生成一个订单。对于实物商品,会涉及的拆单流程。比如用户买了肥皂和书,后台系统需要将肥皂交给卖家A来发货,将书交给卖家B来发。同样的商品,可能还会根据卖家和买家的距离来拆单。
签收
那么当更新订单签收状态时,就有疑问了。一个订单,它可能对应多个商品,那么只有商品全部被签收成功,才应该修改为已签收状态。但这种全部成功或者全部失败的状态,本身就很难保证。
所以签收应该针对具体商品。商城系统中,有两个常用的概念:SPU
和SKU
。那小米手机来举例,小米Note
可以当作是一个SPU
,而具体的红色-32G
等能具体到一个实际的个体的就是SKU
。
最终,签收状态应该是订单号
+SKU_ID
来决定的。
表结构设计
在用户下单、支付的过程中,跟订单内部商品的SKU
关系不大,而且为了保证订单的幂等性
,将订单设置为唯一索引是必须的。
在签收的过程中,无法做到针对订单来签收,而应该对订单下的SKU
做签收。所以签收表
应该独立出来。