Binance 400 response and duplicate values for a parameter detected - php

still trying to get my head around API's and connections.
I am trying to do a buy order to Binance but keep getting a 400 response. I know it's been an issue for some others but I just can't seem to suss out where I am going wrong. So hoping someone can help me out.
It's only issues with POST's, all the GET requests are working fine, and so to the signature and timestamp... or at least I am getting responses for my account so I assume so.
The first CURL is just for the serverTime, but the second CURL is for a buy/sell order.
This is the response I am getting now...
"Object ( [code] => -1102 [msg] => Mandatory parameter 'side' was not
sent, was empty/null, or malformed. )"
If I type the in the string manually it works just fine, but for one reason or another when I pass $qs it presents the above fault. I echoed $qs to the screen and copied that instead of passing $qs and it worked when I put in the new timestamp. I am stumped...
"symbol=TRXUSDC&side=SELL&type=LIMIT&timeInForce=GTC&quantity=63000.00000000&price=0.02550000&recvWindow=1000000&timestamp=1550922237310"
any advice?
$header = array('X-MBX-APIKEY:' . KEY);
$url = BINANCE . 'api/v1/time';
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_ENCODING, "");
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($curl, CURLOPT_URL,$url);
$response = curl_exec($curl);
if (FALSE === $response){
echo curl_error($curl), curl_errno($curl);
}
$serverTime = json_decode($response);
curl_close($curl);
$url = BINANCE . "api/v3/order";
$signature = NULL;
$queryString = NULL;
$query = array(
"symbol" => "TRXUSDC",
"side" => "SELL",
"type" => "LIMIT",
"timeInForce" => "GTC",
"quantity" => number_format(63000.00000000,8,'.',''),
"price" => number_format(0.02550000,8,'.',''),
"recvWindow" => 1000000,
"timestamp" => $serverTime->serverTime);
$qs = htmlentities(http_build_query(array_unique($query)));
$query['signature'] = hash_hmac('SHA256', $qs, SECRET );
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_ENCODING, "application/x-www-form-urlencoded");
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl,CURLOPT_FAILONERROR,FALSE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS,$qs);
curl_setopt($curl, CURLOPT_URL, $url);
$response = curl_exec($curl);
if (FALSE === $response){
echo curl_error($curl).':'.curl_errno($curl);
}
$obj = json_decode($response);
curl_close($curl);

I tried this code and var_dump $qs
symbol=BTCUSDT&side=BUY&...
so I think you must remove amp;

Based on Binance spot api docs:
It is recommended to use a small recvWindow of 5000 or less! The max cannot go beyond 60,000!
so edit your query params with:
"symbol=TRXUSDC&side=SELL&type=LIMIT&timeInForce=GTC&quantity=63000.00000000&price=0.02550000&recvWindow=60000&timestamp=1550922237310"
Also you can check your other query params with exchange info that you can get with https://api.binance.com/api/v3/exchangeInfo that we have for your symbol:
{
"symbol": "TRXUSDC",
"status": "TRADING",
"baseAsset": "TRX",
"baseAssetPrecision": 8,
"quoteAsset": "USDC",
"quotePrecision": 8,
"quoteAssetPrecision": 8,
"baseCommissionPrecision": 8,
"quoteCommissionPrecision": 8,
"orderTypes": [
"LIMIT",
"LIMIT_MAKER",
"MARKET",
"STOP_LOSS_LIMIT",
"TAKE_PROFIT_LIMIT"
],
"icebergAllowed": true,
"ocoAllowed": true,
"quoteOrderQtyMarketAllowed": true,
"isSpotTradingAllowed": true,
"isMarginTradingAllowed": false,
"filters": [
{
"filterType": "PRICE_FILTER",
"minPrice": "0.00001000",
"maxPrice": "1000.00000000",
"tickSize": "0.00001000"
},
{
"filterType": "PERCENT_PRICE",
"multiplierUp": "5",
"multiplierDown": "0.2",
"avgPriceMins": 5
},
{
"filterType": "LOT_SIZE",
"minQty": "0.10000000",
"maxQty": "9000000.00000000",
"stepSize": "0.10000000"
},
{
"filterType": "MIN_NOTIONAL",
"minNotional": "10.00000000",
"applyToMarket": true,
"avgPriceMins": 5
},
{
"filterType": "ICEBERG_PARTS",
"limit": 10
},
{
"filterType": "MARKET_LOT_SIZE",
"minQty": "0.00000000",
"maxQty": "659177.02430556",
"stepSize": "0.00000000"
},
{
"filterType": "MAX_NUM_ORDERS",
"maxNumOrders": 200
},
{
"filterType": "MAX_NUM_ALGO_ORDERS",
"maxNumAlgoOrders": 5
}
],
"permissions": [
"SPOT"
]
}
for other possible reasons check spot api docs in the link https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md

