Binance REST API - Placing a PHP Order (POST) via Query String - php

I am struggling using Binance's REST API. I have managed to get working GET request via query string such as pinging the server, ticker information, etc. My challenge now is performing POST request via query string using cURL. I have been scraping code from various places and referring back to the API to get pieces to work but I am unsure as to why I am getting this error returned from the result... {"code":-1102,"msg":"Mandatory parameter 'signature' was not sent, was empty/null, or malformed."}
(ERROR SHOWN ON WEBPAGE). I echo out the signature and its a load of gibberish so I would believe that the hash_hmac performed at the top would be working, but honestly I got pretty lucky making the GET request work. Does anyone have any suggestions as to why this would be broken? Thanks!
$apikey = "MYKEY";
$apisecret = "MYSECRET";
$timestamp = time()*1000; //get current timestamp in milliseconds
$signature = hash_hmac('sha256', "TRXBTC&type=market&side=buy&quantity=100.00&recvWindow=10000000000000000&timestamp=".$timestamp, $apisecret);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.binance.com/api/v3/order/test");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, "symbol=TRXBTC&type=market&side=buy&quantity=100.00&recvWindow=10000000000000000&timestamp=".$timestamp);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded","X-MBX-APIKEY: ".$apikey,"signature: ".$signature));
$response = curl_exec($ch);
curl_close($ch);
echo $response;

As per their API docs:
SIGNED endpoints require an additional parameter, signature, to be sent in the query string or request body.
You are sending the signature via neither of these methods and are instead sending it through the header.
Change this:
curl_setopt($ch, CURLOPT_POSTFIELDS, "symbol=TRXBTC&type=market&side=buy&quantity=100.00&recvWindow=10000000000000000&timestamp=".$timestamp);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded","X-MBX-APIKEY: ".$apikey,"signature: ".$signature));
To this:
curl_setopt($ch, CURLOPT_POSTFIELDS, "symbol=TRXBTC&type=market&side=buy&quantity=100.00&recvWindow=10000000000000000&timestamp=" . $timestamp . "&signature=" . $signature);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded","X-MBX-APIKEY: ".$apikey));

<?php
$secret = "F................";
$key = "D.................";
$s_time = "timestamp=".time()*1000;
$sign=hash_hmac('SHA256', $s_time, $secret);
$url = "https://api.binance.com/api/v3/account?".$s_time.'&signature='.$sign;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-MBX-APIKEY:'.$key));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
$result = json_decode($result, true);
echo '<pre>';
var_dump($result);
echo '</pre>';
?>

Here is an example, using php-curl-class
// Variables
// url, key and secret is on separate file, called using require once
$endPoint = "/api/v3/order/test";
$coin = "BTC";
$fiat = "EUR";
$symbol = $coin . "" . $fiat;
$side = "BUY";
$type = "LIMIT";
$timeInForce = "GTC";
$quantity = 1;
$price = 10000;
$timestamp = time();
// Constructing query arrays
queryArray = array(
"symbol" => $symbol,
"side" => $side,
"type" => $type,
"timeInForce" => $timeInForce,
"quantity" => $quantity,
"price" => $price,
"timestamp" => $timestamp*1000
);
$signature = hash_hmac("sha256", http_build_query($queryArray), $secret);
$signatureArray = array("signature" => $signature);
$curlArray = $queryArray + $signatureArray;
// Curl : setting header and POST
$curl->setHeader("Content-Type","application/x-www-form-urlencoded");
$curl->setHeader("X-MBX-APIKEY",$key);
$curl->post($url . "" . $endPoint, $curlArray);
if ($curl->error) {
echo 'Error: ' . $curl->errorCode . ': ' . $curl->errorMessage . "\n";
}
$order = $curl->response;
print_r($order);

I had the same problem, and nothing of above doesn't helped.
So I finaly figured out how to make order on my way.
So, maybe this helps someone.
function Kupovina($buy_parametri) {
$key = "xxxxxxxxxxxxxxx";
$secret = "xxxxxxxxxxxx";
$s_time = "timestamp=".time()*1000;
$timestamp = time()*1000; //get current timestamp in milliseconds
$sign = hash_hmac('sha256', $buy_parametri."&timestamp=".$timestamp, $secret);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.binance.com/api/v3/order");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $buy_parametri."&".$s_time."&signature=".$sign);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded","X-MBX-APIKEY: ".$key));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
$buy_parametri = "symbol=BTCUSDT&type=market&side=buy&quantity=0.00086";
Call function:
Kupovina($buy_parametri);

Related

Binance API - 1101 - duplicated value for Symbol parameter

