# 后台管理 API 开发文档

版本：`1.0.0` · 契约修订：`2026-10-28.3`

本文面向需要读取、处理本站本地订单及售后的管理系统。可导入 Apifox、Swagger 等工具的契约见 [management-openapi-v1.yaml](./management-openapi-v1.yaml)，店铺经营对接见 [店铺供货 API](./seller-supply-api-guide.md)。

## 1. 接入信息

接入方保存以下三个参数：

| 参数 | 说明 |
| --- | --- |
| 商户域名 | 商户提供的主站 HTTPS 域名 |
| 管理员账户 | 后台管理员的登录账户名 |
| 管理员 API Key | 绑定该管理员的独立密钥，仅接受 `ADM_` 加 16 位小写十六进制字符，共 20 个字符 |

主管理员在“后台用户”中生成并启用密钥。重置后旧密钥立即失效；管理员停用、API 停用或角色撤权后，相关请求不再允许。密钥只在生成时展示，请保存在服务端密钥配置中，不写入浏览器代码、URL 或日志。

基础地址：

```text
https://{merchant-domain}/openapi/v1/admin
```

该分组只使用主站域名。管理员仍受原订单、售后权限和商户身份要求约束；有订单权限不代表有售后权限。

### 1.1 请求头

```http
X-KYS-Admin-Account: <ADMIN_ACCOUNT>
X-KYS-Key: <ADMIN_API_KEY>
Content-Type: application/json
```

使用管理员登录账户和独立 API Key 验证，不传登录密码、Cookie、API Secret、时间戳或签名。请求头名称不区分大小写。

### 1.2 数据范围

订单列表、订单详情和订单处理覆盖本站所有已付款的以下订单，包括分站成交订单：

1. 本地货源卡密订单。
2. 本地货源充值订单。
3. 无货源的人工充值订单。

不按创建入口或管理员本人限定订单。售后列表、详情和处理覆盖所有来源的售后，包括其他渠道和远程货源订单的售后；售后读取关联订单不受上述本地订单范围限制。

## 2. 通用约定

- 使用 HTTPS、UTF-8。除注明外，请求体和响应为 `application/json`。
- 路径 `{id}` 是订单或售后的整数 ID，1～10 位正整数；它与 `orderNo`、`complainNo` 不同。
- 时间字段为 Unix 秒级整数；列表日期筛选为 `YYYY-MM-DD`，按北京时间自然日计算。
- 金额单位为人民币元。实付及退款金额一般保留两位小数，单价、成本、利润可保留四位小数。后台部分十进制字段返回字符串，应按字段类型读取并用十进制方式计算。
- 列表 `page` 从 1 开始，`pageSize` 默认 10，范围 1～100。
- 列表不附带全站汇总统计。GET 订单详情返回全部卡密，GET 售后详情返回全部消息。
- 资源或权限检查在每次操作时执行；收到详情后，订单状态仍可能因其他操作者而变化。

### 2.1 统一响应

```json
{
  "code": 0,
  "message": "success",
  "data": {},
  "requestId": "req_example"
}
```

`code=0` 表示接口调用成功。批量处理还必须检查 `data` 内每一项的 `result`，不能将外层成功当作所有订单处理成功。问题排查请保存 `requestId`，不要记录密钥或完整卡密。

分页 `data`：

```json
{"list": [], "total": 0, "page": 1, "pageSize": 10}
```

## 3. 接口清单

以下路径均接在 `/openapi/v1/admin` 后。

| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/orders` | 分页获取本地订单 |
| GET | `/orders/{id}` | 获取订单完整详情 |
| POST | `/orders/process` | 单个或批量处理订单 |
| GET | `/aftersales` | 分页获取所有来源售后 |
| GET | `/aftersales/{id}` | 获取售后完整详情 |
| POST | `/aftersales/{id}/process` | 回复、处理售后 |

## 4. 订单接口

### 4.1 获取订单列表

```http
GET /openapi/v1/admin/orders?page=1&pageSize=20&status=pending
```

查询参数均可选，多个条件共同生效。

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| page | integer | 页码，默认 1 |
| pageSize | integer | 每页条数，默认 10，最大 100 |
| keyword | string | 完整的 `D` 加 17 位数字订单号按单号精确查询，其余按商品名称模糊查询 |
| orderNo | string | 订单号模糊查询 |
| externalOrderNo | string | 采购方订单号或销售渠道外部订单号模糊查询 |
| status | string | 订单状态；空或 `all` 不限定 |
| productName | string | 商品名称模糊查询 |
| orderInput | string | 按完整充值输入值查询，例如完整充值账号 |
| productType | string | `card`、`recharge` |
| paymentChannel | string | 支付渠道代码，例如 `balance`；`sales_channel` 用于销售渠道订单筛选 |
| userId | integer | 买家用户 ID，0 表示游客 |
| nickname | string | 买家昵称模糊查询 |
| adminRemark | string | 管理备注模糊查询 |
| startDate / endDate | string | 同时传入起止日期，包含两个日期当天 |
| minAmount / maxAmount | number | 实付金额下限、上限 |
| orderType | string | 来源分类：`platform`、`partner`、`supplier`、`guest`、`redemption`；空或 `all` 不限定 |

示例响应：

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "list": [{
      "id": 12345,
      "orderNo": "D26102812345678901",
      "status": "pending",
      "orderType": "local",
      "sourceType": "local",
      "productType": "recharge",
      "goodsId": 101,
      "goodsName": "充值商品",
      "skuId": 0,
      "skuName": "",
      "quantity": 1,
      "salePrice": "10.0000",
      "totalPrice": 10,
      "refundedAmount": 0,
      "paymentChannel": "balance",
      "createdAt": 1793145600,
      "user": {"id": 1000, "nickname": "示例用户", "avatar": "", "isGuest": false}
    }],
    "total": 1,
    "page": 1,
    "pageSize": 20
  },
  "requestId": "req_example"
}
```

示例展示常用字段，其余条件字段见第 7 节及 YAML。

### 4.2 获取订单详情

```http
GET /openapi/v1/admin/orders/12345
```

