235 lines
5.6 KiB
Markdown
235 lines
5.6 KiB
Markdown
# Ozon Seller API 鉴权与基础
|
||
|
||
> 官方文档:https://docs.ozon.ru/api/seller/zh/#tag/Introduction
|
||
|
||
---
|
||
|
||
## 1. 鉴权方式
|
||
|
||
Ozon Seller API 使用 **API Key 鉴权**(非 OAuth),每个请求需在请求头携带:
|
||
|
||
```http
|
||
Client-Id: <你的 Client ID>
|
||
Api-Key: <你的 API Key>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
### 获取凭证
|
||
|
||
1. 登录 Ozon 卖家后台
|
||
2. 进入「设置」→「Seller API」
|
||
3. 点击「生成 API Key」
|
||
4. 选择权限级别:
|
||
- **只读**(Read):仅查询
|
||
- **读写**(Read & Write):查询 + 创建/更新商品
|
||
- **管理员**(Admin):所有权限
|
||
5. 保存 `Client-Id` 和 `Api-Key`(**Api-Key 仅显示一次**)
|
||
|
||
### 安全约束
|
||
|
||
- ⚠️ **Api-Key 等同密码**:泄露后任何人可操作你的店铺
|
||
- 🔒 **服务端存储**:加密落库(AES-GCM),前端永不传输/回显明文
|
||
- 🔄 **定期轮换**:建议每 90 天更换一次
|
||
- 🚫 **前端禁用**:插件/studio 不得持有店铺凭证,只能持有用户 token
|
||
|
||
---
|
||
|
||
## 2. Base URL
|
||
|
||
```
|
||
https://api-seller.ozon.ru
|
||
```
|
||
|
||
所有接口路径都基于此 URL,例如:
|
||
```
|
||
POST https://api-seller.ozon.ru/v3/product/import
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 请求示例
|
||
|
||
### cURL
|
||
|
||
```bash
|
||
curl -X POST "https://api-seller.ozon.ru/v1/description-category/tree" \
|
||
-H "Client-Id: 123456" \
|
||
-H "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"language":"RU"}'
|
||
```
|
||
|
||
### Python (httpx)
|
||
|
||
```python
|
||
import httpx
|
||
|
||
headers = {
|
||
"Client-Id": "123456",
|
||
"Api-Key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||
"Content-Type": "application/json"
|
||
}
|
||
|
||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||
resp = await client.post(
|
||
"https://api-seller.ozon.ru/v1/description-category/tree",
|
||
headers=headers,
|
||
json={"language": "RU"}
|
||
)
|
||
data = resp.json()
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 通用响应结构
|
||
|
||
### 成功响应(200/201)
|
||
|
||
```json
|
||
{
|
||
"result": { /* 业务数据 */ }
|
||
}
|
||
```
|
||
|
||
部分接口直接返回数组或对象,不包裹 `result`。
|
||
|
||
### 错误响应(4xx/5xx)
|
||
|
||
```json
|
||
{
|
||
"code": 400,
|
||
"message": "INVALID_ARGUMENT",
|
||
"details": [
|
||
{
|
||
"typeUrl": "type.googleapis.com/ozon.ValidationError",
|
||
"value": "..."
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
或简化版:
|
||
|
||
```json
|
||
{
|
||
"error": {
|
||
"code": "INVALID_PARAMETER",
|
||
"message": "offer_id is required"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 错误码
|
||
|
||
| HTTP 状态码 | 含义 | 常见原因 | 处理建议 |
|
||
|---|---|---|---|
|
||
| **400** | 参数错误 | 必填字段缺失 / 格式错误 / 枚举值非法 | 检查请求体字段,读 `details` 定位 |
|
||
| **401** | 未鉴权 | 请求头缺 `Client-Id` 或 `Api-Key` | 检查请求头 |
|
||
| **403** | 权限不足 | Api-Key 权限级别不够(如只读 key 调创建接口) | 重新生成读写权限 key |
|
||
| **404** | 资源不存在 | `product_id` / `category_id` 不存在 | 检查 ID 是否正确 |
|
||
| **409** | 资源冲突 | `offer_id` 重复 / 商品已存在 | 改用唯一 offer_id 或走更新接口 |
|
||
| **429** | 限流 | 请求频率超限 | 指数退避重试(1s → 2s → 4s) |
|
||
| **500** | 服务端错误 | Ozon 内部错误 | 重试 1-2 次,仍失败则联系支持 |
|
||
| **503** | 服务不可用 | 维护中 | 稍后重试 |
|
||
|
||
---
|
||
|
||
## 6. 限流规则
|
||
|
||
官方未公开明确的限流阈值,根据社区经验:
|
||
|
||
- **常规接口**:~10 req/s
|
||
- **批量接口**(如 `/v3/product/list`):~5 req/s
|
||
- **同一 task_id 轮询**:建议间隔 ≥5s
|
||
|
||
触发 429 后:
|
||
1. 解析响应头 `Retry-After`(秒数)
|
||
2. 若无此头,使用指数退避:1s → 2s → 4s → 8s
|
||
3. 最多重试 3 次
|
||
|
||
---
|
||
|
||
## 7. 超时建议
|
||
|
||
| 接口类型 | 超时时间 | 理由 |
|
||
|---|---|---|
|
||
| 查询类(类目/属性/商品列表) | 30s | 轻量请求 |
|
||
| 导入类(`/v3/product/import`) | 60-90s | 后端需校验 + 入库 |
|
||
| 轮询状态(`/v1/product/import/info`) | 30s | 单次轮询快,但需多次 |
|
||
| 图片上传 | 90s | 网络传输耗时 |
|
||
|
||
---
|
||
|
||
## 8. 测试凭证有效性
|
||
|
||
### `/v1/roles` —— 获取当前 Key 的角色与权限
|
||
|
||
```http
|
||
POST https://api-seller.ozon.ru/v1/roles
|
||
```
|
||
|
||
**请求体**:空 `{}`
|
||
|
||
**响应**:
|
||
|
||
```json
|
||
{
|
||
"result": [
|
||
{
|
||
"role_name": "Seller",
|
||
"permissions": [
|
||
"read:products",
|
||
"write:products",
|
||
"read:categories",
|
||
...
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**用途**:
|
||
- ✅ 验证凭证有效性(200 = 有效,401/403 = 无效)
|
||
- ✅ 查看权限范围(判断是否有 `write:products`)
|
||
- ✅ 零业务副作用(不消耗额度,不修改数据)
|
||
|
||
**V2 集成点**:`POST /api/shops/:id/test` 调此接口作连通性校验。
|
||
|
||
---
|
||
|
||
## 9. 请求 ID 追踪
|
||
|
||
部分接口响应包含 `request_id`(如图生图、导入任务),用于:
|
||
- 问题排查:联系 Ozon 支持时提供此 ID
|
||
- 幂等重试:某些接口可根据 `request_id` 避免重复创建
|
||
|
||
建议:每次请求在日志里记录 `request_id`(若有)与请求体摘要,便于回溯。
|
||
|
||
---
|
||
|
||
## 10. 环境
|
||
|
||
Ozon Seller API **仅生产环境**,无测试沙箱。调试时需注意:
|
||
- ⚠️ 所有操作都在真实店铺
|
||
- 💡 建议用「测试商品」标识(如 offer_id 前缀 `TEST-`)
|
||
- 🗑️ 测试后及时删除/归档测试商品
|
||
|
||
---
|
||
|
||
## 11. SDK 与工具
|
||
|
||
官方未提供 Python SDK,社区方案:
|
||
- 自封装 `httpx` 客户端(V2 采用,见 `server/services/ozon_client.py`)
|
||
- 第三方库:`ozon-api`(PyPI,非官方,更新滞后)
|
||
|
||
---
|
||
|
||
## 12. 相关链接
|
||
|
||
- [官方文档(中文)](https://docs.ozon.ru/api/seller/zh/)
|
||
- [官方文档(俄文)](https://docs.ozon.ru/api/seller/)
|
||
- [卖家后台](https://seller.ozon.ru/)
|
||
- [API 状态页](https://status.ozon.ru/)(维护公告)
|