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.
Related
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 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×tamp=".$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×tamp=".$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×tamp=".$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×tamp=" . $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."×tamp=".$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);
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");
I'm trying to use Spreadshirt API to create a product on their platform, but i'm stuck with this weird error:
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML' in /home/anarchoi/public_html/test.php:102 Stack trace: #0 /home/anarchoi/public_html/test.php(102): SimpleXMLElement->__construct('') #1 {main} thrown in /home/anarchoi/public_html/test.php on line 102
Most of the code is just copied from their wiki so i really don't understand why it doesn't work.
I'm looking for help to understand where the error is coming from and why it is happening.
$productTypeId = "210";
$printTypeId = "17";
$printColorIds = "13,20";
$productTypeAppearanceId = "1";
$productTypePrintAreaId = "4";
$designId = "10438193";
// 1. Get shop data
$shopUrl = "http://api.spreadshirt.com/api/v1/shops/266497";
$ch = curl_init($shopUrl);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$result = curl_exec($ch);
// Close the handle
curl_close($ch);
$shop = new SimpleXMLElement($result);
$namespaces = $shop->getNamespaces(true);
// 2. Get product type data
$attributes = $shop->productTypes->attributes($namespaces['xlink']);
$productTypeUrl = $attributes->href . "/" . $productTypeId;
$ch = curl_init($productTypeUrl);
// echo "<br>$productTypeUrl<br>";
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$result = curl_exec($ch);
// Close the handle
curl_close($ch);
$productType = new SimpleXMLElement($result);
// 3. Get design data
$attributes = $shop->designs->attributes($namespaces['xlink']);
$designUrl = $attributes->href . "/" . $designId;
$ch = curl_init($designUrl);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$result = curl_exec($ch);
// Close the handle
curl_close($ch);
$design = new SimpleXMLElement($result);
// 4. Prepare product
// get positioning data for selected product type
$printArea = null;
foreach ($productType->printAreas->printArea as $current) {
if ($current['id'] == $productTypePrintAreaId) {
$printArea = $current;
}
}
$product = new SimpleXMLElement(getFileData("product.xml"));
$product->productType['id'] = $productTypeId;
$product->appearance['id'] = $productTypeAppearanceId;
$configuration = $product->configurations->configuration;
$configuration->printArea['id'] = $productTypePrintAreaId;
$configuration->printType['id'] = $printTypeId;
$configuration->offset->x =
((doubleval($printArea->boundary->size->width) - doubleval($design->size->width)) / 2);
$configuration->offset->y =
((doubleval($printArea->boundary->size->height) - doubleval($design->size->height)) / 4);
$image = $product->configurations->configuration->content->svg->image;
$image['width'] = $design->size->width;
$image['height'] = $design->size->height;
$image['designId'] = $designId;
$image['printColorIds'] = $printColorIds;
// 5. Create product
$attributes = $shop->products->attributes($namespaces['xlink']);
$productsUrl = $attributes->href;
$header = array();
$header[] = createSprdAuthHeader("POST", $productsUrl);
$header[] = "Content-Type: application/xml";
$ch = curl_init("$productsUrl"."?fullData=true");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $product->asXML());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$result = curl_exec($ch);
// Close the handle
curl_close($ch);
$productUrl = parseHttpHeaders($result, "Location");
$ch = curl_init($productUrl);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$result = curl_exec($ch);
// Close the handle
curl_close($ch);
$product = new SimpleXMLElement($result);
$resource = $product->resources->resource[0];
$attributes = $resource->attributes($namespaces['xlink']);
echo '<html><body>';
echo 'Product available at: ' . $productUrl . '</br>';
echo 'Product image is available at: ' . $attributes->href . '</br>';
echo '<img src="' . $attributes->href . '?width=1000"/>';
echo '</body></html>';
function createSprdAuthHeader($method, $url) {
$apiKey = "***";
$secret = "***";
$time = time()*1000;
$data = "$method $url $time";
$sig = sha1("$data $secret");
return "Authorization: SprdAuth apiKey=\"$apiKey\", data=\"$data\", sig=\"$sig\"";
}
function parseHttpHeaders( $header, $headername ) {
$retVal = array();
$fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header));
foreach( $fields as $field ) {
if( preg_match('/('.$headername.'): (.+)/m', $field, $match) ) {
return $match[2];
}
}
return $retVal;
}
function getFileData($file) {
$fp = fopen($file, "r");
$data = "";
while(!feof($fp)) {
$data .= fgets($fp, 1024);
}
fclose($fp);
return $data;
}
product.xml = https://www.ni-dieu-ni-maitre.com/product.xml
I stumbled upon similar issue when implementing Spreadshirt, looks like their API server is sending (at least some) content gzipped regardless of any Accept-Encoding headers. You can tell that it's your case by var_dumping the string before it's passed to SimpleXMLElement (as suggested by others) – if it's gibberish, it's very possible you have the same issue as I did.
Setting the curl option of CURLOPT_ENCODING to an empty string ('') fixed that for me – it "magically" turned on ungzipping the response (see man page for curl_setopt() for more information).
I want to grab json string, set objects and httpheaders in 1.php (for example). Get these values in JSON format and display in next page (2.php).
I tried to use CURL method. I m very new to PHP. Not sure whether CURL method is the best to POST data.. Session or cookie method no need. Is there any other method other than this to POST data?
1.PHP:
<?php
$data = array($item_type = "SubscriptionConfirmation";
$message = "165545c9-2a5c-472c-8df2-7ff2be2b3b1b";
$Token = "2336412f37fb687f5d51e6e241d09c805a5a57b30d712f794cc5f6a988666d92768dd60a747ba6f3beb71854e285d6ad02428b09ceece29417f1f02d6";
$TopicArn = "arn:aws:sns:us-east-1:123456789012:MyTopic";
$Message = "You have chosen to subscribe to the topic arn:aws:sns:us-east-1:123456789012:MyTopic.\nTo confirm ";
$SubscribeURL = "https://sns.us-east-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:us-east-1:123456789012:MyTopic&Token=2336412f37fb6";
$Timestamp = "2012-04-26T20:45:04.751Z";
$SignatureVersion = "1";
$Signature = "EXAMPLEpH+DcEwjAPg8O9mY8dReBSwksfg2S7WKQcikcNKWLQjwu6A4VbeS0QHVCkhRS7fUQvi2egU3N858fiTDN6bkkOxYDVrY0Ad8L10Hs3zH81mtnPk5uvvolIC1CXGu43obcgFxeL3khZl8IKvO61GWB6jI9b5+gLPoBc1Q=";
$SigningCertURL = "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem";);
$json_data = json_encode($data);
$ch = curl_init('http://example.com');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CAINFO, "/path/to/CA.crt");
curl_setopt($ch, CURLOPT_HTTPHEADER,array(
'Content-Type: application/json',
'Content-Length: ' . strlen($json_data))
);
$output = curl_exec($ch);
$result = json_decode($output);
echo $result;
?>
2.PHP:
How to post 1.php json value to 2.php.. either through CURL or other posting method.. Tried my best.. cant able to figure out the solution.
Thanks
1.php
$data = array(
'test' => 'data',
'new' => 'array');
$json_data = json_encode($data);
// Only work with your example, curl need full url
$request_url = 'http://teshdigitalgroup.com/2.php';
$ch = curl_init($request_url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($json_data))
);
$output = curl_exec($ch);
print_r($output);
AND 2.php
print_r(file_get_contents('php://input'));
// Response 1.php's request HTTP Header
function parseRequestHeaders() {
$headers = array();
foreach($_SERVER as $key => $value) {
if (substr($key, 0, 5) <> 'HTTP_') {
continue;
}
$header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
$headers[$header] = $value;
}
return $headers;
}
print_r(parseRequestHeaders());