`data` 为订单对象，包含列表字段及详情字段。卡密位于 `data.cardSecrets`，一次返回全部，不传 `cardPage`。

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "id": 12345,
    "orderNo": "D26102812345678901",
    "status": "success",
    "orderType": "local",
    "sourceType": "local",
    "productType": "card",
    "goodsName": "卡密商品",
    "quantity": 1,
    "totalPrice": 10,
    "refundedAmount": 0,
    "createdAt": 1793145600,
    "cardSecrets": [{
      "id": "10001",
      "cardNumber": "EXAMPLE_CARD_NUMBER",
      "cardSecret": "EXAMPLE_CARD_SECRET",
      "cardType": "卡密+卡号",
      "fixedContentType": 0,
      "cardNumberAlias": "卡号",
      "cardSecretAlias": "卡密"
    }],
    "verificationCodeRequired": false,
    "verificationCodeInfo": null,
    "rechargeProof": null
  },
  "requestId": "req_example"
}
```

不存在或不在本地订单范围时返回 HTTP 404、`code=404002`。

### 4.3 处理订单

```http
POST /openapi/v1/admin/orders/process
```

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| orderIds | integer[] | 是 | 订单 ID 数组，1～100 项；单笔也传数组 |
| status | string | 是 | 目标状态，见第 7 节；能否执行取决于当前订单状态 |
| message | string | 否 | 处理说明，最多 255 字符，默认空 |
| processStart | number | 否 | 进度起点，默认 0 |
| processCurrent | number | 否 | 当前进度，默认 50 |
| processTarget | number | 否 | 目标进度，默认 100；充值成功时进度归为 100/100 |
| refundType | string | 退款时 | `full` 表示剩余可退金额全退；`partial` 表示按指定金额退款 |
| currentRefundAmount | number | 部分退款时 | 本次退款金额，人民币元 |
| totalRefundedAmount | number | 否 | 本次完成后的累计退款金额；须等于已退加本次金额，通常省略由服务端计算 |
| commissionRefundType | string | 否 | `noForce` 默认不强制追回佣金；`force` 按平台规则追回 |
| requestNo | string | 退款时是 | 8～48 位字母、数字、下划线或连字符，作为同一管理员、同一订单退款的稳定请求编号 |
| refundRecord | object | 否 | 兼容退款记录，可传 `refundNo`；一般省略，平台生成退款单号。自定义单号最长 64 位，仅字母、数字、下划线或连字符 |

充值成功或本地卡密出库：

```json
{"orderIds": [12345], "status": "success", "message": "处理完成"}
```

更新处理进度：

```json
{"orderIds": [12345], "status": "processing", "processStart": 0, "processCurrent": 30, "processTarget": 100, "message": "正在处理"}
```

成功订单全额退款示例：

```json
{"orderIds": [12345], "status": "refunded", "refundType": "full", "requestNo": "refund_20261028_0001", "message": "同意退款"}
```

部分退款示例：

```json
{"orderIds": [12345], "status": "partially_refunded", "refundType": "partial", "currentRefundAmount": 2.5, "requestNo": "refund_20261028_0002", "message": "部分退款"}
```

待处理、处理中的订单可按原资格提交 `status=canceled`。需要取消并退款时，同时传 `refundType`、`requestNo` 及对应退款参数；不能把单纯状态改变当成资金已退。退款提交成功不等于资金已经退回；通过订单详情的 `status`、`refundedAmount`、`refundFailure` 确认结果。

响应 `data` 是结果数组，不是分页容器：

```json
{
  "code": 0,
  "message": "success",
  "data": [
    {"id": 12345, "orderNo": "D26102812345678901", "currentStatus": "pending", "result": "success", "message": "处理成功"},
    {"id": 12346, "result": "failure", "message": "订单不存在或不在本地订单范围"}
  ],
  "requestId": "req_example"
}
```

退款受理项可能带 `taskId`。`result=success` 表示该项操作已执行或已受理；退款的最终结果仍以订单详情为准。批量请求可部分成功，不承诺结果顺序与输入顺序一致，必须按 `id` 对应。

同一退款超时重试保留原 `requestNo` 及全部退款参数；改变说明、金额、状态等内容应使用新的请求编号。普通处理不使用 `requestNo` 作为通用幂等键，应先确认详情中的当前状态，再决定是否继续处理。终态订单重复处理可返回单项失败，不会再次出库。

## 5. 售后接口

### 5.1 获取售后列表

```http
GET /openapi/v1/admin/aftersales?page=1&pageSize=20&status=pending
```

| 参数 | 类型 | 说明 |
| --- | --- | --- |
| page / pageSize | integer | 默认 1/10，最大每页 100 |
| status | string | `pending`、`processing`、`completed`、`terminated`；空、`all` 或 `-1` 不限定 |
| keyword | string | 搜索内容，与 `searchType` 同时使用 |
| searchType | string | `userId` 按买家 ID 查询；`orderNo` 按订单号模糊查询 |
| startDate / endDate | string | 同时传起止日期，格式 `YYYY-MM-DD` |
| source | string | 来源分类：`platform` 本站订单、`partner` 合作订单、`supplier` 店铺销售或供货订单、`wechatpay` 微信支付投诉；空或 `all` 不限定 |

`data` 是分页容器。每项包括售后字段及 `order` 订单摘要。返回项的 `source=local/wechatpay` 表示售后通道，与查询参数中的来源分类不同。

### 5.2 获取售后详情

```http
GET /openapi/v1/admin/aftersales/5001
```

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "id": 5001,
    "userId": 1000,
    "complainNo": "CP26102812345678901",
    "topic": "充值未到账",
    "orderNo": "D26102812345678901",
    "status": "pending",
    "source": "local",
    "serviceType": "",
    "serviceStatus": "",
    "createdAt": 1793145600,
    "updatedAt": 1793145600,
    "order": {"id": 12345, "orderNo": "D26102812345678901", "status": "success", "goodsName": "充值商品"},
    "messages": [{"id": 10001, "complainId": 5001, "sender": "user", "content": "充值尚未到账", "messageFormat": "text", "timestamp": 1793145600}]
  },
  "requestId": "req_example"
}
```

`messages` 是完整消息数组，不是分页容器。`order` 是关联订单详情；即使关联订单不属于本地订单 API 范围，这里也可按售后权限读取。实物售后另返回 `physical`，见第 7 节。

### 5.3 回复、处理普通售后或微信投诉

```http
POST /openapi/v1/admin/aftersales/5001/process
```

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| status | string | 是 | `pending`、`processing`、`completed`、`terminated`；微信投诉状态还受平台规则限制 |
| replyContent | string | 条件必填 | 回复正文，最多 255 字符；正文和附件至少一项非空 |
| attachments | string[] | 否 | 图片 URL，最多 5 项；每项为 HTTP/HTTPS URL，最长 255 字符 |
| requestNo | string | 是 | 8～48 位字母、数字、下划线或连字符；重复提交同一回复保持不变 |

```json
{"status": "processing", "replyContent": "已收到，正在核实", "attachments": [], "requestNo": "reply_20261028_0001"}
```

普通售后、微信投诉成功响应：

```json
{
  "code": 0,
  "message": "success",
  "data": {
    "total": 1,
    "successCount": 1,
    "failedCount": 0,
    "successList": [{"index": 0, "id": 5001, "action": "processed"}],
    "failedList": []
  },
  "requestId": "req_example"
}
```

同一售后下，相同 `requestNo` 必须保持状态、正文和附件内容一致。已结束售后不能继续追加新处理。将售后设为 `completed` 本身不代表订单退款；退款需另按订单退款能力执行。

