交易系统一直是电商的核心模块, 几乎所有业务都围绕其展开, 看似简单的下单流程, 实际涉及的模块, 内容也很庞杂. 这次就把订单下单的整体链路抽象出来, 与大家分享.
说到下单, 对于用户而言就是选择商品 - 下单 - 支付 - 商品运输 - 确认收货这样简单的主流程, 保证了即使是网购新手也可以很快上手.
但对于电商交易系统来说, 订单的生命周期远不止上述流程那般简单. 见下图, 对于电商平台来说一个订单的生命周期涉及众多系统, 下图也仅仅是列出了各大系统间的交互流转, 且仅涉及正向流程, 逆向流程会更加复杂.
01 关于订单
1. 什么是订单
首先来聊一下什么是订单?
订单可以简单理解为 买家与卖家签订的一份具备法律效应的合约 . 一般情况下, 合同的订立有要约和承诺两个程序. 卖家展示商品及其价值的行为, 便属于要约; 购买者确认购买商品并提交订单的行为属于承诺, 订单提交后, 合同即成立并生效. 所以大家可以简单理解为订单其实就是一份客户与商家签订的合同, 具有法律效益.
2. 订单的生成与流转
参考上文, 如果从前端的体验来看, 订单的生成就是加车后结算或立即购买, 进入结算界面确认订单各项信息无误, 提交后即生成订单.
但我们从订单在内部系统生成的流程来看, 在生成订单前需要内部各大系统进行配合与支撑, 包括风控系统, 商品系统, 营销系统, 会员系统, 库存系统等. 上述系统流程也仅是对交易主流程的梳理, 涉及数据在各系统中如何交互并没有列出, 可见整个电商交易系统是何其复杂.
02 风控系统 -- 风险订单检测, 拦截
说到风控系统, 最容易联想到的是银行借贷, P2P 等金融领域的风险控制. 无论是金融行业还是电商行业, 风控的本质都是保证平台利益不受损失.
电商订单风控主要侧重于两防 -- 防刷单; 防羊毛党.
1. 防刷单
商家刷单影响平台流量分配, 间接影响商家管理体系的构建; 商家刷单体系大概历经了两个时期: 野蛮生长, 集中刷单; 平台监管, 精细化刷单.
电子商务起步初期, 唯销量论英雄,"培养" 了商家们的刷单习惯, 加上平台监管缺失, 一个人一台电脑就能刷上一天, 那时候管刷单不叫刷单, 叫刷钻 / 刷皇冠, 主要刷的是店铺等级.
但 "好日子" 很快到头了, 随着平台的流量分配由店铺变为单品, 加上管理规则, 风控体系不断完善, 商户们的刷单成本也越来越高, 刷单的工作也要交给 "专业" 人士来, 所谓精细化刷单就是模拟用户真实下单场景, 骗过系统, 让它认为就是普通用户在下单. 精细到怎么搜到商品, 需要浏览多少个商品, 每个页面停留多长时间, 是静默下单还是咨询下单都有严格的规范.
业内早就形成了认知: 没有一劳永逸的防刷单策略, 最好的方法就是不断提高刷单的成本.
2. 防羊毛党
羊毛党薅羊毛的做法直接影响平台 / 商家收益, 损害正常用户购物体验. 说到羊毛党离不开另外一个词: 黑产. 单兵作战的羊毛党不可怕, 可怕的是成体系作战的黑产团队, 他们往往分工明确, 主攻电商平台业务 (规则) 漏洞和系统 BUG, 薅上一天够吃一年.
上述流程图, 在用户提交下单申请后会经过风控系统的风险检测, 但此时的风险检测较为初级, 主要针对确定性事件如用户黑名单, 下单环境等事件进行下单拦截.
因为下单时风控系统能够拿到的字段信息较少, 缺乏大量数据支撑, 难以准确判断用户下单行为, 且下单流程属于高并发场景, 系统反馈需要在毫秒级完成, 进行复杂的风控检测严重拖慢系统进程, 因此更复杂的风控会在用户下单成功后异步进行.
进行异步风控检测后, 系统会对命中风控策略的订单进行关闭(取消订单), 当然风控并不只是拦截订单, 在复杂的场景下还需要有报警机制, 人工介入.
拼多多在 19 年 1 月就因为优惠券事件被黑产薅了数千万羊毛, 就是因为缺乏有效的风控机制.
03 商品系统 -- 商品信息的获取
订单生成时需要通过商品系统获取商品基础信息, 数量, 价格. 同时部分电商平台还会记录交易快照, 同样是需要商品系统支持.
1. 关于交易快照
什么是订单商品快照(交易快照)? 看字面意思, 很容易让人理解为用户下单时针对订单商品详情的一个快照(截图), 其实严格来讲, 商品快照是一个 静态数据合集 , 记录了用户下单时的商品信息, 包含: 商品图片, 标题, 描述, 服务等要素.
淘宝是国内较早启用交易快照的电商平台, 为了解决商家与用户交易纠纷时难以追溯用户下单时的商品情况, 淘宝的产品经理引入了交易快照的概念, 即用户的每一次下单, 都会对下单时的商品信息做一个记录, 快照作为买卖双方发生交易的凭证, 任何交易纠纷或者投诉都将以快照为准.
大多数电商平台做交易快照的初衷是为了解决交易纠纷, 此外, 交易快照还运用于法律诉讼场景, 法院进行相关诉讼的裁定时, 是认可交易快照作为证据的, 但需要证明快照就是用户下单时的商品快照, 无法被篡改.
2. 交易快照的记录
交易快照的记录: 目前主要有两种记录方式, 如图:
第一种: 用户每下一单都对订单商品信息进行一次信息记录, 此操作主要由 交易系统 完成, 弊端也很明显在下单高峰期, 会对系统性能产生影响, 且数据存储量大. 该方案主要 适用于低频交易场景 , 如大宗商品交易等.
第二种方法: 由 商品系统 (基础数据)对每一次商品信息变更做备份, 之后根据用户下单时间映射商品快照. 此方案适用于 高频交易场景 , 且对高并发下交易系统性能不会产生太大影响.
04 库存系统 -- 商品库存校验
1. 库存的定义
关于库存的定义, 百科上给出的解释是:"仓库中实际储存的货物". 但这里我特别提到了虚拟库存, 为了与实际仓库库存做区分.
目前商家在电商平台维护的库存都叫虚拟库存, 虚拟库存可以简单理解为不存在的库存, 它并不跟实际仓库库存关联, 可以认为虚拟库存就是商家指定的平台的一个渠道可售库存. 如果商家有一批商品正在生产中, 采购中, 运输中或正在入库, 亦或者商家觉得能承担住超卖的风险, 有办法从其他地方调货, 设置虚拟库存时就可能大于实际仓库库存.
2. 库存预占与库存校验
说到库存预占, 在电商发展过程中有个很经典的问题: 是下单减库存还是支付减库存?
现在想一想, 应该在什么时候减库存?
线下实体商超是怎样的?
这里不考虑实体商超仓库库存的情况, 只考虑货架库存. 什么时候减库存呢? 或者说什么时候这个库存会被用户占据呢, 应该是在用户从货架拿走商品, 放入购物车的时候.
那么线上购物流程也按照加入购物车即减库存呢? 显然是不行的, 线上购物车的 "加车" 操作几乎是 0 成本, 决定它更像是作为一个商品收藏池或备忘录, 用户把备选的商品放入购物车后再进行二次选品, 加车商品数远大于用户实际购买数, 故在购物车即扣减库存效率是低下的.
如果是在下单的时候扣减库存呢?
相当于用户下单, 系统已经把相应库存分配给此用户, 用户支付成功后即可发货, 这是正常的流程. 但会出现 下单不支付恶意预占库存 的情况, 导致商家商品未能及时售出, 销售受损.
如果更进一步, 支付成功时再扣减库存呢?
此方法一定程度提高了恶意下单的门槛. 但问题也产生了, 当商品供不应求, 出现大量用户抢购的情况, 此时大部分用户都能下单成功, 但在 支付环节仅有少部分用户可完成支付 , 对于未成功支付的用户来说, 体验太差.
上述两种有效方案, 无论是下单减库存还是支付成功减库存, 都不是完美的解决方案. 那么应该选择哪一种呢? 苏杰在《淘宝十年产品事》中回忆当时淘宝的产品经理也是纠结于选择哪种方案, 最后折中, 提供两种方案, 商家自行选择.
在我看来, 对于平台型电商, 下单减库存优于支付成功减库存 .
从体验角度上看: 用户 (购物) 体验是平台型电商的核心竞争力. 下单减库存影响商家销售, 支付减库存影响用户体验, 所以从购物体验角度做取舍, 下单减库存对用户较为友好.
从系统层面上看, 支付减库存是要比下单减库存复杂的. 支付减库存涉及 订单系统 - 库存系统 - 支付系统的交互, 而下单减库存仅由订单系统 - 库存系统完成即可. 支付减库存在高并发的场景下容易出现超卖现象.
下单减库存存在的问题: 恶意下单不支付. 可以通过系统规则来解决: 如单用户限购, 超时未支付自动取消订单(库存返还)
05 订单系统 -- 订单信息记录
1. 订单拆单
1)为什么要进行订单拆单?
核心有两点: 便于结算; 便于发货 .
主要是围绕上述两点核心进行, 常见拆单规则有:
按商家拆单; 不同商家间需要拆单
按仓库拆单; 不同仓库间需要拆单
按商品重量, 体积拆单; 快递公司对包裹最大体积 / 重量有要求
按商品价值拆单; 贵重, 易损商品单独拆分等
按发货方式拆单; 如实物商品与虚拟商品混合下单, 发货方式不同
按配送时效拆单; 如正常商品与预售商品混合下单, 发货时效不同
具体拆单规则根据不同平台不同业务场景而异, 按照便于结算, 便于发货两大方向去做订单拆分便能满足大部分业务需求.
2)什么时候拆单
先来看下京东, 淘宝分别在什么时候进行拆单
京东: 用户订单支付成功后进行拆单
淘宝: 用户提交订单, 支付前即对订单进行拆单
那么什么时候拆单有何讲究? 因为业务形态不同, 淘宝以商家为主, 京东以自营为主. 故淘宝拆单逻辑较为简单, 按商家拆单即可满足绝大部分拆单诉求; 而京东因涉及自营仓 + 商家, 除了商家间的拆单, 还涉及仓间 / 仓内拆单, 拆单逻辑更为复杂, 将拆单逻辑后置到支付成功后, 能够减少无效拆单(未支付订单不拆单), 提升高并发时系统性能.
所以在什么时候进行订单拆分, 遵循两大原则:
占用资源最小原则(特别要考虑高并发场景);
订单推送前需要完成拆单(推送至商家 / 仓库前都需要完成拆单)
2. 订单优惠计算与优惠分摊
早期的淘宝, 商品就一个价格, 即售卖价, 对于商家, 用户来说都足够简单, 所见即所得. 但这种平衡很快被一个功能打破 -- 购物车. 购物车的上线标志着淘宝进入营销时代, 后来我们熟知的满减, 满折, 满赠, M 元 N 件等促销玩法都要仰仗购物车. 那么订单优惠是怎么计算的呢?
1)递进式门槛计算
既然促销活动有了, 有促销就会有优惠, 这些优惠怎么算呢, 让我们记住这个词[递进式门槛计算] , 就是它, 让很多用户抓狂.
提问: 购买两件商品 A 和 B,A 单品优惠价 100 元; B 单品优惠价 200 元, 参加 店铺促销满 300 减 50 , 店铺 优惠券满 280 减 40 ; 同时还参加 跨店铺满减, 每满 290 减 50 . 问: 在递进式门槛计算规则下, 到手价是多少?
按照[递进式门槛计算] 最终到手是: 250, 这就是一顿操作猛如虎, 一看优惠两块五.
递进式优惠计算核心规则即: 根据上一层级优惠扣减后的金额来判断是否满足下一层级的优惠门槛 . 所以在[递进式门槛计算] 时期, 经常出现用户看到某一商品参加了多种活动, 领取了各种优惠券, 最终结算时仅可以使用一种优惠而大骂商家, 平台虚假营销的情况.
2)平行式门槛计算
前文我们提到: 购物体验是平台型电商的核心竞争力, 在此背景下, 淘宝, 京东于 18 年, 19 年相继用[平行式门槛计算] 替代[递进式门槛计算] .
采用平行式门槛计算规则后, 优惠计算清晰明了, 以前要纠结各级优惠的触发门槛, 现在凑单只需要盯着各类优惠里门槛最高那个就行, 如图:
此规则的上线对于平台用户, 商家来说无疑是利好的, 用户能够一目了然感知优惠力度, 商家也能清楚掌握让利程度.
但这里面存在一个大坑, 即平台在切换优惠计算规则时历史产生的促销活动, 优惠券怎么办? 不处理, 商家就要大出血, 如图.
淘宝, 京东面对此坑时也是毅然在上线前将平台所有满减, 满折, 满赠等促销活动及优惠券作废.
3. 订单状态的定义
我们常见的订单状态, 如下: 待付款 - 待发货 - 已发货 - 已完成 - 已评价 (已评价状态有时也不作为主状态存在)
已关闭, 异常
作为电商行业从业者需要经常跟订单打交道, 每个人都能随口说出订单状态包含哪些, 甚至连会网购的大妈都能说出个 123. 订单状态算是一套很成熟的体系, 对于缺少电商行业经验的产品来说, 在定义订单状态时直接照搬这一套, 大概率都不会出错.
但在这里我还是想聊一下对于订单状态的思考:
首先, 说一下状态, 这个词对于产品经理来说一定不陌生, 日常工作中各种单据, 逻辑判断都会用到. 什么是状态? 我的理解: 事物处于某个稳定的情态, 在无外力的影响下会一直处于一个稳定态, 这个稳定态就可以称为状态.
那么反过来说, 在外力的作用下状态是可以改变的, 这里就衍生出来产品设计中的一个法则叫 "一动一态" 即 两状态间有任何数量级的操作都可以抽象为一个动作 , 一动一态的好处主要体现在: 降低用户认知成本; 便于制定, 处理各种状态值
回到订单状态, 如图, 用户下单后的一系列操作其实是由三个维度的状态 (支付状态, 物流 状态, 评价状态) 构成, 但 多维度状态的存在容易引起认知混乱 , 为解决这一问题, 我们倾向于创建一个全局维度的状态 -- 订单状态
但如上图中所示, 构建后的全局维度涉及订单下单 - 配送 - 签收评价全流程, 涉及: 待支付, 待发货, 待揽件, 运输中, 派件中, 已签收, 已评价, 状态值依然庞杂 . 想
一下, 我们创建全局维度状态要解决的就是降低使用者 (商家, 消费者) 认知成本, 知道在什么步骤需要执行什么操作, 所以我们归纳下上述订单状态流转时进行相关操作的执行角色:
消费者: 支付, 签收, 评价
商家: 发货
物流公司: 揽件, 走件, 派件
我们会发现, 需要消费者, 商家操作的仅有: 支付, 发货, 签收, 评价. 在定义一动一态法则时我们讲到: 任何数量级操作都可以抽象为一个操作, 为了降低使用者 (商家, 消费者) 认知成本, 我们可以把[发货, 揽件, 走件, 派件] 这一流程抽象为一个操作 -- 发货. 这样一来就明了了
4. 订单号的设计
订单号的设计是一门艺术, 能够参与订单号规则设计是一件令人兴奋的事情, 这种机会通常只在电商项目从 0 到 1 的时候有. 那么订单号的设计应遵循哪些原则呢?
1)唯一性
订单号作为订单表的主键, 需要确保唯一性.
2)易读性
这里易读性主要体现在系统易读性和沟通易读性.
要求订单号不宜过长且尽量为纯数字, 不宜出现字母, 符号, 数字混用的情况, 否者对于系统存储, 查询性能, 以及与用户的沟通成本来说都是一种负担.
3)安全性
非特殊情况尽量不要在订单号中带入平台运营特征信息, 如订单数量, 避免泄露运营数据. 除非故意要让竞对知道你的运营数据.
瑞幸咖啡较早之前门店订单量就是逐一增加, 后续也加入了随机因子, 就是担心外界通过订单编号获得店铺每天成交量.
4)扩展性
订单号设计需要考虑扩展性, 如随着平台业务发展, 订单量激增订单号不够用的情况
5)语义性
订单编号规则中加入带有语义的特征信息, 能在一定程度上提升平台人员处理订单的效率与便捷性.
常见的特性信息有: 订单生成时间(年月日), 下单渠道, 支付渠道, 业务类型等, 但 订单编号中不宜携带过多特征信息 , 否则会出现不法分子通过描述订单信息博取用户信任进行实施诈骗.
说到语义性, 细心的同学会发现, 自己淘宝订单号后 6 位都是一样的. 订单号后 6 位其实就是用户 id 后 6 位. 那么淘宝订单编号中用了用户 id 后 6 位是否代表了语义性? 答案是否定的, 因为只用后 6 位 id 并不能准确定位到某一个用户.
那么淘宝订单编号后 6 位用户 id 后 6 位的目的是什么?
翻遍了百度, 知乎, 没有找到答案.
我是偶然间翻到一份淘宝技术演变 PPT, 看到订单表分库的逻辑时才恍然大悟.
一般的平台型电商, 订单量大, 为保证查询检索速度, 都会采用分库的形式, 将巨量的订单信息分库存储, 一般情况下订单系统同时维护了一个订单号和 userid 的关联关系, 先根据订单号查到 userid, 再根据 userid 确定分表进而查询得到内容. 而淘宝在订单号上下功夫, 通过订单号后 6 位直接锁定库表, 大大提升高并发下的系统查询性能.
从这个策略我们也可以看到淘宝用户订单库是按照用户 id 后 6 位存储的, 例如: XXXX452154 格式的用户订单都是储存在一个分库中.
来源: http://www.tuicool.com/articles/22eIJvB