How should you design an e-commerce order system?

The design of an order system is not simple. It requires batch after batch of people to maintain, optimize, and make changes and compatibility according to the company's business conditions. This article mainly analyzes how to design the e-commerce order system.

Among all the modules of an e-commerce, the order system is the most core module, which determines whether the entire process can be executed smoothly and plays a role of connecting the previous and the next.

Order system

There are several modules to consider when designing an order system. Only by explicitly considering all modules can the stability and scalability of the order system be guaranteed.

1 Order field
In fact, the order information displayed on the interface consists of various order fields. The completed order field to some extent represents the completeness of the order process.
Insert picture description here
The order field includes several parts, among which the amount information is explained separately because of its particularity. Essentially, the amount information also belongs to the product information.

Commodity information: Commodity information belongs to the upstream end of the order system. All orders are evolved from commodities. From commodity to order, the order system must collect relevant commodity information, including store information, commodity ID, commodity specifications, commodity quantity and commodity price. The obtained product information will be displayed on the order details page. After the order information is formed, the warehouse can easily pick and pack.

User information: User information includes the ID of the purchasing user, consignee, consignee address and contact information. The user growth system of some platforms is calculated based on user activity on the platform. For example, JD.com (JD.com) has similar growth indicators, such as membership levels and point cards. At this time, in addition to the general information fields, user information needs to be obtained. Obtain user level, points obtained after purchase, discounts that can be deducted from the order at the user level, etc. However, these specific operations depend on the company's business direction.

Amount information: Due to the particularity of the amount information, it is theoretically believed that the amount information should belong to commodity information. The particularity of the amount information is that it does not represent the amount, but involves the amount of goods, discount amounts, and payment amounts. The information involved in the discount amount is more complicated. For example, an e-commerce platform with self-operated and third-party settlement will have merchant discounts and cross-store discounts. These discounts are divided into different types, such as cash deductions and consumer coupon deductions, point earning, gift card deductions or a combination of the above. If you want to cover this content well, you need to list the types of offers supported according to the company’s current business conditions, and then enumerate the types of offers under various combinations to ensure the integrity of the process.

Time information: record the time under each status point, one is to record, and the other is to facilitate after-sales verification and customer analysis. The order time is changed according to the status of the order. Time information does not seem important, but it is actually an important part of the order system. For details, see the following:
[Order not paid]: Order creation time, order time;
[Pending delivery status]: Order creation time, order placement Time, payment time;
[To be received status]: order creation time, order time, payment time, delivery time;
[transaction completion status]: order creation time, order time, payment time, delivery time, completion time ;
[Pending refund status]: Refund order creation time, refund request time;
[Transaction closed-user cancellation]: order creation time, order time, user cancellation time;
[transaction closed-refund only]: order creation Time, order time, payment time, refund application time, refund success time;
[Transaction closed-return refund (including partial refund only)]: order creation time, order time, payment time, transaction completion time, Refund application time, refund time.

Order information: Order information is the core of the order system, and the most important of order information is the status of the order. In an e-commerce system, the order status has the following statuses: [Pending Payment], [Pending Shipment], [Pending Receipt], [Pending Evaluation], [Transaction Completed], [User Cancellation], [Refund Only Money], [return and refund]. And we generally put the last three in a unified order and present them separately after order to facilitate the convenience of business operations.
Let's take a look at the flowchart:
Insert picture description here

2 Order process

The order process refers to the process from order generation to completion, including forward and reverse processes.

The forward process is the normal online shopping steps: order generation -> payment order -> seller delivery -> confirm receipt -> transaction success.

The reverse process is the process of various refunds and returns.

(1) Forward process
Insert picture description here
order generation: After the user places an order, the system needs to generate an order. At this time, you need to first obtain the product information involved in the order, and then obtain the discount information related to the product. If the product does not participate in the discount information, There is no such link.

Then get the membership rights of the account (in fact, it should be noted here: there is a difference between discount information and membership rights, just like the discount information is the discount information, the newcomer discount is the member rights, one is for the product, the other is for the Account).

Payment order: After paying the order, the user needs to obtain the payment information of the order, including the payment serial number, payment time, etc. After the order is paid, the merchant will wait for the goods to be delivered. However, during the delivery process, there is often a situation that is normal but more complicated, that is, the order is split.

  • There are two types of order splitting: one is that the products selected by the user come from different channels (self-operated and merchants, merchants and merchants). At this time, the orders need to be split and settled separately. Here is also the argument of parent-child orders, here No longer.

  • The other is to split orders at the SKU level: different warehouses, SKUs with different transportation requirements, package weight and volume restrictions and other factors need to split orders. For example: commodity A is only available in warehouse A, and commodity B is only available in warehouse B. At this time, commodity A and commodity B will be split into two orders. Or the practice of some companies is to transfer goods A/B to another warehouse for unified delivery, which is also convenient for users.

