feat: 开发采集、采集箱和商品编辑功能
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
# 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/)(维护公告)
|
||||
Reference in New Issue
Block a user