资讯专栏INFORMATION COLUMN

电商系统设计之订单

xiangchaobin / 2740人阅读

摘要:退换货退换货淘宝是这样处理的。这个没什么可讲的,一般小的电商也没有刷评价的,类似淘宝的防止刷评价的做法太过于复杂,这里也不过多讲解其实我也没接触过。

前言

用户交易将经历一段艰辛的历程,一般用户感觉不到,实际程序是经历了一段生死离别。具体付款流程如下

不(wo)是(gu)这(yi)张(chuan)图(de),请看正经流程图

之前的几篇文章介绍了

购物车如何设计

用户系统如何设计

商品系统如何设计

其实他们都在为交易系统做铺垫,一个产品如果没有收入,那这只能是寺庙的公益产品。任何产品最终都要走向这步 (收钱)。

付款

用户付款过程中有很多场景也会出现意外,以下是我碰到的“天灾人祸”

成功

用户发起微信支付并成功支付

用户发起支付宝支付并成功支付

用户发起银联支付并成功支付

用户发起其他支付并成功支付

人祸

用户发起微信支付但取消支付

用户发起支付宝支付但取消支付

用户发起银联支付但取消支付

用户发起其他支付但取消支付

天灾

用户发起微信支付“手机爆炸了”

用户发起支付宝支付“瞬间没网了”

用户发起银联支付“老婆来电话了”

用户发起其他支付“老板进来了”

注释

遇到以上的情况,不要害怕、不要惊慌,并且不要“理会”,你只需要将这些操作记录下来即可。
正常我们都会将用户通过哪种支付方式存储到订单表中,方便查询。我想说这种做法没错,但是少了点什么,你应该有一张交易记录表,来记录用户发起了多少次支付,只有支付成功的时候方可记录到订单表中。这样做的优点有以下两点

订单表是比较重要的,迫不得已尽量不要操作这张表,防止出现意外,订单表除了收货发货外一般没有其他需要操作的地方。

可以记录每次用户发起支付的时间,通过所谓大数据分析用户对产品的需求度和认可度,如果用户多次发起付款但取消支付,那就说明(他没钱)他可能很期望得到,但是因为某种原因一直在犹豫,这个时候可以针对当前用户做优惠处理,例如发一张优惠券等等。

表结构 交易表
CREATE TABLE `transaction` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_sn` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "交易单号",
  `member_id` bigint(20) NOT NULL COMMENT "交易的用户ID",
  `amount` decimal(8,2) NOT NULL COMMENT "交易金额",
  `integral` int(11) NOT NULL DEFAULT "0" COMMENT "使用的积分",
  `pay_state` tinyint(4) NOT NULL COMMENT "支付类型 0:余额 1:微信 2:支付宝 3:xxx",
  `source` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "支付来源 wx app web wap",
  `status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "支付状态 -1:取消 0 未完成 1已完成 -2:异常",
  `completion_time` int(11) NOT NULL COMMENT "交易完成时间",
  `note` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "备注",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `transaction_order_sn_member_id_pay_state_source_status_index` (`order_sn`(191),`member_id`,`pay_state`,`source`(191),`status`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
支付记录表
CREATE TABLE `transaction_record` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_sn` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `events` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "事件详情",
  `result` text COLLATE utf8mb4_unicode_ci COMMENT "结果详情",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

这个记录表可能让你匪夷所思,不知你对日志有什么概念,但我能说的就是,将用户的所有动作全部记录下来。这是很重要的,早晚你会懂。

订单表
CREATE TABLE `order` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "订单编号",
  `order_sn` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "交易号",
  `member_id` int(11) NOT NULL COMMENT "客户编号",
  `supplier_id` int(11) NOT NULL COMMENT "商户编码",
  `supplier_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "商户名称",
  `order_status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "订单状态 0未付款,1已付款,2已发货,3已签收,-1退货申请,-2退货中,-3已退货,-4取消交易",
  `after_status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "用户售后状态 0 未发起售后 1 申请售后 -1 售后已取消 2 处理中 200 处理完毕",
  `product_count` int(11) NOT NULL DEFAULT "0" COMMENT "商品数量",
  `product_amount_total` decimal(12,4) NOT NULL COMMENT "商品总价",
  `order_amount_total` decimal(12,4) NOT NULL DEFAULT "0.0000" COMMENT "实际付款金额",
  `logistics_fee` decimal(12,4) NOT NULL COMMENT "运费金额",
  `address_id` int(11) NOT NULL COMMENT "收货地址编码",
  `pay_channel` tinyint(4) NOT NULL DEFAULT "0" COMMENT "支付渠道 0余额 1微信 2支付宝",
  `out_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "订单支付单号",
  `escrow_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "第三方支付流水号",
  `pay_time` int(11) NOT NULL DEFAULT "0" COMMENT "付款时间",
  `delivery_time` int(11) NOT NULL DEFAULT "0" COMMENT "发货时间",
  `order_settlement_status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "订单结算状态 0未结算 1已结算",
  `order_settlement_time` int(11) NOT NULL DEFAULT "0" COMMENT "订单结算时间",
  `is_package` enum("0","1") COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "0" COMMENT "是否是套餐",
  `is_integral` enum("0","1") COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "0" COMMENT "是否是积分产品",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_order_sn_unique` (`order_sn`),
  KEY `order_order_sn_member_id_order_status_out_trade_no_index` (`order_sn`,`member_id`,`order_status`,`out_trade_no`(191))
) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
运输

