Orders API 接口文档
订单服务对外暴露的 REST 接口。围绕订单的创建、查询、更新、取消,以及下单前的价格试算(报价), 提供一致的请求/响应结构、机器可读的错误码与透明限流策略——目标是让接入方在一次性读完本文档后即可完成首笔调用。
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 标记。
本页所有代码示例均可直接复制运行。把示例中的 $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。
鉴权请求头
Authorization: Bearer sk_live_3f8a9c2e7b41d6f0a5c9
Content-Type: application/json
Idempotency-Key: 5f2c1a90-8d3e-4b7a-9c11-77ab0e6d2f54
Idempotency-Key 为可选请求头,建议在所有 POST / PATCH / DELETE 请求中携带。服务端会在 24 小时内缓存同一 Key 的结果,重复提交直接返回首次响应,避免网络重试造成重复下单。
用 curl 发起鉴权请求
curl https://api.orders.dev/v2/orders \
-H "Authorization: Bearer $ORDERS_API_KEY" \
-H "Content-Type: application/json"
请勿在前端代码、移动端包体或公开仓库中暴露密钥。Token 仅应在服务端使用;若疑似泄露,立即在控制台轮换,旧密钥将在 5 分钟内失效。
03查询订单列表
分页返回当前账户下的订单。默认按创建时间倒序,单页最多 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 | 可选 | 按客户维度过滤,常用于「我的订单」页面。 |
请求示例
curl "https://api.orders.dev/v2/orders?status=paid&limit=2" \
-H "Authorization: Bearer $ORDERS_API_KEY"
响应示例
{
"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"
}
状态码
04创建订单
创建一笔新订单,初始状态为 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 个键,值必须是字符串,便于关联你自己的业务单号。 |
请求示例
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": "客户要求加急配送"
}'
响应示例
{
"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。金额拆分规则与报价接口一致,见 报价模型与计费规则。
状态码
05获取订单详情
按订单 ID 返回单笔订单的完整信息,包含商品行、金额拆分、状态、收货信息与全部时间戳。
路径参数 Path
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 必填 | 订单唯一标识,形如 ord_9Lm4Tz7。 |
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 订单 ID。 |
| status | string | 订单状态:pending / paid / shipped / cancelled / refunded。 |
| items | array | 商品行,含 product_id、quantity、unit_price、line_total。 |
| subtotal | integer | 商品小计(分)。 |
| discount | integer | 优惠金额(分),无优惠为 0。 |
| shipping_fee | integer | 运费(分)。 |
| tax | integer | 税费(分),按 6% 计算。 |
| amount | integer | 含税应付总额(分)。 |
| metadata | object | 自定义键值对,原样回传。 |
| created_at / updated_at | string | 创建与最后更新时间(ISO 8601,UTC)。 |
| paid_at / cancelled_at | string | 支付、取消时间,未发生时字段不出现。 |
请求示例
curl https://api.orders.dev/v2/orders/ord_9Lm4Tz7 \
-H "Authorization: Bearer $ORDERS_API_KEY"
响应示例
{
"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"
}
状态码
06更新订单
局部更新一笔订单。仅可修改 note、metadata 与未发货前的 shipping_address。已支付订单的金额与商品行不可变更, 请求体只需包含待修改字段,未出现的字段保持原值。
请求体 Body
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| note | string | 可选 | 订单备注,传 null 可清空。 |
| metadata | object | 可选 | 自定义键值对,最多 20 个键;以整体替换方式更新,不做合并。 |
| shipping_address | object | 可选 | 收货信息,仅 pending / paid 状态可改,发货后返回 400。 |
请求示例
curl https://api.orders.dev/v2/orders/ord_9Lm4Tz7 \
-X PATCH \
-H "Authorization: Bearer $ORDERS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "note": "客户要求加急配送(顺丰)" }'
响应示例
{
"id": "ord_9Lm4Tz7",
"object": "order",
"status": "paid",
"note": "客户要求加急配送(顺丰)",
"amount": 31694,
"updated_at": "2026-10-23T10:05:12Z"
}
状态码
07取消订单
取消一笔订单。pending 状态可直接取消; paid 订单取消会同步触发退款流程,响应中返回 refund 对象,退款到账为异步过程。 已发货(shipped)订单不可取消,需走售后流程。
路径与查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id(path) | string | 必填 | 待取消的订单 ID。 |
| cancel_reason | string | 可选 | 取消原因,最长 200 字符,用于售后统计。 |
请求示例
curl "https://api.orders.dev/v2/orders/ord_9Lm4Tz7?cancel_reason=客户改单" \
-X DELETE \
-H "Authorization: Bearer $ORDERS_API_KEY"
响应示例
{
"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"
}
}
状态码
08报价模型与计费规则
报价(Quote)是下单前的价格快照:给定商品与收货地,服务端一次性算出含优惠、运费、税费的最终价, 并返回一张带有效期的报价单。它解决三件事——价格透明(每一分钱都有出处)、 价格锁定(有效期内下单金额不变)、可核对(报价单可随时按 ID 查回)。
①先算后卖
展示「到手价」前先拿报价,避免前端自行拼凑运费与折扣导致对账不一致。
②报价不占库存
创建报价不锁定库存、不产生订单,可安全地用于商品页与购物车的实时试算。
③过期即失效
默认有效期 30 分钟,过期后状态转 expired,需重新报价。
计费顺序
- 商品小计 = Σ(
unit_price×quantity),取商品当前售价,单位为分。 - 优惠金额:百分比折扣按
round(subtotal × rate)四舍五入到分;固定金额优惠不超过小计,最低减至 0。 - 运费:折后小计 ≥ ¥199.00 免运费,否则普通地区 ¥12.00、偏远地区 ¥25.00。
- 税费 =
round((折后小计 + 运费) × 6%),按分四舍五入。 - 应付总计 = 折后小计 + 运费 + 税费。
优惠在运费与税费之前计算。因此优惠可能改变是否满足包邮门槛;税费始终按「折后小计 + 运费」计征,优惠本身不减免税费基数以外的部分。
报价试算器
下面的试算器与服务端计费规则一致,可直接拖动输入观察金额拆分(结果仅用于理解规则,正式报价请调用接口)。
09创建报价
根据商品与收货地计算价格,返回一张带有效期的报价单。报价不锁定库存、不创建订单; 在有效期内用返回的 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 分钟。 |
请求示例
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
}'
响应示例
{
"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" }, 便于前端直接提示「优惠码已过期」而无需中断流程。
状态码
10查询报价
按报价单 ID 返回报价详情。报价单状态有三种: active(有效期内,可用于下单)、 expired(已过期,需重新报价)、 converted(已用于下单,附带 converted_order_id)。
路径参数 Path
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | string | 必填 | 报价单 ID,形如 quote_T4m8Qp。 |
请求示例
curl https://api.orders.dev/v2/quotes/quote_T4m8Qp \
-H "Authorization: Bearer $ORDERS_API_KEY"
响应示例
{
"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"
}
状态码
11通用错误码
错误响应统一返回非 2xx 状态码,并在响应体的 error 对象中给出机器可读的 code、人类可读的 message,以及可选的 field(指出出错字段)与 request_id(联系支持时提供)。
错误响应结构
{
"error": {
"code": "VALIDATION_ERROR",
"message": "items 为必填项,且至少包含一项商品",
"field": "items",
"request_id": "req_8d31c7a4e0"
}
}
错误码对照
| HTTP | error.code | 含义与处理建议 |
|---|---|---|
| 400 | VALIDATION_ERROR | 请求参数校验失败,检查 field 指出的字段格式与取值范围。 |
| 401 | UNAUTHORIZED | 缺少或无效的 Token,检查 Authorization 头是否为 Bearer <key>。 |
| 403 | FORBIDDEN | 密钥无权访问该资源,确认密钥的权限范围与账户归属。 |
| 404 | RESOURCE_NOT_FOUND | 资源不存在或已删除,核对订单 / 报价单 ID 是否正确、是否属于当前账户。 |
| 409 | CONFLICT | 状态冲突(如取消已发货订单、重复取消),先重新查询最新状态再决定下一步。 |
| 422 | UNPROCESSABLE_ENTITY | 语义校验失败(如商品已下架、数量超过限购),需业务侧调整后重试。 |
| 422 | QUOTE_EXPIRED | 报价单已过期,重新调用 POST /v2/quotes 获取新报价后再下单。 |
| 429 | RATE_LIMITED | 超出限流,读取 Retry-After 秒数后按指数退避重试。 |
| 500 | INTERNAL_ERROR | 服务端异常,携带响应中的 request_id 联系技术支持。 |
请按 error.code 而非 HTTP 状态码分支处理。同一状态码下可能存在多个错误码,未来也可能新增错误码而不改变 HTTP 语义;对未知 code 建议按「不可重试」处理并记录日志。
12限流说明
限流按 API 密钥维度统计,采用滑动窗口算法,与 IP 无关。每个响应都会返回限流头; 触发限流时返回 429 与 Retry-After(秒)。 不同套餐的每分钟请求上限如下:
限流响应头
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1792746780
Retry-After: 42
配额消耗规则
| 端点 | 计费次数 | 说明 |
|---|---|---|
| GET /v2/orders | 1 | 列表查询,含分页续页。 |
| POST /v2/orders | 2 | 创建涉及库存校验与金额重算。 |
| GET /v2/orders/{id} | 1 | — |
| PATCH /v2/orders/{id} | 1 | — |
| DELETE /v2/orders/{id} | 2 | 可能触发退款流程。 |
| POST /v2/quotes | 2 | 报价需调用定价引擎计算优惠与税费。 |
| GET /v2/quotes/{id} | 1 | — |
客户端应实现指数退避重试:收到 429 时读取 Retry-After 等待相应秒数;若未返回该头,则按 1s、2s、4s、8s 递增重试, 最多 5 次并加入随机抖动,避免多个实例同时重试打满配额。
13版本与变更
接口当前为 v2.1,遵循语义化版本。破坏性变更通过新的主版本号发布, 并提供从 v1 到 v2 的迁移指南;弃用字段保留至少 6 个月,弃用期内在响应的 Deprecation 头中标注。