订单服务 Orders API
订单服务 · 接口参考

Orders API 接口文档

订单服务对外暴露的 REST 接口。围绕订单的创建、查询、更新、取消,以及下单前的价格试算(报价), 提供一致的请求/响应结构、机器可读的错误码与透明限流策略——目标是让接入方在一次性读完本文档后即可完成首笔调用。

Base URL
api.orders.dev/v2
鉴权方式
Bearer Token
数据格式
application/json
端点数量
7 · 5 订单 + 2 报价

01API 概览

Orders API 是资源型 REST 接口,所有资源以 JSON 表示并遵循标准 HTTP 语义: GET 读取、POST 创建、 PATCH 局部更新、DELETE 取消。 时间戳统一为 ISO 8601(UTC,形如 2026-10-23T09:12:44Z), 金额统一以分为单位的整数表示(29900 即 ¥299.00),避免浮点误差。

▤可预测的响应

资源结构固定,列表统一使用游标分页。2xx 成功、4xx 客户端错误、5xx 服务端错误,错误原因写在 error.code。

◈密钥级鉴权

请求头携带 Bearer Token,密钥在控制台生成与轮换;支持只读密钥,作用于测试与内部分析场景。

◔先报价后下单

下单前调用报价接口拿到含优惠、运费、税费的最终价,再用 quote_id 锁价创建订单。

订单状态流转

pending→ paid→ shipped· cancelled← refunded

新订单以 pending 创建,支付确认后转为 paid, 发货后转为 shipped。取消操作会进入 cancelled; 已支付订单取消将同时触发退款,退款完成后追加 refunded 标记。

i

本页所有代码示例均可直接复制运行。把示例中的 $ORDERS_API_KEY 换成你的密钥,即可在终端发起第一笔请求。

02鉴权与基础 URL

所有请求必须使用 HTTPS,并在请求头携带 Bearer Token。缺失、格式错误或已失效的 Token 一律返回 401 Unauthorized;Token 有效但无权访问目标资源时返回 403 Forbidden。

基础 URL

环境Base URL用途
生产 https://api.orders.dev/v2 真实交易数据
沙箱 https://api.sandbox.orders.dev/v2 联调与自动化测试

所有端点路径都基于该前缀,例如查询订单列表的完整地址为 https://api.orders.dev/v2/orders。

鉴权请求头

HTTP Header
Authorization: Bearer sk_live_3f8a9c2e7b41d6f0a5c9
Content-Type: application/json
Idempotency-Key: 5f2c1a90-8d3e-4b7a-9c11-77ab0e6d2f54

Idempotency-Key 为可选请求头,建议在所有 POST / PATCH / DELETE 请求中携带。服务端会在 24 小时内缓存同一 Key 的结果,重复提交直接返回首次响应,避免网络重试造成重复下单。

用 curl 发起鉴权请求

Shell · curl200 OK
curl https://api.orders.dev/v2/orders \
  -H "Authorization: Bearer $ORDERS_API_KEY" \
  -H "Content-Type: application/json"
!

请勿在前端代码、移动端包体或公开仓库中暴露密钥。Token 仅应在服务端使用;若疑似泄露,立即在控制台轮换,旧密钥将在 5 分钟内失效。

03查询订单列表

GET /v2/orders

分页返回当前账户下的订单。默认按创建时间倒序,单页最多 100 条。使用游标分页: 下一页游标取自上一页响应的 next_cursor, has_more 为 false 表示已到末尾。

查询参数 Query

参数类型必填说明
status string 可选 按状态过滤:pending / paid / shipped / cancelled / refunded。
limit integer 可选 每页条数,取值 1–100,默认 20。
cursor string 可选 分页游标,取自上一页响应的 next_cursor;首页不传。
created_from string 可选 起始时间(ISO 8601),仅返回该时间之后创建的订单。
customer_id string 可选 按客户维度过滤,常用于「我的订单」页面。

请求示例

Shell · curl
curl "https://api.orders.dev/v2/orders?status=paid&limit=2" \
  -H "Authorization: Bearer $ORDERS_API_KEY"

响应示例