I'm trying to call Binance API via PHP code. But I'm getting the following response
{"code":-1101,"msg":"Duplicate values for parameter 'symbol'."}
Even though there is no duplicated value inside the symbol param, its not even an array, here is the code ->
$apiKey = '';
$apiSecret = '';
$url = 'https://api.binance.com/api/v3/order/test';
$data = [
'symbol' => 'BTCUSDT',
'side' => self::SIDE_BUY,
'type' => 'MARKET',
'quantity' => 0.01,
];
$timestamp = time()*1000; //get current timestamp in milliseconds
$query_str = [];
$query_str = $data;
$query_str['timestamp'] = $timestamp;
$query_str = http_build_query($query_str);
$signature = hash_hmac('sha256', $query_str, $apiSecret);
$query_str .= "&signature=" . $signature;
//Decide content type
$content_type = ["Content-Type: application/x-www-form-urlencoded","X-MBX-APIKEY: ".$apiKey];
// Final url
$url .= '?' . $query_str;
$ch = #curl_init();
#curl_setopt($ch, CURLOPT_HEADER, false);
#curl_setopt($ch, CURLOPT_URL, $url);
#curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
#curl_setopt($ch, CURLOPT_HTTPHEADER, $content_type);
#curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
#curl_setopt($ch, CURLOPT_TIMEOUT, 10);
#curl_setopt($ch, CURLOPT_POSTFIELDS, $query_str);
$response = #curl_exec($ch);
$http_code = #curl_getinfo($ch, CURLINFO_HTTP_CODE);
#curl_close($ch);
at the last part of your code you build your final $url, but $url will be separate from other options/parameters... In the way you do it now, symbol and any other parameter will be posted twice.
So remove
$url .= '?' . $query_str;
and the error is gone!
Hope this will work out fine for you.

Issue sending post request to API | PHP

Essentially I need to send the appropriate POST request to the following Parcel Tracking API that return the shipping data from the courier provided:
API Doc: https://www.kd100.com/docs/real-time-shipment-tracking
The problem I am having, is the response:
[code] => 104
[message] => Invalid signature
Can someone please have a look at my request below and tell me if I've made a mistake based on the doc? Assuming the Key, Secret Key and Tracking data is correct, my request should be completely valid.
My POST Request so far:
$key = 'KEY';
$secret = 'SECRET KEY';
$param = array (
'carrier_id' => 'usps',
'tracking_number' => 'TRACKING #'
);
$post_data = array();
$post_data['param'] = json_encode($param, JSON_UNESCAPED_UNICODE);
$header_data = array();
$header_data['API-Key'] = $key;
$sign = md5($post_data['param'].$key.$secret);
$header_data['signature'] = strtoupper($sign);
$url = 'https://www.kd100.com/api/v1/tracking/realtime';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"signature: $sign",
"API-Key: $key"
));
$result = curl_exec($ch);
$data = json_decode($result, true);
echo '<br/><br/>Start:<br/><pre>';
echo print_r($data);
echo '</pre>';
Your signature is not in uppercase. You set $sign variable but never actually set uppercase to it. You actually set uppercase to $header_data['signature'] and then never use it.
$sign = md5($post_data['param'].$key.$secret);
$header_data['signature'] = strtoupper($sign);
Your problem should be solved if you write it like this:
$sign = strtoupper(md5(post_data['param'].$key.$secret));
Remember to clean your code. You don't actually use $header_data anywhere

Uniquely identify iOS device with DeviceCheck API and server side php code not working

I'm getting error : Missing or incorrectly formatted payload
I'm generating device token from Apple DeviceCheck API in swift language with real device and also passing Transaction ID to this php api.
jwt token generating successfully with this code but further code not working with apple query bit api.
This is my server side code in php :
<?php
require_once "vendor/autoload.php";
use Zenstruck\JWT\Token;
use Zenstruck\JWT\Signer\OpenSSL\ECDSA\ES256;
use \Ramsey\Uuid\Uuid;
$deviceToken = (isset($_POST["deviceToken"]) ? $_POST["deviceToken"] : null);
$transId = (isset($_POST["transId"]) ? $_POST["transId"] : null);
function generateJWT($teamId, $keyId, $privateKeyFilePath) {
$payload = [
"iss" => $teamId,
"iat" => time()
];
$header = [
"kid" => $keyId
];
$token = new Token($payload, $header);
return (string)$token->sign(new ES256(), $privateKeyFilePath);
}
$teamId = "#####";// I'm passing My team id
$keyId = "#####"; // I'm passing my key id
$privateKeyFilePath = "AuthKey_4AU5LJV3.p8";
$jwt = generateJWT($teamId, $keyId, $privateKeyFilePath);
function postReq($url, $jwt, $bodyArray) {
$header = [
"Authorization: Bearer ". $jwt
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $bodyArray); //Post Fields
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$server_output = curl_exec($ch);
//$info = curl_getinfo($ch);
// print_r($info);
//echo 'http code: ' . $info['http_code'] . '<br />';
//echo curl_error($ch);
curl_close($ch);
return $server_output;
}
$body = [
"device_token" => $deviceToken,
"transaction_id" => $transId,
"timestamp" => ceil(microtime(true)*1000)
];
$myjsonis = postReq("https://api.development.devicecheck.apple.com/v1/query_two_bits", $jwt, $body);
echo $myjsonis;
?>
Where is problem in this code? Or any other solution in php code.
Is there anything that I'm missing.
I just checked the Docs. They don't want POST fields like a form, they want a JSON body instead. Here's a snippet of code that you should be able to tweak to do what you require:
$data = array("name" => "delboy1978uk", "age" => "41");
$data_string = json_encode($data);
$ch = curl_init('http://api.local/rest/users');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
Actually, looking again at your code, it could be as simple as running json_encode() on your array.