微信投诉遇到超时、待确认或处理中时，先查询售后详情及已同步消息，保留 `requestId` 与原 `requestNo` 核对结果，不要换编号盲目重复发送。

### 5.4 处理实物售后

仍使用 `POST /aftersales/{id}/process`。依据详情中的 `serviceType`、`serviceStatus` 选择动作，不指定上游或处理渠道。

| action | 用途 | 主要参数 |
| --- | --- | --- |
| reply | 回复消息 | `message` 必填，`requestNo` 必填 |
| approve | 同意申请 | 可传 `message`；仅当前状态允许时执行 |
| reject | 拒绝申请 | 可传 `message` |
| close | 关闭售后 | 可传 `message` |
| receive_return | 确认收到退货 | 可传 `message`；以当前服务状态为准 |
| replacement_ship | 寄出换货 | `carrierCode`、`trackingNo` 必填，可传 `message` |

`message` 最长 255 字符。实物回复的 `requestNo` 规则与普通回复相同。快递编码使用详情 `physical.carrierOptions[].code`，例如 `sf_express`，不要填写快递名称或第三方快递商编码。

```json
{"action": "reply", "message": "请按约定寄回商品", "requestNo": "physical_reply_0001"}
```

```json
{"action": "replacement_ship", "carrierCode": "sf_express", "trackingNo": "SFEXAMPLE0001", "message": "换货已寄出"}
```

实物处理成功时 `data` 直接为实物售后对象，包括 `id`、`serviceType`、`serviceStatus`、`returnAddress`、`returnLogistics`、`replacementLogistics`、`carrierOptions`，与普通售后批量结果结构不同。涉及退款的动作可能只受理退款，需继续查询订单确认。

## 6. 限流、错误和同步

| 类别 | 配额 |
| --- | --- |
| 订单 GET 接口 | 每管理员每分钟 120 次 |
| 售后 GET 接口 | 每管理员每分钟 120 次 |
| 订单处理 | 每管理员每分钟 30 次 |
| 售后处理 | 每管理员每分钟 30 次 |
| 账户总额度 | 每管理员每分钟 600 次，瞬时容量 30 |
| 认证尝试 | 同一商户、同一来源 IP 每分钟 200 次 |

额度由同一管理员的请求共同消耗。响应可携带 `X-RateLimit-Limit`、`X-RateLimit-Remaining`、`X-RateLimit-Reset`；`Reset` 为 Unix 秒级时间，收到 429/503 时按 `Retry-After` 秒数等待。

| HTTP | 常见 code | 处理方式 |
| --- | --- | --- |
| 400 | 400001 | 检查参数、操作资格及当前状态 |
| 401 | 401001 | 检查管理员账户、Key、账户及 API 开关 |
| 403 | 403001 | 检查角色权限、商户身份要求及账户限制 |
| 404 | 404001、404002 | 检查主站域名、完整路径、资源 ID 和本地订单范围 |
| 409 | 409001 | 请求编号内容冲突或操作冲突，先核对原请求 |
| 429 | 429001 | 按 `Retry-After` 退避 |
| 503 | 503001 | 暂时不可用，读取可退避重试，写入先核对结果 |
| 500 | 500001 | 保存 `requestId` 联系商户；写入结果未知时先查详情 |

域名、入口或网关直接拒绝的请求可能不使用上述 JSON 格式，先检查 HTTP 状态和响应类型。

订单及售后采集使用分页列表和详情查询，按 `id` 关联，重复读取按状态、消息 ID 去重。本分组不新增管理事件订阅。订单处理引发的采购方回调由平台按原订单通知约定发送；管理员对接以订单详情确认处理或退款结果，不需要自行重发采购方通知。

## 7. 字段与状态

### 7.1 订单