I tested the code and saw a few glitches in it :
$qs = htmlentities(http_build_query(array_unique($query)));
gave me an error ({"code":-1102,"msg":"Mandatory parameter 'side' was not sent, was empty/null, or malformed."}), so i replaced it with:
$qs = http_build_query(array_unique($query));
After that you created your signature, but never added it to you request. So do the following :
$signature = hash_hmac('sha256', $qs, $apiSecret);
$qs .= "&signature=" . $signature;
Also update your 'recvWindow' to a max of 60000 (I suggest 50000 or less (see the answer of #Tofiq Samali)) and you are ready to go!

Related

Accessing data sent to callback URL

Following a successful response from an API Request to M-PESA where the following JSON code is printed:
{ "MerchantRequestID":"2690XXXXXXX", "CheckoutRequestID":"xx_XX_2779308581984", "ResponseCode": "0", "ResponseDescription":"Success. Request accepted for processing", "CustomerMessage":"Success. Request accepted for processing" }
I would like to access the data sent to my callback url: https://xxxxxxxxxxxxxxxxx.ngrok.io/processL/transact.php . Despite expecting the code to change accordingly upon cancellation or payment, nothing happens although when I inspect the response on the ngrok local tunnel online interface, I see my expected results only that I do not know how to acquire and generate some action with them. Below is the code making the API Request and the results which I expect to be sent to my call back url but in vain.
<!-- transact.php -->
<?php
if (isset($_POST['submit'])) {
$Passkey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$Amount= $_POST['amt'];
$BusinessShortCode = '174379';
$PartyA =$_POST['phone'];
$AccountReference =$_POST['name'];
$TransactionDesc = 'test';
$Timestamp =date('YmdHis');
$Password = base64_encode($BusinessShortCode.$Passkey.$Timestamp);
$headers=['Content-Type:application/json; charset=utf8'];
$initiate_url='https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest';
$callBackURL ='https://xxxxxxxxxxxxxxxxx.ngrok.io/processL/transact.php';
function accessToken() {
$ConsumerKey = 'ubYsxxxxxxxxxxxxx';
$ConsumerSecret = 'xxxxxxxxxxxxx';
$credentials = base64_encode($ConsumerKey.":".$ConsumerSecret);
$url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic ".$credentials,"Content-Type:application/json"));
curl_setopt($curl, CURLOPT_HEADER, false);
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($curl);
$access_token=json_decode($curl_response);
curl_close($curl);
return $access_token->access_token;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $initiate_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.accessToken()));
$curl_post_data = array(
'BusinessShortCode' =>$BusinessShortCode,
'Password' => $Password,
'Timestamp' => $Timestamp,
'TransactionType' => 'CustomerPayBillOnline',
'Amount' => $Amount,
'PartyA' => $PartyA,
'PartyB' => $BusinessShortCode,
'PhoneNumber' => $PartyA,
'CallBackURL' => $callBackURL,
'AccountReference' => $AccountReference,
'TransactionDesc' => $TransactionDesc
);
$data_string = json_encode($curl_post_data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
$curl_response = curl_exec($curl);
print_r($curl_response."<br>");
}
Upon acceptance of payment:
{
"Body": {
"stkCallback": {
"MerchantRequestID": "xxxxxxxxxxxxx",
"CheckoutRequestID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"ResultCode": 0,
"ResultDesc": "The service request is processed successfully.",
"CallbackMetadata": {
"Item": [
{
"Name": "Amount",
"Value": 1
},
{
"Name": "MpesaReceiptNumber",
"Value": "xxxxxxxxxxxxx"
},
{
"Name": "Balance"
},
{
"Name": "TransactionDate",
"Value": 20210927101413
},
{
"Name": "PhoneNumber",
"Value": xxxxxxxxxxxxx
}
]
}
}
}
};
When payment is cancelled:
{
"Body": {
"stkCallback": {
"MerchantRequestID": "xxxxxxxxxxxxx",
"CheckoutRequestID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"ResultCode": 1032,
"ResultDesc": "Request cancelled by user"
}
}
};
I need some guidance.
The documentation for json_decode() is your friend. If you pass true as the second argument then it returns your JSON data as associative arrays.
$access_token=json_decode($curl_response, true);
// Check the response value
$result = $access_token['Body']['stkCallback']['ResultCode'] ?? null;
if ($result == 0) {
// Success
}

How can I create a form, and create a task on a ClickUp task

For few days I am trying to use the ClickUp API. The goal is:
We have a form, and when the form is submitted, it creates a task on a space on ClickUp.
It is a PHP form, and even with the API Doc here, I am not able to understand how it is working.
I found this: https://jsapi.apiary.io/apis/clickup20/reference/0/tasks/create-task.html
But it requires some access token, from the user, but normally, It's not supposed to work like that.
Here the script that I have taken from the doc:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.clickup.com/api/v2/list/17229593/task");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{
\"name\": \"New Task Name\",
\"content\": \"New Task Content\",
\"assignees\": [
183
],
\"tags\": [
\"tag name 1\"
],
\"status\": \"Open\",
\"priority\": 3,
\"due_date\": 1508369194377,
\"due_date_time\": false,
\"time_estimate\": 8640000,
\"start_date\": 1567780450202,
\"start_date_time\": false,
\"notify_all\": true,
\"parent\": null,
\"custom_fields\": [
{
\"id\": \"0a52c486-5f05-403b-b4fd-c512ff05131c\",
\"value\": 23
},
{
\"id\": \"03efda77-c7a0-42d3-8afd-fd546353c2f5\",
\"value\": \"Text field input\"
}
]
}");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: "access_token"",
"Content-Type: application/json"
));
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
When I try that, I get the error 500, and when I go to the API's link, I get an Auth problem.
Is someone know something about this API?

