Initial commit: xian-guanjia API client

This commit is contained in:
kingofmarketing committed 2026-04-10 02:28:16 +08:00
commit 3891554e79
6 files changed
+536

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
__pycache__/
*.pyc
*.pyo
*.pyd
.env
.vscode/
.idea/
*.log
config.py
credentials.json
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 kingofmarketing
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+89
View File
@@ -0,0 +1,89 @@
# xian-guanjia
闲管家 API Python 客户端 - 闲鱼自动化发货、订单管理工具
## 简介
这是一个闲管家开放平台的 Python API 客户端,支持通过 API 进行:
- 订单查询和管理
- 自动发货
- 商品管理
- 余额查询
- 货源对接下单
## 安装
```bash
git clone https://github.com/kingofmarketing/xian-guanjia.git
cd xian-guanjia
pip install requests
```
## 使用方法
### Python 代码调用
```python
from xian_guanjia import XianGuanjiaClient
client = XianGuanjiaClient(
app_id="your_app_id",
app_secret="your_app_secret",
mch_id="your_mch_id",
mch_secret="your_mch_secret"
)
# 查询订单列表
result = client.get_order_list(page=1, page_size=20)
print(result)
# 订单发货
result = client.ship_order(
order_id=12345,
logistics_no="7894561230",
logistics_company="顺丰速运"
)
# 查询余额
result = client.query_balance()
print(result)
```
### 命令行使用
```bash
python scripts/xian_guanjia.py \
--app-id YOUR_APP_ID \
--app-secret YOUR_APP_SECRET \
--mch-id YOUR_MCH_ID \
--mch-secret YOUR_MCH_SECRET
```
## 签名算法
闲管家使用 MD5 签名认证,本客户端已经自动处理签名,无需手动计算。
详细的签名规则参见 [SKILL.md](SKILL.md) 或 [references/api-docs.md](references/api-docs.md)
## 错误码
| 错误码 | 错误描述 |
| --- | --- |
| 0 | 请求成功 |
| 401 | 签名错误 |
| 403 | IP不在白名单 |
| 408 | 时间戳过期 |
| 1000 | 商户不存在 |
| 1002 | 余额不足 |
完整错误码参见 [references/api-docs.md](references/api-docs.md)
## 许可证
MIT License
## 相关链接
- 闲管家官网:https://goofish.pro
- API 文档:https://apifox.com/apidoc/shared-cf4d53fd-8bb2-41c5-8da3-371ba9a38956/doc-4985015
+100
View File
@@ -0,0 +1,100 @@
---
name: xian-guanjia
description: 闲管家 API 集成,用于闲鱼自动化发货、订单管理、商品发布。支持通过 API 批量处理订单、自动发货。Use when: (1) 需要操作闲管家 API,(2) 帮用户处理闲鱼订单发货,(3) 查询订单列表和余额,(4) 用户提到"闲管家"、"闲鱼自动发货"。
---
# 闲管家
闲管家 API 客户端,用于闲鱼自动化发货、订单管理和商品发布。
## API 文档
完整的 API 签名规则和错误码参见 [references/api-docs.md](references/api-docs.md)
## 使用方法
### 初始化客户端
```python
from scripts.xian_guanjia import XianGuanjiaClient
client = XianGuanjiaClient(
app_id="your_app_id",
app_secret="your_app_secret",
mch_id="your_mch_id",
mch_secret="your_mch_secret"
)
```
### 常用操作
**查询订单列表**
```python
result = client.get_order_list(page=1, page_size=20)
```
**查询订单详情**
```python
result = client.get_order_detail(order_id=12345)
```
**订单发货**
```python
result = client.ship_order(
order_id=12345,
logistics_no="物流单号",
logistics_company="快递公司"
)
```
**下单(货源对接)**
```python
result = client.place_order(
goods_no="商品编号",
goods_type=1, # 1-普通 2-虚拟
buyer_nick="买家昵称",
buyer_id="买家ID",
order_no="管家订单号",
price=29.90
)
```
**查询余额**
```python
result = client.query_balance()
```
## 响应格式
所有请求返回格式:
```json
{
"code": 0,
"msg": "OK",
"data": { ... }
}
```
- `code = 0` 表示成功
- 其他值表示失败,错误信息在 `msg`
## 错误码
详见 [references/api-docs.md](references/api-docs.md) 中的全局错误码说明。
## 命令行使用
```bash
python scripts/xian_guanjia.py \
--app-id YOUR_APP_ID \
--app-secret YOUR_APP_SECRET \
--mch-id YOUR_MCH_ID \
--mch-secret YOUR_MCH_SECRET
```
## 依赖
需要安装 requests:
```bash
pip install requests
```
+88
View File
@@ -0,0 +1,88 @@
# 闲管家 API 文档
## 接入说明
生产环境地址:https://open.goofish.pro
## 相关下载
- 闲管家省市区:
- https://file.goofish.pro/doc/闲管家省市区.xlsx
- https://file.goofish.pro/doc/闲管家省市区.sql
- 商品发布异常状态码及处理建议:
- 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. 闲管家所有参数都是强校验,需要严格按照文档的字段类型传参+返回
2. 返回结果 `code = 0` 才是成功,其他值表示失败
## 签名规则说明
### 签名参数说明
```
app_id:管家平台提供的对接应用ID
app_secret:管家平台提供的对接密钥
mch_id:货源平台提供的对接商户ID
mch_secret:货源平台提供的对接密钥
timestamp:发起请求时的时间戳(秒)
bodyString:POST原文字符串
```
### 签名生成示例
```python
app_id = 677859093659717
app_secret = wK63PxlOBaY9NoqMksLeZySzGIW25ifA
mch_id = 100
mch_secret = o9wl81dncmvby3ijpq7eur456zhgtaxs
timestamp = 1724414553
body = {"goods_type":1,"goods_no":"12344532"}
```
### 拼接签名参数
```python
// 接口采用MD5加密算法生成签名值
// 报文值 = md5(Json格式的Body报文)
bodyMd5 = md5({"goods_type":1,"goods_no":"12344532"})
// output:9b8030f5097d5ed123405b003dd247c5
// 接口无body参数时签名字符串(请求时body也需要传入相同的值)
// bodyMd5 = md5("{}") 或者 md5("")
// 签名值 = md5("管家应用ID,管家对接密钥,Body报文Md5值,时间戳,货源商户ID,货源对接密钥")
signMd5 = md5("677859093659717,wK63PxlOBaY9NoqMksLeZySzGIW25ifA,9b8030f5097d5ed123405b003dd247c5,1724414553,1001,o9wl81dncmvby3ijpq7eur456zhgtaxs")
// output:fda5954f48ab32b3b271c84450440ead
```
最终的签名值:`sign = fda5954f48ab32b3b271c84450440ead`
## 全局错误码说明
| 错误码 | 错误描述 |
| --- | --- |
| 0 | 请求成功 |
| 1 | 请求错误(不在定义范围内的错误) |
| 401 | 签名错误 |
| 403 | 访问IP不在IP白名单内 |
| 408 | 时间戳已超过有效期 |
| 500 | 系统异常,请重试 |
| 1000 | 商户不存在 |
| 1001 | 商户不可用 |
| 1002 | 商户余额不足 |
| 1100 | 商品不存在 |
| 1101 | 商品不可用 |
| 1102 | 商品库存不足 |
| 1200 | 订单不存在 |
| 1201 | 下单参数错误 |
| 1202 | 下单金额低于成本价 |
| 1203 | 下单管家订单号已存在 |
| 1209 | 下单超时,请查单确认下单结果 |
+228
View File
@@ -0,0 +1,228 @@
#!/usr/bin/env python3
"""
闲管家 API 客户端
用于通过 API 操作闲鱼自动发货、商品发布等功能
"""
import hashlib
import time
import json
import requests
from typing import Dict, Any, Optional
class XianGuanjiaClient:
"""闲管家 API 客户端"""
def __init__(self, app_id: str, app_secret: str, mch_id: str, mch_secret: str, base_url: str = "https://open.goofish.pro"):
"""
初始化客户端
Args:
app_id: 管家平台提供的对接应用ID
app_secret: 管家平台提供的对接密钥
mch_id: 货源平台提供的对接商户ID
mch_secret: 货源平台提供的对接密钥
base_url: API 基础地址,默认为生产环境
"""
self.app_id = app_id
self.app_secret = app_secret
self.mch_id = mch_id
self.mch_secret = mch_secret
self.base_url = base_url.rstrip('/')
def _generate_sign(self, body: Dict[str, Any]) -> Dict[str, Any]:
"""
生成签名
Args:
body: 请求体字典
Returns:
包含 timestamp 和 sign 的字典
"""
timestamp = int(time.time())
body_str = json.dumps(body, separators=(',', ':')) if body else "{}"
# 计算 body MD5
body_md5 = hashlib.md5(body_str.encode('utf-8')).hexdigest()
# 拼接签名字符串
sign_str = f"{self.app_id},{self.app_secret},{body_md5},{timestamp},{self.mch_id},{self.mch_secret}"
# 计算最终签名
sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest()
return {
'timestamp': timestamp,
'sign': sign
}
def request(self, method: str, path: str, body: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""
发送 API 请求
Args:
method: HTTP 方法 (GET, POST, etc.)
path: API 路径
body: 请求体数据
Returns:
API 响应 JSON
"""
if body is None:
body = {}
url = f"{self.base_url}{path}"
# 生成签名
sign_info = self._generate_sign(body)
# 将签名和时间戳添加到请求头
headers = {
'Content-Type': 'application/json',
'X-App-Id': str(self.app_id),
'X-Mch-Id': str(self.mch_id),
'X-Timestamp': str(sign_info['timestamp']),
'X-Sign': sign_info['sign']
}
response = requests.request(method, url, json=body, headers=headers, timeout=30)
response.raise_for_status()
return response.json()
def get_order_list(self, page: int = 1, page_size: int = 20) -> Dict[str, Any]:
"""
获取订单列表
Args:
page: 页码
page_size: 每页数量
Returns:
订单列表响应
"""
return self.request('POST', '/api/order/list', {
'page': page,
'page_size': page_size
})
def get_order_detail(self, order_id: int) -> Dict[str, Any]:
"""
获取订单详情
Args:
order_id: 订单ID
Returns:
订单详情响应
"""
return self.request('POST', '/api/order/detail', {
'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: 物流公司
Returns:
发货响应
"""
return self.request('POST', '/api/order/ship', {
'order_id': order_id,
'logistics_no': logistics_no,
'logistics_company': logistics_company
})
def get_product_list(self, page: int = 1, page_size: int = 20) -> Dict[str, Any]:
"""
获取商品列表
Args:
page: 页码
page_size: 每页数量
Returns:
商品列表响应
"""
return self.request('POST', '/api/product/list', {
'page': page,
'page_size': page_size
})
def place_order(self, goods_no: str, goods_type: int, buyer_nick: str,
buyer_id: str, order_no: str, price: float) -> Dict[str, Any]:
"""
下单(对接收货源)
Args:
goods_no: 商品编号
goods_type: 商品类型 1-普通 2-虚拟
buyer_nick: 买家昵称
buyer_id: 买家ID
order_no: 管家订单号
price: 下单价格
Returns:
下单响应
"""
return self.request('POST', '/api/order/place', {
'goods_no': goods_no,
'goods_type': goods_type,
'buyer_nick': buyer_nick,
'buyer_id': buyer_id,
'order_no': order_no,
'price': price
})
def query_balance(self) -> Dict[str, Any]:
"""
查询商户余额
Returns:
余额信息响应
"""
return self.request('POST', '/api/mch/balance', {})
def main():
"""
命令行交互示例
"""
import sys
import argparse
parser = argparse.ArgumentParser(description='闲管家 API 客户端')
parser.add_argument('--app-id', required=True, help='应用ID')
parser.add_argument('--app-secret', required=True, help='应用密钥')
parser.add_argument('--mch-id', required=True, help='商户ID')
parser.add_argument('--mch-secret', required=True, help='商户密钥')
parser.add_argument('--base-url', default='https://open.goofish.pro', help='API 地址')
args = parser.parse_args()
client = XianGuanjiaClient(
app_id=args.app_id,
app_secret=args.app_secret,
mch_id=args.mch_id,
mch_secret=args.mch_secret,
base_url=args.base_url
)
# 测试查询余额
try:
result = client.query_balance()
print(json.dumps(result, indent=2, ensure_ascii=False))
except Exception as e:
print(f"错误: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()