Files
license-manager/backend/docs/demand/2026.1.21-取消订单接口.md
T

3.2 KiB
Raw Blame History

取消订单接口

背景

当前客户侧订单支持创建、查询与列表查看(/api/cu/orders),但缺少“取消未支付订单”的能力;用户误下单/重复下单时只能等待支付超时,体验较差。

目标

  • 客户用户可取消“未支付(pending)”订单。
  • 已支付(paid)订单不允许取消,返回明确的业务错误码与错误信息。
  • 返回结构与现有接口保持一致:成功返回 models.APIResponse,失败返回 models.ErrorResponse。

参考接口(已实现)

为保持风格一致,本接口沿用以下已实现接口的路径风格、鉴权方式与返回结构:

  • POST /api/cu/orders:创建订单
  • GET /api/cu/orders/{order_id}:订单详情
  • GET /api/cu/orders:订单列表(含 status 筛选)

业务规则(与当前项目对齐)

说明:当前 cu_orders 表包含 deleted_at(GORM 软删除),但订单列表接口按 status 做筛选;为了支持“已取消订单可追溯/可筛选”,本设计采用状态取消(status=cancelled)而不是直接删除记录。

  • 允许取消:订单属于当前登录客户用户,且订单状态为 pending。
  • 不允许取消:订单状态为 paid(包含试用/免费单,当前实现中免费单直接为 paid)。
  • 幂等性:重复取消同一订单(已为 cancelled)应返回成功(不重复变更),避免前端重复点击导致报错。

接口定义

请求

PUT /api/cu/orders/{order_id}/cancel

Headers

  • Authorization: Bearer <token>(必填)
  • Accept-Language(可选)或 query ?lang=zh-CN(可选):与现有多语言中间件一致

Path 参数

  • order_id:订单ID(必填,字符串,UUID)

Body

无

响应

成功(200)

返回取消后的订单信息(与 GET /api/cu/orders/{order_id} 一致):

{
  "code": "000000",
  "message": "成功",
  "data": {
    "id": "uuid-string",
    "order_no": "ORD202601210001",
    "customer_id": "customer-uuid",
    "cu_user_id": "cu-user-uuid",
    "package_id": "basic",
    "package_name": "基础版",
    "license_count": 10,
    "unit_price": 300,
    "discount_rate": 1,
    "total_amount": 3000,
    "status": "cancelled",
    "authorization_code": null,
    "expired_at": null,
    "created_at": "2026-01-21T10:00:00Z",
    "updated_at": "2026-01-21T10:05:00Z"
  },
  "timestamp": "2026-01-21T10:05:00Z"
}

失败

失败时返回 models.ErrorResponse:

{
  "code": "601006",
  "message": "订单已支付,无法取消",
  "timestamp": "2026-01-21T10:05:00Z"
}

状态约定

  • pending:待支付(允许取消)
  • paid:已支付(不允许取消)
  • cancelled:已取消(重复取消返回成功)

错误码(建议新增/复用)

  • 100004:缺少认证信息(未登录)
  • 100005:权限不足(只能取消自己的订单)
  • 601001:订单不存在
  • 601006:订单已支付,无法取消(建议新增到 backend/configs/i18n/errors/* 的 cu_order 下)
  • 900001:请求参数无效(如 order_id 为空)
  • 900004:服务器内部错误

示例

  • 取消订单:
    • PUT /api/cu/orders/7b8c2c2e-9f2f-4f0b-9f31-0c8d3f6a9c11/cancel