20260722 161403 基于 Django 实现的电商系统功能需求文档

20260722_161403_基于_Django_实现的电商系统功能需求文档.md

基于 Django 实现的电商系统功能需求文档

对标 Shopify Plus(含 Online Store 2.0、Admin/Storefront API、Checkout Extensibility)的全量电商系统需求规格说明书

文档版本:v1.0
编写日期:2026-07-21
适用技术栈:Python 3.11 + Django 5.x + Django REST Framework + Celery + PostgreSQL + Redis


目录


第 1 章 文档说明

1.1 文档目的

本文档以 Shopify Plus(含 Online Store 2.0 主题体系、Admin GraphQL API、Storefront API、Checkout Extensibility)为功能对标基准,落地到 Python + Django 技术栈,形成一份覆盖全量电商业务的功能需求规格说明书。

文档面向以下读者:

  • 产品经理 / 业务负责人:用于确认功能范围、字段口径与业务规则
  • 后端开发工程师:用于理解 Django app 切分、数据模型、API 设计
  • 前端 / 主题开发工程师:用于理解模板系统、Storefront 数据契约
  • 测试工程师:用于逐条拆解验收点

1.2 对标范围

对标来源 覆盖范围
Shopify Admin API (GraphQL) 商品、订单、客户、库存、折扣、营销、分析、文件、Fulfillment 等后台能力
Shopify Storefront API 商城前台(商品检索、购物车、Checkout、客户查询)数据契约
Online Store 2.0 主题架构(sections / blocks / JSON templates / theme settings)
Checkout Extensibility 可扩展结账(Web Pixel、Checkout UI Extensions、Shop Pay 类支付体验)
Shopify Markets 多市场(多币种、多语言、多区域定价、关税)
Shopify Inbox / Email / Audiences 营销自动化与触达
Shopify Flow / Functions 业务自动化与可编程折扣逻辑(用 Django 信号 + Celery + 自定义脚本引擎替代)

1.3 非目标(本期不实现)

  • 不复刻 Shopify 的 SaaS 控制台(不提供”商家注册即开店”的多租户入驻流程,本期默认单商户私有部署,但底层数据结构预留 shop_id 字段以支持未来扩展)
  • 不实现 Shopify App Store 应用市场机制(仅支持以 Django app 方式插件化扩展)
  • 不复刻 Shopify 系、Shop Pay、Shop App 等品牌专属封闭能力,用通用的快捷支付、钱包方案替代
  • 不自建支付网关(接入第三方:Stripe / 支付宝 / 微信支付 / 银联等)

1.4 名词术语

术语 含义 Shopify 对应
店铺(Shop) 一个独立的电商站点实例 Shop
商品(Product) 可售实物或数字品 Product
多属性(Variant) 商品的 SKU 维度组合(颜色×尺码等) Product Variant
收藏(Collection)/集合 商品的分组(手动 / 自动规则) Collection
元字段(Metafield) 业务对象上的自定义扩展字段 Metafield
履约(Fulfillment) 订单出库、发货、物流分配 Fulfillment
多渠道(Channel) 销售渠道:在线店、POS、Facebook、手动等 Sales Channel
草稿订单(Draft Order) 由商家手工创建的订单 Draft Order
放弃结账(Abandoned Checkout) 客户进入结账但未完成付款 Abandoned Checkout
主题(Theme) 前端展示模板集合 Theme
元对象(Metaobject) 业务侧自定义结构化数据类型 Metaobject

第 2 章 系统总体架构

2.1 整体分层架构

系统采用 前后端分离 + 服务端渲染混合 架构(对标 Shopify 由 Liquid 服务端渲染 + Hydrogen 客户端的混合策略)。

