文档目录
电商平台系统

简介

本文件面向电商开发者,系统化梳理 DouPHP 电商平台的核心能力与实现要点,覆盖商品管理、订单处理、购物车、支付集成、物流配送等关键业务;深入说明商品属性、库存控制、价格策略、促销活动、订单生命周期、支付流程、退款处理与物流跟踪;并提供扩展现有功能(新增支付方式、接入第三方物流)的实践指引与技术建议。文档同时给出性能优化、并发安全与数据一致性的工程化方案。

项目结构

DouPHP 采用“前台(front)/后台(admin)/API(api)/插件(plugin)/核心(core)”分层组织,入口统一由根 index.php 引导,经 core/bootstrap.php 完成环境初始化、配置加载、自动加载、容器与路由绑定,再交由前端路由分发到具体控制器与服务。

graph TB
A["入口 index.php"] --> B["引导 bootstrap.php"]
B --> C["配置 config/config.php"]
B --> D["自动加载与别名注册"]
B --> E["DI 容器与 Request/Route 绑定"]
E --> F["前台路由分发"]
F --> G["控制器(如 Product/Order)"]
G --> H["服务层(如 PaymentService)"]
H --> I["数据库/存储/外部网关"]

核心组件

  • 入口与引导:统一异常处理、语言前缀解析、路由委派、请求对象提前注入。
  • 配置与环境:数据库连接、应用密钥、调试开关、模块映射。
  • 商品展示:分类列表与详情渲染,结合 SEO、导航、属性模块与评论模块。
  • 订单入口:默认跳转到购物车页,后续结算/收银台在独立控制器中拆分。
  • 支付服务:支付尝试台账、状态机、幂等回调、混合支付(钱包+网关)、退款分账、对账收尾。

架构总览

系统以“HTTP 边界 -> 路由 -> 控制器 -> 服务 -> 基础设施”的分层架构运行。入口负责异常与响应,引导阶段完成基础依赖注入,控制器聚焦页面/接口编排,服务层承载核心业务(如支付),基础设施提供 DB、存储、事件、日志等能力。

sequenceDiagram
participant U as "用户浏览器"
participant R as "路由/调度"
participant C as "控制器"
participant S as "服务层"
participant DB as "数据库"
participant P as "支付网关/钱包"
U->>R : HTTP 请求
R->>C : 调用控制器方法
C->>S : 执行业务逻辑
S->>DB : 读写订单/支付/商品数据
S->>P : 发起支付/查询状态
P-->>S : 回调/结果
S-->>C : 返回结果
C-->>U : 渲染页面或 JSON 响应

详细组件分析

商品模块(产品列表与详情)

  • 列表页:按分类/品牌/排序/归档维度分页,组装面包屑、SEO、导航与相关商品。
  • 详情页:构建商品主体数据,按需加载属性、优惠券、评论,生成结构化数据与 SEO。
  • 扩展点:通过 Module 机制动态加载 attribute、coupon、comment 等模块,便于扩展商品属性与评价体系。
flowchart TD
Start(["进入商品页"]) --> Parse["解析路由参数<br/>分类/归档/品牌"]
Parse --> BuildList["构建列表数据<br/>分页/排序/筛选"]
BuildList --> RenderCat["渲染分类页视图"]
Start --> Show["进入商品详情"]
Show --> LoadDetail["加载商品主体/属性/评论"]
LoadDetail --> SEO["生成SEO/结构化数据"]
SEO --> RenderDetail["渲染详情页视图"]

订单入口与购物车跳转

  • 裸 order 路由直接重定向至购物车页,将复杂流程拆分为 Cart/Checkout/Cashier/User 等子控制器,职责清晰、易于维护。

支付服务(创建、回调、合并、退款、收尾)

  • 支付尝试台账:每次支付尝试写入 order_payment,作为第三方支付流水 out_trade_no。
  • 状态机与幂等:基于 PaymentStatus 的状态迁移校验;webhook 重复到达不重复联动订单。
  • 混合支付:支持钱包与网关多腿支付,累计金额达到订单金额后推进订单为已支付。
  • 退款分账:按成功支付腿优先顺序拆分退款,钱包腿即时退回余额,网关腿登记待人工/回调收尾。
  • 收尾与对账:当所有成功腿金额覆盖订单金额时,调用订单状态机推进 PAID,并记录最终 pay_id。
sequenceDiagram
participant O as "订单"
participant PS as "PaymentService"
participant DB as "数据库"
participant GW as "支付网关"
participant W as "钱包服务"
O->>PS : 创建支付尝试(createForOrder)
PS->>DB : 插入 pending 支付记录
PS->>GW : 发起支付(插件侧)
GW-->>PS : 回调通知(markSucceeded)
PS->>DB : 标记支付成功/累计已付
PS->>O : 尝试收尾(tryFinalizeOrder)
alt 未付满
PS-->>O : 保持部分支付
else 已付满
PS->>O : 推进订单为已支付
end
Note over PS,W : 若使用余额支付,走 markSucceededByWallet

