全部
常见问题
产品动态
精选推荐
功能建议

分析中 已回复 待规划 {{opt.name}}
分析中 已回复 待规划
京东开放平台API接口完全指南:商品详情、关键词搜索、评论与券后价

管理 管理 编辑 删除

一、接口体系概览

京东开放平台为开发者提供了丰富的API矩阵,主要涵盖以下核心能力:

接口类型方法名适用场景权限要求
商品详情jd.union.open.goods.query / jd.union.open.goods.bigfield.query获取SKU基础信息、大字段详情京东联盟账号+应用授权
关键词搜索jd.union.open.goods.search按关键词检索商品列表基础权限即可
评论数据jd.union.open.goods.search (含评论字段)获取好评率、评论数进阶权限
券后价/佣金jd.union.open.goods.query获取优惠券、佣金、到手价联盟高级权限+推广位绑定
接口统一地址:https://api.jd.com/routerjson


二、接入准备

2.1 账号注册与权限申请

  1. 注册开发者账号:访问京东开放平台,完成实名认证(企业用户需提交营业执照+近3个月经营流水)
  2. 创建应用:选择「自研应用」或「联盟应用」类型,提交审核
  3. 获取密钥:审核通过后获取 App Key 和 App Secret
  4. 申请接口权限:在「服务管理」中申请对应接口权限

2026年权限分级新规


权限等级适用人群可获取数据QPS限制申请要求
基础权限个人开发者商品名称、价格、主图、基础销量5实名认证
进阶权限企业用户+促销详情、评价摘要、店铺评分、优惠券20企业营业执照
高级权限联盟合作伙伴+实时销量、商品成长指数、点击转化率60数据用途承诺书


三、核心接口详解

3.1 商品详情接口

接口方法:jd.union.open.goods.query(基础详情)/ jd.union.open.goods.bigfield.query(大字段详情)

功能说明

  • 通过SKU ID获取商品完整信息
  • 包含价格、库存、品牌、类目、店铺信息
  • 大字段接口额外返回图文详情、规格参数等
  • 请求参数


{
  "method": "jd.union.open.goods.query",
  "app_key": "your_app_key",
  "access_token": "your_access_token",
  "timestamp": "2026-04-30 15:44:00",
  "format": "json",
  "v": "1.0",
  "sign_method": "md5",
  "360buy_param_json": {
    "skuIds": "10335871600",      // 商品SKU ID,支持批量
    "fields": "skuId,title,price,lowestPrice,commissionRate,commission,couponInfo,goodComments,totalComments,score,shopName,isSelf,volume,imgUrl"
  }
}

返回字段说明

 
  
字段类型说明
skuIdLong商品SKU ID
title / productNameString商品标题
priceDouble当前售价
lowestPriceDouble历史最低价
commissionRateDouble佣金比例(%)
commissionDouble佣金金额(元)
couponInfoObject优惠券信息(含面额、使用门槛)
purchasePriceDouble到手价(已计算优惠券抵扣)
goodCommentsInt好评数
totalCommentsInt总评论数
scoreDouble商品评分
volumeInt30天销量
isSelfInt是否自营(1是/0否)


3.2 关键词搜索接口

接口方法:jd.union.open.goods.search

核心能力

  • 支持关键词模糊匹配与多词组合(空格分隔)
  • 支持价格区间、类目、优惠券、自营等维度筛选
  • 支持按价格、销量、佣金、评分、成长指数排序
  • 请求参数


{
  "360buy_param_json": {
    "keyword": "无线蓝牙耳机 主动降噪",    // 搜索关键词
    "pageIndex": 1,                       // 页码(1-50)
    "pageSize": 20,                       // 每页数量(1-50)
    "priceFrom": 100.00,                  // 价格区间起
    "priceTo": 500.00,                    // 价格区间止
    "sortName": "sales",                  // 排序字段
    "sort": "desc",                       // 排序方式
    "hasCoupon": 1,                     // 是否有券(1有/0不限)
    "isSelf": 1,                          // 是否自营(1是/0否)
    "goodRate": 92,                     // 最低好评率(80-100)
    "cid3": 12052,                      // 三级类目ID
    "fields": "skuId,productName,price,commission,couponInfo,goodComments,score,volume"
  }
}

2026年新增参数表格

 
  
参数类型说明
growthScoreInt商品成长指数(≥80为潜力爆款)
shortVideoHotBoolean短视频高热度筛选
clickRateDouble实时点击转化率


3.3 评论数据接口

京东评论数据主要通过搜索接口的字段返回,无独立评论详情接口(需申请特殊权限):