application/json200 OK
{
  "object": "list",
  "data": [
    {
      "id": "ord_7K2a9Xc",
      "object": "order",
      "status": "paid",
      "customer_id": "cust_abc123",
      "amount": 29900,
      "currency": "CNY",
      "created_at": "2026-10-21T08:14:33Z"
    },
    {
      "id": "ord_5Bq3Wd1",
      "object": "order",
      "status": "paid",
      "customer_id": "cust_def456",
      "amount": 15800,
      "currency": "CNY",
      "created_at": "2026-10-20T19:02:10Z"
    }
  ],
  "has_more": true,
  "next_cursor": "cur_8fa2c"
}

状态码

200请求成功 400查询参数非法 401未鉴权 429超出限流

04创建订单

POST /v2/orders

创建一笔新订单,初始状态为 pending,支付确认后转为 paid。服务端按商品当前售价计算金额; 若希望锁定报价单中的价格与优惠,传入 quote_id 即可,此时 items 可省略。

请求体 Body

字段类型必填说明
customer_id string 必填 下单客户的唯一标识。
items array 必填* 商品行数组,至少一项,每项含 product_id 与 quantity。传入 quote_id 时可省略。
quote_id string 可选 报价单 ID,形如 quote_T4m8Qp。使用后按报价单金额下单并锁定价格。
currency string 可选 ISO 4217 货币代码,默认 CNY。
shipping_address object 可选 收货信息,含 name、phone、province、city、detail。
note string 可选 订单备注,最长 500 字符。
metadata object 可选 自定义键值对,最多 20 个键,值必须是字符串,便于关联你自己的业务单号。

请求示例

Shell · curl
curl https://api.orders.dev/v2/orders \
  -X POST \
  -H "Authorization: Bearer $ORDERS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f2c1a90-8d3e-4b7a-9c11-77ab0e6d2f54" \
  -d '{
    "customer_id": "cust_abc123",
    "items": [{ "product_id": "prod_xyz", "quantity": 2 }],
    "currency": "CNY",
    "note": "客户要求加急配送"
  }'

响应示例

application/json201 Created
{
  "id": "ord_9Lm4Tz7",
  "object": "order",
  "status": "pending",
  "customer_id": "cust_abc123",
  "items": [
    {
      "product_id": "prod_xyz",
      "quantity": 2,
      "unit_price": 14950,
      "line_total": 29900
    }
  ],
  "subtotal": 29900,
  "discount": 0,
  "shipping_fee": 0,
  "tax": 1794,
  "amount": 31694,
  "currency": "CNY",
  "note": "客户要求加急配送",
  "created_at": "2026-10-23T09:12:44Z"
}

响应中的 amount 是含税应付总额,等于 subtotal - discount + shipping_fee + tax。金额拆分规则与报价接口一致,见 报价模型与计费规则。

状态码

201创建成功 400参数校验失败 401未鉴权 422商品不可售 / 报价已过期 429超出限流

05获取订单详情

GET /v2/orders/{id}

按订单 ID 返回单笔订单的完整信息,包含商品行、金额拆分、状态、收货信息与全部时间戳。

路径参数 Path

参数类型必填说明
id string 必填 订单唯一标识,形如 ord_9Lm4Tz7。

响应字段

字段类型说明
idstring订单 ID。
statusstring订单状态:pending / paid / shipped / cancelled / refunded。
itemsarray商品行,含 product_id、quantity、unit_price、line_total。
subtotalinteger商品小计(分)。
discountinteger优惠金额(分),无优惠为 0。
shipping_feeinteger运费(分)。
taxinteger税费(分),按 6% 计算。
amountinteger含税应付总额(分)。
metadataobject自定义键值对,原样回传。
created_at / updated_atstring创建与最后更新时间(ISO 8601,UTC)。
paid_at / cancelled_atstring支付、取消时间,未发生时字段不出现。

请求示例

Shell · curl
curl https://api.orders.dev/v2/orders/ord_9Lm4Tz7 \
  -H "Authorization: Bearer $ORDERS_API_KEY"

响应示例

