调用Bybit API返回retCode10004签名错误求助排查
Bybit API签名错误(retCode:10004)排查与修复
调用Bybit统一保证金账户余额接口GET /unified/v3/private/account/wallet/balance时遇到retCode:10004签名错误,问题出在代码的参数传递、URL拼接和签名生成逻辑上,具体错误点和修复方案如下:
核心错误点
- 参数传递混乱:
HTTP_Request函数接收的payload是转成字符串的字典(str(params)),既无法用于正确生成签名,也不能直接拼接到URL中;同时生成签名时误用了全局params而非函数传入的参数。 - URL拼接错误:直接将字符串格式的字典拼接到URL后,导致实际请求的参数格式不符合要求,且与签名生成时的参数不一致。
- 签名生成的参数一致性问题:签名必须基于实际请求的所有参数(排序后)生成,原代码中参数传递链路断裂,导致签名与请求不匹配。
修复后的完整代码
from urllib.parse import urlencode import requests import hmac import hashlib api_key = 'xxxxxxxxxxxx' secret_key = 'xxxxxxxxxxxxxxxxxxxx' httpClient = requests.Session() recv_window = "5000" base_url = "https://api.bybit.com" def HTTP_Request(endpoint, method, params): # 获取服务器时间戳 time_stamp = str(requests.get(base_url + "/v3/public/time").json()["time"]) # 生成签名 signature = genSignature(params, time_stamp) headers = { 'X-BAPI-SIGN-TYPE': '2', 'X-BAPI-SIGN': signature, 'X-BAPI-API-KEY': api_key, 'X-BAPI-TIMESTAMP': time_stamp, 'X-BAPI-RECV-WINDOW': recv_window } # 正确拼接URL查询参数 query_string = urlencode(sorted(params.items(), key=lambda tup: tup[0])) response = httpClient.request(method, f"{base_url}{endpoint}?{query_string}", headers=headers) print(response.text) def genSignature(payload, time_stamp): # 对参数进行排序并URL编码 payload_url_enc = urlencode(sorted(payload.items(), key=lambda tup: tup[0])) # 构造签名原始字符串 param_str = f"{time_stamp}{api_key}{recv_window}{payload_url_enc}" # 生成HMAC-SHA256签名 signature = hmac.new( key=bytes(secret_key, "utf-8"), msg=param_str.encode("utf-8"), digestmod=hashlib.sha256 ).hexdigest() return signature # 调用示例 endpoint = "/unified/v3/private/account/wallet/balance" method = "GET" params = {"coin": "USDT"} HTTP_Request(endpoint, method, params)
关键修复说明
- 统一参数传递:
HTTP_Request直接接收字典类型的params,确保签名生成和请求使用的是同一套参数。 - 正确生成查询字符串:使用
urlencode对排序后的参数进行编码,生成符合要求的URL查询字符串,避免手动拼接错误。 - 签名与请求参数严格一致:签名生成时的参数排序和编码逻辑,与实际请求的查询字符串完全对齐,确保Bybit服务器验证签名时匹配。
- 简化冗余代码:移除了未使用的
uuid和time模块导入,优化代码结构。
内容的提问来源于stack exchange,提问作者Radikulit
相关产品推荐
相关产品推荐