| 字段 | JSON 类型 | 说明 |
| --- | --- | --- |
| id / orderNo | integer / string | 订单 ID、平台订单号 |
| status | string | `pending` 待处理、`processing` 处理中、`success` 成功、`canceled` 已取消、`partially_refunded` 部分退款、`refunded` 已退款 |
| orderType | string | 订单记录的类型代码，常见 `local`、`platform`、`partner`、`supplier`、`sales_channel`、`redemption`；与列表查询参数的来源分类不同，例如 `orderType=platform` 筛选结果可返回 `local` |
| source | string | 详情中的创建入口代码，例如 `front`、`openapi` |
| sourceType | string | 货源类型；本订单分组返回 `local` |
| productType | string | `card` 卡密、`recharge` 充值 |
| goodsId / skuId | integer | 商品、规格 ID；无规格时 skuId 为 0 |
| goodsName / skuName / goodsImage | string 或 null | 商品、规格显示信息 |
| quantity | integer | 购买数量 |
| salePrice / costPrice / profit | number 或 string | 单价、成本、利润，十进制字段可能为字符串，最多四位小数 |
| totalPrice / refundedAmount | number | 实付、累计已退金额 |
| taxType / taxRate / taxAmount / refundedTaxAmount | string / number | 计价类型为 `exclusive` 不含税、`personal` 个人含税、`enterprise` 企业含税；其余为税率、税额和已退税额 |
| paymentChannel / paymentNo / paymentTime | string 或 null / string 或 null / integer | 支付渠道、支付单号、支付时间 |
| createdAt / updatedAt / completedAt | integer | 创建、更新、完成时间；未发生可为 0；updatedAt 在详情中返回 |
| processingTime | integer | 处理耗时，秒 |
| user | object | 买家 `id`、`nickname`、可选 `avatar`、`isGuest` |
| processMessage | string 或 null | 按订单返回的处理进度展示信息；进度写入参数见第 4.3 节 |
| message / remark / adminRemark | string 或 null | 处理说明、订单备注、后台备注；详情返回 |
| orderParams / normalizedInputValues | array | 充值资料；数据字段按该订单模板读取 |
| inputTemplateSnapshot | object 或 array | 输入模板；无模板时可为 `[]`，字段定义在 `fields` 中 |
| currentFulfillmentAttemptId / finalFulfillmentAttemptId | integer 或 null | 当前、最终履约记录 ID；尚无履约记录或历史人工处理订单可为 null |
| cardSecrets | array | 详情的完整卡密数组，项字段见第 4.2 节；卡密项 id 可能是数字字符串 |
| rechargeProof | object 或 null | 充值凭证：`url`、`uploadedAt`、`expiresAt`，按有效期访问，URL 应保密 |
| verificationCodeRequired / verificationCodeInfo | boolean / object 或 null | 是否需要验证码及当前验证码状态 |
| refundHistory / refundFailure | array / object 或 null | 退款历史、退款失败信息，主要在详情返回 |
| storeInfo / subsiteInfo / salesChannelInfo / openApiInfo | object | 按订单来源返回的归属或渠道信息，可能省略 |

字段会随订单类型和可用信息省略或为 null。请忽略未知附加字段，不把展示字段当作操作凭据；不要使用履约内部状态代替 `status` 判断订单最终结果。

### 7.2 售后与实物服务

售后基础字段：`id`、`userId`、`complainNo`、`topic`、`orderNo`、`status`、`source`、`serviceType`、`serviceStatus`、`createdAt`、`updatedAt`、`order`。详情增加完整 `messages` 和按需返回的 `physical`。

消息字段：`id`、`complainId`、`sender`、`content`、`messageFormat`、`timestamp`；部分消息带 `senderLabel`。`messageFormat` 常见 `text`、`image`，按返回类型展示。

`serviceType` 为空表示普通售后或微信投诉；实物为 `refund_only` 仅退款、`return_refund` 退货退款、`exchange` 换货。`serviceStatus` 常见 `pending`、`awaiting_return`、`return_shipped`、`refunding`、`awaiting_replacement`、`completed`、`rejected`、`canceled`，具体允许动作由当前服务状态决定。

物流对象为空时为 null，非空时包括 `carrierCode`、`carrierName`、`trackingNo`、`status`、`shippedAt`。快递选项包含 `code`、`name` 及对应要求。

## 8. 请求示例

通过环境变量提供凭据：

```bash
curl --get "${KYS_BASE_URL}/openapi/v1/admin/orders" \
  -H "X-KYS-Admin-Account: ${KYS_ADMIN_ACCOUNT}" \
  -H "X-KYS-Key: ${KYS_ADMIN_API_KEY}" \
  --data-urlencode 'status=pending' \
  --data-urlencode 'page=1' \
  --data-urlencode 'pageSize=20'
```

```bash
curl "${KYS_BASE_URL}/openapi/v1/admin/orders/process" \
  -H "X-KYS-Admin-Account: ${KYS_ADMIN_ACCOUNT}" \
  -H "X-KYS-Key: ${KYS_ADMIN_API_KEY}" \
  -H 'Content-Type: application/json' \
  --data '{"orderIds":[12345],"status":"success","message":"处理完成"}'
```

其中 `KYS_BASE_URL` 形如 `https://merchant.example.com`，不包含 `/openapi/v1`；示例中的订单、卡密和请求编号均为演示值。