支付状态机与退款流程图

stateDiagram-v2
[*] --> 待支付 : "创建支付尝试"
待支付 --> 已支付 : "回调成功/余额扣款"
待支付 --> 失败 : "网关拒绝/超时关闭"
待支付 --> 已关闭 : "主动关闭/超时"
已支付 --> 部分退款 : "退款部分金额"
已支付 --> 已退款 : "全额退款"
部分退款 --> 已退款 : "剩余金额退款"

依赖关系分析

  • 入口依赖引导程序进行环境初始化与依赖注入。
  • 控制器依赖服务层完成业务编排,避免在控制器内写复杂事务。
  • 支付服务依赖订单状态机、钱包服务与数据库,保证支付与订单一致性。
  • 插件化支付:各支付插件通过 Provider/Service 暴露统一接口,由核心支付服务协调。
graph LR
Index["index.php"] --> Boot["bootstrap.php"]
Boot --> Cfg["config.php"]
Boot --> Router["路由/Request"]
Router --> Ctrl["Product/Order 控制器"]
Ctrl --> PaySvc["PaymentService"]
PaySvc --> DB["数据库"]
PaySvc --> Wallet["钱包服务"]
PaySvc --> OrderState["订单状态机"]

性能与并发

  • 幂等与防重:支付 webhook 通过 gateway+transaction_id 唯一键与状态机双重保障,避免重复处理。
  • 事务与锁:钱包支付使用 FOR UPDATE 行锁与事务包裹,防止并发超扣;退款分账逐腿加锁更新。
  • 金额容差:引入 AMOUNT_EPSILON 避免 decimal 浮点误差导致“已付满”判定漏判。
  • 异步与重试:对账兜底机制允许未立即完成的支付在后续扫描中自愈,提升鲁棒性。
  • 缓存与索引:建议在高频查询字段(order_sn、payment_sn、gateway_txn)建立索引;对商品列表、分类树可考虑缓存层。
  • 限流与安全:API 层具备 ThrottleMiddleware,建议在高并发场景开启限流与验证码。

故障排查指南

  • 未捕获异常:入口统一记录错误日志,并根据 site.debug 输出调试页或 JSON 500。
  • 业务异常:DomainException 会携带错误信息与回跳地址,JSON 请求返回 422。
  • 支付问题:检查 payment 状态迁移是否合法、订单是否处于可收款状态、回调原文是否记录。
  • 退款问题:确认退款分账是否按成功支付腿拆分,钱包腿是否已退回余额,网关腿是否已收尾。

结论

DouPHP 以清晰的层次划分与插件化设计,提供了完整的电商核心能力:商品展示、订单流转、支付与退款、以及可扩展的物流与促销生态。支付服务通过状态机、事务与幂等机制确保资金与订单的一致性;控制器与服务解耦使业务演进更灵活。建议在生产环境启用严格的安全与限流策略,并结合缓存与索引优化性能。

附录:扩展开发示例

新增支付方式(以插件形式)

  • 目标:在不改动核心代码的前提下,新增一个支付渠道。
  • 步骤:
    • 在 plugin 目录下新建支付插件目录,包含 manifest.php、Provider、Service 与 SDK。
    • Provider 负责对外暴露支付动作(下单、回调处理)。
    • Service 封装与网关交互的细节(签名、加密、报文转换)。
    • 在核心支付流程中,通过 gateway slug 选择对应插件执行。
  • 参考路径:
    • 支付服务入口与状态机:core/service/payment/PaymentService.php:84-225
    • 现有支付插件示例:plugin/alipay、plugin/wxpay、plugin/bankpay

接入第三方物流服务

  • 目标:对接快递查询或电子面单打印。
  • 步骤:
    • 在 plugin 下新增物流插件,实现 Provider/Service。
    • 在订单发货流程中调用物流 Service 获取运单号或轨迹。
    • 将物流信息关联到订单,供前后端展示。
  • 参考路径:
    • 订单与支付主流程:core/service/payment/PaymentService.php:237-296
    • 现有物流插件示例:plugin/express、plugin/ems

扩展现有电商功能(属性/促销/评论)

  • 商品属性:通过 Module::make('attribute') 动态加载属性列表,便于扩展 SKU 维度。
  • 促销活动:通过 coupon 模块与商品详情页联动,展示可用券并参与结算。
  • 评论系统:通过 comment 模块加载商品评论,支持分页与互动。
  • 参考路径:
    • 商品详情中的属性/优惠券/评论加载:front/controller/product/ProductController.php:199-253
添加日期:2026-10-05