BingX API v2连接报错:timestamp无效问题求助
BingX API v2 报80014错误(timestamp无效/不匹配)排查方案
此前使用BingX API v1无明显原因突然无法使用,重构升级至v2版本后,调用API执行操作或查询时持续报错:
- 操作类请求返回:
placeMarketOrder: {"code":80014,"msg":"timestamp is invalid","data":{}} - GET查询类请求返回:
placeMarketOrder: {"code":80014,"msg":"Null timestamp or timestamp mismatch","data":{}}
不确定问题源于timestamp还是signature,以下是针对性排查点及代码优化建议:
核心排查方向
1. 时间戳同步与精度问题
- BingX API要求timestamp为13位毫秒级UTC时间,代码中
$date->getTimestamp()*1000的计算逻辑正确,但需确保服务器本地时间与UTC时间偏差不超过5秒(API有时间窗口校验)。 - 强制设置时区为UTC,避免本地时区偏移:
date_default_timezone_set('UTC'); - 可调用BingX的时间同步接口获取服务器时间,对比本地生成的timestamp是否一致。
2. 签名生成逻辑错误
- 签名原始字符串必须按参数key的ASCII升序拼接,当前代码的
getOriginString函数按数组遍历顺序拼接,而PHP关联数组的遍历顺序不一定符合升序要求,会导致签名不匹配。优化后的getOriginString函数:function getOriginString(array $params) { ksort($params); // 按key升序排序 $originString = ""; $first = true; foreach($params as $n => $v) { if (!$first) { $originString .= "&"; } $first = false; $originString .= $n . "=" . $v; } return $originString; } - 确认签名生成时包含了所有必填参数(包括timestamp),且参数值没有被转义或修改。
3. 请求参数传递方式错误
- BingX API v2的POST接口要求参数放在**请求体(application/x-www-form-urlencoded)**中,而非URL查询字符串。当前代码将POST参数拼接到URL中,不符合接口规范,会导致参数解析异常。优化
httpPost和placeMarketOrder函数:function httpPost($url, $params) { global $apiKey; $curl = curl_init($url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params)); // 参数放在请求体 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_USERAGENT, "curl/7.80.0"); curl_setopt($curl, CURLOPT_HTTPHEADER, array( "X-BX-APIKEY:".$apiKey, "Content-Type: application/x-www-form-urlencoded" )); $response = curl_exec($curl); curl_close($curl); return $response; } function placeMarketOrder(string $symbol, string $side, string $quantity, string $positionSide) { $path = "/openApi/swap/v2/trade/order"; $url = "https://open-api.bingx.com" . $path; $params = array(); $params['symbol'] = $symbol; $params['side'] = $side; $params['type'] = "MARKET"; $params['quantity'] = $quantity; $params['positionSide'] = $positionSide; date_default_timezone_set('UTC'); $date = new DateTime(); $params['timestamp'] = $date->getTimestamp()*1000; $originString = getOriginString($params); $signature = getSignature($originString); $params["signature"] = $signature; $result = httpPost($url, $params); echo "\t"; echo $result; echo "\n"; }
4. API密钥权限问题
- 确认使用的是BingX API v2的密钥,v1密钥无法兼容v2接口;检查密钥是否开启了对应接口的权限(如交易、查询权限),且IP白名单设置正确。
附原测试代码
<?php $url = "https://open-api.bingx.com"; $apiKey = "Set your api key here!!"; $secretKey = "Set your secret key here!!"; function getOriginString(array $params) { // combine origin string $originString = ""; $first = true; foreach($params as $n => $v) { if (!$first) { $originString .= "&"; } $first = false; $originString .= $n . "=" . $v; } return $originString; } function getSignature(string $originString) { global $secretKey; $signature = hash_hmac('sha256', $originString, $secretKey, true); $signature = bin2hex($signature); return $signature; } function getRequestUrl(string $path, array $params) { global $url; $requestUrl = $url.$path."?"; $first = true; foreach($params as $n => $v) { if (!$first) { $requestUrl .= "&"; } $first = false; $requestUrl .= $n . "=" . $v; } return $requestUrl; } function httpPost($url) { global $apiKey; $curl = curl_init($url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_USERAGENT, "curl/7.80.0"); curl_setopt($curl, CURLOPT_HTTPHEADER, array( "X-BX-APIKEY:".$apiKey, )); $response = curl_exec($curl); curl_close($curl); return $response; } function placeMarketOrder(string $symbol, string $side, string $quantity, string $positionSide) { // interface info $path = "/openApi/swap/v2/trade/order"; // interface params $params = array(); $params['symbol'] = $symbol; $params['side'] = $side; $params['type'] = "MARKET"; $params['quantity'] = $quantity; $params['positionSide'] = $positionSide; $date = new DateTime(); $params['timestamp'] = $date->getTimestamp()*1000; // generate signature $originString = getOriginString($params); $signature = getSignature($originString); $params["signature"] = $signature; // send http request $requestUrl = getRequestUrl($path, $params); $result = httpPost($requestUrl); echo "\t"; echo $result; echo "\n"; } echo "placeMarketOrder:\n"; placeMarketOrder("LINK-USDT", "BUY", "5", "LONG"); ?>
内容的提问来源于stack exchange,提问作者koruitch
相关产品推荐
相关产品推荐