用户付款结束后接下来就是快递公司的事了,当然咱们不搭理送快递的。到这一步我们就应该给客户展示运输信息。现在一些api开放平台都有快递查询的服务,有收费有免费的,性能方面差异也不大。但这里要注意一点。不是每次用户都会查询到新的信息。对于小公司来说,这样成本极高。所以我们应该定时去查询快递物流信息。这个地方有个简单的算法。

if(用户点击查看了){
    从用户点击查看两小时后更新物流信息 // 这里是按照两小时来更新的,也可以拉长这个时间
}else{
    每两小时更新一次物流信息
}

这种频繁的更新绝对要使用nosql,当用户确认收货后再存储到mysql等数据库中。

收货

当用户收到货后,这其实是最难伺候的时候,用户对产品的各种不满意就可能导致退换货,收货操作既改变订单状态为已收货,复杂点的可能还需要im,短信,推送提醒下。一般都直接提醒,量大的话加入队列内处理。

退换货

退换货淘宝是这样处理的。
淘宝将订单分两种状态

未付款、已付款、已收货、已评价

发起售后、售后审核、售后处理、处理完成

图1展示了每个商品,包括子商品都可以多带带发起售后

图2是点击申请售后之后的页面

图3是选择退换货的相关事项

当完成这些步骤后,就会开启售后审核,卖家审核成功后方可进行下一步操作

售后申请表
CREATE TABLE `order_returns_apply` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "订单单号",
  `order_detail_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "子订单编码",
  `return_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "售后单号",
  `member_id` int(11) NOT NULL COMMENT "用户编码",
  `state` tinyint(4) NOT NULL COMMENT "类型 0 仅退款 1退货退款",
  `product_status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "货物状态 0:已收到货 1:未收到货",
  `why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "退换货原因",
  `status` tinyint(4) NOT NULL DEFAULT "0" COMMENT "审核状态 -1 拒绝 0 未审核 1审核通过",
  `audit_time` int(11) NOT NULL DEFAULT "0" COMMENT "审核时间",
  `audit_why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "审核原因",
  `note` text COLLATE utf8mb4_unicode_ci COMMENT "备注",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
售后表
CREATE TABLE `order_returns` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `returns_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "退货编号 供客户查询",
  `order_id` int(11) NOT NULL COMMENT "订单编号",
  `express_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "物流单号",
  `consignee_realname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "收货人姓名",
  `consignee_telphone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "联系电话",
  `consignee_telphone2` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "备用联系电话",
  `consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "收货地址",
  `consignee_zip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "邮政编码",
  `logistics_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "物流方式",
  `logistics_fee` decimal(12,2) NOT NULL COMMENT "物流发货运费",
  `order_logistics_status` int(11) DEFAULT NULL COMMENT "物流状态",
  `logistics_settlement_status` int(11) DEFAULT NULL COMMENT "物流结算状态",
  `logistics_result_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "物流最后状态描述",
  `logistics_result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT "物流描述",
  `logistics_create_time` int(11) DEFAULT NULL COMMENT "发货时间",
  `logistics_update_time` int(11) DEFAULT NULL COMMENT "物流更新时间",
  `logistics_settlement_time` int(11) DEFAULT NULL COMMENT "物流结算时间",
  `returns_type` tinyint(4) NOT NULL DEFAULT "0" COMMENT "0全部退单 1部分退单",
  `handling_way` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "PUPAWAY:退货入库;REDELIVERY:重新发货;RECLAIM-REDELIVERY:不要求归还并重新发货; REFUND:退款; COMPENSATION:不退货并赔偿",
  `returns_amount` decimal(8,2) NOT NULL COMMENT "退款金额",
  `return_submit_time` int(11) NOT NULL COMMENT "退货申请时间",
  `handling_time` int(11) NOT NULL COMMENT "退货处理时间",
  `remark` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "退货原因",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