Google Speech to text API just returns false

I have tried everything I know to get the Google Speech to text API to return anything but false but to no avail. I made sure my flac file was a single channel file (ffmpeg -i test.flac -ac 1 test1.flac) - still nothing. What am I doing wrong?
<?php
// Your API Key goes here.
$apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$audioFile = realpath(__DIR__ . '/test.flac');
$url="https://speech.googleapis.com/v1/speech:recognize?key={$apiKey}";
$audioFileResource = fopen($audioFile, 'r');
$base64Audio = base64_encode(stream_get_contents($audioFileResource));
$settings=array(
'config'=> array(
'encoding'=>'FLAC',
'sampleRateHertz'=>44100,
'maxAlternatives' => 3,
'languageCode' => 'en-US'
),
'audio'=>array(
'content'=>$base64Audio
)
);
$json=json_encode($settings);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($ch, CURLOPT_POST, 1 );
curl_setopt($ch, CURLOPT_POSTFIELDS, $json );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result=curl_exec ($ch);
var_dump($result);
exit;
UPDATE: I have updated the code so that this now works. I had two things wrong. First it was "sampleRateHertz" instead of "sampleRate" in the config settings. Secondly, I had to disable the SSL verification on the peer. This now works.
Returns the following:
D:\>php GoogleSpeechToText_example.php
string(320) "{
"results": [
{
"alternatives": [
{
"transcript": "the quick brown fox jumped over the lazy dog",
"confidence": 0.9850106
},
{
"transcript": "the quick brown fox jumps over the lazy dog",
"confidence": 0.90610087
}
]
}
]
}
Just by luck I figured out the problem. I had to add the following line of code:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

Obtaining highcharts image URL from PHP