可获取的评论维度

  • goodComments:好评数量
  • totalComments:总评论数
  • score:综合评分(1-5分)
  • goodRate:好评率百分比
  • 注意:评价原文涉及用户隐私,需单独申请「评价内容权限」,并严格遵守数据保护法规。


3.4 券后价与佣金计算

券后价(到手价)计算逻辑



到手价 = 促销价 - 优惠券面额
券后佣金 = 到手价 × 佣金比例

优惠券数据结构
{
  "couponInfo": {
    "couponList": [
      {
        "bindType": 1,              // 券类型
        "discount": 20.00,          // 优惠面额
        "quota": 99.00,             // 使用门槛(满99减20)
        "platformType": 0,          // 平台券/店铺券
        "getStartTime": 1714464000000,  // 领取开始时间
        "getEndTime": 1717056000000,    // 领取结束时间
        "useStartTime": 1714464000000,  // 使用开始时间
        "useEndTime": 1717056000000     // 使用结束时间
      }
    ]
  },
  "purchasePriceInfo": {
    "purchasePrice": 79.00          // 最终到手价
  }
}


四、签名认证机制

京东API采用MD5签名HMAC-SHA256进行请求认证。

4.1 MD5签名算法(标准版)

签名步骤

  1. 参数排序:将所有业务参数按参数名ASCII升序排序
  2. 拼接字符串:appSecret + key1 + value1 + key2 + value2 + ... + appSecret
  3. MD5加密:对拼接字符串进行MD5哈希,结果转大写

Python实现


import hashlib
import urllib.parse
import json
import time

class JDAPIClient:
    def __init__(self, app_key, app_secret, access_token):
        self.app_key = app_key
        self.app_secret = app_secret
        self.access_token = access_token
        self.api_url = "https://api.jd.com/routerjson"
    
    def generate_sign(self, params: dict) -> str:
        """生成MD5签名"""
        # 1. 过滤空值并排序
        sorted_params = sorted(
            [(k, v) for k, v in params.items() if v is not None],
            key=lambda x: x[0]
        )
        
        # 2. 拼接字符串
        sign_str = self.app_secret
        for key, value in sorted_params:
            # URL编码value
            encoded_value = urllib.parse.quote(str(value), safe='')
            sign_str += f"{key}{encoded_value}"
        sign_str += self.app_secret
        
        # 3. MD5加密并转大写
        return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
    
    def build_request(self, method, business_params):
        """构建完整请求"""
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        
        params = {
            "method": method,
            "app_key": self.app_key,
            "access_token": self.access_token,
            "timestamp": timestamp,
            "format": "json",
            "v": "1.0",
            "sign_method": "md5",
            "360buy_param_json": json.dumps(business_params, ensure_ascii=False)
        }
        
        # 生成签名
        params["sign"] = self.generate_sign(params)
        return params
        

4.2 HMAC-SHA256签名(高级版)

部分新版接口要求使用HMAC-SHA256:



import hmac
import hashlib

def generate_hmac_sign(params, app_secret):
    sorted_params = sorted(params.items(), key=lambda x: x[0])
    sign_str = "&".join(f"{k}={urllib.parse.quote_plus(str(v))}" for k, v in sorted_params)
    
    signature = hmac.new(
        app_secret.encode('utf-8'),
        sign_str.encode('utf-8'),
        hashlib.sha256
    ).hexdigest().upper()
    return signature
    


五、完整实战代码

5.1 商品详情查询



import requests
from typing import Dict, Optional

