diff --git a/README.md b/README.md index 5368ac5..9e3cfc4 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,55 @@ # xian-guanjia -闲管家 API Python 客户端 - 闲鱼自动化发货、订单管理工具 +闲管家 API Python 客户端 - 闲鱼自动化发货、商品管理工具 + +[![GitHub](https://img.shields.io/github/stars/thefreelight/xian-guanjia?style=social)](https://github.com/thefreelight/xian-guanjia) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## 简介 -这是一个闲管家开放平台的 Python API 客户端,支持通过 API 进行: +这是一个闲管家开放平台的 Python API 客户端,支持完整的闲鱼自动化操作: -- 订单查询和管理 -- 自动发货 -- 商品管理 -- 余额查询 -- 货源对接下单 +- 🔐 **自动签名** - 按照闲管家规则自动生成 MD5 签名 +- 📦 **商品管理** - 创建、编辑、上架、下架、删除商品,批量创建 +- 📦 **订单管理** - 查询订单、发货、改价、获取卡密 +- 🔍 **查询功能** - 类目查询、属性查询、快递公司查询、余额查询 +- 🪝 **Webhook 支持** - 支持商品和订单推送回调 ## 安装 ```bash -git clone https://github.com/kingofmarketing/xian-guanjia.git +git clone https://github.com/thefreelight/xian-guanjia.git cd xian-guanjia pip install requests ``` -## 使用方法 +## 功能列表 -### Python 代码调用 +| 模块 | 方法 | 功能 | +|------|------|------| +| 用户 | `get_xianyu_shops()` | 查询闲鱼店铺列表 | +| 商品 | `get_categories()` | 查询商品类目 | +| 商品 | `get_product_attributes(category_id)` | 查询商品属性 | +| 商品 | `get_product_list(page, page_size, status)` | 查询商品列表 | +| 商品 | `get_product_detail(product_id)` | 查询商品详情 | +| 商品 | `get_product_skus(product_id)` | 查询商品规格(多规格) | +| 商品 | `create_product(data)` | 创建单个商品 | +| 商品 | `create_products_batch(products)` | 批量创建商品 | +| 商品 | `publish_product(product_id)` | 上架商品 | +| 商品 | `unpublish_product(product_id)` | 下架商品 | +| 商品 | `update_product(product_id, data)` | 编辑商品 | +| 商品 | `update_stock(product_id, stock, sku_id)` | 编辑库存 | +| 商品 | `delete_product(product_id)` | 删除商品 | +| 订单 | `get_order_list(page, page_size, status)` | 获取订单列表 | +| 订单 | `get_order_detail(order_id)` | 获取订单详情 | +| 订单 | `get_order_cards(order_id)` | 获取卡密列表(虚拟商品) | +| 订单 | `ship_order(order_id, logistics_no, logistics_company)` | 订单发货 | +| 订单 | `update_order_price(order_id, price)` | 修改订单价格 | +| 订单 | `place_order(...)` | 下单(货源对接) | +| 其他 | `get_logistics_companies()` | 查询快递公司列表 | +| 其他 | `query_balance()` | 查询商户余额 | + +## 使用方法 ```python from xian_guanjia import XianGuanjiaClient @@ -35,7 +62,7 @@ client = XianGuanjiaClient( ) # 查询订单列表 -result = client.get_order_list(page=1, page_size=20) +result = client.get_order_list(page=1, page_size=20, status=1) # status=1 待发货 print(result) # 订单发货 @@ -45,12 +72,26 @@ result = client.ship_order( logistics_company="顺丰速运" ) +# 创建商品 +product_data = { + "title": "商品标题", + "price": 29.90, + "category_id": 123, + # 更多字段请参考官方 API 文档 +} +result = client.create_product(product_data) + +# 上架商品 +if result['code'] == 0: + product_id = result['data']['product_id'] + client.publish_product(product_id) + # 查询余额 result = client.query_balance() print(result) ``` -### 命令行使用 +## 命令行使用 ```bash python scripts/xian_guanjia.py \ @@ -64,26 +105,44 @@ python scripts/xian_guanjia.py \ 闲管家使用 MD5 签名认证,本客户端已经自动处理签名,无需手动计算。 -详细的签名规则参见 [SKILL.md](SKILL.md) 或 [references/api-docs.md](references/api-docs.md) +**签名流程:** + +1. 将请求体 JSON 序列化得到 `body_str` +2. 计算 `body_md5 = md5(body_str)` +3. 拼接签名字符串:`app_id,app_secret,body_md5,timestamp,mch_id,mch_secret` +4. 计算最终签名:`sign = md5(sign_str)` + +详细的签名规则参见 [references/api-docs.md](references/api-docs.md) ## 错误码 | 错误码 | 错误描述 | | --- | --- | | 0 | 请求成功 | +| 1 | 请求错误(不在定义范围内的错误) | | 401 | 签名错误 | | 403 | IP不在白名单 | | 408 | 时间戳过期 | +| 500 | 系统异常,请重试 | | 1000 | 商户不存在 | -| 1002 | 余额不足 | +| 1001 | 商户不可用 | +| 1002 | 商户余额不足 | +| 1100 | 商品不存在 | +| 1101 | 商品不可用 | +| 1102 | 商品库存不足 | +| 1200 | 订单不存在 | 完整错误码参见 [references/api-docs.md](references/api-docs.md) +## 官方文档 + +- 闲管家开放平台:https://open.goofish.pro +- 完整 API 文档:https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/llms.txt + ## 许可证 -MIT License +MIT License - see [LICENSE](LICENSE) for details ## 相关链接 - 闲管家官网:https://goofish.pro -- API 文档:https://apifox.com/apidoc/shared-cf4d53fd-8bb2-41c5-8da3-371ba9a38956/doc-4985015 diff --git a/SKILL.md b/SKILL.md index b009327..5864b34 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,16 +1,47 @@ --- name: xian-guanjia -description: 闲管家 API 集成,用于闲鱼自动化发货、订单管理、商品发布。支持通过 API 批量处理订单、自动发货。Use when: (1) 需要操作闲管家 API,(2) 帮用户处理闲鱼订单发货,(3) 查询订单列表和余额,(4) 用户提到"闲管家"、"闲鱼自动发货"。 +description: 闲管家 API 集成,用于闲鱼自动化发货、订单管理、商品发布。支持通过 API 批量处理订单、自动发货、商品创建上下架。Use when: (1) 需要操作闲管家 API,(2) 帮用户处理闲鱼订单发货,(3) 查询订单列表和余额,(4) 商品创建上架下架,(5) 用户提到"闲管家"、"闲鱼自动发货"、"闲鱼自动化"。 --- # 闲管家 -闲管家 API 客户端,用于闲鱼自动化发货、订单管理和商品发布。 +闲管家 API 客户端,用于闲鱼自动化发货、订单管理和商品发布。支持完整的商品管理、订单处理流程。 ## API 文档 完整的 API 签名规则和错误码参见 [references/api-docs.md](references/api-docs.md) +## 功能列表 + +### 用户接口 +- `get_xianyu_shops()` - 查询闲鱼店铺列表 + +### 商品接口 +- `get_categories()` - 查询商品类目 +- `get_product_attributes(category_id)` - 查询商品属性 +- `get_product_list(page, page_size, status)` - 查询商品列表 +- `get_product_detail(product_id)` - 查询商品详情 +- `get_product_skus(product_id)` - 查询商品规格(仅多规格) +- `create_product(data)` - 创建单个商品 +- `create_products_batch(products)` - 批量创建商品 +- `publish_product(product_id)` - 上架商品 +- `unpublish_product(product_id)` - 下架商品 +- `update_product(product_id, data)` - 编辑商品 +- `update_stock(product_id, stock, sku_id)` - 编辑库存 +- `delete_product(product_id)` - 删除商品 + +### 订单接口 +- `get_order_list(page, page_size, status)` - 获取订单列表 +- `get_order_detail(order_id)` - 获取订单详情 +- `get_order_cards(order_id)` - 获取订单卡密列表(虚拟商品) +- `ship_order(order_id, logistics_no, logistics_company)` - 订单发货 +- `update_order_price(order_id, price)` - 修改订单价格 +- `place_order(...)` - 下单(货源对接) + +### 其他接口 +- `get_logistics_companies()` - 查询快递公司列表 +- `query_balance()` - 查询商户余额 + ## 使用方法 ### 初始化客户端 @@ -26,42 +57,47 @@ client = XianGuanjiaClient( ) ``` -### 常用操作 +### 示例:查询待发货订单 -**查询订单列表** ```python -result = client.get_order_list(page=1, page_size=20) +# 获取订单列表(不指定status则返回全部) +result = client.get_order_list(page=1, page_size=20, status=1) +print(result) ``` -**查询订单详情** -```python -result = client.get_order_detail(order_id=12345) -``` +### 示例:订单发货 -**订单发货** ```python result = client.ship_order( order_id=12345, - logistics_no="物流单号", - logistics_company="快递公司" + logistics_no="7894561230", + logistics_company="顺丰速运" ) ``` -**下单(货源对接)** +### 示例:创建并上架商品 + ```python -result = client.place_order( - goods_no="商品编号", - goods_type=1, # 1-普通 2-虚拟 - buyer_nick="买家昵称", - buyer_id="买家ID", - order_no="管家订单号", - price=29.90 -) +# 创建商品 +product_data = { + "title": "商品标题", + "price": 29.90, + "category_id": 123, + # ... 其他必填字段见API文档 +} +result = client.create_product(product_data) + +if result['code'] == 0: + product_id = result['data']['product_id'] + # 上架商品 + client.publish_product(product_id) ``` -**查询余额** +### 示例:查询余额 + ```python result = client.query_balance() +print(result) ``` ## 响应格式 diff --git a/references/api-docs.md b/references/api-docs.md index 7188850..7353023 100644 --- a/references/api-docs.md +++ b/references/api-docs.md @@ -4,6 +4,42 @@ 生产环境地址:https://open.goofish.pro +## 相关文档 + +完整的 API 列表: + +### 用户接口 +- [查询闲鱼店铺](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586388.md) + +### 商品接口 +- [查询商品类目](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-97448687.md) +- [查询商品属性](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-95804125.md) +- [查询商品列表](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586381.md) +- [查询商品详情](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586380.md) +- [查询商品规格](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-165788779.md) - 仅多规格商品才能查询 +- [创建商品(单个)](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586377.md) +- [创建商品(批量)](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586378.md) +- [上架商品](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-95038267.md) +- [下架商品](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586382.md) +- [编辑商品](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586379.md) +- [编辑库存](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586384.md) +- [删除商品](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586383.md) + +### 订单接口 +- [查询订单列表](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-95074856.md) +- [查询订单详情](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586385.md) +- [订单卡密列表](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-97142794.md) +- [订单物流发货](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586386.md) +- [订单修改价格](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-333703388.md) + +### 推送回调接口 +- [商品回调通知](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-98676477.md) - 请商家自行在上架商品和编辑商品接口填写真实的推送地址 +- [商品推送通知](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-108700789.md) - 请商家自行在闲管家的开放平台填写真实的推送地址 +- [订单推送通知](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-93586387.md) - 请商家自行在闲管家的开放平台填写真实的推送地址 + +### 其他接口 +- [查询快递公司](https://s.apifox.cn/3ac13d69-5a38-4536-ae9b-a54001854ef8/api-97431955.md) - 如列表内没有需要的快递公司,可以联系闲管家技术支持补充 + ## 相关下载 - 闲管家省市区: @@ -14,9 +50,6 @@ - https://file.goofish.pro/doc/商品异常状态码.xlsx - https://file.goofish.pro/doc/商品异常状态码.sql -- 闲管家虚拟货源标准接口: - - https://apifox.com/apidoc/shared-cf4d53fd-8bb2-41c5-8da3-371ba9a38956/doc-4985015 - ## 注意事项 1. 闲管家所有参数都是强校验,需要严格按照文档的字段类型传参+返回 diff --git a/scripts/xian_guanjia.py b/scripts/xian_guanjia.py index e4b3e42..b2de458 100755 --- a/scripts/xian_guanjia.py +++ b/scripts/xian_guanjia.py @@ -8,7 +8,7 @@ import hashlib import time import json import requests -from typing import Dict, Any, Optional +from typing import Dict, Any, Optional, List class XianGuanjiaClient: @@ -92,21 +92,214 @@ class XianGuanjiaClient: return response.json() - def get_order_list(self, page: int = 1, page_size: int = 20) -> Dict[str, Any]: + # ==================== 用户接口 ==================== + + def get_xianyu_shops(self) -> Dict[str, Any]: + """ + 查询闲鱼店铺列表 + + Returns: + 店铺列表响应 + """ + return self.request('POST', '/api/user/shops', {}) + + # ==================== 商品接口 ==================== + + def get_categories(self) -> Dict[str, Any]: + """ + 查询商品类目 + + Returns: + 类目列表响应 + """ + return self.request('POST', '/api/product/categories', {}) + + def get_product_attributes(self, category_id: int) -> Dict[str, Any]: + """ + 查询商品属性 + + Args: + category_id: 类目ID + + Returns: + 属性列表响应 + """ + return self.request('POST', '/api/product/attributes', { + 'category_id': category_id + }) + + def get_product_list(self, page: int = 1, page_size: int = 20, status: Optional[int] = None) -> Dict[str, Any]: + """ + 查询商品列表 + + Args: + page: 页码 + page_size: 每页数量 + status: 商品状态 (可选) 1-上架 2-下架 + + Returns: + 商品列表响应 + """ + body = { + 'page': page, + 'page_size': page_size + } + if status is not None: + body['status'] = status + return self.request('POST', '/api/product/list', body) + + def get_product_detail(self, product_id: int) -> Dict[str, Any]: + """ + 查询商品详情 + + Args: + product_id: 商品ID + + Returns: + 商品详情响应 + """ + return self.request('POST', '/api/product/detail', { + 'product_id': product_id + }) + + def get_product_skus(self, product_id: int) -> Dict[str, Any]: + """ + 查询商品规格(仅多规格商品) + + Args: + product_id: 商品ID + + Returns: + 规格列表响应 + """ + return self.request('POST', '/api/product/skus', { + 'product_id': product_id + }) + + def create_product(self, data: Dict[str, Any]) -> Dict[str, Any]: + """ + 创建单个商品 + + Args: + data: 商品数据(包含标题、图片、价格等完整信息) + + Returns: + 创建响应 + """ + return self.request('POST', '/api/product/create', data) + + def create_products_batch(self, products: List[Dict[str, Any]]) -> Dict[str, Any]: + """ + 批量创建商品 + + Args: + products: 商品数据列表 + + Returns: + 创建响应 + """ + return self.request('POST', '/api/product/create_batch', { + 'products': products + }) + + def publish_product(self, product_id: int) -> Dict[str, Any]: + """ + 上架商品 + + Args: + product_id: 商品ID + + Returns: + 上架响应 + """ + return self.request('POST', '/api/product/publish', { + 'product_id': product_id + }) + + def unpublish_product(self, product_id: int) -> Dict[str, Any]: + """ + 下架商品 + + Args: + product_id: 商品ID + + Returns: + 下架响应 + """ + return self.request('POST', '/api/product/unpublish', { + 'product_id': product_id + }) + + def update_product(self, product_id: int, data: Dict[str, Any]) -> Dict[str, Any]: + """ + 编辑商品 + + Args: + product_id: 商品ID + data: 更新的商品数据 + + Returns: + 更新响应 + """ + body = {'product_id': product_id} + body.update(data) + return self.request('POST', '/api/product/update', body) + + def update_stock(self, product_id: int, stock: int, sku_id: Optional[int] = None) -> Dict[str, Any]: + """ + 编辑库存 + + Args: + product_id: 商品ID + stock: 库存数量 + sku_id: SKU ID(多规格商品需要) + + Returns: + 更新响应 + """ + body = { + 'product_id': product_id, + 'stock': stock + } + if sku_id is not None: + body['sku_id'] = sku_id + return self.request('POST', '/api/product/update_stock', body) + + def delete_product(self, product_id: int) -> Dict[str, Any]: + """ + 删除商品 + + Args: + product_id: 商品ID + + Returns: + 删除响应 + """ + return self.request('POST', '/api/product/delete', { + 'product_id': product_id + }) + + # ==================== 订单接口 ==================== + + def get_order_list(self, page: int = 1, page_size: int = 20, status: Optional[int] = None) -> Dict[str, Any]: """ 获取订单列表 Args: page: 页码 page_size: 每页数量 + status: 订单状态 (可选) Returns: 订单列表响应 """ - return self.request('POST', '/api/order/list', { + body = { 'page': page, 'page_size': page_size - }) + } + if status is not None: + body['status'] = status + return self.request('POST', '/api/order/list', body) def get_order_detail(self, order_id: int) -> Dict[str, Any]: """ @@ -122,14 +315,28 @@ class XianGuanjiaClient: 'order_id': order_id }) + def get_order_cards(self, order_id: int) -> Dict[str, Any]: + """ + 获取订单卡密列表(虚拟商品) + + Args: + order_id: 订单ID + + Returns: + 卡密列表响应 + """ + return self.request('POST', '/api/order/cards', { + 'order_id': order_id + }) + def ship_order(self, order_id: int, logistics_no: str, logistics_company: str) -> Dict[str, Any]: """ - 订单发货 + 订单物流发货 Args: order_id: 订单ID logistics_no: 物流单号 - logistics_company: 物流公司 + logistics_company: 物流公司代码/名称 Returns: 发货响应 @@ -140,20 +347,20 @@ class XianGuanjiaClient: 'logistics_company': logistics_company }) - def get_product_list(self, page: int = 1, page_size: int = 20) -> Dict[str, Any]: + def update_order_price(self, order_id: int, price: float) -> Dict[str, Any]: """ - 获取商品列表 + 修改订单价格 Args: - page: 页码 - page_size: 每页数量 + order_id: 订单ID + price: 新价格 Returns: - 商品列表响应 + 修改响应 """ - return self.request('POST', '/api/product/list', { - 'page': page, - 'page_size': page_size + return self.request('POST', '/api/order/update_price', { + 'order_id': order_id, + 'price': price }) def place_order(self, goods_no: str, goods_type: int, buyer_nick: str, @@ -181,6 +388,18 @@ class XianGuanjiaClient: 'price': price }) + # ==================== 其他接口 ==================== + + def get_logistics_companies(self) -> Dict[str, Any]: + """ + 查询快递公司列表 + + Returns: + 快递公司列表响应 + 如果列表内没有需要的快递公司,可以联系闲管家技术支持补充 + """ + return self.request('POST', '/api/logistics/companies', {}) + def query_balance(self) -> Dict[str, Any]: """ 查询商户余额