I need to get a highcharts image, and I found a code to resolve my problem, obtaining the name of the image via ajax, and then I paste before the url of the Highcharts API, and I can download the image in PHP, now, I want to do this process in PHP, since the name, until the download; I have this code to get the name of highcharts image:
var optionsStr = JSON.stringify({
"xAxis": {
"categories": [
"PRUEBA",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
]
},
"series": [
{
"data": [1, 3, 2, 4],
"type": "line"
},
{
"data": [5, 3, 4, 2],
"type": "line"
}
]
}),
exportUrl ='https://export.highcharts.com/';
dataString = encodeURI('async=true&type=image/jpeg&width=800&options=' + optionsStr);
$.ajax(
{
type: 'POST',
data: dataString,
url: exportUrl,
success: function(data)
{
console.log('get the file from relative url: ', data);
grafica=exportUrl+data;
},
error: function(err)
{
console.log('error', err.statusText)
}
});
I get the name of the graphic: charts/chart.9973ffbcf0d748d6aae04ef6ec01979c.jpeg
I want to know how get the same in PHP, I have this code:
$DataEncoded = json_encode(
array(
'xAxis'=>
array(
'categories'=> ['Ene','Feb', 'Mar', 'Abr']
),
'series'=>
array(
array(
'data'=>[1,2,3,4],
'type'=>'line'
),
array(
'data'=>[5,6,7,8],
'type'=>'line'
)
)
)
);
$DataExtra = 'async=true&type=image/jpeg&width=800&options=';
$dataString = urlencode('async=true&type=image/jpeg&width=800&options='.$DataEncoded);
$url ='https://export.highcharts.com/';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
$json=curl_exec($ch);
if(curl_errno($ch)){
echo "Entro al curl Error";
throw new Exception(curl_error($ch));
}
var_dump(json_decode($json));
curl_close($ch);
But I receive a fantastic: NULL. Someone made this before?
I tried making this process via Angular 5, but, I must to program a cron job to delegate the process, so, I decided to use PHP. I tried with file_get_contents() but the webservice give me: "No data chart found".
I suspect your issue is here:
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
I believe this is expecting a String or an Array.
This parameter can either be passed as a urlencoded string like 'para1=val1&para2=val2&...' or as an array with the field name as key and field data as value. If value is an array, the Content-Type header will be set to multipart/form-data. As of PHP 5.2.0, value must be an array if files are passed to this option with the # prefix. As of PHP 5.5.0, the # prefix is deprecated and files can be sent using CURLFile.
Consider trying the following:
$dataArray = array(
"async" => true,
"type" => "image/jpeg",
"width" => 800,
"options" => $DataEncoded
);
And...
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataArray);
Credit to #Patrick Q for catching the Encoding Type. You're not exactly sending it JSON encoded data, but Form data essentially.
I used the recommendations of Twisty and finally I obtain the name of the image, thank you so much.
$dataString = ('async=true&type=image/jpeg&width=800&options='.$DataEncoded);
$url ='https://export.highcharts.com/?';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$dataString);
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = "Accept: application/json";
$headers[] = "Content-Type: application/x-www-form-urlencoded";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);

Sending post JSON to an api - no output

I'm working with a new API and I'm trying to understand how to correctly login and send post requests to the api.
Here are some screenshots:
Also , should this authentication be done every time a request is sent or ??(it says something about a token every 8 hours in the notes)
Here is what I did so far but I'm getting no output from that print_r(probably because I haven't authenticated as shown in the notes(Something I don't know how to do correctly):
$data_string = '{
"nameOnCard":"Johnny",
"userDetail": {
"lastName":"Smith",
"firstName":"John",
"middleInitial":"xx",
"dateOfBirth":"1975-02-28",
"addressLine1":"222333 PEACHTREE PLACE",
"city":"Winchester",
"zipCode":"GU14 7JF",
"country":"GB",
"mobileNumber":"2071234567",
"landlineNumber":"57647564234",
"email":"demouser#mailinator.com",
"currencyCode":"EUR",
"externalReferenceId":"WC34930",
"registeredFromIp":"10.10.10.10",
"acceptTermsAndConditions": true,
"acceptEsign" : true
},
"channelType": "1",
"cardProgramId": "0",
"localeTime": "2013-06-04T00:00:00.000+05:00",
"refId": "1",
"dlvAddress": {
"addressLineOne":"222333 DELIVERY PLACE",
"city":"Winchester",
"zipCode":"GU14 7JF",
"country":"GB"
}
}';
$ch = curl_init('https://wcapi.wavecrest.in/apisandbox/cards');
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',
'Developerid: xxxxxxxxxx',
'Developerpassword: xxxxxxx',
'X-Method-Override: login',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
print_r($result);
Would appreciate if anyone can help me, thanks!
EDIT: other post got inactive , editing it wouldn't have helped me.

Categories