┌────────────────────────────────────────────────────────────────────┐
│                          客户端层 (Clients)                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌──────────┐ │
│  │ Online Store │  │ Headless 站点│  │ 第三方渠道   │  │ Admin 后台│ │
│  │ (Django 模板)│  │ (React/Vue 等│  │ (POS/社交/Mk│  │ (Django+JS│ │
│  │              │  │  走Storefront│  │  走Admin API│  │  Admin)  │ │
│  └──────────────┘  └──────────────┘  └──────────────┘  └──────────┘ │
└────────────────────────────────────────────────────────────────────┘
                                  │
        ┌─────────────────────────┼─────────────────────────┐
        ▼                         ▼                         ▼
┌──────────────┐          ┌──────────────┐         ┌──────────────┐
│  Storefront  │          │   Admin API  │         │ Webhook /    │
│  API (DRF)   │          │   (DRF/Graph │         │ Event Bus    │
│  只读+下单   │          │  ql via      │         │ (Celery+     │
│              │          │   strawberry)│         │  Redis pubsub)│
└──────────────┘          └──────────────┘         └──────────────┘
        └─────────────────────────┬─────────────────────────┘
                                  ▼
        ┌─────────────────────────────────────────────┐
        │           核心业务领域层 (Domain Apps)         │
        │  products │ inventory │ orders │ payments    │
        │  checkout │ customers │ discounts │ marketing│
        │  themes   │ content   │ analytics │ channels │
        │  shops    │ settings  │ metafields│ users     │
        └─────────────────────────────────────────────┘
                                  ▼
        ┌─────────────────────────────────────────────┐
        │   基础设施层 (Infrastructure)                  │
        │  PostgreSQL │ Redis │ Celery │ Storage(S3)   │
        │  Search(Postgres FTS/Elastic) │ Cache │ MQ   │
        └─────────────────────────────────────────────┘

2.2 技术选型

层次 技术 选型原因
Web 框架 Django 5.x 成熟 ORM、Admin、权限、i18n、模板系统一站到位
API 框架 Django REST Framework + strawberry-graphql-django REST 用于第三方 Admin API 对接;GraphQL 复刻 Shopify Storefront 数据契约
异步任务 Celery + Redis broker 放弃结账提醒、邮件发送、报表生成、库存同步等异步场景
缓存 Redis (django-redis) 商品列表、变体解析、限流、Session
全文检索 PostgreSQL FTS(Phase 1)→ Elasticsearch/Meilisearch(Phase 2) 商品搜索、筛选、聚合
数据库 PostgreSQL 15+ 支持 JSONB(metafields)、btree_gin、分区表(orders)
对象存储 S3 兼容(MinIO / OSS / COS) 商品图、主题资源、导出文件
任务调度 Celery Beat 定时任务(每日对账、库存阈值告警)
前端模板 Django Template + TailwindCSS / HTMX(兼容 Liquid 思路) 服务端渲染对标 Shopify Liquid
头部电商前端 React + Hydrogen-like(Phase 3) 通过 Storefront API 实现 Headless,对标 Shopify Hydrogen
鉴权 django-allauth + JWT (djangorestframework-simplejwt) 客户端账户、社交登录
权限 django-guardian + 自定义对象级权限 商家员工分对象授权
Webhook django-restframework + 自签校验 + HMAC SHA256 对外推送事件
可观测 Sentry + Prometheus + Grafana 错误/性能监控
容器 Docker + docker-compose / k8s 部署
CI/CD GitHub Actions + 蓝绿/滚动 自动发布

2.3 Django App 拆分

采用 DDD 限界上下文 切分,每个 app 内含 models.py / services.py / api.py / admin.py / signals.py / migrations

project/
├── apps/
│   ├── shops/              # 店铺、店铺设置、域名
│   ├── accounts/           # 员工、权限、客户账户
│   ├── products/           # 商品、变体、收藏、图片
│   ├── inventory/          # 库存、库位、调拨、库存事件
│   ├── pricing/            # 价格、多市场定价、汇率
│   ├── cart/               # 购物车、运费预估
│   ├── checkout/           # 结账会话、地址、运费、税额、订单生成
│   ├── orders/             # 订单、履约、退款、取消、退货
│   ├── payments/           # 支付意图、支付凭证、对账、网关适配
│   ├── customers/          # 客户档案、地址簿、积分
│   ├── discounts/          # 折扣码、自动折扣、购物车规则
│   ├── marketing/          # 邮件/SMS 触达、自动化、Audience 分群
│   ├── analytics/          # 销售分析、漏斗、留存、报表
│   ├── themes/             # 主题、模板、sections、blocks、资源
│   ├── content/            # 页面、博客、文章
│   ├── catalog/            # 导航、菜单、Shopify Metaobject
│   ├── metafields/         # 通用元字段
│   ├── seo/                # SEO 模板、 redirects、URL 别名
│   ├── channels/           # 多渠道(POS / Online / 手动 / Facebook 等)
│   ├── tax/                # 税率、税务计算引擎
│   ├── shipping/           # 运费策略、承运商适配
│   ├── webhooks/           # Webhook 订阅、推送、重试
│   ├── notifications/      # 通知模板(邮件/SMS/站内)
│   └── web/                # 商城前台视图(Liquid-like 渲染入口)
├── core/                   # 公共:BaseModel、混入、枚举、错误码
├── infra/                  # 基础设施接入:storage、cache、mq、observability
├── config/                 # settings、urls、wsgi/asgi
└── tests/

2.4 与 Shopify 概念的映射策略

  • Shopify 的 Liquid + Sections architecture → 在 Django 中以”主题资源 + 模板引擎 JSON schema + 区块组件类” 实现,见第 13 章
  • Shopify 的 Admin/Storefront 双 API → 同样拆分两套 endpoint:Admin API 走 /api/admin/*(店铺员工鉴权),Storefront API 走 /api/storefront/*(Public Token 鉴权,对应 Shopify 的 Storefront Access Token)
  • Shopify 的 Metafields → 通用 apps/metafields/,所有主业务模型 mixin HasMetafieldsMixin,以 JSONB 列存储 + schema 校验
  • Shopify 的 Functions / Flow → 用 apps/discounts + services/script_engine.py 实现基于 Python 的可执行折扣/运费/税脚本(受控沙箱,禁用 import

第 3 章 功能模块总览

按业务对象划分共 17 个一级模块,每个模块下若干功能点(FP,Function Point)。

编号 模块 主要功能点数 优先级 章节
M01 商品与目录 28 P0 第 4 章
M02 库存与履约 16 P0 第 5 章
M03 购物车与结账 22 P0 第 6 章
M04 订单管理 26 P0 第 7 章
M05 支付与结算 18 P0 第 8 章
M06 客户与会员 17 P1 第 9 章
M07 折扣与促销 19 P1 第 10 章
M08 营销与触达 14 P1 第 11 章
M09 数据分析 16 P1 第 12 章
M10 主题与模板 21 P0 第 13 章
M11 页面与博客 9 P1 第 14 章
M12 SEO 与域名 11 P1 第 15 章
M13 多渠道销售 8 P2 第 16 章
M14 权限/多语言/税务 15 P1 第 17 章

优先级说明:P0 = MVP 必须具备;P1 = 首个大版本必须具备;P2 = 后续迭代。

每个功能模块的章节统一格式:
1. 业务目标
2. 角色与流程
3. 功能点清单(按 FR 编号)
4. 关键业务规则
5. 数据要点
6. 接口要点(Admin / Storefront / Webhook)
7. Shopify 对标说明
8. 验收要点


第 4 章 商品与目录管理

4.1 业务目标

对标 Shopify 的 Products / Variants / Collections / Inventory / Metafields,提供从商品建模、多属性管理、商品分组、自动集合规则到自定义字段扩展的完整能力,支撑实物 / 数字 / 服务三类商品。

4.2 角色与流程

  • 商品编辑员:建商品、配变体、配图、配元字段、配 SEO
  • 商品管理员:批量上下架、调价、归类、调库存
  • 主题开发者:通过 sections 渲染商品数据
  • 客户:浏览、搜索、加入购物车

关键流程示例:商品创建→变体生成→库存初始化→上架

编辑员新建 Product (draft)
  ↓ 配置 Option(颜色/尺码)→ 自动生成 Variant 笛卡尔积
  ↓ 为每个 Variant 维护 SKU / Barcode / Price / Weight / Inventory Policy
  ↓ 绑定 Image(多图,可设主图)
  ↓ 加入 Collection 或建立自动集合规则
  ↓ 设置 Status = active → 商城可见

4.3 功能点清单

4.3.1 商品(Product)
FR 编号 功能点 说明
FR-4.1.1 商品基础字段 标题、描述(富文本)、Handle(URL slug)、状态(draft/active/archived)、商品类型、厂商、模板后缀(用于模板路由)
FR-4.1.2 商品状态管理 draft → active → archived;archived 商品不出现在前台与管理统计中但仍可访问明细
FR-4.1.3 商品 Tag 标签 多对多自由标签,用于搜索筛选与 automatic collection 规则匹配
FR-4.1.4 商品选项(Options) 最多 3 个选项维度(颜色/尺码/材质等);每个选项最多 100 个取值;变体数 ≤ 1000
FR-4.1.5 商品多图管理 支持多张图片,每张可指定变体归属,主图置顶;图片走对象存储;自动生成多规格缩略图(200/400/800/1600/2400)
FR-4.1.6 商品 SEO 字段 meta_title、meta_description、og_image、handle 别名
FR-4.1.7 商品元字段(Metafield) 业务对象挂自定义结构化数据,支持 namespace.key、类型(string/integer/json/boolean/color/date/file/reference),支持列表型
FR-4.1.8 商品模板后缀(template_suffix) 指定专题模板文件名,前端按 product.<suffix>.liquid 渲染,未指定走默认 product.liquid
FR-4.1.9 商品礼品卡/数字类型 标记为 digital,下单后触发文件/卡密发放;标记 gift_card 类型走礼品卡逻辑
FR-4.1.10 商品重量与海关编码 weight、weight_unit、hs_code、country_of_origin,用于运费与关税计算
4.3.2 变体(Variant)
FR 编号 功能点 说明
FR-4.2.1 单变体默认 仅一个变体 = 单品;至少保留一个默认变体
FR-4.2.2 变体属性 SKU、Barcode(EAN/UPC/GTIN)、价格(含税价/不含税价)、对比价(划线价)、重量、税费类目、图片关联
FR-4.2.3 变体库存策略 inventory_policy = deny(缺货停售)/ continue(继续售卖)/ oversell(限量超卖);与库位库存数量联动
FR-4.2.4 变体调价与多币种 价格可按市场(Market)覆盖定义;与 M14 多市场定价打通
FR-4.2.5 变体成本字段 cost 字段对客户不可见,用于毛利分析
FR-4.2.6 变体重量计算 用于前端按重量配运费,可继承自父商品
FR-4.2.7 变体条码 同 SKU 允许多条码;条码唯一性可选(按店铺设置)
4.3.3 收藏/集合(Collection)
FR 编号 功能点 说明
FR-4.3.1 手动集合 人工挑选商品;支持排序(best_selling/price_asc/manual/created_desc/title_asc)
FR-4.3.2 自动集合 规则引擎:条件 = tag / price / type / vendor / stock / metafield,逻辑 AND/OR;规则变更触发 Celery 重算
FR-4.3.3 集合层级 不支持多级嵌套(与 Shopify 一致),通过 menu + handle 模拟分层
FR-4.3.4 集合图片与描述 用于集合页 SEO 与首图
FR-4.3.5 集合模板后缀 collection.<suffix>.liquid,可分集合定制专属展示
FR-4.3.6 集合商品数量与分页 默认 24/48/96 每页;支持 faceted 过滤 facet(按选项)
FR-4.3.7 Smart 集合规则预览 在保存前预览将匹配到的商品列表
FR-4.3.8 集合排序同步 修改集合内商品顺序需 Redis 缓存失效并广播 channel 事件
4.3.4 元字段与元对象(Metafield / Metaobject)
FR 编号 功能点 说明
FR-4.4.1 Metafield 定义 由管理员预先定义 namespace + key + type,前端可引用
FR-4.4.2 Metafield 引用类型 list.metaobjectfile_referenceproduct_reference,建立弱关联
FR-4.4.3 Metaobject 类型 自定义实体类型,如”品牌故事”、”门店信息”、”规格参数组”,含字段定义
FR-4.4.4 Metaobject CRUD 商家后台可视化编辑、批量导入导出
FR-4.4.5 Metafield 权限 区分 PUBLIC(前台可读)与 PRIVATE(仅后台),防止敏感字段泄露

4.4 关键业务规则

  • R-4.1:商品至少一个变体,且变体价格、库存策略均可独立设置。删除父商品须级联归档所有变体,不物理删除(保留 90 天软删除以兼容历史订单)。
  • R-4.2:Handle 在店铺内唯一,自动根据标题生成(中文走 pinyin slugify 或拼音首字母),手动改后保留 301 重定向至新 handle。
  • R-4.3:自动集合规则匹配采用”快照+定时刷新”双策略——保存即时快照匹配一次,之后每 15 分钟由 Celery 周期重算一次以保证新上架商品被收录。
  • R-4.4:变体数 > 1000 时禁止前端”加载全部变体”,须改为按选项展开懒加载(与 Shopify 后台一致)。
  • R-4.5:商品图片上传单文件默认上限 20MB,超过自动 WebP 转码并保留原图链接。SVG 须校验无 <script>
  • R-4.6:Metafield 删除时记录 deleted_metafield 审计表,便于回滚。
  • R-4.7:商品库存可见性 = is_published AND status='active' AND inventory_policy != 'deny' OR inventory > 0,三重判断。

4.5 数据要点

ProductProductVariantCollectionCollectionProduct(排序表)、ImageMetafield 等。详见 第 18 章 数据模型设计。关键约束:

  • Product.handle 联合 shop_id 唯一索引
  • ProductVariant.sku 联合 shop_id 唯一索引(可配置为可空非唯一)
  • CollectionProduct(collection_id, product_id, position) 复合索引支撑分页与排序
  • Metafield.owner_type + owner_id + namespace + key 组合唯一
  • 商品搜索:Product.search_vector(PostgreSQL tsvector + GIN 索引,由 title/tags/description 拼接构建)

4.6 接口要点

Admin API(REST)
Method Path 用途
GET /api/admin/products.json 商品列表(支持 limit/page/ids/collection_id/published_status/updated_at_min 等过滤)
GET /api/admin/products/{id}.json 商品详情
POST /api/admin/products.json 创建商品(含变体)
PUT /api/admin/products/{id}.json 更新商品
DELETE /api/admin/products/{id}.json 归档商品
POST /api/admin/products/{id}/metafields.json 添加元字段
GET/POST/PUT /api/admin/variants/* 变体 CRUD
GET/POST/PUT /api/admin/collections/* 集合 CRUD
GET/POST /api/admin/collections/{id}/products.json 集合内商品管理
POST /api/admin/inventory_levels/set.json 设置库位库存(见库存模块)
GET /api/admin/products/count.json 计数(用于仪表盘)
Storefront API(GraphQL,对标 Shopify Storefront)
query productByHandle($handle: String!) {
  productByHandle(handle: $handle) {
    id title description handle
    featuredImage { url altText width height }
    images(first: 20) { edges { node { url altText } } }
    variants(first: 50) {
      edges { node { id title sku priceV2 { amount currencyCode }
        availableForSale selectedOptions { name value } } }
    }
    options { id name values }
    metafields(namespace: "custom") { edges { node { key value } } }
  }
}
Webhook 事件
事件 触发时机 Payload
products/create 商品创建后 商品对象
products/update 任意字段更新 商品对象
products/delete 归档后 90 天物理删除 {id}
collections/createcollections/updatecollections/delete 集合变更 集合对象
inventory_levels/update 库存数量变更(详见第 5 章) 库位库存对象

4.7 Shopify 对标说明

  • 字段粒度上完整对齐 Shopify Product / ProductVariant / Collection / Image / Metafield 模型
  • automatic collection 规则引擎实现 Shopify 的 5 类条件 + AND/OR 组合
  • template_suffix 等同 Shopify 的”模板后缀”机制
  • 缺省不实现的 Shopify 功能:Product.media(视频/3D 模型),标注为 P2 后续迭代
  • Product.quoted_pricepriceV2 等价格对象对标 Storefront API 的多币种价格结构

4.8 验收要点

  • [ ] 单个商品 100 个变体在管理后台可在 1.5s 内完成列表渲染
  • [ ] 删除商品后历史订单仍可查询到SKU 与商品名(软删除生效)
  • [ ] 自动集合规则修改后 15 分钟内新匹配商品可见
  • [ ] Metafield PRIVATE 类型不出现在 Storefront API 响应中
  • [ ] 商品搜索 1 万商品库下 p95 < 200ms

第 5 章 库存与履约

5.1 业务目标

对标 Shopify Inventory Locations / Inventory Levels / Inventory Adjust / Fulfillment / FulfillmentService,提供多仓多库位的库存跟踪、调拨、出库履约。

5.2 角色与流程

  • 库存管理员:建库位、调拨、盘点
  • 履约运营:订单分仓、生成发货单、对接物流
  • 系统自动:库存阈值告警、超卖拦截、跨库位分配
订单支付完成 → inventory engine 按"就近+充足"算法选库位 → 锁库存 →
履约:拣货 → 包装 → 称重 → 生成物流面单 → 发出 → 库存递减 →
完成履约,订单状态进入 shipped

5.3 功能点清单

5.3.1 库位(Location)
FR 编号 功能点 说明
FR-5.1.1 库位 CRUD 名称、地址、是否活跃、是否兼作发货点
FR-5.1.2 库位类型 physical(自仓)/ fulfillment_service(第三方履约服务,对接口回传库存)
FR-5.1.3 多库位库存 同 SKU 在多库位维护不同库存数量
5.3.2 库存数量与变动
FR 编号 功能点 说明
FR-5.2.1 库存级别(InventoryLevel) location_id + variant_id + available 三元组
FR-5.2.2 库存调整 手工调整 + 备注原因(损益、盘点、退货入库);写 inventory_adjustment 日志表
FR-5.2.3 库存事件流 所有变动(售出、履约扣减、退款回库、调整)写入 inventory_event 不可变事件表
FR-5.2.4 安全库存阈值 每库位单独配,低于阈值触发 Celery 邮件 + 站内通知
FR-5.2.5 库存预留(reserved) 进入结账 5 分钟内预留库存,过期释放;预留数量计入 committed,不可再次售卖
FR-5.2.6 入库预期(incoming) 采购单字段,可见但不可售;到达后转换为 available
FR-5.2.7 多店统一视图 商家后台一屏查看所有库位某 SKU 的总库存与分布
5.3.3 履约(Fulfillment)
FR 编号 功能点 说明
FR-5.3.1 履约单创建 订单按 line_item 与库位拆出 FulfillmentOrder,可拆单履约
FR-5.3.2 履约状态机 unfulfilled → in_progress → fulfilled / on_hold / cancelled
FR-5.3.3 物流面单集成 支持顺丰/京东/德邦/中通/UPS/FedEx 等承运商 API 自动下单取单号
FR-5.3.4 手动填单 允许运营手工填写运单号与公司,触发客户通知
FR-5.3.5 履约事件回写 客户在订单详情页可查询物流轨迹(轨迹异步拉取并缓存)
FR-5.3.6 部分履约 一单可拆多次履约,每笔履约分别关闭对应 line_item
FR-5.3.7 履约取消 履约未发出前可取消,库存重新入库;发出后只能走退货反向流程
FR-5.3.8 履约服务回调 fulfillment_service 类型库位通过回调接口反向回传状态

5.4 关键业务规则

  • R-5.1:库存 = available(可售)+ committed(预留/已售未发)+ incoming(在途);available 是前端可见可购买的库存,不允许超卖除非 inventory_policy=continueoversell
  • R-5.2:跨库位库存同步必须使用 Redis 分布式锁防并发扣减竞争。
  • R-5.3:退货入库必须走人工审核,自动入库仅限未发出的履约取消。
  • R-5.4:库位发货能力受限于店铺设置:商家可指定仅某些库位对外发货。
  • R-5.5:每个 SKU 在每个库位保留独立的安全库存,触发阈值告警必须包含库位名、当前库存、阈值、商品名/SKU。

5.5 数据要点

Location / InventoryLevel / InventoryAdjustment / InventoryEvent / FulfillmentOrder / Fulfillment / FulfillmentEvent。详细字段见第 18 章。

5.6 接口要点

Admin API
Method Path 用途
GET/POST /api/admin/locations.json 库位 CRUD
GET /api/admin/inventory_levels.json 查库存
POST /api/admin/inventory_levels/set.json 设置库位库存(覆盖式)
POST /api/admin/inventory_levels/adjust.json 调整库存(delta)
POST /api/admin/inventory_levels/connect.json 变体激活到某库位
GET/POST /api/admin/fulfillment_orders.json 履约单查询/状态流转
POST /api/admin/fulfillments.json 创建履约(含跟踪号)
POST /api/admin/fulfillment_events.json 物流轨迹事件
Storefront API
query variantAvailability($id: ID!) {
  node(id: $id) {
    ... on ProductVariant { availableForSale quantityAvailable }
  }
}
Webhook 事件
  • inventory_levels/update
  • fulfillment_orders/create/fulfilled/cancelled
  • fulfillments/create/update

5.7 Shopify 对标说明

  • 完整对齐 Shopify 的 Location / InventoryLevel / InventoryAdjustment / FulfillmentOrder / Fulfillment 抽象
  • quantity_available 字段定义、committed/incoming 三态语义复用 Shopify Inventory API 1:1
  • 缺省不实现 Shopify 配套的”FulfillmentService 应用市场”机制,仅支持本地配置的履约服务

5.8 验收要点

  • [ ] 100 并发下单同一 SKU 不出现超卖(基于行级锁 + Redis 锁双保障)
  • [ ] 库存调整日志可追溯到操作员、时间、原因、前后值
  • [ ] 部分履约后的订单状态与库存数据自洽
  • [ ] 物流轨迹自动拉取,缓存 30 分钟,超时回源

第 6 章 购物车与结账

6.1 业务目标

对标 Shopify Cart API + Checkout(结合 Checkout Extensibility),实现商品入车、改数量、加备注、估算运费税额,最终生成订单前完整的地址+运费+税额+支付方式选择会话。

6.2 角色与流程

  • 客户:访问商城 → 加购物车 → 进入结账 → 填地址 → 选运费 → 选支付 → 完成下单
  • 系统自动:结账会话创建后倒计时 30 分钟,过期清空预留库存

核心状态机:

[GUEST/LOGGED_IN]
   ↓ add-to-cart
[CART] ── 持久化 (Session + DB 行)
   ↓ enter-checkout (校验商品 still for_sale)
[CHECKOUT_SESSION]  预留库存 5~15 分钟
   ↓ submit_shipping_address
[SHIPPING_VALIDATED]
   ↓ select_shipping_rate
[RATES_LOCKED]
   ↓ submit_payment_intent
[PAYMENT_AUTHED]
   ↓ complete (原子事务)
[ORDER_CREATED] → release/persist reserved stock

6.3 功能点清单

6.3.1 购物车(Cart)
FR 编号 功能点 说明
FR-6.1.1 多 line item 同购物车可包含多个不同变体
FR-6.1.2 同变体合并 重复 add 同一变体默认累加数量,可设置为替换
FR-6.1.3 数量修改 支持增减、直接覆盖,0 表示删除
FR-6.1.4 购物车备注 客户可填购物车备注(如包装要求),写入 order.note 而非 line item
FR-6.1.5 购物车属性(attributes) key-value 用作渠道来源、AB 测试 cookie 等隐藏元数据,写入 order.attributes
FR-6.1.6 优惠码预览 在购物车输入折扣码可即时计算预估优惠,但实际优惠应用发生在结账阶段
FR-6.1.7 持久化与归属 登录用户合并匿名购物车(按 variant 重新计算),存入 DB;匿名用户存 Session/Redis,30 天有效
FR-6.1.8 主题 / API 双写 模板里 {{ cart.items }} 渲染,等同 Storefront API cart 对象
FR-6.1.9 购物车行级属性 line item 可挂自定义属性(如刻字内容),保留展示与不重复计费
FR-6.1.10 礼品卡 / 数字处理 行内显示”礼品卡将于付款后自动发送至收件人邮箱”
6.3.2 结账会话(Checkout Session)
FR 编号 功能点 说明
FR-6.2.1 结账会话创建 由 cart 派生,独立 checkout_token,5 分钟无操作自动回收,最长 30 分钟
FR-6.2.2 地址表单 收件人姓名、电话、邮箱、地址行 1/2、城市、省、邮编、国家;自动填充已登录用户默认地址
FR-6.2.3 地址校验 调外部地址服务(如阿里云邮政编码/顺丰地址校验);校验失败给提示但仍允许继续
FR-6.2.4 账单地址 默认同收件地址,可分开填写;账单地址用于发票
FR-6.2.5 运费策略计算 apps/shipping 返回可用 rate 列表(条件 = 重量/订单金额/地区/承运商);默认锁定 24 小时
FR-6.2.6 税额计算 apps/tax 计算,按客户收货地+商品税类;含税/不含税显示由店铺设置
FR-6.2.7 折扣码应用 单结账会话最多 5 个折扣码,冲突由 services/discount_engine.py 解决
FR-6.2.8 礼品卡核销 输入礼品卡码扣减余额,多次可叠加
FR-6.2.9 支付方式选择 基于订单/账单地址过滤可用支付渠道;信用卡/借记卡/支付宝/微信/银联/银行转账/PayPal/Apple Pay
FR-6.2.10 完成结账 原子事务:建订单 + 支付凭证上链 + 库存预留转扣减 + 触发 webhook + 转入 paid/authorized 状态
FR-6.2.11 放弃结账判定 会话过期未完成 → 写入 abandoned_checkout,按配置时间发送 1~2 次挽回邮件
FR-6.2.12 多步/单页切换 商家后台可切换”多步结账”或”单页结账”
FR-6.2.13 字段自定义 商家可启用/禁用”公司名”“备注”“电话必填”等开关
FR-6.2.14 Webhook 与扩展点(Checkout Extensibility 对标) 在结账关键步骤支持注入自定义 UI 与跟踪 Pixel:page_view/add_payment_info/checkout_complete

6.4 关键业务规则

  • R-6.1:购物车中已下架 / 断货变体加入购物车时返回”无法购买”提示并保留其他项;进入结账时强制重新校验,不通过则回退购物车并提示。
  • R-6.2:结账会话 5 分钟无操作释放库存预留;保留 30 分钟内可继续(地址等已填信息不变)。
  • R-6.3:运费 rate 列表必须包含”运费金额+预估时效(天)+承运商名+是否免税”四要素。
  • R-6.4:税额由 apps/tax 集中计算,单一来源;前端任何展示都必须来自 tax_lines 字段。
  • R-6.5:当 inventory_policy=deny 且库存不足时,结账前调整数量并提示客户。
  • R-6.6:完成结账用 transaction.atomic() 包裹:”建订单 → 锁定 line_items → 扣减库存 → 记录 payment_intent”。任一步骤异常整体回滚。
  • R-6.7:放弃结账挽回邮件默认 1 小时 + 24 小时各一封,模板可配;同一 checkout_token 不重复发送。
  • R-6.8:商家可后台查询”放弃结账”列表,手动重发挽回邮件或一键创建草稿订单。

6.5 数据要点

  • Cart / CartItem(line item 的购物车态)
  • CheckoutSession:状态 IN_PROGRESS / COMPLETED / EXPIRED,记录快照化字段(避免后续商品价格变化导致金额混乱)
  • CheckoutAddress(收件/账单)
  • CheckoutShippingRate(rate 快照,含金额、时效、承运商 ID)
  • CheckoutTaxLine(每行税目)
  • AbandonedCheckoutcheckout_token + email + created_at + abandoned_at + line_items_snapshot

6.6 接口要点

Storefront API(Cart / Checkout,对标 Shopify Storefront Cart)
mutation cartCreate($input: CartInput!) {
  cartCreate(input: $input) {
    cart { id totalQuantity cost { totalAmount { amount currencyCode } }
      lines(first: 50) { edges { node { id quantity merchandise { ... on ProductVariant { id sku } } } } } }
  }
}
mutation cartLinesAdd / cartLinesUpdate / cartLinesRemove
mutation checkoutCreate($input: CheckoutCreateInput!)
mutation checkoutShippingAddressUpdateV2
mutation checkoutShippingLineUpdate
Admin API
Method Path 用途
GET /api/admin/abandoned_checkouts.json 放弃结账列表
POST /api/admin/abandoned_checkouts/{id}/reclaim.json 重发挽回邮件
Webhook
  • carts/createcarts/update(仅 API 购物车)
  • checkouts/createcheckouts/updatecheckouts/delete
  • abandoned_checkouts/create

6.7 Shopify 对标说明

  • 完全采用 Shopify 的 Cart + Checkout 拆分:Cart 是无身份会话态,Checkout 是产生 Order 必经的”已分配库存且校验通过”过渡态
  • Checkout Extensibility 通过 apps/checkout/extensions.py 加插件机制实现(hooks: address_stepshipping_steppayment_stepsummary_widgetthank_you_page),与 Shopify 的 UI Extensions 语义对齐
  • 实现 Web Pixel 接口:可注册 Pixel 监听 add_to_cart / begin_checkout / add_payment_info / purchase 等事件

6.8 验收要点

  • [ ] 50 并发同一变体加购物车,库存不超卖
  • [ ] 结账会话过期机制 5 分钟内不可下单(释放后再次完成会重派库存)
  • [ ] 运费 rate 改变后前端实时校准
  • [ ] 支付完成原子性:支付凭证与订单 1:1,无孤立支付凭证

第 7 章 订单管理

7.1 业务目标

对标 Shopify Order / Draft Order / Refund / Return / Cancel / Order Edit,提供完整订单生命周期管理。

7.2 角色与流程

  • 客户:下单 → 查订单 → 申请退款/退货
  • 客服:编辑订单、改地址、退款、换货、手动改状态
  • 仓库:履约(详见第 5 章)
  • 系统:订单状态机自动推进

订单状态机(financial_status × fulfillment_status):

financial_status:
  pending  authorized  paid  partially_paid  refunded  partially_refunded  voided

fulfillment_status:
  null  unfulfilled  partial  fulfilled  restocked

order status:
  open  closed (90 天自动 closed) / cancelled

7.3 功能点清单

7.3.1 订单基本信息
FR 编号 功能点 说明
FR-7.1.1 订单 ID 与编号 数据库自增 ID + 店铺前缀 + 年月生成的可读编号 #1001-BJ-2026-000721
FR-7.1.2 订单客户 关联 Customer(含游客下单创建轻量客户对象)
FR-7.1.3 收件/账单地址 快照式存储,姓名/单位/地址/邮编/电话/邮箱
FR-7.1.4 line_items 快照 含 variant_id/sku/title/variant_title/已售数量、单价(含税不含税均保留)、税费、折扣分摊、税费分摊
FR-7.1.5 折扣分摊 discount_allocations:每条 line item 分摊到的折扣金额
FR-7.1.6 运费行 shipping_lines[]:title + price + tax_lines + code
FR-7.1.7 税费行 tax_lines[]:rate + price + title + channel;含 line item 与运费税款
FR-7.1.8 总额对象 subtotal / total_shipping / total_tax / total_discounts / total_price / total_paid
FR-7.1.9 订单备注与标签 note(内部备注)+ tags(标签筛选)+ attributes(KV 来自结账)
FR-7.1.10 下单渠道 source_name:web/pos/api/手动(POS 借助 channel)
7.3.2 订单状态流转
FR 编号 功能点 说明
FR-7.2.1 财务状态 自动跟踪:支付授权→paid;部分付款→partially_paid;全退款→refunded
FR-7.2.2 履约状态 与 fulfillment 模块联动
FR-7.2.3 取消订单 取消原因枚举(库存/欺诈/客户改单/其他),自动归还库存,按需发退款
FR-7.2.4 关闭订单 90 天自动关闭,可手动重新打开
FR-7.2.5 订单编辑(Order Edit) 已下单未发货可编辑:增删 line item、改数量、改地址、调运费;编辑版本存档可回滚,差额走二次支付或退款
FR-7.2.6 草稿订单转正 draft → confirmed 触发客户付款邮件;不直接扣库存,待客户付款完成
7.3.3 退款与退货
FR 编号 功能点 说明
FR-7.3.1 退款单(Refund) 一订单可多次退款,含 line items、运费、调整金、税额分摊
FR-7.3.2 退货流程(Return) 客户申请 → 客服审核 → 收货确认 → 入库 → 退款;RMA 单号对接
FR-7.3.3 退货运费承担 配置退货规则:商家承担/客户承担/按金额阈值
FR-7.3.4 库存归还策略 退款时按 restock flag 决定是否回库;默认 true
FR-7.3.5 退款来源 自动退回原支付渠道;原渠道不可用走礼品卡或人工入账
FR-7.3.6 部分退款 一笔订单允许多笔退款,总额不可超订单实付总额
FR-7.3.7 退款与履约解耦 即使已发货也可退款(仅退款不退货),由客服人工审核
7.3.4 草稿订单
FR 编号 功能点 说明
FR-7.4.1 手工创建 客服代客下单,支持自定义价格、备注、客户邮箱
FR-7.4.2 邮件付款链接 生成付款链接发客户,客户付款后转为正式订单
FR-7.4.3 发票创建关联 草稿可关联发票模板,付款前发送
FR-7.4.4 转 POS 直接收款 POS 渠道可直接收银将草稿订单转正式订单

7.4 关键业务规则

  • R-7.1:所有金额以”最小货币单位 ×10^decimal_places”整数保存(防浮点),与 Shopify cents 模型一致。
  • R-7.2:取消订单产生 cancel_reasoncancelled_at,触发 orders/cancelled webhook。
  • R-7.3:line_items 在订单生成时深度快照,原商品/变体删除不影响已存订单查询。
  • R-7.4:order_edit 产生新版本,旧版本可查询;编辑差额生成 OrderAdjustment
  • R-7.5:退款必须遵循”先发支付再退款”原则,未付款订单不存在退款。
  • R-7.6:自动同步 tags 至客户记录(如 wholesale),便于后续营销分群。

7.5 数据要点

  • Order / OrderLineItem / OrderAddress(收件 + 账单)/ OrderShippingLine / OrderTaxLine / OrderAdjustment / Refund / RefundLineItem / Return / DraftOrder / DraftOrderLineItem
  • 订单按月分区表 orders_2026_07,历史归档冷库

7.6 接口要点

Admin API
Method Path 用途
GET /api/admin/orders.json?status=any&financial_status=paid&fulfillment_status=shipped 多维过滤订单
GET /api/admin/orders/{id}.json 订单详情
POST /api/admin/orders.json 手动创建订单
POST /api/admin/orders/{id}/cancel.json 取消订单
POST /api/admin/orders/{id}/close.json 关闭订单
POST /api/admin/orders/{id}/edit.json 编辑订单
POST /api/admin/orders/{id}/refunds.json 创建退款
GET/POST /api/admin/returns.json 退货 CRUD
GET/POST/PUT /api/admin/draft_orders.json 草稿订单 CRUD
POST /api/admin/draft_orders/{id}/send_invoice.json 发付款邮件
Storefront API(客户订单查询)
query customerOrders {
  customer {
    orders(first: 20) {
      edges { node { orderNumber processedAt fulfillments(first: 5) {
        edges { node { trackingInfo { number url } } } }
        totalPrice { amount currencyCode } } }
    }
  }
}
Webhook
  • orders/createorders/updatedorders/paidorders/cancelledorders/fulfilledorders/partially_fulfilledorders/deleted
  • refunds/create
  • draft_orders/createdraft_orders/updatedraft_orders/delete

7.7 Shopify 对标说明

  • 订单字段、状态、退款结构 1:1 对齐 Shopify Order REST API
  • DraftOrder 与 Shopify 行为完全一致(先草稿后客户付款链接)
  • Order Edit 机制对标 Shopify 2022 起开放的 editing API
  • Return 流程对标 Shopify Returns API(含 RMA)

7.8 验收要点

  • [ ] 已下单商品删除后订单查询历史价/名 SKU 无损
  • [ ] 部分退款再部分退款,最终退款金额不超过订单实付
  • [ ] 取消订单后库存正确归还
  • [ ] 草稿订单付款邮件链接 24 小时有效

第 8 章 支付与结算

8.1 业务目标

对标 Shopify Payments / 第三方支付网关 / 礼品卡 / 支付网关适配层,提供统一的支付意图管理、清算对账、防欺诈。

8.2 角色与流程

  • 客户:选支付方式 → 跳转网关 or 站内支付 → 回跳确认
  • 系统:支付意图 → 凭证上链 → 订单状态推进
  • 财务:日终对账
CheckoutSession  创建 PaymentIntent多条候选支付方式
    选定方式
[EXTERNAL_AUTH] 第三方托管 / iframe 内嵌
    用户完成授权
[AUTHORIZED] payment_id 返回 + 3DS 校验通过
    capture即时/延后
[CAPTURED] 财务 paid
    对账日终核对
[RECONCILED]

8.3 功能点清单

8.3.1 支付意图与凭证
FR 编号 功能点 说明
FR-8.1.1 PaymentIntent 对象 关联订单 / checkout,存储 amount、currency、status、provider、processor_response
FR-8.1.2 多支付方式并存 一订单允许多笔支付凭证(如礼品卡 + 信用卡)
FR-8.1.3 authorize/capture 分离 支持延时扣款(预授权 + 货发后 capture)
FR-8.1.4 凭证上链日志 所有网关响应原文落库(敏感字段脱敏),用于争议处理
FR-8.1.5 凭证幂等键 客户端 Idempotency-Key,避免双扣
8.3.2 支付网关适配
FR 编号 功能点 说明
FR-8.2.1 抽象 PaymentGateway 统一 authorize / capture / void / refund 接口
FR-8.2.2 内置适配器 Stripe、Adyen、PayPal、支付宝、微信支付、银联、Apple Pay、Google Pay
FR-8.2.3 自定义网关 apps/payments/gateways/custom/ 允许商家后台填入 endpoint+签名规则,热插拔
FR-8.2.4 测试与生产模式 shop 设置切换;测试凭证不写真实对账表
FR-8.2.5 网关配置加密 API Key 用 cryptography.Fernet 加密落库
8.3.3 礼品卡
FR 编号 功能点 说明
FR-8.3.1 礼品卡产品类型 商品类型 = gift_card,下单触发自动生成礼品卡码
FR-8.3.2 礼品卡 CRUD 客服可手动创建/作废;余额变更审计
FR-8.3.3 礼品卡核销 结账阶段输入卡号 + PIN,核销优先于其他支付方式
FR-8.3.4 礼品卡余额退回 部分退款时礼品卡支付优先按原卡退回
8.3.4 对账与防欺诈
FR 编号 功能点 说明
FR-8.4.1 每日对账任务 拉取各网关日流水,与 PaymentCapture 落账比较,差异入”对账异常”队列
FR-8.4.2 对账报告 月度日维度出报表,含成功/失败/退款笔数金额
FR-8.4.3 风控规则 基于规则(高金额/IP/同卡多次失败)拦截;外接风控引擎
FR-8.4.4 3DS 强制 商家可按金额/IP 风险强制启用 3DS
FR-8.4.5 支付链接(Pay by Link) 客服可对草稿订单生成支付链接发客户

8.4 关键业务规则

  • R-8.1:所有支付凭证必须可凭 (shop_id, transaction_id) 唯一定位;网关侧 ID 与本地 transaction_id 双向存储。
  • R-8.2:金额必须以”整数最小货币单位”在前后端流转,仅在展示时按 currency.decimal_places 格式化。
  • R-8.3:退款金额累计不得超过实付金额;礼品卡退款不可超过原核销金额。
  • R-8.4:网关响应原文保留 90 天后归档冷库。
  • R-8.5:所有 capture 失败必须有 failure_code + failure_message + next_retry_at 三元日志。

8.5 数据要点

  • PaymentIntentPaymentTransaction(authorize / capture / void / refund 各一笔)、GiftCardGiftCardTransactionReconciliationReportReconciliationLineFraudFlag
  • 敏感字段(卡号、CVV)不入库;仅存 masked_pan(4242****4242

8.6 接口要点

Admin API
Method Path 用途
GET /api/admin/orders/{id}/transactions.json 订单支付凭证
POST /api/admin/orders/{id}/transactions.json 手工 capture 或 void
POST /api/admin/orders/{id}/refunds.json 创建退款(含退款支付凭证)
GET/POST /api/admin/gift_cards.json 礼品卡 CRUD
GET /api/admin/gift_cards/lookup.json?code=XXX 查礼品卡余额
Storefront API
mutation checkoutCompleteWithCreditCardV2
mutation checkoutGiftCardApply
mutation giftCardCredit
Webhook
  • payment_intent/payment_failedpayment_intent/payment_authorizedpayment_intent/payment_captured
  • gift_cards/create/update

8.7 Shopify 对标说明

  • 抽象层与 Shopify Transaction API 字段(kind = authorization / capture / sale / void / refund)一一对齐
  • 礼品卡对标 Shopify GiftCard 资源(含 balance、initial_value、currency、code、disabled_at)
  • Shop Pay 不实现,用”快捷钱包”插件抽象留扩展位

8.8 验收要点

  • [ ] 同卡同金额两个相同请求只生成一笔支付凭证
  • [ ] 网关失败重试不超过 3 次,且单笔订单 24 小时内最多 10 次
  • [ ] 对账任务异常自动告警,财务人员在 24h 内确认
  • [ ] 敏感字段(如卡号)一律不入库

第 9 章 客户与会员体系

9.1 业务目标

对标 Shopify Customer / Customer Address / Customer Saved Search / Customer Group / Customer Tags / Customer Metafields,提供客户档案、地址簿、客户分群、消费历史、积分会员成长体系。

9.2 角色与流程

  • 客户:访问商城 → 注册/游客下单 → 自动建档 → 查询订单/地址 → 申请退货
  • 客服:合并/拆分客户档案、调标签、发分群邮件
  • 营销:基于分群发起新一批营销活动

9.3 功能点清单

9.3.1 客户档案
FR 编号 功能点 说明
FR-9.1.1 客户基本字段 first_name/last_name/email/phone(email 或 phone 至少一项)、accepts_marketing、note、tags
FR-9.1.2 自动建档 游客下单后订单完成时自动创建/合并客户档案(按 email 或 phone 匹配)
FR-9.1.3 客户账户激活 商家可邀请客户开账户;账户激活链接 7 天有效
FR-9.1.4 账户字段(password / 身份) Django auth.User + 自定义 Customer,密码强度策略与双因素(TOTP)可选
FR-9.1.5 社交账号关联 Google/Apple/Facebook/微信,通过 django-allauth 实现
FR-9.1.6 客户删除请求 GDPR 删除请求 → 14 天宽限 → 真实删除(订单保留但客户字段脱敏)
FR-9.1.7 客户合并 客服发现两份档案指向同一人时合并(保留创建时间最早者);历史订单关联迁移
9.3.2 地址簿
FR 编号 功能点 说明
FR-9.2.1 多地址 客户可管理多个收件/账单地址,每条地址含详情+是否默认
FR-9.2.2 地址软删除 删除地址但保留 90 天关联订单地址快照可查
FR-9.2.3 地址校验冗余 客户保存地址时验证国家+邮编格式
9.3.3 客户分群
FR 编号 功能点 说明
FR-9.3.1 保存搜索(Saved Search) 客服保存查询条件,复用过滤
FR-9.3.2 静态分群(Segment) 手工圈选客户,可发邮件
FR-9.3.3 动态分群 规则 = 订单数/累计消费/标签/城市/最后下单时间/会员等级 等条件;按日重算
FR-9.3.4 分群与营销联动 营销活动可选目标分群,支持过滤排除某些子集
9.3.4 会员等级与积分
FR 编号 功能点 说明
FR-9.4.1 会员等级规则 等级与累计消费挂钩,自动升降,跨级回退有 90 天宽限
FR-9.4.2 积分获取 下单支付完成按比例计算积分;可设置不同品类不同倍率
FR-9.4.3 积分核销 结账可使用积分抵扣;过期策略 1 年
FR-9.4.4 积分流水 积分增减均写 point_ledger(earn/spend/expire/adjust)
FR-9.4.5 等级权益 不同等级不同折扣码、不同运费、不同免邮门槛、礼品生日礼

9.4 关键业务规则

  • R-9.1:客户唯一性 = shop + emailshop + phone(phone 仅在主短信登录场景作为唯一键)
  • R-9.2:客户合并必须经财务/合规确认;订单归属变更需记录 customer_merge_audit
  • R-9.3:积分有效期由”获赠日期 + 店铺设置”决定;过期日 Cron 自动清零并记录
  • R-9.4:会员等级每次订单完成后即时判定,但降级延迟生效(保护客户体验)
  • R-9.5:删除客户时其订单保留为 guest_order,仅客户可识别信息脱敏

9.5 数据要点

  • CustomerCustomerAddressCustomerMetafieldCustomerSegmentCustomerSegmentMemberCustomerSavedSearchMembershipTierPointLedgerCustomerMergeAudit
  • Customer.summary 字段(last_order_at、orders_count、total_spent)由 Celery 任务异步更新

9.6 接口要点

Method Path 用途
GET/POST/PUT /api/admin/customers.json 客户 CRUD + 字段过滤
GET /api/admin/customers/{id}/orders.json 客户订单列表
GET /api/admin/customers/search.json?query=email:test@x.com Lucene 风格查询(简化版)
POST /api/admin/customers/{id}/account_activation_url.json 生成账户激活链接
POST /api/admin/customers/{id}/merge.json 客户合并
Storefront API
query customer {
  customer { id displayName email firstName lastName defaultAddress { ... }
    orders(first: 10) { edges { node { orderNumber } } } }
}
Webhook
  • customers/createcustomers/updatecustomers/deletecustomers/mergecustomers/disablecustomers/enable

9.7 Shopify 对标说明

  • Customer 主表字段与 Shopify 一致;Segment 模块对标 Shopify Audiences(静态+动态)
  • 客户合并是 Shopify Plus 增强,本系统完整实现以适应中国市场对客档合并的强需求
  • 引入 Shopify 未提供的会员等级/积分体系(中国市场标配)

9.8 验收要点

  • [ ] 同 email 在 30 秒内连续两次游客下单只生成一个客户档案
  • [ ] 客户合并后订单历史可追溯
  • [ ] GDPR 删除 14 天后真实删除验证

第 10 章 折扣、优惠与促销

10.1 业务目标

对标 Shopify DiscountCode / AutomaticDiscount / PriceRule,提供折扣码、自动折扣、限时活动、买赠、阶梯优惠、组合购物优惠、可编程折扣函数。

10.2 角色与流程

  • 营销:定义 PriceRule → 生成 Discount Code(批量)或 Automatic Discount
  • 客户:结账输入折扣码 / 自动应用满足条件的折扣
  • 系统:折扣引擎在结账阶段计算并分摊至 line_items

10.3 功能点清单

10.3.1 Price Rule(规则)
FR 编号 功能点 说明
FR-10.1.1 折扣类型 固定金额 / 百分比 / 免运费 / 买X送Y / 阶梯总价折扣
FR-10.1.2 适用范围 全店 / 指定集合 / 指定商品 / 指定客户分组
FR-10.1.3 最低消费门槛 全单金额门槛 OR 指定商品累计
FR-10.1.4 数量门槛 “满 3 件”、”满 500g”等数量阈值规则
FR-10.1.5 时间窗口 起止时间 + 每日循环窗口(如仅工作日)
FR-10.1.6 使用次数上限 总次数 + 单客户次数 + 单订单次数
FR-10.1.7 叠加策略 是否允许多码叠加 / 是否与自动折扣叠加 / 与礼品卡是否叠加
FR-10.1.8 市场范围 是否仅适用某 Market(市场)
10.3.2 Discount Code(折扣码)
FR 编号 功能点 说明
FR-10.2.1 折扣码生成 单码 or 批量(CSV 导入 / 随机生成 + 长度/前缀)
FR-10.2.2 唯一性 店铺内码唯一,大小写不敏感(可配)
FR-10.2.3 客户绑定 单 code 绑定单客户(一对一邮件发放)
FR-10.2.4 使用记录 每码记录 usage_count,超额拒绝
FR-10.2.5 过期时间 code 自身过期时间可短于 rule
10.3.3 Automatic Discount(自动折扣)
FR 编号 功能点 说明
FR-10.3.1 自动应用 满足条件自动应用,客户无需输入码
FR-10.3.2 多档自动 同规则可多档阶梯,按最高档执行
FR-10.3.3 突出展示 前端在购物车/商品页展示”已为您优惠 ¥X”
10.3.4 可编程折扣函数(Discount Functions,对标 Shopify Functions)
FR 编号 功能点 说明
FR-10.4.1 脚本引擎 apps/discounts/script_engine.py,Python 子集沙箱执行(基于 RestrictedPython)
FR-10.4.2 输入契约 输入 = cart + customer + market + config;输出 = 修改后的 line_items 价格
FR-10.4.3 版本管理 脚本版本化,部署需灰度(5%→50%→100%)
FR-10.4.4 性能上限 单次执行 < 100ms;超时降级至默认 PriceRule

10.4 关键业务规则

  • R-10.1:折扣金额不可超过 line_item 小计;免运费仅作用于已选定 shipping_line
  • R-10.2:折扣分摊按”价格比例”分配至各 line_item,写入 discount_allocations,便于按行退款
  • R-10.3:折扣与已应用礼品卡的优先级:先礼品卡再折扣码、再自动折扣
  • R-10.4:折扣码使用日志 discount_usage 表记录 code/rule/cart_snapshot/customer/order_id,用于审计
  • R-10.5:自动折扣与折扣码冲突时,按 rule 配置选择”最大优惠” or “禁用”

10.5 数据要点

  • PriceRuleDiscountCodeAutomaticDiscountDiscountUsageDiscountAllocation(写在 order_line_item 上)、DiscountScriptDiscountScriptVersionDiscountScriptRun

10.6 接口要点

Method Path 用途
GET/POST /api/admin/price_rules.json PriceRule CRUD
GET/POST /api/admin/price_rules/{id}/discount_codes.json 折扣码 CRUD
GET /api/admin/discount_codes/lookup.json?code=NEWYEAR 折扣码查询
POST /api/admin/discount_codes/batch.json 批量生成
GET/POST /api/admin/automatic_discounts.json 自动折扣 CRUD
Storefront API
mutation checkoutDiscountCodeApplyV2($discountCode: String!)
query discountByCode($code: String!) { discountByCode(code: $code) { ... } }
Webhook
  • discounts/creatediscounts/deletediscounts/redeem

10.7 Shopify 对标说明

  • 字段完全对齐 Shopify PriceRule + DiscountCode + AutomaticDiscount
  • Discount Functions 用 RestrictedPython 复刻 Shopify Functions 思路(WASM/Rust 不引入)
  • 不可叠加策略支持 Shopify 全部场景

10.8 验收要点

  • [ ] 折扣分摊后所有 line_item 折扣金额之和等于折扣总金额
  • [ ] 折扣码达到使用上限后立即失效
  • [ ] 折扣脚本性能 < 100ms,超时降级

第 11 章 营销与触达

11.1 业务目标

对标 Shopify Email / SMS / Marketing Campaign / Audience / Automation,提供邮件 / 短信 / 站内信多渠道营销、活动效果归因、自动化工作流。

11.2 角色与流程

  • 营销:选目标分群 → 设计邮件 → 设置发送时间 → 发送 → 监控效果
  • 系统:弃单挽回 / 生日问候 / 库存到货提醒等场景化自动化触发

11.3 功能点清单

11.3.1 模板编辑
FR 编号 功能点 说明
FR-11.1.1 邮件/短信模板 可视化拖拽 sections + MJML 渲染 HTML + 文本版双发
FR-11.1.2 模板变量 {{customer.first_name}}{{order.number}} 等 Liquid-like 占位
FR-11.1.3 邮件预览 测试邮箱 + 多客户真实预览
FR-11.1.4 发件人配置 店铺自定义发件域名 + DKIM/SPF/DMARC 校验提示
11.3.2 活动与发送
FR 编号 功能点 说明
FR-11.2.1 单次活动 选目标 Segment + 选模板 + 投放渠道和时刻
FR-11.2.2 退订管理 每封营销邮件含退订链接,自动维护 customer.accepts_marketing
FR-11.2.3 触达限流 单客户单日最多 N 封;硬弹退订永不发送
FR-11.2.4 渠道配额 邮件用 SES / 阿里云 DM;短信用阿里云 / 腾讯云;账户配额耗尽降级或排队
11.3.3 自动化工作流
FR 编号 功能点 说明
FR-11.3.1 触发器类型 弃单留存、新客户欢迎、订单完成、生日、库存到货、价格降低、加入心愿单
FR-11.3.2 步骤编排 触发 → 等待 → 邮件/短信 → 条件判断 → 分支跳转 → 结束
FR-11.3.3 进入与退出条件 客户中途完成转化自动退出弃单流;硬弹触发出流
FR-11.3.4 多分支并发 同客户可同时进入多个自动化,但同流程不可重复进入
11.3.4 营销归因
FR 编号 功能点 说明
FR-11.4.1 UTM 自动注入 邮件/短信链接自动注入 utm_medium=email&campaign=xxx
FR-11.4.2 归因窗口 投放 → 客户点击 → 7 天内下单记一笔归因
FR-11.4.3 多触点归因 首次触点 / 末次触点 / 线性归因三种模型可切

11.4 关键业务规则

  • R-11.1:所有营销触达必须基于 accepts_marketing=True 客户;交易性邮件(订单确认、退款)不受此限制
  • R-11.2:硬弹邮件地址自动加入 email_suppression 表永不重发;软弹 3 次后加入
  • R-11.3:自动化工作流执行使用 Celery + 编排引擎(轻量状态机),单客户同一工作流不并发
  • R-11.4:营销效果统计延迟 1 小时聚合,未触达实时告警

11.5 数据要点

  • EmailTemplate / SmsTemplate / Campaign / CampaignSend(单客户单发送)/ Automation / AutomationStep / AutomationEnrollment / MarketingAttribution / EmailSuppression

11.6 接口要点

Method Path 用途
GET/POST /api/admin/marketing/campaigns.json 活动 CRUD
POST /api/admin/marketing/campaigns/{id}/send.json 立即/定时发送
GET/POST /api/admin/automations.json 自动化流程 CRUD
POST /api/admin/automations/{id}/enroll.json 手工加入客户
GET /api/admin/marketing/attribution.json 归因报表
Webhook
  • marketing/campaign_sentmarketing/email_deliveredmarketing/email_openedmarketing/email_clicked

11.7 Shopify 对标说明

  • Shopify Email + Shopify Audiences + Shopify Automation 三合一,对标其字段与触发器
  • 自动化工作流节点设计基于 Shopify Flow 的 Trigger / Condition / Action 三段式
  • 与外部 ESP(如 Mailchimp / Klaviyo / 阿里云 DM)可通过 webhook + API 实现对接

11.8 验收要点

  • [ ] 退订链接点击后立即更新客户档案,30 分内不再发送
  • [ ] 硬弹地址永不重发
  • [ ] 自动化工作流并发数稳定(同客户不重复触发)

第 12 章 数据分析与报表

12.1 业务目标

对标 Shopify Analytics / Live View / Reports / Cohorts / LTV,提供实时业务看板、销售分析、客户行为分析、可自定义报表。

12.2 角色与流程

  • 老板/CEO:每日看核心 KPI、Live View、经营趋势
  • 营销:分析活动 ROI、分群表现
  • 运营:分析品类、渠道、退货率
  • 财务:导出对账与税务报表

12.3 功能点清单

12.3.1 实时看板(Live View)
FR 编号 功能点 说明
FR-12.1.1 今日会话/订单/销售额 秒级延迟(基于 Redis 计数器)
FR-12.1.2 地图分布 客户分布与下单热点(按国家/省/市)
FR-12.1.3 实时订单流 最新订单流式滚动
12.3.2 销售报表
FR 编号 功能点 说明
FR-12.2.1 销售概览 总销售额、退款额、净销售额、订单数、客单价、转化率
FR-12.2.2 按时段分析 时/日/周/月/季/年维度
FR-12.2.3 品类 / 商品 TopN 销售量、销售额、毛利、退货率
FR-12.2.4 渠道分析 各 Channel 销售贡献与转化
FR-12.2.5 折扣分析 各折扣码使用次数与核销金额、ROI
12.3.3 客户分析
FR 编号 功能点 说明
FR-12.3.1 同期群分析(Cohort) 按首单月份分群,跟踪回访率与人均消费
FR-12.3.2 RFM 模型 R/F/M 三维度评分,自动归类为”高价值”、”沉睡”、”流失”等
FR-12.3.3 客户 LTV 基于历史与留存算法预测 LTV
FR-12.3.4 复购分析 复购率、复购周期、跨品类复购
12.3.4 转化漏斗
FR 编号 功能点 说明
FR-12.4.1 漏斗定义 访问 → 商品详情 → 加车 → 开始结账 → 完成下单
FR-12.4.2 多维度过滤 按渠道、设备、地区、商品、客户分层
12.3.5 自定义报表
FR 编号 功能点 说明
FR-12.5.1 自定义列与过滤 维度 + 度量交叉,存为模板
FR-12.5.2 调度与导出 报表定时邮件 + Excel/CSV 导出

12.4 关键业务规则

  • R-12.1:报表数据来自专用 ETL(每晚从 OLTP 同步至 OLAP,Postgres 可用 crosstab / 物化视图或独立 DuckDB)
  • R-12.2:所有金额按订单时点币种与汇率折算
  • R-12.3:退款与售后金额以负数计入销售维度
  • R-12.4:实时看板允许 ±5% 误差(异步聚合),日报/月报必须 100% 精确

12.5 数据要点

  • 物化视图:mv_order_dailymv_customer_cohortmv_product_sales_monthly
  • 报表元数据:Report / ReportColumn / ReportFilter / ReportScheduleReportSnapshot
  • 实时计数器:Redis 自增键 + SETEX TTL

12.6 接口要点

Method Path 用途
GET /api/admin/analytics/live_view.json 实时看板
GET /api/admin/reports/sales_over_time.json 销售概览
GET /api/admin/reports/cohort.json 同期群
GET /api/admin/reports/custom/{id}.json 自定义报表
POST /api/admin/reports/export.json 导出任务
Webhook
  • reports/export_completed

12.7 Shopify 对标说明

  • 完整覆盖 Shopify Analytics 五大块:Live View、Sales、Customer、Conversion、Reports
  • 引入 RFM / Cohort / LTV 三种中国市场习惯的分析模型
  • 自定义报表对标 Shopify Custom Reports

12.8 验收要点

  • [ ] 实时看板数据延迟 ≤ 5 秒
  • [ ] 月报数据与财务对账误差 0
  • [ ] 自定义报表可在 10s 内返回结果

第 13 章 主题与模板系统

13.1 业务目标

对标 Shopify Online Store 2.0 的 sections + blocks + JSON templates + theme settings 架构,提供可视化拖拽的主题编辑器、模板文件系统和主题资源管理,让商家在不改代码前提下完整定制店铺外观。

13.2 角色与流程

  • 主题开发者:通过本地开发工具链开发并打包 .zip 主题包
  • 商家:上传主题 → 选择模板 → 在 sections 中添加/移动 blocks → 实时预览 → 发布
  • 前端访客:访问店铺 → Django 模板引擎按 “Liquid-like” 渲染

主题目录结构(复刻 Shopify 2.0):

my-theme/
├── assets/         # CSS/JS/图片等静态资源
├── config/         # settings_schema.json + settings_data.json
├── layout/         # theme.liquid 主布局
├── locales/        # en.default.json / zh.json 多语言
├── sections/       # 可复用的 section schema
   ├── header.liquid
   ├── product-card.liquid
   └── ...
├── snippets/       # 可复用片段
└── templates/
    ├── index.liquid          # 首页
    ├── product.liquid / product.<suffix>.liquid
    ├── collection.liquid / collection.<suffix>.liquid
    ├── cart.liquid
    ├── page.liquid / page.<suffix>.liquid
    ├── blog.liquid
    ├── article.liquid
    ├── list-collections.liquid
    ├── 404.liquid
    ├── password.liquid
    ├── search.liquid
    ├── gift_card.liquid
    ├── customers/
       ├── account.liquid
       ├── login.liquid
       ├── register.liquid
       ├── order.liquid
       ├── addresses.liquid
       └── reset_password.liquid
    └── *.json                # 模板配置持久化 section 顺序与 block 实例

13.3 功能点清单

13.3.1 主题管理
FR 编号 功能点 说明
FR-13.1.1 主题上传 支持 .zip 上传;解压校验目录结构必含 8 个固定目录
FR-13.1.2 主题激活 同一店铺可有多个主题,但只有一个 active;切换前做”准发布预览”链接
FR-13.1.3 主题预览 通过特殊 token 访问未激活主题
FR-13.1.4 主题下载 当前主题可一键打包下载
FR-13.1.5 主题版本 主题更新记录版本号、最后修改时间、修改者
FR-13.1.6 市场主题库 内置若干模板供商家免费使用
13.3.2 Sections 与 Blocks(核心)
FR 编号 功能点 说明
FR-13.2.1 Section schema JSON schema 声明:name、tag、class、settings、blocks、max_blocks、presets
FR-13.2.2 Section 类型 全局 section(如 header/footer)+ 模板 section(动态加入)
FR-13.2.3 Block 类型 section 内可重复挂载的小组件,如图片、轮播、富文本、视频
FR-13.2.4 Block 实例化 每个 block instance 序列化到模板 JSON 文件中(settings + order)
FR-13.2.5 拖拽排序 商家在主题编辑器拖拽 section / block 实时调整顺序
FR-13.2.6 Section settings 单 section 全局配置,类型支持 text/range/select/radio/checkbox/image_picker/url/rich_text/color/font_picker
FR-13.2.7 Block settings 在每个 block 实例上独立配置,schema 同 section settings
FR-13.2.8 Section group header / footer / aside 等不随模板变化的 section 集合
13.3.3 JSON Templates
FR 编号 功能点 说明
FR-13.3.1 模板 JSON 持久化 资源(如 product)的某模板对应一份 JSON 文件,记录 sections 顺序+block 配置
FR-13.3.2 资源专属模板 单商品可绑定自己的模板 JSON(覆盖默认 product.json)
FR-13.3.3 模板数量上限 单店铺每类资源最多 50 个模板 JSON
FR-13.3.4 默认模板 必须存在 default,否则该资源不可访问
13.3.4 主题设置(Theme Settings)
FR 编号 功能点 说明
FR-13.4.1 settings_schema.json 全局设置:店铺 logo、字体、配色、社交链接等
FR-13.4.2 settings_data.json 全局设置的回填值,分为 current + preset
FR-13.4.3 字体加载 仅允许主题预设字体子集,避免性能问题
13.3.5 主题渲染引擎
FR 编号 功能点 说明
FR-13.5.1 Liquid 子集 实现 Liquid 关键 tag:{% for %}{% if %}{% assign %}{% capture %}{% include %}{% section %}{% render %}{% schema %}{% style %}{% javascript %}
FR-13.5.2 对象注入 模板上下文中可访问 product / collection / cart / customer / shop / page / blog / article / search / template / request / linklists / settings / snippets 等 drop 对象
FR-13.5.3 过滤器 价格 moneymoney_with_currencydatetruncateescape 等 40+ 过滤器
FR-13.5.4 安全沙箱 禁用 import/os/sys/subprocess;模板编译失败给前端兜底页
FR-13.5.5 模板缓存 编译产物按 (theme_id, version, file_hash) 缓存至 Redis,请求时按 hash 命中
13.3.6 资源 URL 生成
FR 编号 功能点 说明
FR-13.6.1 资源 CDN assets/ 资源上传 S3,URL 由 CDN 域名生成,自动带版本 hash
FR-13.6.2 图片处理 支持动态缩放/裁剪/webp 转码的 URL 参数 ?width=400&height=400&format=webp

13.4 关键业务规则

  • R-13.1:schema 校验不通过的 section 不会被加载,且在主题编辑器中置灰;模板 JSON 必须能通过 schema 校验
  • R-13.2:所有渲染基于”已发布主题 + 当前模板 JSON”,未发布预览主题需 ?preview_token=xxx
  • R-13.3:模板编译错误必须降级到”简化 error page”,绝不向访客暴露 500
  • R-13.4:theme settings 的图片必须落到店铺的 CDN bucket,禁止外链图片
  • R-13.5:Liquid 模板执行时长上限 500ms,超时降级到 cached HTML

13.5 数据要点

  • Theme(name/version/status/active_at/preview_token)
  • ThemeAsset(path/type/content/checksum)
  • ThemeTemplate(template_type/handle/json_content)
  • ThemeSettings(theme_id + value JSON)
  • 资源静态文件落对象存储

13.6 接口要点

Method Path 用途
GET/POST /api/admin/themes.json 主题上传/列表
PUT /api/admin/themes/{id}.json 主题元数据更新
POST /api/admin/themes/{id}/activate.json 激活
GET/PUT /api/admin/themes/{id}/assets.json 资源操作
POST /api/admin/themes/{id}/preview.json 预览链接生成

第 14 章 页面、博客与内容

14.1 业务目标

对标 Shopify Pages / Blogs / Articles / Menus / Navigation,提供企业页面(关于我们/联系/政策)、博客内容、店铺导航菜单管理。

14.2 功能点清单

FR 编号 功能点 说明
FR-14.1 页面 CRUD 标题、handle、富文本 body_html、模板后缀、SEO 元字段、作者、可见性(公开/私密/密码保护)
FR-14.2 博客 CRUD 一个店铺可多个 blog;每个 blog 单独 feed RSS
FR-14.3 文章 CRUD 标题、handle、body_html、作者、标签、封面、发布时间、状态(draft/published)、SEO 元字段
FR-14.4 评论 可选开启;审核模式(先审后显/先显后审/关闭);防 Spam
FR-14.5 菜单(Menu / Linklist) 导航菜单层级最多 3 级;菜单项可指向 page/collection/product/blog/url 手动填
FR-14.6 主菜单 / Footer 菜单 / Mobile 菜单 内置固定 handle(main-menu / footer / mobile),主题直接引用
FR-14.7 重定向 任意路径走 redirect 表(详见 SEO)

14.3 业务规则

  • R-14.1:page/article 的 handle 在店铺内唯一;修改保留 301 redirect
  • R-14.2:博客发布文章采用 future-dated 调度(Celery Beat 按时发布)
  • R-14.3:私密页面访问需密码或登录

14.4 数据要点

Page / Blog / Article / ArticleComment / Menu / MenuItem(自引用实现层级)

14.5 接口

Method Path 用途
GET/POST /api/admin/pages.json/api/admin/blogs.json/api/admin/blogs/{id}/articles.json CRUD
GET/POST /api/admin/menus/{id}/items.json 菜单项

第 15 章 SEO 与域名

15.1 业务目标

对标 Shopify 的内置 SEO(meta 标签、URL handle、canonical、redirect、sitemap、robots.txt)与多域名绑定能力。

15.2 功能点清单

FR 编号 功能点 说明
FR-15.1 每个 SEO 对象 商品/集合/页面/文章均含 meta_title、meta_description、og_image、handle
FR-15.2 自动生成 模板字段留空时根据规则回退(如 product.meta_title = title)
FR-15.3 canonical URL 商品/集合/分页 canonical 自动生成;商品多变体页面对应同一 canonical
FR-15.4 sitemap.xml 自动生成 index + per-type sitemap;按 50000 条/50MB 切分;每日刷新缓存
FR-15.5 robots.txt 可在后台直接编辑,覆盖默认
FR-15.6 redirect 表 任意路径 → 目标路径 + 状态码(301/302),优先级匹配
FR-15.7 多域名 一个店铺可绑多个域名(主域 + 别名),所有别名 301 到主域;支持二级路径子站
FR-15.8 HTTPS 强制 HTTPS;自动管理 Let’s Encrypt 证书(开发期)或对接 ACME 服务
FR-15.9 hreflang 多语言 与多语言标识符配合输出 hreflang 标签
FR-15.10 structured data 自动输出 Product / BreadcrumbList / Article / Organization schema.org JSON-LD
FR-15.11 搜索引擎抓取日志 简版爬虫日志(按 UA),用于 SEO 诊断

15.3 数据要点

SeoTemplate(按类型组合模板如 {{product.title}} - {{shop.name}})、Redirect(from_path/to_path/status/priority)、DomainBinding


第 16 章 多渠道销售

16.1 业务目标

对标 Shopify Sales Channels(Online Store、POS、Manual、Facebook/Instagram、Google、TikTok、Wholesale 等),抽象统一的渠道适配层,让同一商品池与订单池服务多渠道。

16.2 功能点清单

FR 编号 功能点 说明
FR-16.1 渠道抽象 Channelid/name/type/status;所有订单、商品发布都挂 channel_id
FR-16.2 Online Store 渠道 默认存在的渠道;商品可见性默认开
FR-16.3 POS 渠道 实体店收银;订单本地缓存离线创建,联网同步;支持会员、礼品卡、扫码
FR-16.4 Manual 渠道 客服代客下单或外部销售渠道登记订单的来源
FR-16.5 Facebook/Instagram/TikTok/Google 通过适配器将商品发布到对应平台(目录同步)+ 订单回流
FR-16.6 集成开放 通过 apps/channels/adapters/ 抽象,支持自定义渠道
FR-16.7 商品渠道发布状态 单商品可启/停某些渠道;价格/库存可按渠道覆盖
FR-16.8 多渠道对账 平台侧费用/退货对账按渠道出表

16.3 业务规则

  • R-16.1:每个订单必有 channel_id;缺省 = Online Store
  • R-16.2:渠道适配失败不应阻塞主订单流程,回退到 manual,留日志
  • R-16.3:产品目录与外部平台同步频率可配置(默认 1 小时)

16.4 数据要点

Channel / ChannelProduct(商品配置覆盖)/ ChannelAdapter / ChannelSyncLog


第 17 章 权限、多语言与税务

17.1 权限与多账号

FR 编号 功能点 说明
FR-17.1.1 员工(Staff Account) 每个 shop 下多员工账号,关联 Django auth.User,归属 shop
FR-17.1.2 角色与权限 预设角色:Owner / Admin / Manager / Staff / Developer;可自定义权限集
FR-17.1.3 权限粒度 模块级(如订单读/写/退款)+ 对象级(如仅看到自己客服的客户)
FR-17.1.4 二次验证 TOTP 关键操作(退款、删除商品、改支付凭证)强制 TOTP
FR-17.1.5 操作日志 所有改动写 audit_log(用户/IP/操作/前后值)
FR-17.1.6 API Token 每员工可生成 Access Token + scope + 过期;轮转支持

17.2 多语言与多币种(Markets 对标)

FR 编号 功能点 说明
FR-17.2.1 内容多语言 商品标题/描述、页面、文章、邮件模板均多语言;i18n 用 django-modeltranslation
FR-17.2.2 翻译工作流 自动翻译(对接云翻译 API)+ 人工润色状态机
FR-17.2.3 Markets 概念 一个 Market = 区域 + 默认币种 + 域名/子目录 + 税率 + 价格表
FR-17.2.4 多币种定价 价格可按 Market 覆盖;未覆盖走基础价 × 汇率
FR-17.2.5 自动货币识别 按 IP / 浏览器语言识别市场并切换币种
FR-17.2.6 汇率源 每日 from ECB / 中央银行;人工可锁定汇率
FR-17.2.7 Rounding 规则 商家可设置每个币种圆整规则(如 JPY 取整百)

17.3 税务

FR 编号 功能点 说明
FR-17.3.1 税率配置 按国家+省+邮编+商品税类配置;支持免税/含税切换
FR-17.3.2 自动计算 结账阶段 → 地址 → 税率 → 行级税款
FR-17.3.3 税务引擎 内嵌简单引擎 / 接入外部(Avalara、TaxJar)
FR-17.3.4 免税客户 B2B 客户可设免税 ID,下单 0 税
FR-17.3.5 税务报告 按时段按地区导出销售税报表(增值税/消费税)
FR-17.3.6 关税与 DDP 对标 Shopify Markets Duties,支持 DDP(送达付税)选项

17.4 业务规则

  • R-17.1:所有面向客户的字段变更走”翻译工作流”流程;非默认语言缺省回退默认语言
  • R-17.2:税率以结算时点为准;订单 line_item tax_lines 快照锁定
  • R-17.3:员工删除/降权需 Owner 同意审签
  • R-17.4:API Token 不可读取 owner 与 staff 完整列表,避免越权

第 18 章 核心数据模型设计

18.1 设计约定

  • 所有业务表继承 core.models.TimeStampedOwnerModel,包含统一字段:id (BigAutoField)、shop_id (FK)、created_atupdated_atdeleted_at(软删除,默认 NULL)
  • 金额一律存 整数最小货币单位(如人民币:分);展示时按 Shop.currency.decimal_places 格式化
  • 所有”国际化名称”字段使用 django-modeltranslation 注册翻译,DB 多列 name_en / name_zh 自动生成
  • 所有”对外 ID”用 gid://shop/<Type>/<numeric_id> 格式(对标 Shopify GraphQL Global ID),Admin/Storefront API 输出统一转 base64
  • 多租户预留:所有表带 shop_id,单店铺部署写在配置 DEFAULT_SHOP_ID
  • 使用枚举:枚举值定义在 core/enums.py,模型字段统一用 django-enumchoice 或自定义 CharField + choices

18.2 店铺与基础设施

Shop
字段 类型 说明
id BigAutoField 主键
name CharField(120) 店铺名
slug SlugField URL 友好标识,店铺内部使用
email EmailField 主联系邮箱
default_currency CharField(3) 默认币种 ISO 4217
timezone CharField(40) 店铺时区
weight_unit CharField(8) g/kg/lb/oz
domain CharField(255) 主域名
is_password_protected BooleanField 全店密码保护
password CharField(60) 全店访问密码(哈希)
money_format CharField(60) Liquid-like 价格显示模板
tax_included BooleanField 商品价是否含税
settings JSONField 其他店铺级配置
created_at / updated_at DateTimeField 时间戳
Location
字段 类型 说明
shop FK(Shop) 归属店铺
name CharField(120) 库位名
address1/address2/city/province/zip/country CharField 地址
active BooleanField 是否活跃
fulfills BooleanField 是否对外发货
location_type CharField physical / fulfillment_service
legacy BooleanField 历史数据,只读不删
StaffAccountStaffRolePermission
  • StaffAccount.user FK → auth.Usershop FK;role FK
  • StaffRole 预设记录:owner/admin/manager/staff/developer
  • Permission(role_id, module, action, scope):action ∈ read/create/update/delete/refund;scope ∈ all/owned/warehouse

18.3 商品与目录

Product
字段 类型 说明
shop FK(Shop)
title CharField(255) 模板翻译
body_html TextField 富文本
vendor CharField(100) 厂商
product_type CharField(100) 商品类型
handle SlugField 店铺内唯一
status CharField draft/active/archived
tags ArrayField(CharField) PG array 或多对多
template_suffix CharField(60) 模板后缀
options JSONField [{name:'Color', values:[...]}, ...],最多 3 个
published_at DateTimeField 上架时间
published_scope CharField web/global
search_vector SearchVectorField GIN 索引
metafields GenericRelation(Metafield) 反向
created_at / updated_at / deleted_at

索引:(shop_id, handle) unique(shop_id, status)search_vector GIN

ProductVariant
字段 类型 说明
product FK(Product, related_name=’variants’)
title CharField(255)
sku CharField(64) 店铺内唯一可配
barcode CharField(64) EAN/UPC/GTIN
price BigIntegerField 不含税价(分)
compare_at_price BigIntegerField 划线价
cost BigIntegerField 成本(仅后台)
taxable BooleanField
tax_code CharField(64)
weight DecimalField
weight_unit CharField(8)
requires_shipping BooleanField
inventory_policy CharField deny/continue/oversell
inventory_management CharField shopify → ‘system’
image FK(Image) 主图
position IntegerField 显示顺序
option1/option2/option3 CharField 与父商品 options 顺序对应
metafields GenericRelation(Metafield)

索引:(shop_id, sku)(product_id, position)

Image(商品图)

shop, product(FK), variant(FK nullable), src(url), alt, width, height, position ;图片实体存 S3

Collection

shop, title, body_html, handle, sort_order(char Enum: manual/best_selling/...), disjunctive(bool: True=OR, False=AND), rules(JSONArray of {column, relation, condition}), template_suffix, published_at, image(FK)

CollectionProduct

collection(FK), product(FK), position(Integer),索引 (collection_id, product_id) unique, (collection_id, position)

MetafieldMetaobject
  • Metafield: shop, owner_type, owner_id, namespace, key, value(JSON), type(CharField Enum), description, is_public(Boolean)
  • Metaobject: shop, type(CharField), handle, fields(JSONField: {name: value}), display_name
  • MetaobjectDefinition: shop, name, type, field_definitions(JSONArray)

18.4 库存与履约

InventoryLevel
字段 类型 说明
variant FK(ProductVariant)
location FK(Location)
available IntegerField 可售
committed IntegerField 预留/已售未发
incoming IntegerField 在途
safety_stock IntegerField 安全库存阈值

唯一索引 (variant_id, location_id)

InventoryAdjustment

id, variant(FK), location(FK), delta(Integer), previous_available, after_available, reason(Enum: correction/cycle_count/received/cancelled_order/return), note, staff(FK nullable), created_at

InventoryEvent

不可变事件表:event_type(Enum), variant_id, location_id, delta, source(refund_id/order_id/...), created_at

FulfillmentOrderFulfillment
  • FulfillmentOrder: order(FK), location(FK), status(unfulfilled/in_progress/on_hold/cancelled), assigned_location.location, line_items(JSON of order_line_item ids + quantity), fulfill_at, deadline
  • Fulfillment: fulfillment_order(FK), status(open/success/cancelled/error), tracking_company, tracking_number, tracking_url, receipt(JSON), notify_customer, created_at

18.5 购物车与结账

CartCartLine
  • Cart: shop, customer(FK nullable), token(UUID UNIQUE), note, attributes(JSON), created_at, updated_at, expires_at
  • CartLine: cart(FK), variant(FK), quantity, properties(JSON), attributes(JSON);唯一索引 (cart_id, variant_id)
CheckoutSession
shop, customer(FK), cart(FK), token(UUID UNIQUE),
status(Enum: in_progress/completed/expired),
shipping_address(JSON), billing_address(JSON),
shipping_rate(JSON snapshot), tax_lines(JSON),
discount_codes(Array), gift_cards(Array),
total_price, total_tax, total_shipping, total_discount,
payment_provider(CharField),
expires_at, completed_at, abandoned_at
AbandonedCheckout

shop, checkout_session(FK), email, line_items_snapshot(JSON), created_at, abandoned_at, recovery_email_sent_at

18.6 订单

Order
字段 类型 说明
shop FK
order_number CharField(20) 可读编号
name CharField(60) 显示名 #1001
customer FK(Customer) 可为 NULL(脱敏)
email / phone CharField
financial_status CharField pending/authorized/paid/partially_paid/refunded/partially_refunded/voided
fulfillment_status CharField null/unfulfilled/partial/fulfilled/restocked
status CharField open/closed/cancelled
currency CharField(3)
subtotal_price BigIntegerField
total_shipping BigIntegerField
total_tax BigIntegerField
total_discounts BigIntegerField
total_price BigIntegerField
total_paid BigIntegerField
taxes_included BooleanField
cancel_reason CharField
cancelled_at DateTimeField
closed_at DateTimeField
processed_at DateTimeField
note TextField
tags ArrayField
attributes JSONField
source_name CharField(40) web/pos/api/manual
shipping_address / billing_address JSONField
channel FK(Channel)
created_at / updated_at

按月分区 pg_partmanorders_YYYY_MM

OrderLineItem

order(FK), variant_id_snapshot, sku_snapshot, title, variant_title, quantity, price(price_each), total_discount, tax_lines(JSON), discount_allocations(JSON), requires_shipping, taxable, fulfillment_status, fulfillable_quantity, properties(JSON), position

OrderShippingLineOrderTaxLine
  • ShippingLine: order(FK), title, code, price, tax_lines(JSON), carrier_identifier, requested_fulfillment_service_id
  • TaxLine: order(FK), price, rate, title, channel
OrderAdjustmentRefundRefundLineItemReturnDraftOrder
  • OrderAdjustment: order(FK), amount, kind(order_edit/discount/refund_diff), note
  • Refund: order(FK), created_at, note, restock, amount, transactions(GenericRelation), refund_line_items
  • RefundLineItem: refund(FK), line_item(FK), quantity, restock_type, subtotal, total_tax, subtotal_set
  • Return: order(FK), status(requested/approved/received/cancelled), line_items(JSON), restocking_fee
  • DraftOrder: shop, customer(FK nullable), line_items, shipping_address, billing_address, total, invoice_url, status(open/invoice_sent/completed), completed_at

18.7 支付

PaymentIntent

shop, order(FK nullable), checkout_session(FK nullable), amount, currency, status(None/requires_payment_method/requires_confirmation/requires_action/processing/requires_capture/canceled/succeeded), provider, provider_data(JSON), metadata(JSON), created_at

PaymentTransaction

payment_intent(FK), kind(Enum: authorization/capture/sale/void/refund), gateway, amount, currency, status(success/pending/failure/error), provider_transaction_id, failure_code, failure_message, response_raw(JSON), masked_pan, created_at

GiftCard

shop, code(CharField UNIQUE), initial_value, balance, currency, customer_id(FK nullable), disabled_at, expires_on, note, template_suffix

GiftCardTransaction

gift_card(FK), order(FK nullable), amount, action(Enum: debit/credit/expire), created_at

18.8 客户与会员

Customer

shop, first_name, last_name, email, phone, accepts_marketing, accepts_marketing_updated_at, marketing_opt_in_level, note, tags, last_order_at, orders_count, total_spent,verified_email, state(enabled/disabled/invited/declined), tax_exempt, tax_exemptions(Array), currency, default_address(FK nullable), created_at, updated_at, deleted_at(软删除时 email 改为 deleted_<id>@removed.local)

唯一索引 (shop_id, email)(shop_id, phone) 软唯一

CustomerAddress

customer(FK), first_name, last_name, company, address1, address2, city, province, province_code, zip, country, country_code, phone, default(Boolean)

CustomerSegmentCustomerSegmentMember
  • CustomerSegment: shop, name, kind(static/dynamic/saved_search), definition(JSON rule expression), last_evaluated_at
  • CustomerSegmentMember: segment(FK), customer(FK), joined_at
  • 动态分群由 Celery Beat 每日重算
MembershipTierPointLedger
  • MembershipTier: shop, name, threshold_amount, multiplier(Decimal), benefits(JSON), active
  • PointLedger: customer(FK), action(earn/spend/expire/adjust), delta, balance_after, expires_on, ref(order_id/coupon_id), note, created_at

18.9 折扣

PriceRule
shop, title, target_type(line_item/shipping_line), target_selection(all/entitled),
allocation_method(each/across), value_type(fixed_amount/percentage),
value, once_per_customer(Boolean), usage_limit(Integer nullable),
once_per_order(Boolean), starts_at, ends_at, prerequisite_subtotal_range,
prerequisite_quantity, prerequisite_to_entitlement_quantity_ratio(JSON),
entitled_product_ids, entitled_collection_ids, entitled_country_ids,
prerequisite_product_ids, prerequisite_collection_ids, prerequisite_customer_segment_ids,
prerequisite_to_entitlement_purchase, allocation_method, market_ids
DiscountCode

price_rule(FK), code(CharField shop_unique), usage_count(Integer default 0), usage_limit(Integer nullable), customer_id(FK nullable for bound code), created_at, expires_at(nullable)

AutomaticDiscountDiscountUsageDiscountScriptDiscountScriptVersion
  • AutomaticDiscount: price_rule(FK), title, status(active/expired/scheduled), starts_at, ends_at
  • DiscountUsage: discount_code(FK nullable), automatic_discount(FK nullable), customer(FK nullable), order(FK nullable), used_at
  • DiscountScript: title, type(Enum: discount/shipping/payment), source_code, version, status(draft/active/archived), active_version
  • DiscountScriptVersion: script(FK), version, source_code, published_by, published_at, gray_percent

18.10 主题与内容

Theme

shop, name, version, status(unpublished/published/deleted), active_at, preview_token, processing, created_at

ThemeAsset

theme(FK), key(CharField, e.g. 'templates/product.liquid'), content(Text), checksum(CharField), attachment(URL for binary), content_type, size, updated_at,索引 (theme_id, key) unique

ThemeTemplate

theme(FK), template_type(Enum: product/collection/page/...), handle, json_content(JSON), published_scope(web/global), created_at, updated_at

ThemeSettings

theme(FK), data(JSON) 单条记录

PageBlogArticleArticleCommentMenuMenuItem
  • Page: shop, title, handle, body_html, template_suffix, author(FK), published_at, published_scope,seo_title, seo_description, admin_graphql_api_id, visible(public/private/password), password
  • Blog: shop, title, handle, template_suffix, feed_url, commentable
  • Article: blog(FK), title, handle, body_html, author(FK), tags(Array), image(FK), published_at, status, summary, seo_title, seo_description
  • ArticleComment: article(FK), author, email, body, status(unapproved/published/spam), ip, user_agent, created_at
  • Menu: shop, handle, title,内置 handle main-menu, footer, mobile
  • MenuItem: menu(FK), parent(FK self nullable), title, link_type(page/collection/product/blog/url/manual), link_value, position

18.11 渠道与 SEO

ChannelChannelProduct
  • Channel: shop, name, type(online_store/pos/manual/facebook/instagram/google/tiktok/wholesale/custom), status, configuration(JSON), created_at
  • ChannelProduct: channel(FK), product(FK), published(Boolean), price_override(BigInteger nullable), inventory_override(Integer nullable), external_id
RedirectSeoTemplateDomainBinding
  • Redirect: shop, path(CharField), target(CharField), status(301/302), priority(Integer)
  • SeoTemplate: shop, content_type(product/collection/article/page), title_template, description_template
  • DomainBinding: shop, domain(CharField unique), primary(Boolean), ssl_enabled, ssl_expires_at, subdirectory_prefix

18.12 Webhook 与通知

WebhookSubscription

shop, topic(CharField), address(URL), format(json/xml), api_version, fields(Array), metafield_namespaces(Array), secret, created_at, status(active/disabled)

WebhookDelivery

webhook_subscription(FK), payload(Text), headers(JSON), status(success/failure/queued), attempts(Integer), last_attempt_at, response_code, response_body

NotificationTemplate

shop, type(CharField Enum: order_confirmation/order_cancelled/refund_issued/...), channel(email/sms), subject, body_html, body_text, active

18.13 ER 关系总览(关键关联)

Shop ── Location
Shop ── Product ── ProductVariant ── InventoryLevel ── Location
Shop ── Collection ──< CollectionProduct >── Product
Shop ── Customer ── CustomerAddress
Shop ── Order ──< OrderLineItem >── ProductVariant  (snapshot)
Order ── Customer
Order ──< FulfillmentOrder ──< Fulfillment
Order ──< Refund ──< RefundLineItem >── OrderLineItem
Order ──< PaymentIntent ──< PaymentTransaction
Shop ── PriceRule ──< DiscountCode  ──< DiscountUsage >── Order
Shop ── Theme ──< ThemeAsset ; Theme ──< ThemeTemplate
Shop ── Page / Blog ──< Article
Shop ──< Channel ──< ChannelProduct >── Product
Shop ──< Menu ──< MenuItem

详细 Model 代码生成另出《Django 模型实现规范》(v1.0 落地版本)。


第 19 章 REST API 设计

19.1 API 总览

本系统开放三套对外接口,对标 Shopify:

API 路径前缀 用途 鉴权
Admin REST API /api/admin/*.json 后台与 ERP/WMS/CRM 集成 OAuth2 Access Token / API Token
Admin GraphQL API /api/admin/graphql 富查询场景(strawberry) 同上
Storefront API /api/{year}-{month}/graphql.json 商城前端 / Headless 客户端 公共 Storefront Token(Public)
Webhook 商家自定义 URL 系统主动推送 HMAC SHA256 签名
Partner / App API /api/partner/* 应用市场适配(预留) OAuth2

19.2 通用规范

19.2.1 版本与兼容
  • API 版本以 YYYY-MM 命名(如 2026-07),写在 URL 或 Header X-API-Version
  • 每年发布 4 个稳定版本;旧版本至少保留 12 个月
  • 弃用字段在响应中标 "deprecated": true,并在响应头 X-Shopify-API-Deprecated-Reason 解释
19.2.2 请求/响应规范
  • 列表默认每页 50 条,最大 250 条;分页使用 page_info cursor 令牌
  • 创建/更新接口要求 Content-Type: application/json
  • 所有时间字段 UTC ISO 8601 字符串;金额按各模型说明字段类型在响应中输出 {amount, currency_code} 结构对象
  • 错误响应统一结构:
{
  "errors": {
    "title": "Resource Not Found",
    "code": "NOT_FOUND",
    "message": "Product#gid://shop/Product/999 not found",
    "status": 404
  }
}
19.2.3 限流
  • Admin API:每 App 40 req/s(leaky bucket);超限 HTTP 429 + Retry-After
  • Storefront API:每 Token 100 req/s
  • 写操作(POST/PUT/DELETE)额外每 5 秒 2 次/资源
  • Burst:最多 2× 平均速率
19.2.4 幂等性
  • 写操作支持请求头 Idempotency-Key: <uuid>,5 分钟内同 key 重复请求复用原响应
  • 幂等键记录表 IdempotencyRecord(key, response, created_at)

19.3 Admin REST API 资源清单

下表仅列核心资源(细分 fields/relations 见 API 详设文档):

资源 路径 主要操作
Shop /api/admin/shop.json GET
Location /api/admin/locations.json GET/POST/PUT/DELETE
Product /api/admin/products.json GET/POST/PUT/DELETE
ProductVariant /api/admin/variants/{id}.json GET/POST/PUT
Collection /api/admin/custom_collections.json/api/admin/smart_collections.json GET/POST/PUT/DELETE
Collect /api/admin/collects.json GET/POST/DELETE(关联表)
InventoryLevel /api/admin/inventory_levels.json GET/POST(set/adjust/connect)
InventoryAdjustment /api/admin/inventory_adjustments.json GET
FulfillmentOrder /api/admin/fulfillment_orders.json GET/POST(cancel/hold/move)
Fulfillment /api/admin/fulfillments.json GET/POST/PUT
FulfillmentEvent /api/admin/fulfillment_events.json GET/POST
Order /api/admin/orders.json GET/POST/PUT/DELETE
OrderRisk /api/admin/orders/{id}/risks.json GET/POST/PUT
Refund /api/admin/orders/{id}/refunds.json GET/POST
Return /api/admin/returns.json GET/POST/PUT
DraftOrder /api/admin/draft_orders.json GET/POST/PUT/DELETE
Transaction /api/admin/orders/{id}/transactions.json GET/POST
GiftCard /api/admin/gift_cards.json GET/POST/PUT
Customer /api/admin/customers.json GET/POST/PUT/DELETE
CustomerAddress /api/admin/customers/{id}/addresses.json GET/POST/PUT/DELETE
CustomerSavedSearch /api/admin/customer_saved_searches.json GET/POST/PUT/DELETE
CustomerSegment /api/admin/customer_segments.json GET/POST/PUT/DELETE
PriceRule /api/admin/price_rules.json GET/POST/PUT
DiscountCode /api/admin/price_rules/{id}/discount_codes.json GET/POST/PUT/DELETE
AutomaticDiscount /api/admin/automatic_discounts.json GET/POST/PUT
MarketingCampaign /api/admin/marketing/campaigns.json GET/POST
Automation /api/admin/automations.json GET/POST
Page /api/admin/pages.json GET/POST/PUT/DELETE
Blog / Article /api/admin/blogs.json/api/admin/blogs/{id}/articles.json GET/POST/PUT/DELETE
Menu / MenuItem /api/admin/menus.json/api/admin/menus/{id}/items.json GET/POST/PUT
Theme / Asset /api/admin/themes.json/api/admin/themes/{id}/assets.json GET/POST/PUT/DELETE
Metafield /api/admin/{resource}/{id}/metafields.json GET/POST/PUT/DELETE
Metaobject /api/admin/metaobjects.json GET/POST/PUT/DELETE
Webhook /api/admin/webhooks.json GET/POST/PUT/DELETE
Redirect /api/admin/redirects.json GET/POST/PUT/DELETE
Domain /api/admin/domains.json GET/POST/PUT
Report /api/admin/reports.json/api/admin/analytics/*.json GET/POST

19.4 Storefront API(GraphQL)

19.4.1 Query 类型(对标 Shopify Storefront)
type Query {
  shop: Shop!
  productByHandle(handle: String!): Product
  product(id: ID!): Product
  products(first: Int, after: String, query: String, sortKey: ProductSortKeys, reverse: Boolean): ProductConnection!
  collectionByHandle(handle: String!): Collection
  collection(id: ID!): Collection
  collections(first: Int, after: String): CollectionConnection!
  node(id: ID!): Node
  nodes(ids: [ID!]!): [Node]!
  cart(id: ID!): Cart
  customer: Customer
  pageByHandle(handle: String!): Page
  blogByHandle(handle: String!): Blog
  articleByHandle(blogHandle: String!, articleHandle: String!): Article
  search(query: String!, first: Int, after: String): SearchResultConnection!
  publicMetafields(identifiers: [MetafieldIdentifier!], ownerType: String): [Metafield]
}
19.4.2 Mutation 类型
type Mutation {
  cartCreate(input: CartCreateInput!): CartCreatePayload
  cartLinesAdd(cartId: ID!, lines: [CartLineInput!]!): CartLinesAddPayload
  cartLinesUpdate(cartId: ID!, lines: [CartLineUpdateInput!]!): CartLinesUpdatePayload
  cartLinesRemove(cartId: ID!, lineIds: [ID!]!): CartLinesRemovePayload
  cartDiscountCodesUpdate(cartId: ID!, discountCodes: [String!]): CartDiscountCodesUpdatePayload
  cartGiftCardApply ...)
  cartBuyerIdentityUpdate(...)
  checkoutCreate(input: CheckoutCreateInput!): CheckoutCreatePayload
  checkoutShippingAddressUpdateV2(...)
  checkoutShippingLineUpdate(...)
  checkoutDiscountCodeApplyV2(...)
  checkoutEmailUpdate(...)
  checkoutCompleteWithCreditCardV2(...)
  checkoutCompleteWithTokenPayment(...)
  customerAccessTokenCreate(input: CustomerAccessTokenCreateInput!): ...
  customerCreate(input: CustomerCreateInput!): ...
  customerUpdate(input: CustomerUpdateInput!): ...
  customerAddressCreate/Update/Delete(...)
  customerRecover/Reset/Activate(...)
}
19.4.3 核心对象与字段(节选)
  • Product:title handle description featuredImage variants(first:Int) options priceRange metafields
  • ProductVariant:id sku title priceV2 {amount currencyCode} compareAtPriceV2 availableForSale selectedOptions image weight
  • Collection:title handle description image products(first,after,filters:ProductFilters)
  • Cart:id totalQuantity cost{subtotalAmount totalAmount} lines(first){edges{node{id quantity merchandise{…on ProductVariant{id}} cost{…}}}}
  • Checkout:id ready webUrl lineItemsShippingAddress shippingLine taxLines totalPriceV2 appliedGiftCards discountApplications
  • Customer:id displayName email firstName lastName defaultAddress orders(first){edges}

19.5 Webhook 设计

19.5.1 订阅

POST /api/admin/webhooks.json

{ "webhook": { "topic": "orders/create", "address": "https://erp.demo/hook/orders", "format": "json" } }
19.5.2 推送机制
  • HMAC-SHA256 请求头:X-TeleAgent-Signature: sha256=<hex> + X-TeleAgent-Topic + X-TeleAgent-Hmac-Sha256
  • 推送为 HTTP POST,body 为 JSON
  • 失败重试:指数退避(10s/1m/10m/1h/3h/12h/24h/48h),共 8 次;超过 24h 仍失败标记 disabled 并发邮件告警
  • 重放:商家可在 Admin API 触发 POST /webhooks/{id}/replay 手动重推最近 30 天任意事件
19.5.3 关键事件清单(已散见各模块,此处汇总)
  • products/create|update|delete
  • collections/create|update|delete
  • inventory_levels/updateinventory_items/update
  • carts/create|update
  • checkouts/create|update|delete
  • abandoned_checkouts/create
  • orders/create|updated|paid|cancelled|fulfilled|partially_fulfilled|delete
  • orders/editedtransactions/create
  • refunds/create
  • draft_orders/create|update|delete
  • fulfillment_orders/create|fulfilled|cancelled
  • fulfillments/create|update
  • customers/create|update|delete|disable|enable|merge
  • discounts/create|delete|redeem
  • gift_cards/create|update
  • payment_intent/payment_authorized|payment_captured|payment_failed
  • themes/publishthemes/update
  • marketing/campaign_sent|email_delivered|email_opened|email_clicked
  • reports/export_completed
  • app/uninstalled(OAuth 应用卸载)

19.6 鉴权与权限

19.6.1 Admin API 鉴权

OAuth2 流程(用于第三方集成):

GET /admin/oauth/authorize?client_id=XXX&scope=read_products,write_orders&redirect_uri=...
   ↓ 商家同意
GET /admin/oauth/redirect?code=AAAA&hmac=BBB&shop=xxx
POST /admin/oauth/access_token {client_id, client_secret, code}
   ↓
{ access_token, scope }

API Token 流程(员工自建):

  • 在 Admin 后台生成 Token,绑定 ShopStaff;可指定 scope 与过期时间
  • 请求头 X-TeleAgent-Access-Token: <token>
  • 权限校验:scope 必须覆盖资源(read_productswrite_orders 等)
19.6.2 Storefront API 鉴权
  • 每个 Theme / Channel 生成一个 Public Storefront Token
  • 请求头 X-TeleAgent-Storefront-Access-Token: <public_token>
  • Public Token 不可读 Admin 资源,只能读已发布商品 + 创建购物车/结账
  • 后台可禁用某 Token,30 秒内全球生效(Redis 失效广播)
19.6.3 权限矩阵(节选)
Scope 含义
read_products / write_products 商品/变体/集合
read_inventory / write_inventory 库存
read_orders / write_orders 订单
read_customers / write_customers 客户
read_discounts / write_discounts 折扣
read_draft_orders / write_draft_orders 草稿订单
read_locations 库位
read_fulfillments / write_fulfillments 履约
read_marketing_events / write_marketing_events 营销
read_themes / write_themes 主题
read_content / write_content 页面博客
read_analytics 分析只读
read_price_rules / write_price_rules 折扣规则
read_gift_cards / write_gift_cards 礼品卡

19.7 OpenAPI / GraphQL Schema

  • Admin REST 通过 drf-spectacular 自动生成 OpenAPI 3.0 文档,访问 /api/admin/openapi.json/api/admin/docs/
  • GraphQL 通过 strawberry-django 输出 schema,访问 /api/admin/graphql/schema.graphql

第 20 章 非功能性需求

20.1 性能指标

指标 目标
首页(10万 SKU 库)TTFB p95 ≤ 200ms
商品详情页 TTFB p95 ≤ 250ms(含 Liquid 渲染)
集合页带过滤器 TTFB p95 ≤ 400ms
加购物车(单次) p95 ≤ 150ms
结账页生成 p95 ≤ 800ms
Admin 商品列表 50 行 p95 ≤ 500ms
Admin 订单详情(含交易/履约) p95 ≤ 600ms
API Webhook 推送延迟 p95 ≤ 1s
主题 Liquid 模板编译缓存命中后渲染 p95 ≤ 300ms
单实例 QPS(4C8G) ≥ 500 商品/集合类只读

20.2 可用性与可扩展性

  • 可用性 SLA 99.9% / 月(电商旺季 99.95%);数据库主从 + Read replica;多 AZ 部署
  • 读扩展:商品/集合读流量 100% 走 Read replica,写流量走主库
  • 写扩展:订单写高峰按 shop_id 分片(Phase 3 引入),第一阶段单库分区表
  • 水平扩展:Web + Celery 无状态、可水平扩;Redis Cluster;对象存储天然多副本
  • 缓存策略:商品详情(10 分钟 + 主动失效)+ 集合列表(5 分钟)+ 主题渲染(编译缓存 + 内容 hash)+ 用户 session
  • 降级预案:搜索服务不可用 → 降级到 PG like 搜索;推荐服务不可用 → 降级到时序热门;支付网关熔断 → 暂用其他网关
  • 熔断:所有外部网关(支付、物流、短信)走 circuitbreaker

20.3 安全

  • 传输:全站 HSTS + TLS 1.3;API 仅 HTTPS
  • 存储:API Key 用 Fernet 加密;密码 BCrypt;DB 字段级加密敏感信息
  • CSRF:DRF SessionAuthentication + SameSite=Strict;Admin 表单 {% csrf_token %}
  • XSS:富文本 body_html 经 bleach 白名单清洗,禁用 iframe/script
  • SQL 注入:ORM 强制参数化;禁止 raw query 拼接
  • IDOR:所有对象级查询带 shop_id + owner_id 过滤,靠 BaseShopQuerySet 强制
  • 限流:基于 IP + Token 双维度,按 API 与 IP 双重阈值
  • 审计:敏感操作(退款、删除、Token 生成、权限变更)写 audit_log,保留 ≥ 3 年
  • GDPR / 个保法:客户删除请求 → 14 天宽限 → 真实删除(订单客户字段脱敏);客户可导出全部个人数据
  • PCI DSS:不落地卡号;用 Stripe/AliPay 等已认证网关;不追求独立过 PCI
  • WAF:接 Cloudflare / 阿里云 WAF,规则 OWASP Top 10
  • DDoS:CDN 前置;管理后台强制 IP allowlist / VPN

20.4 可观测性

维度 工具
错误 Sentry(前后端)
性能 Prometheus + Grafana + Django Silk(开发)
日志 结构化 JSON 日志 → ELK / Loki
链路 OpenTelemetry → Jaeger / Tempo
业务 自建埋点:订单、结账、关键 CTA
告警 Alertmanager + 钉钉/企业微信通知

20.5 数据备份与灾备

  • 数据库:每日全量 + 每小时增量,保留 30 天;PITR 支持
  • 对象存储:跨区复制
  • 异地灾备:异地热备 RPO ≤ 1h,RTO ≤ 4h
  • 定期演练:每季度一次恢复演练

20.6 国际化与本地化

  • 后端 i18n:django.utils.translation + DB 翻译
  • 前端 i18n:主题 locales/*.json 文件
  • 时区:服务端全 UTC,展示按店铺时区
  • 货币:所有金额多币种支持,符合 ISO 4217
  • 文字排布:支持 LTR/RTL(预留)

20.7 浏览器兼容与无障碍

  • 主流浏览器:Chrome/Edge/Safari/Firefox 最近 2 个大版本;移动端 iOS Safari/Android Chrome 最近 2 个大版本
  • 主题默认符合 WCAG 2.1 AA;图片 alt、按钮 ARIA 标签
  • 视图组件预留 Lighthouse ≥ 90 分要求

20.8 容量评估(基于 10 万 SKU / 月 GMV 5000 万)

模块 单月数据量 一年累计 备注
products/variants 10 万 / 50 万 静态
orders 5 万行 / 30 万行 line_items 600 万 按月分区
customers 3 万 35 万
page_view 与 cart_event 5000 万 6 亿 独立 OLAP
audit_log 50 万 600 万

建议 Phase 1 用 PG 单库 + 主从,Phase 2 引入只读库分库 + OLAP ClickHouse/DuckDB。


第 21 章 开发阶段与里程碑

21.1 阶段总览

阶段 周期 交付目标 章节覆盖
Phase 0 基础设施 W1~W3 项目脚手架、CI/CD、环境、Docker、监控 整体
Phase 1 MVP 顶配 W4~W16 P0 模块上线、可走通完整购买闭环 M01/M02/M03/M04/M05/M10
Phase 2 商家增强 W17~W28 P1 模块、营销与分析、客户体系 M06/M07/M08/M09/M11/M12/M14
Phase 3 多渠道与生态 W29~W40 多渠道适配 + Headless 前端 + 开放平台 M13、Hydrogen-like、App 体系

21.2 Phase 0 基础设施(3 周)

  • 仓库结构、Docker Compose 一键启动
  • CI:lint(ruff/black/mypy)+ pytest + 安全扫描(pip-audit、trivy)
  • 基础设施层:PostgreSQL、Redis、MinIO、Celery、Sentry、Prometheus 接入示例
  • 公共 core 模型基类、错误码、JWT/OAuth 框架

21.3 Phase 1 MVP(13 周,关键路径)

里程碑 周次 模块 / 任务
M1 W4-W5 shops、accounts、products 模型与 Admin API
M2 W6-W7 variants、images、collection(含自动集合)+ Storefront 商品 API
M3 W8 inventory + location 模块
M4 W9-W10 cart、checkout 核心 + 多步结账流程
M5 W11 orders、payment adapter(Stripe/支付宝/微信)+ order 状态机
M6 W12 themes 渲染引擎 + 默认主题样式(参考 Shopify 默认主题 Dawn)
M7 W13-W14 内部集成测试 + E2E(Playwright)+ 限流、Webhook
M8 W15-W16 内测、Bug Bash、文档化

Phase 1 完成 = 冷启动可用:商家可上架、前台搜索购物、完成下单、看到订单。

21.4 Phase 2 商家增强(12 周)

里程碑 周次 模块 / 任务
M9 W17-W18 draft orders、order edit、returns、refunds 闭环
M10 W19-W20 customers + customer segments + admin 全文搜索
M11 W21-W22 price_rules + discount_codes + automatic + discount functions sandbox
M12 W23-W24 gift cards + 多支付凭证 + 对账
M13 W25-W26 marketing:邮件/SMS/自动化工作流
M14 W27-W28 analytics:live view、销售报表、cohort、自定义报表
M15 W29 多语言多币种 + Markets
M16 W30 SEO 全套 + 域名多绑
M17 W31-W32 性能调优 + 压力测试

21.5 Phase 3 生态与扩展(12 周)

里程碑 周次 模块 / 任务
M18 W33-W34 channels adapter 框架 + Online Store + Manual
M19 W35-W36 POS 适配器(含离线模式与同步)
M20 W37-W38 外部渠道(Facebook/Meta/TikTok)适配
M21 W39-W40 Headless Storefront SDK(React + Hydrogen-like)
M22 W41-W44 开放平台 / 应用市场适配(OAuth2、Embedded App)

21.6 团队建议

角色 建议人数 关键产出
产品经理 1 需求拆解、原型、验收
后端 3 Django app 开发、API、性能
前端 2 Admin UI + 主题模板引擎
DevOps/SRE 1 CI/CD、监控、部署
测试 1 E2E 与回归
UI/UX 1 默认主题设计

21.7 关键里程碑甘特图(Mermaid)

gantt
    title Django 电商平台开发节奏
    dateFormat  YYYY-MM-DD
    section Phase0
    基础设施        :p0, 2026-08-01, 21d
    section Phase1
    MVP 核心模块    :p1, 2026-08-22, 91d
    section Phase2
    商家增强        :p2, 2026-11-21, 84d
    section Phase3
    多渠道生态      :p3, 2027-02-13, 84d

第 22 章 风险与合规

22.1 风险登记

ID 风险分类 描述 影响 缓解
R-1 技术 Liquid 模板引擎自研成本高 限制子集;引入 liquidpy / python-liquid 开源实现
R-2 技术 主题 schema 校验与可视化编辑器前端复杂 第一版降级到表单编辑,第二版再上拖拽
R-3 业务 多币种汇率与关税边界复杂 仅做主流币种;接入外部 Avalara
R-4 性能 订单月分区 + 写入热点 主键设计避开同 shop 单库写热点,考虑 sharding
R-5 支付 第三方网关 SLA 与跨境合规 多网关冗余;按地区 routing
R-6 数据 客户数据合规(GDPR / 个保法) 法务参与设计;删除链路提前打通
R-7 团队 关键工程师流动 双盲交接 + 高测试覆盖 + 文档化
R-8 质量 第三方对接回归工作量大 适配器契约测试 + mocking 框架

22.2 法律与合规清单

  • 《个人信息保护法》/ GDPR 数据字段最小化;同意弹窗;删除权
  • 《电子商务法》商家资质存档;订单保存 3 年
  • 《网络安全法》等级保护 2.0(建议三级);日志保留 ≥ 6 个月
  • PCI DSS:通过使用合规第三方网关规避直接获取卡数据
  • 海关/进口:跨境订单按平台/集货/直报模式分别对接
  • 税务:增值税开票系统集成(电子发票 / 数电票)
  • 招投标与商业条款相关留痕审计

22.3 数据治理

  • 数据分类:公开 / 内部 / 机密 / 受限
  • 数据脱敏:开发与测试环境强制脱敏;生产数据访问需 ticket + 双审
  • 数据传输:内部服务 mTLS
  • 数据导出:所有大表导出走审批;导出文件加水印与有效期 24 小时

22.4 文档与变更管理

  • 文档体系:本功能需求 → 接口规约(OpenAPI/GraphQL)→ 数据模型详设 → 设计决策记录 (ADR) → 运维手册
  • 变更管理:所有破坏性 API 改动走 RFC,需 2 人 review + 1 周 window
  • 版本:使用 SemVer;每次 Release 配 CHANGELOG

附录 A Shopify 与 Django 概念映射表

Shopify 概念 本系统实现 章节
Shop Shop model + shop_id 多租户预留 18.2
Admin API /api/admin/*.json REST + /api/admin/graphql GraphQL 19.3-19.4
Storefront API /api/{ver}/graphql.json GraphQL 19.4
Webhook apps/webhooks/ HMAC 签名 + 重试 + 重放 19.5
Liquid 自研 Python 沙箱子集(参考 python-liquid) 13.3.5
Online Store 2.0 / Sections apps/themes/ + JSON templates schema 13
Cart apps/cart/ + Storefront cartCreate 等 mutation 6.3.1
Checkout apps/checkout/ + Checkout Extensibility 6.3.2
Order / DraftOrder apps/orders/ 7
Fulfillment / Location apps/inventory/ 5
Product / Variant / Collection / Image apps/products/ 4
Metafield / Metaobject apps/metafields/ 4.3.4
Customer / SavedSearch / (Audiences) apps/customers/ + 自定义 segments 9
Discount / PriceRule / AutomaticDiscount apps/discounts/ + RestrictedPython script 10
Functions / Flow apps/discounts/script_engine.py + Celery 编排 11.3
GiftCard apps/payments/giftcard.py 8.3.3
Shop Pay / Wallet 抽象 WalletProvider(预留) 8
Markets(多市场) apps/pricing/market.py + 域名/币种/税率 17.2
Markets Duties / DDP apps/tax/ 17.3.6
Plus Apps / App Bridge 第三方 OAuth + Embedded App(Phase 3) 21.5
Analytics / Live View apps/analytics/ + 物化视图 12
Custom Reports apps/analytics/reports/ 12.3.5
Audiences 客户 Segment + 营销自动化 9.3.3 + 11
Email / SMS apps/marketing/ 11
Robots.txt / Sitemap / Redirects apps/seo/ 15
Sales Channels apps/channels/ adapter 16
POS Offline-first 适配器 16.2
Theme App Extension / UI Extensions ThemeExtension 抽象(Phase 3) 13.3
Web Pixel WebPixel 注册表 + JS SDK 6.3.2

文档结束。

本文档为对标 Shopify Plus 全量电商系统的 Django 实现需求规格说明书。各模块 API 字段细则、OpenAPI 文档、数据迁移规范将在独立交付物中以工程化形式输出。本文作为功能基线供产品评审与开发对接使用。

AI生成