application/json200 OK
{
  "id": "ord_9Lm4Tz7",
  "object": "order",
  "status": "paid",
  "customer_id": "cust_abc123",
  "items": [
    {
      "product_id": "prod_xyz",
      "quantity": 2,
      "unit_price": 14950,
      "line_total": 29900
    }
  ],
  "subtotal": 29900,
  "discount": 0,
  "shipping_fee": 0,
  "tax": 1794,
  "amount": 31694,
  "currency": "CNY",
  "shipping_address": {
    "name": "李伟",
    "province": "广东省",
    "city": "江门市"
  },
  "metadata": { "erp_no": "SO-20261023-0087" },
  "paid_at": "2026-10-23T09:14:08Z",
  "created_at": "2026-10-23T09:12:44Z",
  "updated_at": "2026-10-23T09:14:08Z"
}

状态码

200请求成功 401未鉴权 403无权访问该订单 404订单不存在

06更新订单

PATCH /v2/orders/{id}

局部更新一笔订单。仅可修改 note、metadata 与未发货前的 shipping_address。已支付订单的金额与商品行不可变更, 请求体只需包含待修改字段,未出现的字段保持原值。

请求体 Body

字段类型必填说明
note string 可选 订单备注,传 null 可清空。
metadata object 可选 自定义键值对,最多 20 个键;以整体替换方式更新,不做合并。
shipping_address object 可选 收货信息,仅 pending / paid 状态可改,发货后返回 400。

请求示例

Shell · curl
curl https://api.orders.dev/v2/orders/ord_9Lm4Tz7 \
  -X PATCH \
  -H "Authorization: Bearer $ORDERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "客户要求加急配送(顺丰)" }'

响应示例

application/json200 OK
{
  "id": "ord_9Lm4Tz7",
  "object": "order",
  "status": "paid",
  "note": "客户要求加急配送(顺丰)",
  "amount": 31694,
  "updated_at": "2026-10-23T10:05:12Z"
}

状态码

200更新成功 400字段不可变更 401未鉴权 404订单不存在 409状态冲突

07取消订单

DELETE /v2/orders/{id}

取消一笔订单。pending 状态可直接取消; paid 订单取消会同步触发退款流程,响应中返回 refund 对象,退款到账为异步过程。 已发货(shipped)订单不可取消,需走售后流程。

路径与查询参数

参数类型必填说明
id(path) string 必填 待取消的订单 ID。
cancel_reason string 可选 取消原因,最长 200 字符,用于售后统计。

请求示例

Shell · curl
curl "https://api.orders.dev/v2/orders/ord_9Lm4Tz7?cancel_reason=客户改单" \
  -X DELETE \
  -H "Authorization: Bearer $ORDERS_API_KEY"

响应示例

application/json200 OK
{
  "id": "ord_9Lm4Tz7",
  "object": "order",
  "status": "cancelled",
  "cancel_reason": "客户改单",
  "cancelled_at": "2026-10-23T10:20:40Z",
  "refund": {
    "status": "processing",
    "amount": 31694,
    "expected_at": "2026-10-26T10:20:40Z"
  }
}

状态码

200取消成功 401未鉴权 404订单不存在 409当前状态不允许取消

08报价模型与计费规则

报价(Quote)是下单前的价格快照:给定商品与收货地,服务端一次性算出含优惠、运费、税费的最终价, 并返回一张带有效期的报价单。它解决三件事——价格透明(每一分钱都有出处)、 价格锁定(有效期内下单金额不变)、可核对(报价单可随时按 ID 查回)。

①先算后卖

展示「到手价」前先拿报价,避免前端自行拼凑运费与折扣导致对账不一致。

②报价不占库存

创建报价不锁定库存、不产生订单,可安全地用于商品页与购物车的实时试算。

③过期即失效

默认有效期 30 分钟,过期后状态转 expired,需重新报价。

计费顺序

  1. 商品小计 = Σ(unit_price × quantity),取商品当前售价,单位为分。
  2. 优惠金额:百分比折扣按 round(subtotal × rate) 四舍五入到分;固定金额优惠不超过小计,最低减至 0。
  3. 运费:折后小计 ≥ ¥199.00 免运费,否则普通地区 ¥12.00、偏远地区 ¥25.00。
  4. 税费 = round((折后小计 + 运费) × 6%),按分四舍五入。
  5. 应付总计 = 折后小计 + 运费 + 税费。
