背景
对接抖店开放平台的订单接口,通常需要先处理 OAuth2.0 授权、请求签名、参数规范等一整套流程。对于只想快速拿到订单数据的开发者来说,这部分工作量不小。
本文以某第三方封装的抖店订单列表接口为示例,分享如何用 Python 调用这类接口,以及封装时需要注意的几个技术点。示例接口来源于小于科技的公开接口文档,其参数设计有一定的参考价值。
文章重点在调用思路和封装方法,不涉及具体产品的注册和使用引导。
一、接口概览
示例接口的定位是“简化版订单列表查询”,把官方复杂的授权和签名逻辑收敛到服务端,对上暴露一个普通的 HTTP POST 接口。
接口地址格式:
{host_prefix}/api/doudian/order/searchlist
请求方式: POST,Content-Type: application/json
核心参数:
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
| appId | 是 | string | 应用 AppId |
| appSecret | 是 | string | 应用 AppSecret |
| platformShopId | 是 | string | 店铺 ID |
| filter | 否 | object | 查询条件 |
| pageIndex | 否 | int | 页码,默认 1 |
| pageSize | 否 | int | 每页记录数,默认 20 |
filter 支持的查询条件:
| 参数名 | 类型 | 说明 |
|---|---|---|
| order_status | string | 订单状态:unpaid / stock_up / on_delivery / received / closed |
| aftersale_status | string | 售后状态:aftersale_close / have_aftersale / refund_success / in_aftersale |
| order_by | string | 排序字段:create_time / update_time / ship_time |
| sort | string | 排序方向:desc / asc |
| order_id | string | 订单编号 |
| product | string | 商品名称或 ID |
| create_time_start | string | 下单开始时间(秒级时间戳) |
| create_time_end | string | 下单结束时间(秒级时间戳) |
| close_time_start | string | 完成开始时间(秒级时间戳) |
| close_time_end | string | 完成结束时间(秒级时间戳) |
请求示例:
{
"appId": "******",
"appSecret": "********",
"platformShopId": "doudian_xxxxxxxxx",
"filter": {
"order_status": "stock_up"
},
"pageIndex": 1,
"pageSize": 20
}
二、Python 调用示例
2.1 基础调用
用 requests 发起请求:
import requests
def fetch_orders(host, app_id, app_secret, shop_id, page_index=1, page_size=20, **filters):
url = f"{host}/api/doudian/order/searchlist"
payload = {
"appId": app_id,
"appSecret": app_secret,
"platformShopId": shop_id,
"pageIndex": page_index,
"pageSize": page_size,
}
if filters:
payload["filter"] = filters
resp = requests.post(url, json=payload, timeout=10)
resp.raise_for_status()
return resp.json()
调用:
result = fetch_orders(
host="https://your-host",
app_id="your_app_id",
app_secret="your_app_secret",
shop_id="doudian_xxxxxxxxx",
order_status="stock_up",
)
print(result)
2.2 分页拉取封装
订单列表通常需要翻页拉全量。封装一个生成器,逐页返回:
def iter_orders(host, app_id, app_secret, shop_id, page_size=100, **filters):
page_index = 1
while True:
data = fetch_orders(
host, app_id, app_secret, shop_id,
page_index=page_index,
page_size=page_size,
**filters,
)
orders = data.get("data", {
}).get("orders", [])
if not orders:
break
yield from orders
if len(orders) < page_size:
break
page_index += 1
使用:
for order in iter_orders(
host, app_id, app_secret, shop_id,
order_status="stock_up",
create_time_start="1722441600",
create_time_end="1722528000",
):
print(order["order_id"])
2.3 时间参数的处理
接口的下单时间、完成时间都用秒级时间戳。Python 里用 datetime 转换时要注意时区:
from datetime import datetime, timezone
def to_timestamp(dt: datetime) -> str:
"""将 datetime 转为秒级时间戳字符串(UTC)"""
return str(int(dt.replace(tzinfo=timezone.utc).timestamp()))
# 示例:2024-08-01 00:00:00 UTC
start = to_timestamp(datetime(2024, 8, 1, 0, 0, 0))
print(start) # 1722470400
如果业务侧用的是本地时间(如东八区),转换前需要先减去时差,避免查询范围偏移 8 小时。
三、封装时的几个注意点
3.1 凭证不要硬编码
appId 和 appSecret 属于敏感信息,不要直接写在代码里。推荐用环境变量或配置中心:
import os
APP_ID = os.environ["DOUDIAN_APP_ID"]
APP_SECRET = os.environ["DOUDIAN_APP_SECRET"]
SHOP_ID = os.environ["DOUDIAN_SHOP_ID"]
3.2 控制分页大小
接口的 pageSize 通常有上限(示例接口支持 10、20、50、100)。拉全量数据时建议用 100,减少请求次数;但也要注意单次响应体大小,避免超时。
3.3 处理限流和重试
第三方接口一般也有频率限制。拉取大量订单时,建议加入退避重试:
import time
def fetch_with_retry(fetch_func, max_retry=3, **kwargs):
for attempt in range(max_retry):
try:
return fetch_func(**kwargs)
except requests.HTTPError as e:
if e.response.status_code == 429 and attempt < max_retry - 1:
time.sleep(2 ** attempt)
continue
raise
3.4 数据落库前做去重
分页拉取过程中,如果订单状态发生变化,可能出现同一条订单被重复拉取。落库时建议以 order_id 为唯一键做 upsert,避免重复。
四、总结
本文以一个第三方封装的抖店订单列表接口为例,分享了 Python 调用的基本方法和封装思路。核心要点:
- 接口把授权和签名收敛到服务端,调用方只需传业务参数
- 分页拉取建议用生成器封装,避免一次性加载全量数据
- 时间参数注意时区转换
- 凭证走环境变量,不要硬编码
- 加退避重试和落库去重,提升稳定性
这类封装接口的价值在于降低接入门槛,适合不想在授权和签名上投入过多时间的场景。如果业务对接口有深度定制需求,直接对接官方平台仍然更灵活。