🔑《九家电商API认证门槛对照:个人号能调哪些?企业号能调哪些?》(附Python源码)
一、九家认证门槛总表(2026现行)
平台 | 个人号 | 个体工商户 | 企业号 | 核心限制 |
|---|---|---|---|---|
淘宝TOP | ✅ 基础读(自研应用) | ✅ 全接口 | ✅ 全接口+奇门 | 个人不能"发布/交易/解密",部分API需店铺实人认证 |
1688 | ⚠️ 部分读(验签受限) | ✅ | ✅ | 个人号AppKey验签易失败;API权限包按场景买 |
京东JOS | ❌ 仅沙箱 | ⚠️ 有限 | ✅ 全接口 | 商家Key需企业认证+OAuth卖家token |
拼多多 | ❌ | ⚠️ 自用型 | ✅ 全接口 | 个人只能"自用型开发者",不能上架工具 |
抖店 | ❌ | ✅(需实名+保证金) | ✅ 全接口 | 开通服务市场/开放平台需主体认证+类目保证金 |
快手 | ❌ | ✅ | ✅ | 需开放平台认证+应用审核 |
微店 | ❌(仅开微店+轻量) | ✅ | ✅ | 重同步需企业买包 |
苏宁 | ❌ | ⚠️ | ✅ | 开放平台主体认证 |
亚马逊SP-API | ❌(无个人号概念) | ⚠️(可注册SPP开发者) | ✅ 主用 | 必须AWS IAM + LWA,无个人买家号直接调用 |
规律:读类(商品/搜索)普遍放宽到个人/个体,写类(订单/库存/发货/解密/广告/财务)一律锁企业主体 + 保证金 + 类目。 认证门槛的本质是"责任可追溯"——平台需要知道出了事能找谁赔。
二、最容易踩的三个认证坑
坑1:淘宝个人号"能读不能写"
taobao.item.get / taobao.trades.sold.get 等读自己店铺可用,但:taobao.item.add/taobao.skus.quantity.update→ 返回permission deniedtaobao.trade.fullinfo.get(含收货地址解密) → 需"御城河+敏感字段权限",仅企业奇门(QIMEN)接口 → 必须企业+服务商资质
坑2:1688个人号验签玄学失败
Invalid signature且无规律——本质是没买"API权限包"。个人号只能调不收费的基础读,一碰付费/高级接口就403。坑3:亚马逊"个人卖家号"调不了SP-API
注册为 Selling Partner Developer(2025 SPP 合并后一个控制台)
创建 SP-API Application(选择 Use Case / 角色)
用 AWS IAM Role(推荐)或 IAM User 持有
AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEYLWA 凭证(
LWA_CLIENT_ID/LWA_CLIENT_SECRET/REFRESH_TOKEN)对目标 marketplace 授权(OAuth 授权码换 refresh_token)
个人号在SP-API语境下根本不存在——如果你只有"买家账号"或"个人卖家账号",第一步注册开发者就会卡主体。
三、Python:CertGuard(认证门槛守卫 + 启动自检)
# cert_guard.py
"""
九家电商API 认证门槛守卫
- 主体类型 × 应用类型 × 接口族 → 是否允许调用
- 启动自检:一次性校验所有已配置Key的主体/权限合法性
- 亚马逊特殊处理:必须是 AWS IAM + LWA(无个人号概念)
"""
from enum import Enum
from dataclasses import dataclass, field
from typing import Dict, List, Tuple
class EntityType(Enum):
PERSONAL = "personal" # 个人
INDIVIDUAL = "individual" # 个体户
ENTERPRISE = "enterprise" # 企业
class AppType(Enum):
SELF_USE = "self_use" # 自研/自用型
THIRD_PARTY = "third_party" # 三方/工具型
SERVICE_PROVIDER = "sp" # 服务商/ISV
# 接口族所需的最低主体/应用门槛
# (最低EntityType, 是否必须企业, 是否必须服务商)
REQUIREMENTS = {
"taobao": {
"read_self": (EntityType.PERSONAL, False, False), # 读自己店铺
"read_public": (EntityType.PERSONAL, False, False), # 商品搜索等公开读
"trade_read": (EntityType.ENTERPRISE, True, False), # 订单/解密
"write": (EntityType.ENTERPRISE, True, False), # 发布/库存回写
"qimen": (EntityType.ENTERPRISE, True, True), # 奇门
},
"1688": {
"read_basic": (EntityType.PERSONAL, False, False),
"paid_pack": (EntityType.ENTERPRISE, True, False), # 高级/实时库存
},
"jd": {
"sandbox": (EntityType.PERSONAL, False, False),
"jos_normal": (EntityType.ENTERPRISE, True, False),
},
"pdd": {
"self_use": (EntityType.INDIVIDUAL, False, False), # 个体可申请自用型
"tool": (EntityType.ENTERPRISE, True, True), # 工具上架必须企业+ISV
},
"douyin": {
"basic": (EntityType.ENTERPRISE, True, False), # 抖店需主体+保证金
},
"kuaishou": {
"basic": (EntityType.ENTERPRISE, True, False),
},
"weidian": {
"basic": (EntityType.ENTERPRISE, True, False),
},
"suning": {
"basic": (EntityType.ENTERPRISE, True, False),
},
"amazon": {
# 亚马逊:不分个人/企业,只看"是否完成SPP开发者注册 + IAM + LWA"
"sp_api": (EntityType.ENTERPRISE, True, False), # 占位,实际由aws_iam_present覆盖
},
}
@dataclass
class AppCredential:
platform: str
entity: EntityType
app_type: AppType
has_bond: bool = False # 是否缴保证金
has_api_pack: bool = False # 是否买API权限包(1688)
# 亚马逊专用
aws_iam_present: bool = False # 是否有 IAM Role/User + AccessKey
lwa_present: bool = False # 是否有 LWA 凭证 + refresh_token
authorized_marketplaces: List[str] = field(default_factory=list)
@property
def is_enterprise(self) -> bool:
return self.entity == EntityType.ENTERPRISE
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
class CertGuard:
def __init__(self):
self.rules = REQUIREMENTS
def check(self, cred: AppCredential, api_family: str) -> Tuple[bool, str]:
# ---- 亚马逊:IAM + LWA 特殊流程 ----
if cred.platform == "amazon":
if not cred.aws_iam_present:
return False, "亚马逊SP-API必须配置AWS IAM Role/User(AccessKey)"
if not cred.lwa_present:
return False, "亚马逊SP-API必须配置LWA凭证(ClientID+Secret+RefreshToken)"
if not cred.authorized_marketplaces:
return False, "尚未对目标marketplace完成OAuth授权(无refresh_token)"
return True, "OK"
# ---- 其他平台:查表 ----
family_map = self._family(cred.platform, api_family)
req = self.rules.get(cred.platform, {}).get(family_map)
if req is None:
return False, f"未配置 {cred.platform}/{family_map} 的权限规则"
min_entity, must_enterprise, must_sp = req
# 主体等级检查
if must_enterprise and not cred.is_enterprise:
return False, f"{cred.platform} {family_map} 要求企业主体(当前{cred.entity.value})"
if not self._entity_ge(cred.entity, min_entity):
return False, f"{cred.platform} {family_map} 最低要求{min_entity.value}(当前{cred.entity.value})"
# 服务商检查
if must_sp and cred.app_type not in (AppType.SERVICE_PROVIDER, AppType.THIRD_PARTY):
return False, f"{cred.platform} {family_map} 要求服务商/ISV资质"
# 保证金
if must_enterprise and not cred.has_bond:
return False, f"{cred.platform} 企业主体需缴类目保证金(has_bond=False)"
# 1688权限包
if cred.platform == "1688" and family_map == "paid_pack" and not cred.has_api_pack:
return False, "1688高级/实时库存需购买API权限包"
return True, "OK"
def _family(self, platform: str, api_family: str) -> str:
"""把通用api_family映射到平台具体档位"""
if platform == "taobao":
m = {"read": "read_self", "public": "read_public", "order": "trade_read",
"stock": "write", "publish": "write"}.get(api_family, api_family)
return m
if platform == "1688":
return "paid_pack" if api_family in ("stock_realtime", "value") else "read_basic"
if platform == "pdd":
return "tool" if api_family in ("tool", "publish") else "self_use"
if platform in ("douyin", "kuaishou", "weidian", "suning"):
return "basic"
if platform == "jd":
return "sandbox" if api_family == "sandbox" else "jos_normal"
return api_family
def _entity_ge(self, a: EntityType, b: EntityType) -> bool:
order = {EntityType.PERSONAL: 0, EntityType.INDIVIDUAL: 1, EntityType.ENTERPRISE: 2}
return order.get(a, 0) >= order.get(b, 0)
# ---- 启动自检:返回所有不通过项 ----
def self_check(self, credentials: List[AppCredential]) -> Dict:
report = {"pass": [], "fail": []}
for c in credentials:
for family in self._all_families(c.platform):
ok, msg = self.check(c, family)
row = {"platform": c.platform, "entity": c.entity.value,
"app_type": c.app_type.value, "api_family": family, "msg": msg}
report["pass" if ok else "fail"].append(row)
return report
def _all_families(self, platform: str) -> List[str]:
if platform == "amazon":
return ["sp_api"]
return list(self.rules.get(platform, {}).keys())
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# ==================== 演示 ====================
if __name__ == "__main__":
guard = CertGuard()
cases = [
# 淘宝个人号:读OK,写/解密/奇门NO
(AppCredential("taobao", EntityType.PERSONAL, AppType.SELF_USE, has_bond=False),
["read", "order", "publish", "qimen"]),
# 1688个人号:基础读OK,实时库存需企业+包
(AppCredential("1688", EntityType.PERSONAL, AppType.SELF_USE, has_api_pack=False),
["read", "stock_realtime"]),
# 1688企业号买了包
(AppCredential("1688", EntityType.ENTERPRISE, AppType.SELF_USE, has_bond=True, has_api_pack=True),
["read", "stock_realtime"]),
# 拼多多个体自用型:自用OK,工具上架NO
(AppCredential("pdd", EntityType.INDIVIDUAL, AppType.SELF_USE),
["self_use", "publish"]),
# 亚马逊:缺IAM/缺LWA/缺授权 三种失败 + 全配OK
(AppCredential("amazon", EntityType.ENTERPRISE, AppType.SELF_USE,
aws_iam_present=False, lwa_present=False, authorized_marketplaces=[]),
["sp_api"]),
(AppCredential("amazon", EntityType.ENTERPRISE, AppType.SELF_USE,
aws_iam_present=True, lwa_present=False, authorized_marketplaces=[]),
["sp_api"]),
(AppCredential("amazon", EntityType.ENTERPRISE, AppType.SELF_USE,
aws_iam_present=True, lwa_present=True,
authorized_marketplaces=["ATVPDKIKX0DER"]),
["sp_api"]),
]
print("=== 逐条校验 ===")
for cred, families in cases:
for fam in families:
ok, msg = guard.check(cred, fam)
tag = "✅" if ok else "❌"
print(f"{tag} {cred.platform:<8} {cred.entity.value:<10} {fam:<14} {msg}")
print("\n=== 启动自检(示例配置集)===")
all_creds = [
AppCredential("taobao", EntityType.PERSONAL, AppType.SELF_USE),
AppCredential("1688", EntityType.ENTERPRISE, AppType.SELF_USE, has_api_pack=True),
AppCredential("pdd", EntityType.ENTERPRISE, AppType.SERVICE_PROVIDER, has_bond=True),
AppCredential("douyin", EntityType.ENTERPRISE, AppType.SELF_USE, has_bond=True),
AppCredential("amazon", EntityType.ENTERPRISE, AppType.SELF_USE,
aws_iam_present=True, lwa_present=True,
authorized_marketplaces=["ATVPDKIKX0DER", "A1F83G8C2ARO7P"]),
]
rep = guard.self_check(all_creds)
print(f"通过 {len(rep['pass'])} 项,不通过 {len(rep['fail'])} 项")
for f in rep["fail"][:10]:
print(f" ❌ {f['platform']} {f['entity']} {f['api_family']}: {f['msg']}")✅ taobao personal read OK ❌ taobao personal order 亚马逊SP-API... ← 淘宝个人号不能读交易 ❌ taobao personal publish ...要求企业主体 ❌ taobao personal qimen ...要求服务商/ISV ✅ 1688 enterprise stock_realtime OK ← 企业+买包后才行 ❌ amazon ... aws_iam_present=False 亚马逊SP-API必须配置AWS IAM Role/User ❌ amazon ... lwa_present=False 亚马逊SP-API必须配置LWA凭证 ✅ amazon ... sp_api OK ← IAM+LWA+授权三件套齐全
四、九家认证"最小可用主体"速查(落地用)
你想干的事 | 最小主体 | 备注 |
|---|---|---|
爬淘宝/1688商品公开数据 | 个人号 | 限频严、不能商用 |
管自己淘宝/1688店铺(读订单) | 个体户 | 淘宝需实人认证 |
淘宝/1688 发布商品、库存回写 | 企业 | 部分需保证金 |
淘宝订单地址解密/奇门 | 企业 + 服务商资质 | 御城河审核 |
拼多多自用ERP(管自己店) | 个体户 | 申请"自用型开发者" |
拼多多做SaaS工具给别人用 | 企业 + ISV | 需应用市场审核 |
抖店/快手/微店/苏宁 任何正式调用 | 企业(抖店/快手个体可试) | 主体认证+类目保证金 |
亚马逊SP-API | IAM + LWA(无个人号) | 开发者注册+Use Case+IAM Role+授权 |
五、四个认证配置铁律
个人号只配"只读公开数据",代码层把个人Key绑死到
read/public族,一旦调order/publish在ApiGateway.call()入口就被CertGuard拦——别等线上返回permission denied才暴露。企业号必须缴保证金再调写接口,
has_bond=False的调用一律前置拦截,避免"调通了但平台事后追责冻结Key"。亚马逊单独走
aws_iam_present + lwa_present + authorized_marketplaces三件套校验,不要复用"个人/企业"枚举——它的认证语义是IAM主体 + OAuth授权,和国内"营业执照"体系完全两套。启动自检进CI:把
CertGuard.self_check()挂到服务启动时跑一遍,配置错了直接exit(1),禁止"带非法Key上线"。
六、和前几篇的衔接
把CertGuard装到前篇ApiGateway.call()的第一道闸(在CloudResidencyGuard/TripleGuardClient之前):
签名/限流都建立在"认证合法"之上,认证不合法调了也是白调甚至违规;
CertGuard.self_check()复用前篇配置中心已注册的九家AppKey,启动时一次性出"哪些Key能调哪些接口族"矩阵;亚马逊段的三件套校验(
aws_iam_present/lwa_present/authorized_marketplaces)直接喂给前篇LWASigV4Strategy,缺哪个凭证启动时明确报错,不再等到第一次call()才401。
认证门槛是九家中台的"准入层"——它不做成本优化、不做限流,只回答一个问题:这个Key有没有资格调这个接口。把它独立成一个Guard,比把逻辑散在九个Adapter里可维护十倍。
cert_guard.py 和前八篇的 CloudResidencyGuard / TripleGuardClient / FreeTierProbe / JdKeyTypeGuard 统一收口成 commerce-mesh/guards/ 中间件链——CertGuard → ResidencyGuard → KeyTypeGuard → QuotaGuard → CostAttributor 一次装配,配置驱动、启动自检、调用时按序拦截?