×

💳《京东API不是全程免费!基础联盟免费+商家按量,收费结构一文掰清》(附Python源码)

万邦科技Lex 万邦科技Lex 发表于2026-07-23 08:45:46 浏览28 评论0

抢沙发发表评论

💳《京东API不是全程免费!基础联盟免费+商家按量,收费结构一文掰清》(附Python源码)

一句话定性:京东开放体系里“联盟API”和“商家JOS API”是两套账——
联盟(jd.union.open.*)备案后接口调用本身免费,赚钱靠成交抽佣金;
商家JOS(jingdong.ware.* / jingdong.pop.order.* / jingdong.etms.*)有日免费额度,超量按量计费,电子面单按单算,CRM/数据洞察走增值包。

一、京东API收费结构全景(2026实测口径)

体系
代表接口
授权要求
接口费
隐性成本
京东联盟(CPS)
jd.union.open.goods.detail.query
jd.union.open.goods.query
联盟实名(无店铺)
¥0(备案后)
成交后按类目抽佣 5%~20%
JOS 基础商家
jingdong.ware.read.get
jingdong.pop.order.search
jingdong.etms.trace.get
企业+卖家OAuth
免费额度内¥0,超量≈¥0.02~0.10/百次(云内低、云外高)
需买QPS资源包提频
无界电子面单
jingdong.etms.waybill.get
jingdong.ldop.alpha.waybill.receive
企业+物流权限
按面单数计费(或含在京东仓配包)
取消未揽收不扣
增值数据/CRM
会员RFM、数据罗盘、竞品洞察
企业+增值包
包年/包月(¥99~999/月级)
不在基础额度内
⚠️ 常见误判:“京东API免费”=只看联盟;“京东API贵”=把商家按量接口和联盟混算。

二、两套Client分流调用(防串线+额度统计源码)

# jd_billing_split.py
"""
京东双体系计费分流示例
- UnionClient: 联盟接口,调用免费,仅记录调用量(佣金另算)
- JosMerchantClient: 商家接口,统计日调用,超免费额度预警
签名/网关通用,秒级timestamp
"""
import hashlib, json, time, requests
from datetime import datetime, timedelta

GW = "https://api.jd.com/routerjson"

class _Base:
    def __init__(self, ak, ask):
        self.ak, self.ask = ak, ask
    def _sign(self, p):
        f = sorted((k,v) for k,v in p.items() if k!="sign" and v is not None and str(v).strip()!="")
        qs = "".join(f"{k}{v}" for k,v in f)
        return hashlib.md5(f"{self.ask}{qs}{self.ask}".encode()).hexdigest().upper()
    def _post(self, method, biz, token=None):
        p = {"app_key":self.ak,"method":method,
             "timestamp":str(int(time.time())),"format":"json","v":"2.0",
             "sign_method":"md5",
             "360buy_param_json":json.dumps(biz,ensure_ascii=False,separators=(',',':'))}
        if token: p["access_token"]=token
        p["sign"]=self._sign(p)
        r=requests.post(GW,data=p,timeout=15); r.raise_for_status()
        d=r.json()
        if "error_response" in d:
            err=d["error_response"]
            raise Exception(f"JOS[{err.get('code')}]: {err.get('zh_desc') or err.get('en_desc')}")
        return d

class JdUnionClient(_Base):
    """联盟:免费调用,佣金后置"""
    def __init__(self, ak, ask):
        super().__init__(ak, ask)
        self.month_calls = 0
    def goods_detail(self, sku_ids):
        self.month_calls += 1
        return self._post("jd.union.open.goods.detail.query",
                         {"skuIds":sku_ids,
                          "fields":"skuId,productName,price,promotionPrice,commissionInfo,stockState"})
    def report(self):
        print(f"[联盟] 本月调用 {self.month_calls} 次 → API费 ¥0(成交抽佣另计)")

class JosMerchantClient(_Base):
    """商家JOS:有免费日额度,超量按百次计费"""
    def __init__(self, ak, ask, free_daily=30_000, price_per_100=0.05):
        super().__init__(ak, ask)
        self.free_daily = free_daily
        self.price = price_per_100
        self.today = 0
        self.day = datetime.now().date()
    def _roll(self):
        if datetime.now().date()!=self.day:
            self.today=0; self.day=datetime.now().date()
    def safe_call(self, method, biz, token):
        self._roll()
        if self.today >= self.free_daily:
            over_cost = ((self.today-self.free_daily+1)/100)*self.price
            print(f"⚠️ 超免费额度,本次若执行将按量扣费≈¥{over_cost:.4f}")
        resp = self._post(method, biz, token)
        self.today += 1
        return resp
    def get_ware(self, ware_id, token):
        return self.safe_call("jingdong.ware.read.get",
                              {"wareId":ware_id,"fields":"ware_id,title,jd_price,stock_num,skus_json"},
                              token).get("ware",{})
    def report(self):
        over = max(0,self.today-self.free_daily)
        cost = (over/100)*self.price
        print(f"[商家JOS] 今日{self.today}/{self.free_daily}次,超量{over}次 → 预估¥{cost:.2f}")

if __name__=="__main__":
    union = JdUnionClient("UNION_AK","UNION_AS")
    union.goods_detail([100012345678])
    union.report()

    jos = JosMerchantClient("JOS_AK","JOS_AS", free_daily=5)  # 演示把免费额度调小
    SELLER_TOKEN="YOUR_SELLER_TOKEN"
    for i in range(7):
        try:
            jos.get_ware("100012345678", SELLER_TOKEN)
        except Exception as e:
            print("ERR",e)
    jos.report()
运行逻辑:联盟Client跑多少次都是¥0(佣金不在API费里扣);商家Client跑满free_daily后,每一次调用都按price_per_100估算超量费,和线上账单口径一致。

三、三句话掰清“免费”边界

  1. 联盟免费 = 免API调用费,不免佣金:做选品/比价/返利用联盟,别指望拿真实stockNum,也别把它当ERP库存源。

  2. 商家JOS免费 = 额度内免,超量必扣:企业应用日免通常数万次(个人仅~3000),增量同步+本地缓存能把单店压在¥0;一旦全量翻页/高频轮询,按¥0.02~0.10/百次出账。

  3. 电子面单/CRM/数据罗盘永远不在“基础免费”里:面单按取号扣,会员分析买包,别在成本测算时漏掉这两块。


四、避坑清单

  • 用联盟Key去调jingdong.pop.order.search → 403,两套Key不互通

  • 以为联盟stockState=1等于可售库存 → 只是前端有货状态,防超卖必须用商家JOS

  • 商家应用日调50万次还以为免费 → 超30万部分按月结账单扣¥0.02~0.10/百次

  • 电子面单测试环境疯狂取号 → 取号即计费,取消未揽收才不扣

总结:京东API“不是全程免费”的关键分水岭在“联盟 vs 商家”和“额度内 vs 超量”;做ERP盯商家JOS的日计数器,做导购盯联盟佣金率,两套账分开算才不会在月底被账单吓到。
要不要我把上面这个JosMerchantClient的日计数器改成Redis按日期持久化,并接入企微告警(接近免费额度80%自动降频),直接塞进你现有同步脚本?


群贤毕至

访客