i

优惠在运费与税费之前计算。因此优惠可能改变是否满足包邮门槛;税费始终按「折后小计 + 运费」计征,优惠本身不减免税费基数以外的部分。

报价试算器

下面的试算器与服务端计费规则一致,可直接拖动输入观察金额拆分(结果仅用于理解规则,正式报价请调用接口)。

报价试算 实时 金额按分计算,展示换算为元
商品小计¥0.00
优惠 —−¥0.00
运费 ¥0.00
税费 6%¥0.00
应付总计¥0.00
折后小计满 ¥199.00 免运费。

09创建报价

POST /v2/quotes

根据商品与收货地计算价格,返回一张带有效期的报价单。报价不锁定库存、不创建订单; 在有效期内用返回的 id 作为 quote_id 调用 创建订单,即可锁定本次金额。

请求体 Body

字段类型必填说明
customer_id string 必填 客户唯一标识。用于匹配会员折扣与历史价策略。
items array 必填 商品行数组,至少一项,每项含 product_id 与 quantity,最多 50 项。
currency string 可选 ISO 4217 货币代码,默认 CNY;当前支持 CNY、HKD、USD。
discount_code string 可选 优惠码,大小写不敏感。无效或已过期时报价仍然成功,但 discount.amount 为 0 且给出 discount.reason。
shipping_address object 可选 收货地,仅 province 与 city 参与运费与税费计算;缺省按普通地区计价。
valid_minutes integer 可选 报价有效期,取值 5–1440,默认 30 分钟。

请求示例

Shell · curl
curl https://api.orders.dev/v2/quotes \
  -X POST \
  -H "Authorization: Bearer $ORDERS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_abc123",
    "items": [{ "product_id": "prod_xyz", "quantity": 2 }],
    "discount_code": "SAVE10",
    "shipping_address": { "province": "广东省", "city": "江门市" },
    "valid_minutes": 30
  }'

响应示例

application/json201 Created
{
  "id": "quote_T4m8Qp",
  "object": "quote",
  "status": "active",
  "customer_id": "cust_abc123",
  "items": [
    {
      "product_id": "prod_xyz",
      "quantity": 2,
      "unit_price": 14950,
      "line_total": 29900
    }
  ],
  "subtotal": 29900,
  "discount": {
    "code": "SAVE10",
    "type": "percent",
    "amount": 2990
  },
  "shipping_fee": 0,
  "tax": 1615,
  "total": 28525,
  "currency": "CNY",
  "expires_at": "2026-10-23T09:42:44Z",
  "created_at": "2026-10-23T09:12:44Z"
}

若传入的优惠码不可用,响应仍为 201,但 discount 会变成 { "code": "SAVE10", "type": "percent", "amount": 0, "reason": "CODE_EXPIRED" }, 便于前端直接提示「优惠码已过期」而无需中断流程。

状态码

201报价成功 400参数校验失败 401未鉴权 422商品不可售 429超出限流

10查询报价

GET /v2/quotes/{id}

按报价单 ID 返回报价详情。报价单状态有三种: active(有效期内,可用于下单)、 expired(已过期,需重新报价)、 converted(已用于下单,附带 converted_order_id)。

路径参数 Path

参数类型必填说明
id string 必填 报价单 ID,形如 quote_T4m8Qp。

请求示例

Shell · curl
curl https://api.orders.dev/v2/quotes/quote_T4m8Qp \
  -H "Authorization: Bearer $ORDERS_API_KEY"

响应示例

application/json200 OK
{
  "id": "quote_T4m8Qp",
  "object": "quote",
  "status": "converted",
  "subtotal": 29900,
  "discount": { "code": "SAVE10", "type": "percent", "amount": 2990 },
  "shipping_fee": 0,
  "tax": 1615,
  "total": 28525,
  "currency": "CNY",
  "converted_order_id": "ord_9Lm4Tz7",
  "expires_at": "2026-10-23T09:42:44Z",
  "created_at": "2026-10-23T09:12:44Z"
}

