[特殊字符] 京东JOS API Sign签名算法详解与MD5实现(Java / Python / PHP 三版)

发布时间:2026/7/6 3:58:57

[特殊字符] 京东JOS API Sign签名算法详解与MD5实现(Java / Python / PHP 三版) 京东JOS API Sign签名算法详解与MD5实现Java / Python / PHP 三版京东开放平台JOS统一使用MD5签名规则和1688/TOP非常接近但有两个关键差异时间戳用秒级10位不是毫秒业务参数必须放360buy_param_json紧凑JSON字符串参与签名一、JOS 签名算法官方步骤背下来假设App Key 123456App Secret abcdefg收集所有API参数含公共参数app_key,method,timestamp,format,v,sign_method360buy_param_json值为业务参数字典的紧凑JSON字符串若有access_token订单类也参入剔除sign字段、值为None或空字符串、file二进制按参数名 ASCII 升序排序拼接 keyvalue无无app_key123456formatjsonmethodjingdong.ware.read.gettimestamp1700000000v2.0360buy_param_json{wareId:1000123,fields:title,price}首尾拼 AppSecretAppSecret 上步字符串 AppSecretMD5 → 32位大写sign MD5( AppSecret KV_ASCII_sorted AppSecret ).upper()⚠️360buy_param_json值必须是JSON紧凑格式无空格中文ensure_asciiFalse原样参与签名不 URL-Encode 再签名。二、Python 实现推荐直接用# jd_jos_sign.py import hashlib import json from typing import Dict, Optional # 封装好API供应商demo urlhttps://console.open.onebound.cn/console/?iLex def jd_sign(params: Dict[str, Optional[str]], app_secret: str) - str: JOS MD5 Sign params: 所有API参数(含 app_key/method/timestamp/360buy_param_json/access_token) 不包含 sign 空值/None 剔除 filt { k: v for k, v in params.items() if v is not None and str(v).strip() ! and k ! sign } # ASCII 升序 sorted_items sorted(filt.items(), keylambda x: x[0]) # 拼 keyvalue qs .join(f{k}{v} for k, v in sorted_items) # 首尾拼 secret → MD5 → 大写 raw f{app_secret}{qs}{app_secret} return hashlib.md5(raw.encode(utf-8)).hexdigest().upper() # 验证示例 if __name__ __main__: APP_SECRET YOUR_JD_APP_SECRET # 业务参数 → 紧凑JSON biz {wareId: 100012345678, fields: ware_id,title,price,jd_price,stock_num,skus_json} api_params { app_key: YOUR_JD_APP_KEY, method: jingdong.ware.read.get, timestamp: str(int(__import__(time).time())), # ← 秒级 format: json, v: 2.0, sign_method: md5, 360buy_param_json: json.dumps(biz, ensure_asciiFalse, separators(,, :)) # 紧凑 # access_token: SELLER_TOKEN # 订单类接口加这句 } sign jd_sign(api_params, APP_SECRET) api_params[sign] sign print(✅ sign , sign) print(\n发送参数示例:) for k, v in api_params.items(): print(f {k} {v if k!sign else sign})三、Java 实现// JdSignUtil.java import java.security.MessageDigest; import java.util.Map; import java.util.TreeMap; # 封装好API供应商demo urlhttps://console.open.onebound.cn/console/?iLex public class JdSignUtil { public static String sign(MapString, String params, String appSecret) throws Exception { // 1. 剔除 sign 空值 TreeMapString, String tree new TreeMap(); for (Map.EntryString, String e : params.entrySet()) { if (!sign.equals(e.getKey()) e.getValue() ! null !e.getValue().trim().isEmpty()) { tree.put(e.getKey(), e.getValue()); } } // 2. 拼 keyvalue StringBuilder sb new StringBuilder(); for (Map.EntryString, String e : tree.entrySet()) { sb.append(e.getKey()).append(e.getValue()); } // 3. 首尾拼 secret String toSign appSecret sb.toString() appSecret; MessageDigest md MessageDigest.getInstance(MD5); byte[] digest md.digest(toSign.getBytes(UTF-8)); StringBuilder hex new StringBuilder(); for (byte b : digest) { hex.append(String.format(%02X, b 0xFF)); } return hex.toString(); // 已大写 } // 用法: // MapString,String p new HashMap(); // p.put(method,jingdong.ware.read.get); // p.put(app_key,KEY); // p.put(timestamp, String.valueOf(System.currentTimeMillis()/1000)); // 秒! // p.put(format,json); p.put(v,2.0); p.put(sign_method,md5); // p.put(360buy_param_json, {\wareId\:\1000123\,\fields\:\title,price\}); // String sign JdSignUtil.sign(p, APP_SECRET); }四、PHP 实现?php // jd_sign.php function jdSign(array $params, string $appSecret): string { unset($params[sign]); $filtered array_filter($params, fn($v) $v ! null $v ! ); ksort($filtered); $str ; foreach ($filtered as $k $v) { $str . $k . $v; } $toSign $appSecret . $str . $appSecret; return strtoupper(md5($toSign)); } # 封装好API供应商demo urlhttps://console.open.onebound.cn/console/?iLex // ---- 示例 ---- $params [ method jingdong.ware.read.get, app_key YOUR_JD_APP_KEY, timestamp (string)(time()), // ← 秒级 format json, v 2.0, sign_method md5, 360buy_param_json json_encode( [wareId100012345678,fieldsware_id,title,price], JSON_UNESCAPED_UNICODE ) ]; $sign jdSign($params, YOUR_JD_APP_SECRET); $params[sign] $sign; echo sign {$sign}\n; ?五、签名排错清单JOS特有现象原因排查Invalid Signaturetimestamp 用毫秒必须int(time.time())秒级​Invalid Signature360buy_param_json含空格/\n用separators(,,:)/JSON_UNESCAPED_UNICODE紧凑Invalid Signature空值参入签名严格过滤None/sign fail偶发系统时钟偏差大服务器 NTP 同步±5分钟内商品接口OK订单403非签名问题订单需企业应用卖家AccessToken见之前订单对接文360buy_param_jsonURL编码再签签错先签原始JSON串签完再整体URL Encode放POST body​六、面试/对接一句话京东JOS签名 参数按key ASCII升序拼keyvalue含360buy_param_json紧凑JSON串空值/sign剔除→ 首尾拼AppSecret→ MD5 → 大写timestamp必须用秒级10位不同于1688的毫秒。需要我补京东商品全量SKU翻页同步​ 或京东订单增量同步APScheduler断点续跑Token刷新​ 完整脚本吗

相关新闻