简单聊聊电商系统的订单号⽣成规则
编辑导语:订单号、⽀付流⽔号、售后订单号、快递取货号、电⼦券核销码等,这些都是我们⽇常在⽣活中进⾏会遇见和使⽤的⼀些单号,那么为什么有些单号那么长,有些只有⼏位数?有些单号⼀看就知道年⽉⽇的信息,有些却看不出任何意义?为什么我淘宝订单的后⼏位数都是⼀样的?今天就来带⼤家看⼀下订单号的是怎样⽣成的。
单号在实际的业务过程中是做为⼀个订单的唯⼀标识码的存在,提供订单号就很⽅便业务⼈员快速定位订单信息,给予⽤户帮助。
1. ⽤户订单遇到问题,需要客服进⾏协助
我们⽇常在电商平台上⾯购买商品的时候,很多时候需要去向平台客服反馈在订单过程中遇到的问题,⼀般这个时候平台客户都是要求⽤户填写订单编号的,这样客服可以快递锁定订单信息,给⽤户信息问题的解答和处理。
2. 对订单进⾏操作,如线下收款,订单核销
我们在第三⽅平台上购买了某⼀个店铺的线下优惠券的时候,⼯作⼈员需要对我们提供的优惠券进⾏核销,核销的依据⼀般来说就是订单编号。
⽽在某些场景涉及到的线下收款,也会根据订单号来进⾏订单的确认和收款,不过⽇常在业务过程中将⼀般都将订单号⽣成⼆维码,再由⼯作⼈员扫码进⾏操作,因此⽤户在线下对于订单号的感知并不是很强烈。
3. 内部进⾏订单的处理或者跟进
从技术的层⾯去讲,很多时候搜索订单相关信息的时候都是以订单ID作为唯⼀标识符,这是由于订单号的⽣成规则的唯⼀性决定的(后⾯讲订单号⽣成规则会讲到)。
由此公司内部在进⾏业务操作处理时候,⽐如对通知仓库按单发货,内部交流某个订单信息时候,也会直接根据订单号来进⾏信息传达。
⼆、编号规则的设计原则
订单号的在业务中的使⽤⼀般都是基于唯⼀性的需求,因此在订单号的设计上需要遵循⼏个原则:
1. 不得重复
由于我们在业务中对于订单编号的要求是唯⼀的,所以订单编号⽣成的时候⼀定要遵循不可重复这⼀特性,⽽实际在底层⽣成订单编号的时候由于业务流⽔很⼤,处于⼀个⾼并发的状态,并且订单号的⽣成规则⼀般是固定的,所以可能会
层⽣成订单编号的时候由于业务流⽔很⼤,处于⼀个⾼并发的状态,并且订单号的⽣成规则⼀般是固定的,所以可能会造成在同⼀时间多个线程读取的⽣成参数相同,从⽽造成⽣成的订单号相同(当然这是开发⼈员应该注意的问题)。
其次就是业务的长时间积累可能导致新⽣成的订单号会与过去很久的订单号产⽣重复,所以在设计订单号的时候⼀定要充分考虑到不可重复性的原则(后⾯讲到订单号设计中的变量部分会详细讲到)。
2. 安全性
编号不能透露公司的运营情况,⽐如⽇销、公司流⽔号等信息,以及商业信息和⽤户⼿机号,⾝份证等隐私信息。并且不能有明显的整体规律(可以有局部规律),任意修改⼀个字符就能查询到另⼀个订单信息,这也是不允许的。
类⽐于我们⾼考时候的考⽣编号的⽣成规则,⼀定不能是连号的,否则只需要根据顺序往下查询就能搜索到别的考⽣的成绩,这是绝对不可允许。
3. 具备⼀定的可读性
位数要便于操作,因此要求订单号的位数适中,且局部有规律。这样可以⽅便在订单异常,或者退货时客服查询。
过长的订单号或易读性差的订单号会导致客服输⼊困难且易错率较⾼,影响⽤户体验的售后体验。因此在实际的业务场景中,订单号的设计通常都会适当携带⼀些允许公开的对使⽤场景有帮助的信息,如时间,星期,类型等等,这个主要根据所涉及的编号对应的使⽤场景来。
⽽且像时间、星期这些⾃增长的属于作为订单号的设计的⼀部分元素,有助于解决业务累积⽽导致的订单号重复的问题。
三、编号设计中的常⽤变量
在遵循涉及原则的基础上,我们常会使⽤⼀些变量来进⾏编号的设计,这也是为了满⾜订单编号的局部可读性带来的业务优势,通常会有以下⼏类:
1. 时间
如20220525105959这种类型的年⽉⽇时分秒,编号中使⽤这个变量就把重复的可能性降低到⼀秒内的不重复。
常⽤的时间变量还有很多变种类型,如取年份的后2位数、如20220525只保留到天。通常在快递取件码的设计中会使⽤⽉、⽇、周等+其他元素的设计,这是为了⽅便取件码可以快速重复使⽤,因为快递取件码通常有效期不会超过⼀个⽉就会原路退货然后被销毁。
2. 时间戳
时间戳是⼀个10位数的数字,代表的是当前时间距离1970年1⽉1⽇UTC/GMT的午夜)开始所经过的秒数。也是经常⽤来代表时间的⼀种⽅式,时间戳也可以精确到毫秒,形成⼀个13位数的数字。
3. 类型
如订单类型、售后类型、商品类型、⽀付类型等等,不同类型的可以使⽤不同参数进⾏。通常⽀付类型的应⽤场景是,线上⽀付和线下⽀付共⽤⼀套业务后台,所以为了⽅便区分会加⼊⽀付类型这个参数⽤于区分线上线下。
类⽐还有店铺代码、⽀付的机器代码、操作员代码等等。
4. ⽤户ID
对⼀些涉及到⽤户的编号规则时候,可以使⽤到⽤户ID作为变量来进⾏设计,如淘宝的订单号中最后⼏位数就使⽤了⽤户ID,不过要注意不能使⽤完整的⽤户ID,需要进⾏⼀些规则的设计再使⽤。
5. 商家ID
5. 商家ID
对电商系统中,可以把商家ID脱敏后也作为⼀个变量设计到编号规则中。
6. ⼿机号
使⽤⽤户的⼿机号中的某些位数作为编号中的⼀个变量;使⽤类似于⼿机号部分号码这种重复度较⾼的属性设计订单编号的时候,切记不能只有⼀个变量,否则很容易出现订单编号重复。
7. 平台形态
如果是多终端多平台的系统,那么可以考虑在编号中把平台作为⼀个变量考虑进去。如⼩程序平台⽤01,安卓app使⽤01,PC版本使⽤03,第三⽅平台04类型这样的规则。
8. 其他业务属性
可以根据业务场景,把⼀些业务属性的信息也作为变量设计进去。
9. 随机数
随机数就是系统根据程序在⼀定规则内随机⽣成的字符,可以为数字也可以是字符串,⼀般可以⽤来降低重复;随机数在订单⽣成中的使⽤频率⾮常⾼,常常是前⾯⼏位都是⼀些显式的规律性数字,⽐如订单⽣成的时分秒,然后最后加上四位随机数从⽽组成订单号。所以读者在设计订单编号的时候,如果不知道如何加密,就可以简单的插⼊⼏位随机数即可。
10. 序列位
代表顺序的数字,如10,11,12这样的。
11. 验证位
⼀般放在最后,根据前⾯的多位字符按照⼀定的规则计算最后得到的⼀个数字,⼀般为1位,主要⽬的是提⾼编号的安全性;⾝份证的最后⼀位就是校验位,其计算原理也是通过前⾯⼏位数字加密算法算出来的,感兴趣的读者可以去了解⼀下⾝份证的⽣成规则。
12. 地区信息
对有区域性质的编号规则⾥⾯可以考虑把区域作为变量考虑进去,如某地区分店、某地区线下的售货机等。
13. 数据库数据的⾃增ID
每条数据录⼊系统时候,⼀般情况都有⼀个唯⼀的ID,这个ID也可以作为编号的⼀种变量进⾏使⽤。
四、编号实践⽅案分享 1. UUID
通⽤唯⼀识别码,是⼀种软件建构的标准,亦为开放软件基⾦会组织在分布式计算环境领域的⼀部分。
输入手机号查所有快递其⽬的是让分布式系统中的所有元素,都能有唯⼀的辨识信息,⽽不需要通过中央控制端来做辨识信息的指定。
1.1~8位采⽤系统时间,在系统时间上精确到毫秒级保证时间上的惟⼀性。
2.9~16位采⽤底层的IP地址,在服务器集中的惟⼀性。
3.17~24位采⽤当前对象的HashCode值,在⼀个内部对象上的惟⼀性。
4.25~32位采⽤调⽤⽅法的⼀个随机数,在⼀个对象内的毫秒级的惟⼀性。
通过以上4种策略可以保证惟⼀性。在系统中需要⽤到随机数的地⽅都可以考虑采⽤UUID算法。但是呢直接使⽤这个作为单号。虽然具有唯⼀性,安全性,但是却没有任何的可读性⽽⾔。因此在这种情况下,UUID只是能作为系统中间的标识码,可以在业务中数据流转的时候配合订单号使⽤,绝不可直接给予客户和业务⼈员使⽤。
2. 时间戳+随机数
对于⼀些编号需求不是很⼤的场景,如果可读性也没什么场景的要求,可以简单的使⽤时间戳和随机数进⾏拼接作为编号规则使⽤;如时间戳1635302466+随机数2313,则编号为16353024662313。
3. 淘宝订单号的⽣成规则
⼀共19位数,前⾯13位数为根据时间戳和内部定义序列,后⾯6位数为跟购买者ID相关的⽤户位。
4. 有赞商家端的订单号
⽇期+时分秒+随机数。
5. 时间+时间戳+⽤户+序列位
时间:取时间的年份后2位+⽉份+⽇期形成如211027。
时间戳:取时间戳的后6位数
⽤户:取⽤户ID的后5位数,序列位2位数随机。
6. 综合各种变量
下单渠道1位+⽀付渠道1位+业务类型1位+时间信息4位+下单时间的Unix时间戳后8位(加上随机码随机后的数字)+⽤户userid后4位共19位并不⼀定需要把19位全加上。
7. 预先⽣成
系统预先⽣成不重复的编号,业务系统要使⽤时候按顺序取数即可。这种编号⼀般系统拥有⼀套成熟的加密规则,不属于常规的订单⽣成规则,⼀般⽤于加密程度较⾼的业务。
本⽂由 @卖⼲货的产品⼩谢原创发布于⼈⼈都是产品经理,未经许可,禁⽌转载。
题图来⾃ Unsplash,基于CC0协议。
发布评论