状态码

200请求成功 401未鉴权 404报价单不存在

11通用错误码

错误响应统一返回非 2xx 状态码,并在响应体的 error 对象中给出机器可读的 code、人类可读的 message,以及可选的 field(指出出错字段)与 request_id(联系支持时提供)。

错误响应结构

application/json400 Bad Request
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "items 为必填项,且至少包含一项商品",
    "field": "items",
    "request_id": "req_8d31c7a4e0"
  }
}

错误码对照

HTTPerror.code含义与处理建议
400VALIDATION_ERROR请求参数校验失败,检查 field 指出的字段格式与取值范围。
401UNAUTHORIZED缺少或无效的 Token,检查 Authorization 头是否为 Bearer <key>。
403FORBIDDEN密钥无权访问该资源,确认密钥的权限范围与账户归属。
404RESOURCE_NOT_FOUND资源不存在或已删除,核对订单 / 报价单 ID 是否正确、是否属于当前账户。
409CONFLICT状态冲突(如取消已发货订单、重复取消),先重新查询最新状态再决定下一步。
422UNPROCESSABLE_ENTITY语义校验失败(如商品已下架、数量超过限购),需业务侧调整后重试。
422QUOTE_EXPIRED报价单已过期,重新调用 POST /v2/quotes 获取新报价后再下单。
429RATE_LIMITED超出限流,读取 Retry-After 秒数后按指数退避重试。
500INTERNAL_ERROR服务端异常,携带响应中的 request_id 联系技术支持。
i

请按 error.code 而非 HTTP 状态码分支处理。同一状态码下可能存在多个错误码,未来也可能新增错误码而不改变 HTTP 语义;对未知 code 建议按「不可重试」处理并记录日志。

12限流说明

限流按 API 密钥维度统计,采用滑动窗口算法,与 IP 无关。每个响应都会返回限流头; 触发限流时返回 429 与 Retry-After(秒)。 不同套餐的每分钟请求上限如下:

免费版 Free
60
请求 / 分钟
标准版 Pro
300
请求 / 分钟
企业版 Scale
1200
请求 / 分钟

限流响应头

HTTP Response Headers429 Too Many Requests
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1792746780
Retry-After: 42

配额消耗规则

端点计费次数说明
GET /v2/orders1列表查询,含分页续页。
POST /v2/orders2创建涉及库存校验与金额重算。
GET /v2/orders/{id}1—
PATCH /v2/orders/{id}1—
DELETE /v2/orders/{id}2可能触发退款流程。
POST /v2/quotes2报价需调用定价引擎计算优惠与税费。
GET /v2/quotes/{id}1—

客户端应实现指数退避重试:收到 429 时读取 Retry-After 等待相应秒数;若未返回该头,则按 1s、2s、4s、8s 递增重试, 最多 5 次并加入随机抖动,避免多个实例同时重试打满配额。

13版本与变更

接口当前为 v2.1,遵循语义化版本。破坏性变更通过新的主版本号发布, 并提供从 v1 到 v2 的迁移指南;弃用字段保留至少 6 个月,弃用期内在响应的 Deprecation 头中标注。

2026-10-23
v2.1.0 当前版本
新增报价模块:POST /v2/quotes 与 GET /v2/quotes/{id};创建订单新增 quote_id 锁价能力;订单对象新增 subtotal / discount / shipping_fee / tax 金额拆分字段。
2026-06-22
v2.0.0
正式发布。新增游标分页 next_cursor;金额统一改为以分(整数)表示; 错误结构标准化为 error.code;移除 v1 中的偏移分页参数。
2026-04-10
v1.4.0
为 PATCH /orders/{id} 增加 metadata 字段; 订单详情新增 paid_at 时间戳。
2026-01-18
v1.0.0
Orders API 首个稳定版,支持订单的创建、查询与取消,以及 Bearer Token 鉴权与基础限流。
订单服务 Orders API · 接口参考文档 v2.1.0 最后更新 2026-10-23 · 本文档为单文件离线版本,无外部依赖