I cant create an order with kucoin api with php

Hello im using that code to create buy order but it shows me that error "{"code":"UNAUTH","msg":"Signature verification failed","success":false,"timestamp":1517154443105}"
$ku_key = 'KEY';
$ku_secret = 'SECRET';
$host = "https://api.kucoin.com";
$nonce = round(microtime(true) * 1000);
$endpoint = "/v1/order";
$querystring = "symbol=POE-BTC&price=0.00000748&amount=5514.70588235&type=BUY";
$signstring = $endpoint.'/'.$nonce.'/'.$querystring;
$hash = hash_hmac('sha256', base64_encode($signstring) , $ku_secret);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host . $endpoint);
$headers = [ 'KC-API-SIGNATURE:' . $hash, 'KC-API-KEY:' . $ku_key, 'KC-API-NONCE:' . $nonce, 'Content-Type:application/json' ];
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; Kucoin Bot; '.php_uname('a').'; PHP/'.phpversion().')' );
/*
YOU CAN USE THIS SECTION, I USE BOTH OF THEM WITH THIS AND WITHOUT THIS. NOT WORKING WITH BOTH.
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "symbol=POE-BTC&price=0.00000748&amount=5514.70588235&type=BUY");
*/
curl_setopt($ch, CURLOPT_URL, $host . $endpoint);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = curl_exec($ch);
var_dump($data);
I was facing the same error message today when I was implementing the KuCoin API in my trader software. However, I got it working. Please find my working solution below:
/**
*
* #see https://kucoinapidocs.docs.apiary.io/#introduction/authentication/signature-calculation
*
*/
private function signedRequest($endpoint, $params = array())
{
$ch = curl_init();
// Must be synced, KuCoin rejects requests > 3s
$nonce = round(microtime(true) * 1000);
// Build the data string.
// Note - According documentation:
// Arrange the parameters in ascending alphabetical order (lower cases first)
$queryString = http_build_query($params, '', '&');
// Splice string for signing
$auth = $endpoint . '/' . $nonce . '/' . $queryString;
// Make a base64 encoding of the completed string
$signedStr = base64_encode($auth);
$signature = hash_hmac('sha256', $signedStr, $this->secret);
$headers = array (
'KC-API-KEY:' . $this->key,
'KC-API-NONCE:' . $nonce,
'KC-API-SIGNATURE:' . $signature,
);
// POST is not allowed so we attach the parameter to the url
$curl = $this->base . $endpoint . "?" . $queryString;
// make the request
curl_setopt($ch, CURLOPT_URL, $curl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// do not print output to screen
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
return $result;
}
Tested with endpoint '/v1/account/balances'
public function getWalletBalance()
{
$params = array(
'limit' => '12',
'page' => '1'
);
$balance = $this->signedRequest("/v1/account/balances", $params);
return $this->_getFormattedBalance($balance);
}
You need to order your params alphabetically in both the query string and post request. Their docs need a little improvement but this is stated in them somewhere.
$querystring = "amount=5514.70588235&price=0.00000748&symbol=POE-BTC&type=BUY";
curl_setopt($ch, CURLOPT_POSTFIELDS, "amount=5514.70588235&price=0.00000748&symbol=POE-BTC&type=BUY");

JSON RPC 2.0 API Call using CURL in PHP - Changelly API

I am trying to call changelly API with below codes but it is returning "Unauthorized" in response.
Appreciate if someone can help in identifying the mistake I am making in below code.
$API_URL = 'https://api.changelly.com';
$API_KEY = 'XXXXX';
$API_SECRET = 'XXXXX';
$message = array();
$message['jsonrpc'] = '2.0';
$message['method'] = 'getMinAmount';
$message['params'] = array('from' => 'BTC', 'to' => 'LTC');
$message['id'] ='12345';
$data = json_encode($message);
$sign = hash_hmac('SHA512', $data, $API_SECRET);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_URL);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_GET, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json",'Authorization:api-key: '.$API_KEY.':sign: '.$sign));
$final_result = curl_exec($ch);
curl_close($ch);
echo '<pre>';
print_r($final_result);
Changelly API guide is at https://changelly.com/developers
Thanks
in your code you have wrong set of headers.
please check this example: https://github.com/changelly/changelly-examples/blob/master/php/example.php, hope it helps.

Categories