I'm trying to connect to the Bitunix API and change the margin mode using PHP. I followed the documentation provided on their web site but keep encountering a signature error message.
I've attempted several changes in my code but haven't been able to resolve the issue.
Could anyone help me understand what might be causing this error and how to properly connect to the API? Any insights or examples would be greatly appreciated.
Bitunix API Documentation : .html
Here's a snippet of my code for API class reference:
<?php
namespace App\Classes\Api;
use GuzzleHttp\Client;
class BitunixFuturesApi{
public string $base_url = "/";
public string $klineE = "api/v1/futures/market/kline";
public string $marginModeE = "api/v1/futures/account/change_margin_mode";
public string $apiKey = "random";
public string $secretKey = "random";
public function set_margin_mode($symbol="BTCUSDT", $marginMode = "ISOLATED", $marginCoin = "USDT"):array{
try{
$client = new Client();
$params = [
"marginMode" => $marginMode,
"symbol" => $symbol,
"marginCoin" => $marginCoin
];
$apiKey = $this->apiKey;
$secretKey = $this->secretKey;
$nonce = bin2hex(random_bytes(16));
$queryParamsString = '';
ksort($params);
foreach ($params as $key => $value) {
$queryParamsString .= $key . $value;
}
$body = json_encode($params);
$timestamp = (int)(microtime(true)*1000);
$digest = hash('sha256' , $nonce.$timestamp.$apiKey.$queryParamsString.$body);
$sign = hash('sha256', $digest.$secretKey);
$response = $client->post($this->base_url.$this->marginModeE,[
'headers'=>[
'api-key' => $apiKey,
'sign' =>$sign,
'timestamp' => $timestamp,
'nonce'=>$nonce,
'Content-Type'=> 'application/json'
],
'json'=>$params
]);
$response = json_decode($response->getBody()->getContents(),false,512,JSON_THROW_ON_ERROR);
if($response->code ==0){
return ['success'=>true, 'message'=>"Margin mode changed successfully", 'data' => $response->data];
}
return ['success'=>false, 'message'=>"Error changing margin mode", 'data' => $response->msg, 'code'=>$response->code];
}catch(\Exception $e){
return ['success'=>false, 'message'=>$e->getMessage(),'line'=>$e->getLine(),'file'=>$e->getFile(), 'data' => ''];
}
}
}
Here's a snippet of my code for controller reference:
<?php
namespace App\Http\Controllers\Dashboard;
use App\Classes\Api\BitunixFuturesApi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class TradeController extends Controller
{
public function __construct(){
$this->middleware('auth');
}
public function index(){
$bit = new BitunixFuturesApi();
$data = $bit->set_margin_mode("BTCUSDT", "CROSS");
return view('dashboard.trade')->with('data',$data);
}
}
And here is my error:
I'm trying to connect to the Bitunix API and change the margin mode using PHP. I followed the documentation provided on their web site but keep encountering a signature error message.
I've attempted several changes in my code but haven't been able to resolve the issue.
Could anyone help me understand what might be causing this error and how to properly connect to the API? Any insights or examples would be greatly appreciated.
Bitunix API Documentation : https://openapidoc.bitunix.com/doc/common/sign.html
Here's a snippet of my code for API class reference:
<?php
namespace App\Classes\Api;
use GuzzleHttp\Client;
class BitunixFuturesApi{
public string $base_url = "https://fapi.bitunix.com/";
public string $klineE = "api/v1/futures/market/kline";
public string $marginModeE = "api/v1/futures/account/change_margin_mode";
public string $apiKey = "random";
public string $secretKey = "random";
public function set_margin_mode($symbol="BTCUSDT", $marginMode = "ISOLATED", $marginCoin = "USDT"):array{
try{
$client = new Client();
$params = [
"marginMode" => $marginMode,
"symbol" => $symbol,
"marginCoin" => $marginCoin
];
$apiKey = $this->apiKey;
$secretKey = $this->secretKey;
$nonce = bin2hex(random_bytes(16));
$queryParamsString = '';
ksort($params);
foreach ($params as $key => $value) {
$queryParamsString .= $key . $value;
}
$body = json_encode($params);
$timestamp = (int)(microtime(true)*1000);
$digest = hash('sha256' , $nonce.$timestamp.$apiKey.$queryParamsString.$body);
$sign = hash('sha256', $digest.$secretKey);
$response = $client->post($this->base_url.$this->marginModeE,[
'headers'=>[
'api-key' => $apiKey,
'sign' =>$sign,
'timestamp' => $timestamp,
'nonce'=>$nonce,
'Content-Type'=> 'application/json'
],
'json'=>$params
]);
$response = json_decode($response->getBody()->getContents(),false,512,JSON_THROW_ON_ERROR);
if($response->code ==0){
return ['success'=>true, 'message'=>"Margin mode changed successfully", 'data' => $response->data];
}
return ['success'=>false, 'message'=>"Error changing margin mode", 'data' => $response->msg, 'code'=>$response->code];
}catch(\Exception $e){
return ['success'=>false, 'message'=>$e->getMessage(),'line'=>$e->getLine(),'file'=>$e->getFile(), 'data' => ''];
}
}
}
Here's a snippet of my code for controller reference:
<?php
namespace App\Http\Controllers\Dashboard;
use App\Classes\Api\BitunixFuturesApi;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class TradeController extends Controller
{
public function __construct(){
$this->middleware('auth');
}
public function index(){
$bit = new BitunixFuturesApi();
$data = $bit->set_margin_mode("BTCUSDT", "CROSS");
return view('dashboard.trade')->with('data',$data);
}
}
And here is my error:
I don't know if you got this working. After much testing, it looks like the only problem in your code is the timestamp. Use date('YmdHisz')
Looks like $nonce can be any random string. Length does not appear to matter. I used a simple random alpha-numeric string generator with various random lengths. All worked.
Also, if the API call has no url parameters, $queryParamsString should be excluded from the hash. If it has no POST data, the JSON $body should be excluded from the hash.
Sign signature error
which probably means there's something wrong with your$sign
. – ewokx Commented Jan 2 at 1:26$sign
. Unfortunately, that's the limit of my understanding. – ewokx Commented Jan 2 at 1:28timestamp
in the digest? Looking at the docs it looks like a date time in the format:YmdHis
. Example in the doc:timestamp = "20241120123045"
– Raghavendra N Commented Jan 2 at 6:21$timestamp = date("YmdHis");
– MohsenCreative Commented Jan 2 at 12:54queryParams
and thebody
. I believe it is supposed to be one or the other. Since you're making a POST request, the parameters will be in thebody
, so thequeryParams
should be empty. 2) The docs say the nonce is a 32-bit string, whereas you're providing a 32-byte string. Try usingstr()->random(4)
for the nonce. 3) Regarding the timestamp, the docs say the timestamp is in milliseconds, so your original posted code is correct for that. Their examples do not match their docs very well. – patricus Commented Jan 2 at 16:59