class JDGoodsAPI:
    def __init__(self, app_key: str, app_secret: str, access_token: str):
        self.client = JDAPIClient(app_key, app_secret, access_token)
    
    def get_goods_detail(self, sku_id: str, fields: Optional[str] = None) -> Dict:
        """
        获取商品详情
        """
        if not fields:
            fields = ("skuId,title,price,lowestPrice,commissionRate,commission,"
                     "couponInfo,purchasePriceInfo,goodComments,totalComments,"
                     "score,shopName,isSelf,volume,imgUrl,materialUrl")
        
        business_params = {
            "skuIds": sku_id,
            "fields": fields
        }
        
        params = self.client.build_request(
            "jd.union.open.goods.query",
            business_params
        )
        
        try:
            response = requests.get(self.client.api_url, params=params, timeout=30)
            result = response.json()
            
            if "error_response" in result:
                error = result["error_response"]
                return {"success": False, "error": error.get("msg")}
            
            data = result.get("jd_union_open_goods_query_response", {})
            goods_list = data.get("result", [])
            
            if not goods_list:
                return {"success": False, "error": "商品不存在"}
            
            return {"success": True, "data": self._format_goods(goods_list[0])}
            
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    def _format_goods(self, item: dict) -> dict:
        """格式化商品数据"""
        coupon_info = item.get("couponInfo", {})
        coupons = coupon_info.get("couponList", []) if isinstance(coupon_info, dict) else []
        
        # 计算券后价
        price = float(item.get("price", 0))
        best_coupon = max(coupons, key=lambda x: x.get("discount", 0)) if coupons else None
        coupon_amount = best_coupon.get("discount", 0) if best_coupon else 0
        final_price = round(price - coupon_amount, 2)
        
        return {
            "sku_id": item.get("skuId"),
            "title": item.get("title") or item.get("productName"),
            "price": price,
            "lowest_price": float(item.get("lowestPrice", 0)),
            "coupon_amount": coupon_amount,
            "final_price": final_price,
            "commission_rate": f"{item.get('commissionRate', 0)}%",
            "commission": item.get("commission"),
            "has_coupon": bool(coupons),
            "coupon_detail": best_coupon,
            "shop_name": item.get("shopName"),
            "is_self": item.get("isSelf") == 1,
            "sales_volume": item.get("volume"),
            "good_comments": item.get("goodComments"),
            "total_comments": item.get("totalComments"),
            "good_rate": item.get("score"),
            "image": item.get("imgUrl"),
            "product_url": f"https://item.jd.com/{item.get('skuId')}.html"
        }

# 使用示例
if __name__ == "__main__":
    api = JDGoodsAPI(
        app_key="your_app_key",
        app_secret="your_app_secret",
        access_token="your_access_token"
    )
    
    result = api.get_goods_detail("10335871600")
    if result["success"]:
        goods = result["data"]
        print(f"商品:{goods['title']}")
        print(f"原价:¥{goods['price']}")
        print(f"券后价:¥{goods['final_price']} (省¥{goods['coupon_amount']})")
        print(f"佣金比例:{goods['commission_rate']}")
        print(f"销量:{goods['sales_volume']}")
    else:
        print(f"查询失败:{result['error']}")
        

5.2 关键词搜索(含券后价筛选)



class JDSearchAPI(JDGoodsAPI):
    def search_goods(
        self,
        keyword: str,
        page: int = 1,
        page_size: int = 20,
        price_range: tuple = None,
        has_coupon: bool = False,
        min_good_rate: int = None,
        sort: str = "sales_desc"
    ) -> Dict:
        """
        关键词搜索商品
        """
        sort_mapping = {
            "price_asc": ("price", "asc"),
            "price_desc": ("price", "desc"),
            "sales_desc": ("volume", "desc"),
            "commission_desc": ("commissionRate", "desc"),
            "rating_desc": ("score", "desc"),
            "growth_desc": ("growthScore", "desc")  # 2026新增
        }
        
        business_params = {
            "keyword": keyword,
            "pageIndex": page,
            "pageSize": min(max(page_size, 1), 50),
            "fields": ("skuId,productName,price,lowestPrice,commissionRate,commission,"
                      "couponInfo,purchasePriceInfo,goodComments,totalComments,score,"
                      "shopName,isSelf,volume,imgUrl,growthScore")
        }
        
        # 价格区间
        if price_range and len(price_range) == 2:
            business_params["priceFrom"] = price_range[0]
            business_params["priceTo"] = price_range[1]
        
        # 排序
        if sort in sort_mapping:
            business_params["sortName"], business_params["sort"] = sort_mapping[sort]
        
        # 优惠券筛选
        if has_coupon:
            business_params["hasCoupon"] = 1
        
        # 好评率筛选
        if min_good_rate and 80 <= min_good_rate <= 100:
            business_params["goodRate"] = min_good_rate
        
        params = self.client.build_request(
            "jd.union.open.goods.search",
            business_params
        )
        
        try:
            response = requests.get(self.client.api_url, params=params, timeout=30)
            result = response.json()
            
            if "error_response" in result:
                return {"success": False, "error": result["error_response"].get("msg")}
            
            data = result.get("jd_union_open_goods_search_response", {})
            search_result = data.get("result", {})
            goods_list = search_result.get("data", [])
            total = search_result.get("totalCount", 0)
            
            # 数据清洗
            items = [self._format_goods(item) for item in goods_list]
            
            # 券后价二次筛选(如果API返回的purchasePrice不准确)
            if has_coupon:
                items = [item for item in items if item["has_coupon"]]
            
            return {
                "success": True,
                "total": total,
                "page": page,
                "items": items
            }
            
        except Exception as e:
            return {"success": False, "error": str(e)}

