很多技术同学在选型时一看"京东API"就默认免费,结果大促前账单突然炸了——问题就出在把京东联盟(CPS)选品接口和宙斯(JOS)商家接口两套体系混为一谈。本文基于京东官方收费规则实测梳理,把账掰清楚。
一、先纠偏:京东API其实有"两套账"
京东开放体系下至少有两套相互独立的API体系,计费逻辑完全不同:
体系 | 代表接口 | 授权要求 | 计费逻辑 |
|---|---|---|---|
京东联盟(CPS) | jd.union.open.goods.query、jd.union.open.goods.detail.query | 联盟实名(无店铺) | 接口调用免费,成交后按类目抽佣 5%~20% |
宙斯 JOS 商家接口 | jingdong.ware.read.get、jingdong.pop.order.search、jingdong.etms.trace.get | 企业+卖家OAuth | 有日免费额度,超量按量计费 |
⚠️ 常见误判:"京东API免费"=只看联盟;"京东API贵"=把商家按量接口和联盟混算。两套账分开看,才是真实成本。
二、JOS商家接口:分层的按量计费
根据《京东商家开放平台收费规则》官方文档,接口按功能、安全性、数据价值分为免费API / 基础API / 增值API,其中基础类和增值类为收费API,所有增值类API未经平台允许禁止鼎外调用。
收费标准(鼎内 vs 鼎外价差10倍)
类型 | 说明 | 鼎内价格 | 鼎外价格 |
|---|---|---|---|
开放平台基础 | POP店铺交易、商品、库存基础功能 | ¥0.01/百次 | ¥0.1/百次 |
开放平台增值 | 营销引流、会员管理、经营分析 | ¥0.03/百次 | ¥0.3/百次 |
自营业务基础 | 自营商品、库存相关 | ¥0.02/百次 | ¥0.2/百次 |
自营业务增值 | 自营交易、消费者相关信息 | ¥0.06/百次 | ¥0.6/百次 |
品类业务基础 | 学习/直播/业绩等运营管理 | ¥0.05/百次 | — |
品类业务增值 | 交易/流量/财务等品类级数据 | ¥20000/百次 | — |
数据来源:京东商家开放平台官方收费规则
三个关键认知
- 免费额度是有的,但有上限:商品查询、订单同步、物流跟踪、库存快照等接口对企业应用通常有日免费额度,超量后才进入按量计费。免费≠无限制。
- 鼎内/鼎外价差10倍:同样的基础接口,部署在云鼎内调用是¥0.01/百次,公网直调是¥0.1/百次。ERP/中台系统务必迁云鼎,否则成本直接×10。
- 增值API禁鼎外调用:会员RFM、数据罗盘、竞品洞察等增值接口,未经平台允许不能在云鼎外调用,且多是包月/包年制(¥99~999/月级)。
电子面单的隐性成本
无界电子面单(
jingdong.etms.waybill.get)单独计费——按面单数计费,不计入API调用费。取消未揽收的面单不扣费,但已揽收的按单结算。这部分成本常被漏算。三、联盟接口:免费的背后是抽佣
京东联盟的选品/商品查询/佣金查询接口(
jd.union.open.*)备案后调用免费,但有两个隐性约束:- 成交抽佣:通过联盟链接成交的订单,按类目抽佣 5%~20%
- 数据粒度受限:联盟接口只返回"有货/无货"状态,看不到实时库存数字、SKU维度价格
所以"联盟免费"的真实含义是:用佣金换API调用费。适合选品/导购/CPS分发场景;不适合做商家自用ERP的库存同步。
四、2026年的两个变量
变量1:宙斯开发者中心融合迁移
2026-06-24 京东发布《关于宙斯开发者中心融合迁移的通知》,宙斯已从"接口开放平台"升级为"以开发者为中心的技术服务平台"。老接口
360buy.ware.get / jingdong.ware.get 已关闭新申请,需迁移到新版 jingdong.ware.read.get。变量2:QPS与免费额度收紧
个人开发者应用默认QPS很低(通常1~2/s),调订单/商品高频会返回
code=16 / ISP_FLOW_CONTROL_LIMIT。企业应用需购买QPS资源包才能提到50/100[site:5]。免费日额度企业应用通常数万~百万次/天,个人应用仅500~2000次/天。五、Python源码:JOS商品接口兼容封装(新老接口平滑迁移)
下面这段代码基于京东宙斯OAuth2.0 + MD5签名机制,兼容老接口
jingdong.ware.get 和新接口 jingdong.ware.read.get,可直接用于生产:import hashlib
import json
import time
import urllib.parse
import requests
from typing import Optional, Dict, Any
class JdJosClient:
"""
京东宙斯JOS API客户端
兼容老接口 jingdong.ware.get -> 新接口 jingdong.ware.read.get
"""
GW_PROD = "https://api.jd.com/routerjson"
GW_SANDBOX = "https://api.sandbox.jd.com/routerjson"
OAUTH_TOKEN_URL = "https://auth.jd.com/oauth/token"
OAUTH_AUTH_URL = "https://auth.jd.com/oauth/authorize"
def __init__(self, app_key: str, app_secret: str, sandbox: bool = False):
self.app_key = app_key
self.app_secret = app_secret
self.gw = self.GW_SANDBOX if sandbox else self.GW_PROD
# ─────────────────────────────────────────────
# 1. OAuth2.0 授权:构造授权URL(店铺主扫码)
# ─────────────────────────────────────────────
def build_auth_url(self, redirect_uri: str, state: str = "anti_csrf") -> str:
params = {
"response_type": "code",
"client_id": self.app_key,
"redirect_uri": redirect_uri,
"state": state,
}
return self.OAUTH_AUTH_URL + "?" + urllib.parse.urlencode(params)
# ─────────────────────────────────────────────
# 2. 用授权码换 access_token(有效期30天)
# ─────────────────────────────────────────────
def fetch_access_token(self, authorization_code: str, redirect_uri: str) -> Dict[str, Any]:
payload = {
"grant_type": "authorization_code",
"client_id": self.app_key,
"client_secret": self.app_secret,
"code": authorization_code,
"redirect_uri": redirect_uri,
}
resp = requests.post(self.OAUTH_TOKEN_URL, data=payload, timeout=10)
resp.raise_for_status()
return resp.json()
# ─────────────────────────────────────────────
# 3. MD5 签名(JOS标准:AppSecret + KV_ASCII排序 + AppSecret)
# ─────────────────────────────────────────────
def _sign(self, params: Dict[str, str]) -> str:
sorted_kv = sorted(params.items(), key=lambda x: x[0])
query = self.app_secret
for k, v in sorted_kv:
query += f"{k}{v}"
query += self.app_secret
return hashlib.md5(query.encode("utf-8")).hexdigest().upper()
# ─────────────────────────────────────────────
# 4. 通用调用
# ─────────────────────────────────────────────
def execute(self, method: str, access_token: str,
biz_params: Dict[str, Any],
is_cloud_inner: bool = True) -> Dict[str, Any]:
"""
:param method: 接口名,如 jingdong.ware.read.get
:param is_cloud_inner: 是否在云鼎内调用,影响计费档位
"""
ts = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
sys_params = {
"app_key": self.app_key,
"method": method,
"timestamp": ts,
"format": "json",
"v": "2.0",
"sign_method": "md5",
}
if access_token:
sys_params["access_token"] = access_token
# 业务参数拍平
all_params = dict(sys_params)
for k, v in biz_params.items():
all_params[k] = v if isinstance(v, str) else json.dumps(v)
all_params["sign"] = self._sign(all_params)
resp = requests.post(self.gw, data=all_params, timeout=10)
resp.raise_for_status()
return resp.json()
# ─────────────────────────────────────────────
# 5. 兼容封装:商品查询(老->新平滑切换)
# ─────────────────────────────────────────────
def get_ware(self, access_token: str, ware_id: str,
use_new_api: bool = True,
fields: Optional[str] = None) -> Dict[str, Any]:
"""
老: jingdong.ware.get
新: jingdong.ware.read.get(2026推荐)
"""
method = "jingdong.ware.read.get" if use_new_api else "jingdong.ware.get"
biz = {"wareId": ware_id}
if fields:
biz["fields"] = fields
elif use_new_api:
# 新接口建议补全fields,包含sku库存
biz["fields"] = "wareId,title,price,skus_json,stock_num"
return self.execute(method, access_token, biz)
# ─────────────────────────────────────────────
# 6. 订单查询(按量计费接口示例)
# ─────────────────────────────────────────────
def search_pop_order(self, access_token: str,
start_time: str, end_time: str,
page: int = 1, page_size: int = 100) -> Dict[str, Any]:
"""
jingdong.pop.order.search —— 属于开放平台基础API,鼎内0.01元/百次
"""
biz = {
"startTime": start_time,
"endTime": end_time,
"page": page,
"pageSize": page_size,
}
return self.execute("jingdong.pop.order.search", access_token, biz)
# ─────────────────────────────────────────────
# 使用示例
# ─────────────────────────────────────────────
if __name__ == "__main__":
client = JdJosClient(
app_key="YOUR_APP_KEY",
app_secret="YOUR_APP_SECRET",
sandbox=False, # 生产环境置False
)
# Step 1: 构造授权URL,给店铺主扫码
auth_url = client.build_auth_url("https://your-callback.url")
print(f"请店铺主访问授权URL: {auth_url}")
# 店铺主扫码授权后,回调拿到 authorization_code
# Step 2: 换取 access_token
# token_data = client.fetch_access_token("AUTH_CODE", "https://your-callback.url")
# access_token = token_data["access_token"]
access_token = "YOUR_ACCESS_TOKEN" # 实际项目中从Step 2获取
# Step 3: 调用商品接口(新接口)
result = client.get_ware(
access_token=access_token,
ware_id="100012345678",
use_new_api=True,
)
print(json.dumps(result, ensure_ascii=False, indent=2))代码要点说明
- 签名算法:JOS采用
MD5(AppSecret + 参数KV按ASCII升序拼接 + AppSecret)的标准签名,最后转大写 - 接口迁移:只需改
method字符串 + 补全fields(skus_json,stock_num),Client/签名/网关/token一行不动 - 云鼎内调用:
is_cloud_inner=True时计费率下降10倍,生产环境ERP务必部署在云鼎内 - token有效期:access_token有效期30天,需做好刷新机制
六、成本测算:什么规模该花多少钱
场景 | 预估月调用量 | 月成本估算 |
|---|---|---|
单店自用(日单<100) | <3万次 | ¥0(在免费额度内) |
中型ERP(10~50店) | 50~200万次 | 鼎内≈¥50~200;鼎外≈¥500~2000 |
跨平台SaaS(千店级) | 2000万+次 | 必须迁云鼎+买QPS包,月¥2000~10000+ |
联盟选品调用 | 不限 | 接口费¥0,成交抽佣5~20% |
💡 省流建议:
单店自用 → 免费额度够用,别花冤枉钱 多店ERP → 必须迁云鼎,否则鼎外×10倍费率 增值数据/CRM → 走包月/包年,别按量硬刷 联盟接口只做选品/导购,别指望拿库存数据
七、写在最后的避坑清单
⚠️ 上线前务必核对这5件事:
接口类型确认:调的接口是免费/基础/增值哪一类?价格档位差30倍 鼎内/鼎外确认:应用是否部署在云鼎?差价10倍 日免费额度监控:企业应用通常30万~100万次/天,超量前要有告警 QPS资源包:个人默认1~2/s,企业高频需购包提至50/100 老接口迁移:jingdong.ware.get已停新申请,2026年必须切到jingdong.ware.read.get
数据口径说明:本文收费数字综合自京东商家开放平台官方收费规则与2026年开发者实测,联盟抽佣比例、具体免费额度上限等平台保留调整权,生产环境请以宙斯开发者中心最新公告为准。
多平台横向对比:京东这套"联盟免费+商家按量+鼎外×10"的结构,在淘宝TOP/1688/拼多多/抖店里都能找到影子——下一期我们把五家《2026电商API免费额度&收费对照表》完整拆解,看看同样一笔订单同步,在五家分别要花多少钱。关注不迷路。