评价

如果用户收货后直接评价了,那恭喜你,这笔订单基本成交了。这个没什么可讲的,一般小的电商也没有刷评价的,类似淘宝的防止刷评价的做法太过于复杂,这里也不过多讲解(其实我也没接触过)。

评价数据表
CREATE TABLE `order_appraise` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL COMMENT "订单编码",
  `info` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "评论内容",
  `level` enum("-1","0","1") COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "级别 -1差评 0中评 1好评",
  `desc_star` tinyint(4) NOT NULL COMMENT "描述相符 1-5",
  `logistics_star` tinyint(4) NOT NULL COMMENT "物流服务 1-5",
  `attitude_star` tinyint(4) NOT NULL COMMENT "服务态度 1-5",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_appraise_order_id_index` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
致谢

感谢你看到这里,希望我的文章和代码可以帮助到你。如果有什么疑问可以在评论区留言,谢谢

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29107.html

相关文章

  • 电商系统设计商品 (下)

    摘要:订单号用户商品标题商品价格商品封面图商品其他属性小明爱疯手机其他属性像上表中设计,有人会问了那关联的意义何在呢我的回答是保持数据关联,虽然商户有可能改变商品属性,但作为一名程序员,应该尽可能的记录用户所有的动作。 showImg(https://segmentfault.com/img/bVbdtuc?w=1824&h=1028); 电商大伙每天都在用,类似某猫,某狗等。电商系统设计看...

    shiguibiao 评论0 收藏0
  • 电商系统设计商品[番外篇]

    摘要:前言这是电商系统设计系列在商品设计这块的最后一篇文章。电商系统商品相关的文章已经到了尾声如果有其他商品相关的文章需要编写可以私信联系我毕竟我也是公司员工写这些文章并不是我的工作,只是记录我的职业生涯。 showImg(https://segmentfault.com/img/bVbePdh?w=1260&h=628); 前言 这是电商系统设计系列在商品设计这块的最后一篇文章。以下是其他...

    crossoverJie 评论0 收藏0
  • 电商系统设计购物车

    摘要:可扩展性百度百科的定义是设计良好的代码允许更多的功能在必要时可以被插入到适当的位置中。正常购物车商品优惠券都是独立的系统及功能,不要看做商品在购物车内。可维护性百度百科的定义是系统的可维护性是衡量一个系统的可修复恢复性和可改进性的难易程度。 showImg(https://segmentfault.com/img/bVbcqJE?w=506&h=326); 本章适合初级工程师及中级工程...

    TigerChain 评论0 收藏0
  • Kubernetes架构为什么是这样的?

    摘要:目前为止,我们有已经研究过几个非常有代表性的调度系统和。当时学习完这些调度系统的架构后,脑子里面形成个大大的疑问是二次调度的架构么和相比它的扩展性如何为什么所有调度系统都是无法横向扩展的后面我们就针对这两个问题深入讨论一下。 小编序:在上周发布的《从鸿沟理论看云原生,哪些技术能够跨越鸿沟?》一文中,灵雀云CTO陈恺表示:Kubernetes在云计算领域已经成为既定标准,进入主流市场,最...

    xushaojieaaa 评论0 收藏0

发表评论

0条评论

xiangchaobin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<