四种下单方式:标准 / 单页 / 渐进式 / COD
本文档说明前台 四种结账形态 的逻辑关系、共用基础设施、差异对比与主流程。优惠/活动/优惠券在各形态下的计价与落库,见 promotion-discount-checkout.md;API 逐步细节见 checkout-flows-detail.md。
与实现冲突时以代码为准。
目录
- 1. 一句话区分
- 2. 逻辑关系总图
- 3. 常量与配置
- 4. 共用基础设施
- 4.1 checkout_token 与 Redis 购物车
- 4.2 分形态逐步链路(详细)
- 5. 四形态对比总表
- 6. 标准结账(standard)
- 7. 单页结账(one_page)
- 8. 渐进式结账(single_page)
- 9. COD 结账(cod)
- 10. 智能结账(smart)
- 11. 优惠体系在各形态下的落点(摘要)
- 12. 如何选择阅读路径
- 13. 文档拆分说明
1. 一句话区分
| 中文名 | 代码常量 | URL 前缀 | 交互形态 |
|---|---|---|---|
| 标准 | standard | /checkouts/{token} | 多步 Liquid 页面,每步 GET 渲染 + POST 提交 |
| 单页 | one_page | /one-page-checkouts/{token} | 单屏 SPA,REST API 批量落盘 |
| 渐进式 | single_page | /single-page-checkouts/{token} | 分步 REST API(类似标准步骤,但无整页刷新) |
| COD | cod | /cod-checkouts/{token} | 货到付款专用,独立订单表,在线支付流程的平行线 |
另有 智能结账(smart):店铺配置项,首次访问随机/按设备分配 standard / one_page / single_page 之一,Cookie 锁定 30 天。
COD 单页着陆(无 token 商品维下单)是 COD 的 子场景,见 cod-one-page-checkout.md,不在本文四种「带 checkout_token 主流程」之列。
2. 逻辑关系总图
flowchart TB subgraph entry [从购物车出发] Cart[CartService 加购 / buynow] Token[checkout_token 生成] end subgraph config [店铺配置 checkout_process] Std[standard] OP[one_page] SP[single_page] Smart[smart → Cookie 选其一] end subgraph codcfg [店铺配置 cod_checkout_type] OnlyOL[仅在线] OnlyCOD[仅 COD] FirstOL[在线首选 + COD 可选] FirstCOD[COD 首选 + 在线可选] end Cart --> Token Token --> config Token --> codcfg config --> StdFlow[标准 Liquid 多步] config --> OPFlow[单页 API] config --> SPFlow[渐进式 API] codcfg --> OLFlow[在线三形态之一] codcfg --> CODFlow[COD 页 + CodOrder] OLFlow -.->|共用| Shared[CartService.getList 计价] CODFlow -.->|平行| CodCart[CodCartService.getCartList]
核心关系:
- 在线三种(标准 / 单页 / 渐进式)共用
o_order、CartService::getList计价链、同一套 promotion/coupon/diy_offer 规则(细节见优惠文档)。 - COD 使用
CodOrderModel(COD 订单表)、CodCartService,不写o_order_diy_offer,部分券逻辑与在线不一致。 checkout_type写入o_order.checkout_type,创单后 URL 由订单类型决定(CheckoutService::generateCheckoutUrlByOrder),不再随店铺配置切换。- COD 与在线 由
cod_checkout_type决定入口 URL 数组(是否同时提供两种链接),不是checkout_process的子项。
3. 常量与配置
3.1 OrderModel.checkout_type
定义:common/models/OrderModel.php
| 常量 | 值 | 说明 |
|---|---|---|
CHECKOUT_PROCESS_STANDARD | standard | 标准多步 |
CHECKOUT_PROCESS_ONE_PAGE | one_page | 单页 |
CHECKOUT_PROCESS_SINGLE_PAGE | single_page | 渐进式 |
CHECKOUT_PROCESS_SMART | smart | 仅配置层,不落订单 |
CHECKOUT_PROCESS_COD | cod | COD 订单 |
3.2 店铺配置
| 配置键 | 作用 |
|---|---|
checkout_process | 在线结账默认形态:standard / one_page / single_page / smart |
checkout_process_smart_update_time | smart 模式下强制重新分配 Cookie |
cod_checkout_type | 1 仅在线 / 2 仅 COD / 3 在线首选 / 4 COD 首选 |
cod_checkout_use_coupon | COD 是否允许优惠券 |
URL 生成:CheckoutService::generateCheckoutUrlByConfig()(未创单)、generateCheckoutUrlByOrder()(已创单)。
4. 共用基础设施
4.1 checkout_token 与 Redis 购物车
生成、Cookie 关系、清理时机见 cart-checkout-token-visit-id.md。常见概念速查见 faq.md。
4.2 分形态逐步链路(详细)
| 形态 | 文档 |
|---|---|
| 标准 standard | standard-checkout-flow.md |
| 单页 one_page | one-page-checkout-flow.md |
| 渐进式 single_page | single-page-checkout-flow.md |
| COD 单页 | cod-one-page-checkout.md |
| COD 带 token | cod-checkout-flow.md |
4.3 共用组件
| 组件 | 作用 |
|---|---|
CartService::getList | 商品行价 + diy_offer + 满减 + 券 +(有订单时)税/运费/order_diy_offer |
OrderService::saveProducts | 写 o_order_product、行 discount_price |
OrderService::renew | 重算 total_price |
CouponHandlerService | 用券 / 预券 / 替换型券清满减 |
OrderDiyOfferHandleService | 订单级积分 / Seel / deliveryprotec |
4.4 COD 独立
| 组件 | 作用 |
|---|---|
CodCartService::getCartList | 仅 Redis cart,不读 o_order |
CodOrderHandlerService::saveOrder | 写 COD 订单 |
CodCouponService | COD 用券(未走 checkCouponUseWithPromotionStatus) |
5. 四形态对比总表
| 维度 | 标准 standard | 单页 one_page | 渐进式 single_page | COD |
|---|---|---|---|---|
| 前端 | Liquid 多模板 | 单页 JS | 分步 JS(API 驱动) | Liquid checkout 模板 |
| Controller | home/Order::checkout | homeapi/OrderOnePage | homeapi/OrderSinglePage | home/OrderCodPage + homeapi/OrderCodPage |
| Service | OrderService 各 save* | CheckoutOnePageService | CheckoutSinglePageService | CodOrderHandlerService |
| 创单时机 | contact_information POST | presave 邮箱失焦 / complete | email POST | saveOrder POST(可未先创在线单) |
| checkout_type | standard(默认) | one_page | single_page | cod(COD 表) |
| 计价 | CartService::getList | getCart + calCart* | CartService::getList | CodCartService |
| 用券 | GET /coupon/use/{token} | trans_info.coupon_code | POST use-coupon | POST use-coupon |
| order_diy_offer 写入 | shipping_method POST | complete/preComplete | shipping-method POST | 无 |
| 支付 | payment_gateway 步 | complete 后 paymentform | gateway POST | 无在线支付(货到付款) |
| 事件 | OrderCreate 等 | complete 触发 | 各步 save 触发 | COD 成功事件 |
6. 标准结账(standard)
入口:GET|POST /{store}-{rand}/checkouts/{checkout_token}?step=...
实现:app/home/controller/Order.php::checkout
6.1 主流程
sequenceDiagram participant U as 用户 participant L as Liquid 页面 participant O as Order.php participant CS as CartService participant OS as OrderService U->>L: GET contact_information L->>CS: getList U->>O: POST 联系信息 O->>OS: saveContactInformation / createOrder Note over OS: savePreCoupon + saveProducts U->>L: GET shipping_method U->>O: POST 配送 + offer_from_name O->>OS: saveShippingMethod + saveOtherInformation O->>OS: OrderDiyOfferHandleService.saveDiyOffer U->>L: GET payment_method U->>O: POST 支付方式 O->>OS: savePaymentMethod U->>L: GET payment_gateway U->>O: 跳转支付 / 0 元单
6.2 步骤与 URL
| step | 模板 | POST 持久化 |
|---|---|---|
contact_information | order/contact_information | 创单、地址、savePreCoupon |
shipping_method | order/shipping_method | 运费、小费/保险、order_diy_offer |
payment_method | order/payment_method | payment_id、手续费 |
payment_gateway | 支付网关 | 第三方支付 |
步骤跳转由 OrderService::getCheckoutStep() 根据 has_contact_information / has_shipping_method / has_payment_method 决定。
6.3 特点
- 唯一在 shipping 步通过 Liquid POST 传
offer_from_name写积分/Seel 的典型路径。 - 快捷支付(express)可能 强制 走标准 URL 的 payment_gateway(
CheckoutService::isExpressPayment)。 - 优惠券:结账前
GET /coupon/use/{token};创单时savePreCoupon从 Cookie 绑定。
7. 单页结账(one_page)
入口:POST /{store}/one-page-checkouts/{token}/*
实现:CheckoutOnePageService + homeapi/OrderOnePage
7.1 主流程
sequenceDiagram participant FE as 单页前端 participant API as OrderOnePage participant S as CheckoutOnePageService participant CS as CartService FE->>API: POST presave(邮箱失焦) API->>S: preSave → 创/更新单 FE->>API: POST price API->>S: getCart(纯算价,不写 diy offer DB) FE->>API: POST shippings / payments / insurance FE->>API: POST complete 或 preComplete API->>S: saveOrder + saveProducts + handlerOrderDiyOffer Note over S: offer_from_name 在 complete 最后写入 API->>S: savePaymentMethod → 支付表单 / 0 元
7.2 关键 API
| 端点 | 作用 | 是否落库 |
|---|---|---|
presave | 邮箱、地址预写、创单 | 是 |
price | 返回计价 cart | 否(仅内存) |
shippings / payments | 选项列表 | 否 |
precomplete | 全量落盘,不触发部分事件 | 是 |
complete | 全量落盘 + 事件 + 支付 | 是 |
7.3 计价链
getCart() 内部:
CartService::getListcalCartCouponPrice→CouponHandlerService::useCouponHandlercalCartTaxPrice/calCartShippingPrice/calCartTipPrice/calCartPaymentPricecalCartTotalPrice
orderPreData() 把 cart 各 current_* 映射到 o_order(含 checkout_type=one_page)。
7.4 与标准的差异
| 项 | 单页 | 标准 |
|---|---|---|
| order_diy_offer | complete 时 trans_info.offer_from_name | shipping POST |
| 页面 | 无 step URL | 四步 Liquid |
| 价格刷新 | 频繁调 price | 每步 getList |
| preSave 锁 | OnePageCheckoutPresaveLockKey 防并发创单 | — |
8. 渐进式结账(single_page)
路由注释:渐进式结账(app/homeapi/route/route.php 145 行)。
入口:/{store}/single-page-checkouts/{token}/*
实现:CheckoutSinglePageService + homeapi/OrderSinglePage
8.1 主流程
sequenceDiagram participant FE as 渐进式前端 participant API as OrderSinglePage participant S as CheckoutSinglePageService participant CS as CartService FE->>API: POST email API->>S: saveEmail → createOrder Note over S: checkout_type=single_page FE->>API: POST contact-information FE->>API: POST shipping-method API->>S: saveShippingMethod + saveDiyOffer FE->>API: POST use-coupon(可选) FE->>API: POST payment-method FE->>API: POST gateway → 支付 URL
8.2 与标准 / 单页的异同
| 项 | 渐进式 | 标准 | 单页 |
|---|---|---|---|
| 交互 | API 分步,前端控 UI | 服务端渲染分步 | 单屏一次提交 |
| 创单 | email 步 | contact_information | presave |
| diy_offer | shipping-method(同标准) | shipping_method | complete |
| 用券 | POST use-coupon | GET coupon/use | trans_info |
| GET 辅助接口 | shippings/payments/diy-offer 等 | 合并在 Liquid 渲染 | POST 为主 |
渐进式在业务步骤上 最接近标准多步,但技术栈是 REST + 前端路由,无 ?step= 整页跳转。
9. COD 结账(cod)
页面:GET /{store}/cod-checkouts/{token} → OrderCodPage::index(Liquid checkout 模板)
API:POST /{store}/cod-checkouts/{token} → OrderCodPage::saveOrder
9.1 主流程
sequenceDiagram participant U as 用户 participant P as OrderCodPage Liquid participant API as homeapi/OrderCodPage participant CC as CodCartService participant H as CodOrderHandlerService U->>P: GET cod-checkouts P->>CC: getCartList(无 o_order) U->>API: POST 地址/物流/提交 API->>H: saveOrder Note over H: CodOrderModel,checkout_type=cod
9.2 与在线的本质差异
| 项 | COD | 在线 |
|---|---|---|
| 订单表 | COD 订单(CodOrderModel) | o_order |
| 购物车服务 | CodCartService | CartService |
| 读已创单 | 否(getCartList 不 hydrate order) | getList 读 o_order |
| order_diy_offer | 无 | 有 |
| 替换型优惠券 | 可能 不清满减(见优惠文档 §6.7) | 有 checkCouponUseWithPromotionStatus |
| 支付 | 货到付款,无 gateway 步 | 在线支付 |
9.3 COD 与在线入口并存
CheckoutService::generateCheckoutUrlArrayByCodConfig() 根据 cod_checkout_type 返回:
online_checkout_url— 由checkout_process决定三种在线之一cod_checkout_url—/cod-checkouts/{token}
模板可在页内切换「在线付 / 货到付款」(配置 3、4 时)。
9.4 COD 单页(扩展)
商品维着陆、无 checkout_token 的 COD 下单见 cod-one-page-checkout.md,API 前缀 cod-one-page-checkouts,仍走 CodOrderHandlerService,但与本文「购物车 token 主流程」分离。
10. 智能结账(smart)
配置 checkout_process=smart 时:
- 首次访问
getCurrentRequestCheckoutProcessType()随机 分配 one_page / standard / single_page 之一(array_rand)。 - 写入 Cookie
COOKIE_CHECKOUT_PROCESS_SMART(30 天)。 - 若后台更新
checkout_process_smart_update_time晚于 Cookie,重新分配。
注意:smart 只影响 未创单前 的 URL;订单创建后以 order.checkout_type 为准。
11. 优惠体系在各形态下的落点(摘要)
完整规则见 promotion-discount-checkout.md。此处只强调 与结账形态相关 的差异。
| 能力 | 标准 | 单页 | 渐进式 | COD |
|---|---|---|---|---|
| Cart diy_offer + 满减 | getList | getList | getList | CodCartService |
| 优惠券 | Cookie + useCoupon | useCouponHandler | use-coupon API | CodCouponService |
| order_diy_offer | shipping POST | complete | shipping-method POST | 无 |
| getList 回写 order | 有 | 有 | 有 | 无 |
持久化时机详表:checkout-flows-detail.md §3
12. 如何选择阅读路径
| 你的问题 | 去看 |
|---|---|
| 四种方式有什么区别 | 本文 §5 对比表 |
| 标准 Liquid 每一步写什么库 | 本文 §6 + detail §2.1 |
| 单页 complete 里调用顺序 | 本文 §7 + detail §2.2 |
| 渐进式 API 列表 | detail §2.3 |
| COD 为何没有积分落库 | 本文 §9.2 + 优惠文档 §3 |
| 活动谁先谁后、能否叠加 | promotion-discount-checkout.md |
| COD 单页商品着陆 | cod-one-page-checkout.md |
13. 文档拆分说明
| 文件 | 内容 |
|---|---|
| checkout-flows.md(本文) | 关系、对比、各形态主流程 |
| checkout-flows-detail.md | API 逐步、落库表、Service 方法索引 |
| promotion-discount-checkout.md | 优惠四体系、互斥、type 细拆 |
文档版本:与 OrderModel checkout_type、app/homeapi/route/route.php 路由注释一致。