# 搜索示例
if __name__ == "__main__":
    search_api = JDSearchAPI(
        app_key="your_app_key",
        app_secret="your_app_secret",
        access_token="your_access_token"
    )
    
    # 搜索"保温杯",10-50元,有优惠券,按销量排序
    result = search_api.search_goods(
        keyword="保温杯",
        price_range=(10, 50),
        has_coupon=True,
        sort="sales_desc",
        min_good_rate=95
    )
    
    if result["success"]:
        print(f"找到 {result['total']} 件商品,当前第{result['page']}页")
        for item in result["items"][:5]:
            print(f"\n【{item['title'][:30]}...】")
            print(f"  券后价:¥{item['final_price']} | 佣金:{item['commission_rate']}")
            print(f"  销量:{item['sales_volume']} | 好评率:{item['good_rate']}")
            


六、错误处理与限流策略

6.1 常见错误码



错误码含义解决方案
1001签名错误检查参数排序、编码、密钥是否正确
2001商品ID无效确认SKU ID存在且已上架
429请求频率超限降低QPS,增加请求间隔
500/502/503服务端错误启用指数退避重试

6.2 限流与重试机制


from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import time

class JDAPIClient:
    def __init__(self, app_key, app_secret, access_token):
        # ... 原有初始化 ...
        
        # 配置重试机制
        self.session = requests.Session()
        retry = Retry(
            total=3,
            backoff_factor=0.5,  # 间隔 0.5, 1, 2 秒
            status_forcelist=[429, 500, 502, 503]
        )
        self.session.mount('https://', HTTPAdapter(max_retries=retry))
    
    def request_with_rate_limit(self, params):
        """带频率控制的请求"""
        time.sleep(1.5)  # 基础QPS限制:每秒不超过1次(基础权限)
        return self.session.get(self.api_url, params=params, timeout=30)
        


七、合规与注意事项

  1. 数据使用合规:不得将数据用于非法用途,严格遵守《京东开放平台开发者协议》
  2. 密钥安全:App Secret 禁止硬编码,建议使用环境变量或密钥管理服务
  3. 频率控制:基础权限QPS为5,超限可能导致IP被封禁
  4. 数据延迟:库存、价格数据可能存在5-10分钟延迟,重要场景建议搭配官方数据推送服务
  5. 评论隐私:评价原文需单独申请权限,禁止泄露用户个人信息


八、相关接口速查


功能接口方法文档
商品转链jd.union.open.promotion.common.get生成推广链接
订单查询jd.union.open.order.query查询推广订单及佣金
类目查询jd.union.open.category.goods.get获取商品分类树
优惠券查询jd.union.open.coupon.query查询优惠券详情
京粉精选jd.union.open.goods.jingfen.query获取推荐商品库

如遇任何疑问或有进一步的需求,请随时与我私信或者评论联系。

{{voteData.voteSum}} 人已参与
支持
反对
请登录后查看

123c001fa85d 最后编辑于2026-04-30 16:50:27

快捷回复
回复
回复
回复({{post_count}}) {{!is_user ? '我的回复' :'全部回复'}}
排序 默认正序 回复倒序 点赞倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理员 企业

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推荐': '推荐'}}
{{item.is_suggest == 1? '取消推荐': '推荐'}} 【已收集】
{{item.floor}}# 沙发 板凳 地板 {{item.floor}}# 【已收集】
{{item.user_info.title || '暂无简介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打赏
已打赏¥{{item.reward_price}}
{{item.like_count}}
分享
{{item.showReply ? '取消回复' : '回复'}}
删除
回复
回复

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回复 {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打赏
已打赏¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回复' : '回复'}}
删除
回复
回复
收起 展开更多
查看更多
打赏
已打赏¥{{reward_price}}
35
{{like_count}}
{{collect_count}}
添加回复 ({{post_count}})

相关推荐

快速安全登录

使用微信扫码登录
回复
回复
问题:
问题自动获取的帖子内容,不准确时需要手动修改. [获取答案]
答案:
提交
bug 需求 取 消 确 定
打赏金额
当前余额:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
请输入 0.1-{{reward_max_price}} 范围内的数值
打赏成功
¥{{price}}
完成 确认打赏

微信登录/注册

切换手机号登录

{{ bind_phone ? '绑定手机' : '手机登录'}}

{{codeText}}
切换微信登录/注册
暂不绑定
CRMEB客服
CRMEB咨询热线 400-8888-794

扫码领取产品资料

功能清单
思维导图
安装教程
CRMEB开源商城下载 源码下载 CRMEB帮助文档 帮助文档
返回顶部 返回顶部
CRMEB客服