[特殊字符]《京东开放平台JOS接入全指南:注册、AppKey、OAuth2.0授权与沙箱调试(2026最新)》(附Python源码)
《京东开放平台JOS接入全指南注册、AppKey、OAuth2.0授权与沙箱调试2026最新》附Python源码京东开放平台JOS JD Open Service是京东POP商家/ISV对接商品、订单、物流、售后、仓储的官方渠道。爬虫不可取JOS免费额度内零成本下面按实际接入顺序给你完整说明 Python签名/授权/沙箱调用代码。一、接入四步曲先记这个① 注册京东商家/开发者 → 创建JOS应用(自用/ISV) https://jos.jd.com → 获取 AppKey AppSecret(别名AppPassword) ② 申请接口权限商品/订单/物流… ③ OAuth2.0 授权店铺卖家登录→code→access_token/refresh_token *只有订单/私有店铺数据需要 token商品公开查询可不传* ④ 沙箱调通签名 → 切生产网关正式同步二、创建应用 获取 AppKey / AppSecret登录 京东开放平台→控制台 → 创建应用应用类型商家自用应用推荐绑定自己店铺→ 免ISV入驻ISV应用 → 需软服中心入驻、商家授权托管应用审核通过后详情页复制App Key也叫app_key/client_idApp Secret也叫app_password/client_secret接口管理 → 申请权限勾选所需如jingdong.pop.order.search、jingdong.ware.sku.read、jingdong.etms.trace.get等⚠️ 京东JOS签名用360buy/jd参数名规范详见下文。三、JOS 签名算法必须掌握京东JOS使用MD5签名规则收集所有业务参数 公共参数app_key,method,timestamp,v,sign_method若有access_token也参入剔除sign、file字段、值为空(/None)按参数名 ASCII 升序排序拼接key1value1key2value2...无无首尾拼 AppSecretAppSecret 拼接串 AppSecretMD5 → 大写待签名 APP_SECRET app_keyxxxformatjsonmethodjd.xxxv2.0timestampxxx APP_SECRET sign MD5(待签名).upper() 京东参数名多为jd.xxxmethod值如jingdong.pop.order.searchtimestamp是秒级10位不同于TOP的毫秒四、OAuth2.0 卖家授权获取 AccessToken订单/私有店铺接口需卖家账号授权① 引导卖家访问 https://auth.jd.com/oauth2/toLogin.action ?response_typecode client_idYOUR_APP_KEY redirect_uriURLENCODE(你在应用配置的回调地址) stateerp_jd ② 回调 → redirect_uri?codexxxstateerp_jd ③ 换 token POST https://auth.jd.com/oauth2/accessToken grant_typeauthorization_code client_idAPP_KEY client_secretAPP_SECRET codexxx redirect_uri同上 → {access_token, refresh_token, expires_in, uid, user_nick}五、Python完整封装签名 OAuth 沙箱/生产调用# jd_jos_client.py 京东开放平台(JOS) API Client — 2026版 网关: 生产: https://api.jd.com/routerjson 沙箱: https://api.sandbox.jd.com/routerjson (部分接口支持) 签名: MD5(AppSecret KV_sorted AppSecret) → upper timestamp: 秒级(10位) import hashlib import time import requests import urllib.parse from typing import Dict, Optional from datetime import datetime, timedelta # 封装好API供应商demo urlhttps://console.open.onebound.cn/console/?iLex class JdJosClient: PROD https://api.jd.com/routerjson SANDBOX https://api.sandbox.jd.com/routerjson def __init__(self, app_key: str, app_secret: str, sandbox: bool False): self.ak app_key self.as_ app_secret self.gw self.SANDBOX if sandbox else self.PROD # ─────────────── 签名 ─────────────── def _sign(self, params: Dict) - str: filt sorted((k, v) for k, v in params.items() if v is not None and str(v).strip() ! and k ! sign) qs .join(f{k}{v} for k, v in filt) raw f{self.as_}{qs}{self.as_} return hashlib.md5(raw.encode(utf-8)).hexdigest().upper() # ─────────────── 通用调用 ─────────────── def call(self, method: str, biz: Dict, access_token: str None) - Dict: method: 如 jingdong.pop.order.search biz: 业务参数字典会变成 JSON 串放 360buy_param_json api_params { 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) } if access_token: api_params[access_token] access_token api_params[sign] self._sign(api_params) # JOS推荐 POST x-www-form-urlencoded r requests.post(self.gw, dataapi_params, timeout15) r.raise_for_status() d r.json() # JOS返回结构: {method_response: {error_response / xxx_response}} resp_key method.replace(., _) _response if resp_key not in d: # 有些接口直接用 method名作为key 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) if resp_key in d else d.get(error_response) if err: raise Exception(fJOS Err[{err.get(code)}]: {err.get(zh_desc) or err.get(en_desc)} fsub:{err.get(sub_code)}) raise Exception(fJOS 未知错误: {d}) return data # ─────────────── 示例商品详情公开可不传token──────── def get_sku_detail(self, sku_id: str) - Dict: return self.call( jingdong.ware.sku.read.findSkuById, {skuId: sku_id, fields: skuId,wareId,title,price,jdPrice,stockNum} ).get(skuReadResult, {}).get(skuEntity, {}) # ─────────────── 示例订单列表需token──────── def list_orders(self, access_token: str, start_modified: str, end_modified: str, page1, page_size50) - Dict: return self.call( jingdong.pop.order.search, { start_modified: start_modified, end_modified: end_modified, order_state: WAIT_SELLER_STOCK_OUT, # 已付款待发货示例 page: page, page_size: min(page_size, 100) }, access_tokenaccess_token ).get(popOrderSearch, {}).get(orderSearch, {}) # ─────────────── 物流轨迹需token──────── def get_trace(self, access_token: str, waybill_code: str, customer_code: str None) - Dict: biz {waybillCode: waybill_code} if customer_code: biz[customerCode] customer_code return self.call(jingdong.etms.trace.get, biz, access_token ).get(etmsTraceGetResponse, {}).get(traceApiResult, {}) # ── OAuth 换 token 辅助 ── def jd_oauth_exchange(app_key, app_secret, code, redirect_uri): r requests.post(https://auth.jd.com/oauth2/accessToken, data{ grant_type: authorization_code, client_id: app_key, client_secret: app_secret, code: code, redirect_uri: redirect_uri, state: }, timeout15) r.raise_for_status() return r.json() # access_token / refresh_token / expires_in / uid def json_dumps(d: Dict) - str: import json return json.dumps(d, ensure_asciiFalse, separators(,, :)) # # 使用示例 # if __name__ __main__: client JdJosClient( app_keyYOUR_JD_APP_KEY, app_secretYOUR_JD_APP_SECRET, sandboxTrue # 生产切 False ) try: # ① 公开商品沙箱返回mock生产需真实skuId sku client.get_sku_detail(100012345678) print(✅ SKU查询签名通title, sku.get(title)) # ② 订单需卖家AccessToken沙箱多返回空 # from datetime import datetime,timedelta # now datetime.now() # start (now - timedelta(minutes30)).strftime(%Y-%m-%d %H:%M:%S) # end now.strftime(%Y-%m-%d %H:%M:%S) # orders client.list_orders(SELLER_ACCESS_TOKEN, start, end) # print(订单数:, orders.get(orderTotal)) except Exception as e: print(❌, e)六、沙箱 vs 生产注意点项目沙箱生产网关api.sandbox.jd.com/routerjsonapi.jd.com/routerjson数据Mock商品ID原样回显/空订单真实店铺数据订单接口返回空列表正常需卖家AccessToken 申请权限AppKey同一应用Key同一应用Key淘宝客类不适用京东无淘宝客API✅沙箱能调通签名JSON结构 生产一定通返回空不报错属预期。七、高频避坑坑现象解决timestamp 毫秒Invalid TimestampJOS用秒级int(time.time())不是毫秒360buy_param_json格式错Missing Required Parameter值是紧凑JSON字符串无空格中文不URL编码但 ensure_asciiFalse订单403个人应用/未申请创建商家自用应用 申请jingdong.pop.order.search 卖家OAuthsession传买家token空/403须是店铺卖家授权换的 access_tokensign mismatch参入 sign / 空值参入严格过滤空值剔除sign再排序沙箱空订单慌—正常切生产验证八、面试/方案一句话京东JOS接入 创建商家自用应用拿AppKey/Secret → MD5签名(参按ASCII升序拼AppSecretKVAppSecret,秒级timestamp) →360buy_param_json放业务JSON → 订单类接口需卖家OAuth AccessToken沙箱验签通后切生产网关取真实数据基础接口有免费额度。需要我补京东订单增量同步APScheduler断点续跑Token刷新 或京东商品全量SKU翻页同步完整字段解析 吗