Order splitting looks simple, in fact, it involves the support of the underlying system. For example, you need to take a relatively accurate inventory of the goods in each warehouse, and achieve real-time synchronization (involving refined management of the warehouse) to accurately classify the goods And placement, the record of product information is accurate, etc.

Which one of these modules is a huge project. When PM enters a company, it will be optimized on the basis of the original (semi-finished product). You may wish to think more about the underlying business. Only by doing fine management at the bottom can you support online Rich user needs.

Merchant delivery: The merchant delivery process also has a standardized process. It is also mentioned above that when an order is split, it will involve the transfer between warehouses, and then the warehouse will order, pick, pack, and deliver the goods by express delivery. If this set of standardized processes is optimized, it is also a big project. I won't repeat it here. I suggest you read books on inventory and warehouse management for detailed understanding.

Confirm receipt: After the merchant ships the goods, they are waiting for the express delivery. The order system needs to be connected to the interfaces of some common express companies to facilitate users and merchants to inquire about express delivery information on the site.

Successful transaction: After receiving the goods, it is not the end of a service, but the beginning of a service. The order system needs to remind the user to comment on the product after the express is signed. It should be noted here that confirming the receipt of the goods does not mean that the transaction is successful. The successful transaction refers to the status of receiving the goods within X days. At this time, the order is not within the after-sales support time range. Inside. At this point, the forward flow of an order is complete.

Related data table design
Transaction table

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;

Payment Record Form

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;

Order form

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;

(2) Reverse process
Insert picture description here
The basic reverse process of an e-commerce is shown in the figure above. The complexity of the reverse process of an order is that it allows almost any link in the forward process. Some people may ask: Why can the user refund the goods without receiving it?

In fact, it is easy to understand when we think in another place. Suppose you are a user, you bought a pair of shoes, paid for the delivery, and you were waiting to receive the express delivery. Then you just passed a shoe store and saw the big sale of the same shoes you just bought, so you picked up your phone and clicked to refund , Bought this pair of promotional shoes.

This kind of scenario is actually a very common and normal user's daily life, so our order system must support users' various rich scene needs, and it also tests PM's business penetration ability. Fortunately, Taobao, the pioneer of e-commerce, has already done it. We can directly apply a lot of infrastructure and user education, but we still need to modify it according to the business situation of each company.

Cancel order: When the user submits the order, he exits directly before jumping to the payment. At this time, the user cancels the order in principle, because the payment has not been made, it is relatively simple, only the original inventory deducted when the order was submitted can be replaced .

Payment failure: When the user exits or cancels the payment when making a payment, we will classify it as a payment failure status. At this time, the process is the same as the above, and the deducted inventory can be returned to the saleable inventory.

Refund after payment: After the user has successfully paid, the merchant has not delivered the goods, and the user is supported to apply for a refund. At this time, if the warehouse and customer service are separated, you need to check whether the warehouse has been shipped, and if it has been shipped, you should contact the customer Communicate whether it is possible to refund after receiving the goods. If the warehouse has not delivered the goods, you can directly agree to the user to refund. Or the enterprise may connect to Cainiao Logistics and implement the interception function, but this kind of operation is not yet mature and the cost will be relatively high, which is not suitable for small and medium entrepreneurial companies.

Out-of-stock refund: After the user has successfully paid, the merchant finds that the warehouse is out of stock when delivering the goods (if the order is submitted to deduct the inventory, the out-of-stock situation will be reduced, why is it reduced and not avoided? Because the warehouse can’t manage the goods at 100 % Is accurate, so the information is sometimes inaccurate, causing the online saleable inventory to show that there is inventory and the warehouse has been sold out), you need to negotiate with the user whether to refund.

This process order system can be proceduralized and automated, connecting the message center and the warehouse management system to achieve it. The difficulty lies in the real-time nature of the message. I've encountered a coat bought on Taobao. One day later, the merchant told me that it was out of stock, and I had a murderous heart.

Refund pending receipt: There is currently no perfect solution to this problem. After the merchant ships the goods, the user has not received the goods, and the goods are on the way. There are roughly two approaches: one is that the user re-sends the package after receiving it; the other is that the user directly rejects the package, and the package is directly returned to the original address.

Return refund: After receiving the goods, the user wants to apply for after-sales. At this time, he needs to provide the user to enter the reason for the after-sales, including the function of uploading the voucher. If the negotiation with the merchant fails, the portal of the platform customer service needs to be added to facilitate the user. Appeal. After the negotiation result/appeal is successful, the automatic refund mechanism is directly triggered, and the message notification is triggered after the refund, and the transaction closed state is triggered at the same time, and the entire after-sales process is considered to be over.

Related data sheet reference
After-sales application form

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;

After-sales table

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;

Guess you like

Origin blog.csdn.net/phpCenter/article/details/105407251