[特殊字符]《京东JOS宙斯迁移实录:jingdong.ware.get → jingdong.ware.read.get 平滑切(2026版)》(附Python源码)
《京东JOS宙斯迁移实录jingdong.ware.get→jingdong.ware.read.get平滑切2026版》附Python源码京东宙斯JOS在2024~2026年间持续推进接口标准化老接口jingdong.ware.get及别名360buy.ware.get已进入维护期新应用不再支持申请官方推荐统一迁移至jingdong.ware.read.get只读商品读取接口权限更清晰、支持SKU快照字段。迁移只需改method 微调fields网关/签名/AccessToken完全不变下面给你一份可直接执行的平滑切换实录。一、老 vs 新接口对照一目了然维度老接口即将下线新接口推荐Methodjingdong.ware.get/360buy.ware.get✅jingdong.ware.read.get网关https://api.jd.com/routerjson完全相同签名算法MD5(AppSecretKV_ASCIIAppSecret) 秒级timestamp完全相同一行不改必传参数wareId,fields完全相同wareId,fields返回根节点jingdong_ware_get_response.warejingdong_ware_read_get_response.wareSKU库存可见需传seller token相同传seller token可看stockNuminskus_json权限申请老入口已关闭新申请应用→接口权限→申请jingdong.ware.read.get即时生效✅迁移量代码中只改method 字符串 fields 补全skus_json,stock_num其余Client/签名/网关/token一行不动。二、Python老接口 vs 新接口调用对比 兼容封装# jd_ware_migration_2026.py 京东JOS宙斯迁移实录 old: jingdong.ware.get → new: jingdong.ware.read.get 同一个 JdClient 复用仅 method fields 不同 支持 沙箱/生产 切换 import hashlib import json import requests import time from typing import Dict, Optional 封装好API供应商demo urlhttps://console.open.onebound.cn/console/?iLex class JdWareClient: 京东JOS商品接口客户端兼容新旧两套 GW_PROD https://api.jd.com/routerjson GW_SANDBOX https://api.sandbox.jd.com/routerjson def __init__(self, app_key: str, app_secret: str, sandbox: bool False): self.ak app_key self.ask app_secret self.gw self.GW_SANDBOX if sandbox else self.GW_PROD # ───── JOS MD5签名秒级timestamp紧凑JSON───── def _sign(self, params: Dict) - str: filt sorted( (k, v) for k, v in params.items() if k ! sign and v is not None and str(v).strip() ! ) qs .join(f{k}{v} for k, v in filt) raw f{self.ask}{qs}{self.ask} return hashlib.md5(raw.encode(utf-8)).hexdigest().upper() def _call(self, method: str, biz: Dict, token: str None) - Dict: 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_asciiFalse, separators(,, :)) } if token: p[access_token] token p[sign] self._sign(p) r requests.post(self.gw, datap, timeout15) r.raise_for_status() d r.json() # 提取响应兼容新旧method对应的resp_key resp_key method.replace(., _) _response if resp_key not in d: for k in d: if k.endswith(_response): resp_key k break data d.get(resp_key, d) if error_response in str(data): err d.get(resp_key, {}).get(error_response) or d.get(error_response) if err: code str(err.get(code, )) zh err.get(zh_desc) or err.get(en_desc) sub err.get(sub_code, ) if no permission in zh: raise PermissionError( f❌ 无权限确认已申请 {method} 接口订单类需传卖家AccessToken\n原始: {zh} ) raise Exception(fJOS[{code}]: {zh} sub{sub}) raise Exception(fJOS error: {d}) return data # ─── 老接口不推荐仅作对比/过渡期兼容─── def get_ware_old(self, ware_id: str, fields: str None, token: str None) - Dict: fields fields or ( ware_id,title,price,jd_price,stock_num,skus_json,image_path ) return self._call( jingdong.ware.get, # ← 老 method {wareId: ware_id, fields: fields}, token ).get(ware, {}) # ─── ✅ 新接口推荐迁移目标─── def get_ware_new(self, ware_id: str, fields: str None, token: str None) - Dict: fields fields or ( ware_id,title,brand_name,cid,category_name, price,jd_price,market_price,stock_num, skus_json,image_path,desc,outer_id,approve_status ) return self._call( jingdong.ware.read.get, # ← 新 method {wareId: ware_id, fields: fields}, token ).get(ware, {}) # # 使用示例平滑切换 # if __name__ __main__: client JdWareClient( app_keyYOUR_JD_APP_KEY, app_secretYOUR_JD_APP_SECRET, sandboxFalse # 沙箱测试 True ) WARE_ID 100012345678 # ← 替换真实 wareId SELLER_TOKEN None # 查自己店铺SKU库存需传卖家AccessToken try: # ★ 迁移后只用这一行 ★ ware client.get_ware_new(WARE_ID, tokenSELLER_TOKEN) print(✅ [新接口] 商品标题:, ware.get(title)) print( 京东价:, ware.get(jd_price)) print( SPU库存:, ware.get(stock_num)) # skus_json 解析查自己店铺时才有真实库存 import json as _j skus_raw ware.get(skus_json) or if skus_raw: skus _j.loads(skus_raw) print(f SKU数: {len(skus)}) for s in skus[:3]: print(f skuId:{s.get(skuId)} 价:{s.get(jdPrice)} f库:{s.get(stockNum)} 商家码:{s.get(outerId,)}) print(\n→ 迁移完成仅需改 methodjingdong.ware.read.get fields补skus_json) except PermissionError as pe: print(pe) except Exception as e: print(❌, e) print(→ 确认: AppKey/Secret正确、接口已申请、wareId有效)三、迁移 Checklist照着做5分钟切完应用后台申请新权限→ 接口权限 → 勾选jingdong.ware.read.get→ 提交通常即时生效代码改动极小- method jingdong.ware.get method jingdong.ware.read.get - fields ware_id,title,price fields ware_id,title,price,jd_price,stock_num,skus_json,image_pathwareId参数名不变驼峰同老接口回归测试5分钟沙箱调通签名 ✓生产比对新旧返回字段一致性标题/价格/SKU数应一致自家店铺查 SKU 库存需传access_token同旧逻辑下线老调用确认所有环境切新 method 后删除get_ware_old()分支四、避坑清单坑现象解决新接口返回 403未申请jingdong.ware.read.get应用→接口权限→申请skus_json空公开查询别人商品 / 未传 token查自己店铺商品须传卖家 AccessToken老代码wareId写成ware_id部分SDK自动映射推荐用wareId(首字母大写)与文档保持一致返回结构 key 变jingdong_ware_get_response→jingdong_ware_read_get_response解析用.get(ware)不依赖外层 keytimestamp毫秒Invalid TimestampJOS用秒级int(time.time())沙箱返回 mock 数据正常沙箱只验签不返真数据切生产验证五、面试/方案一句话京东JOS宙斯迁移老接口jingdong.ware.get→ 新接口jingdong.ware.read.get只改 method 字符串 fields 补skus_json,stock_num网关/签名/AccessToken 完全不变应用需申请新接口权限返回值结构外层key变但内层ware节点字段一致解析取.get(ware)即兼容5分钟平滑切换。需要我补京东订单增量同步(jingdong.pop.order.search) 或 库存快照定时校正脚本 的完整迁移示例吗