$merchantRefNumber = $payment[ID];
$signature = $merchantCode.$merchantRefNumber.$secureKey;
$signature = hash('sha256', $signature);
$URL = ("https://www.atfawry.com/ECommerceWeb/Fawry/payments/status?merchantCode=".($merchantCode)."&merchantRefNumber=".($merchantRefNumber)."&signature=".($signature));
$response = file_get_contents($URL);
if ( $response )
{
this is the link it show from this code
https://www.atfawry.com/ECommerceWeb/Fawry/payments/status?merchantCode=CB8Q95Jr&merchantRefNumber=AGHUY&signature=135bfd157a9ac13931b512120609dc31ff31879
and it is should be show without amp; to be
https://www.atfawry.com/ECommerceWeb/Fawry/payments/status?merchantCode=CB8Q95Jr&merchantRefNumber=AGHUY&signature=135bfd157a9ac13931b512120609dc31ff31879
Try using http_build_query:
$url = "https://www.atfawry.com/ECommerceWeb/Fawry/payments/status";
$data = array(
'merchantCode' => $merchantCode,
'merchantRefNumber' => $merchantRefNumber,
'signature' => $signature
);
$response = file_get_contents($url . "?" . http_build_query($data));
See also: https://www.php.net/manual/en/function.http-build-query.php
Related
I found a sample github that is able to properly generate a signature for the API in question, their code is as follows:
so i found their github which has a sample in object oriented like this:
if ($api === 'private') {
$this->check_required_credentials();
$timestamp = $this->seconds();
$xPhemexRequestExpiry = $this->safe_integer($this->options, 'x-phemex-request-expiry', 60);
$expiry = $this->sum($timestamp, $xPhemexRequestExpiry);
$expiryString = (string) $expiry;
$headers = array(
'x-phemex-access-token' => $this->apiKey,
'x-phemex-request-expiry' => $expiryString,
);
$payload = '';
if ($method === 'POST') {
$payload = $this->json($params);
$body = $payload;
$headers['Content-Type'] = 'application/json';
}
$auth = $requestPath . $queryString . $expiryString . $payload;
$headers['x-phemex-request-signature'] = $this->hmac($this->encode($auth), $this->encode($this->secret));
}
$url = $this->urls['api'][$api] . $url;
return array( 'url' => $url, 'method' => $method, 'body' => $body, 'headers' => $headers );
}
my code is core and looks like this, and I can not seem to get the proper result of a valid signature, any guidance possible?
$epoch=strtotime(date('r', time()).'+2 days');
$data = '{"clOrdId":"123456","ordType":"LIMIT","symbol":"BTC-USD","side":"BUY","orderQty":"0.1","price":"100"}';
$content=("/orders".$epoch.$data);
//SECRET KEY
$str = 'cn87t3Z8wLw-OR626cuAZFIUhHT2z3XSfEt6X8OBSyFjU3Ny05ZWYyLTQ3ZjItODkwNy1mODlhNWMxM2UzMWY';
$decode= base64_decode($str);
$signature = hash_hmac('SHA256',$content,'$decode');
In short I need to send the signature inside the headers like so:
"x-phemex-request-signature: $signature)",
UPDATED CODE:
$epoch=strtotime(date('r', time()).'+5 minutes');
$data = '{"clOrdId":"123456","ordType":"LIMIT","symbol":"BTC-USD","side":"BUY","orderQty":"0.1","price":"100"}';
$content="/orders".$epoch.$data;
//SECRET KEY
$str = 'cn87t3Z8wLw-OR626cuAZFIUhHT2z3XSfEt6X8OBSyFkMjE0NjU3Ny05ZWYyLTQ3ZjItODkwNy1mODlhNWMxM2UzMWY';
$signature = hash_hmac('SHA256',$auth,'cn87t3Z8wLw-OR626cuAZFIUhHT2z3XSfEt6X8OBSy***5ZWYyLTQ3ZjItODkwNy1mODlhNWMxM2UzMWY');
$headers = array(
"accept: application/json",
//API KEY
"x-phemex-access-token:e92028ca-4704-4317-8149-c1c7a7f85226",
"Content-Type: application/json",
"x-phemex-request-expiry: $epoch",
//this right here is what we need to have working proper
"x-phemex-request-signature: $signature)",
);
The format of a proper signature looks like:
API REST Request URL: https://api.phemex.com/orders
Request Path: /orders
Request Query:
Request Body: {"symbol":"BTCUSD","clOrdID":"uuid-1573058952273","side":"Sell","priceEp":93185000,"orderQty":7,"ordType":"Limit","reduceOnly":false,"timeInForce":"GoodTillCancel","takeProfitEp":0,"stopLossEp":0}
Request Expiry: 1575735514
Signature: HMacSha256( /orders + 1575735514 + {"symbol":"BTCUSD","clOrdID":"uuid-1573058952273","side":"Sell","priceEp":93185000,"orderQty":7,"ordType":"Limit","reduceOnly":false,"timeInForce":"GoodTillCancel","takeProfitEp":0,"stopLossEp":0})
signed string is /orders1575735514{"symbol":"BTCUSD","clOrdID":"uuid-1573058952273","side":"Sell","priceEp":93185000,"orderQty":7,"ordType":"Limit","reduceOnly":false,"timeInForce":"GoodTillCancel","takeProfitEp":0,"stopLossEp":0}
I am trying to get Product Reviews from Amazon but getting this error ,
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Below is my code ,
define('AMAZON_URL','http://webservices.amazon.com/onca/xml?');
define('AMAZON_ACCESS_KEY',--access_key--);
define('AMAZON_SECRET_KEY',--secret_key--);
define('AMAZON_ASSOCIATE_TAG',--tag--);
$dr['model_no'] = --model_no--;
$dr['manufacturer'] = --manufacturer--;
//get amazon data
$timestamp = gmdate("Y-m-d\TH:i:s\Z");//rawurlencode(gmdate("Y-m-d\TH:i:s\Z"));
$url = "AWSAccessKeyId=".AMAZON_ACCESS_KEY;
$url .= "&AssociateTag=".AMAZON_ASSOCIATE_TAG;
$url .= "&IncludeReviewsSummary=True";
$url .= '&Keywords='.$dr['model_no'];
$url .= "&Manufacturer=".$dr['manufacturer'];
$url .= "&Operation=ItemSearch";
$url .= "&ResponseGroup=Reviews";
$url .= "&ReviewSort=HelpfulVotes";
$url .= "&SearchIndex=Electronics";
$url .= "&Service=AWSECommerceService";
$url .= "&Timestamp=".$timestamp;
$url .= "&Version=2013-05-31";
$prepend = "GET\nwebservices.amazon.com\n/onca/xml\n";
$prepend_string = $prepend . $url;
$signature = base64_encode(hash_hmac("sha256", $prepend_string, AMAZON_SECRET_KEY, True));
$signature = str_replace("+", "%2B", $signature);
$signature = str_replace("=", "%3D", $signature);
// $signature = base64_encode(hash_hmac("sha256", $prepend_string, AMAZON_SECRET_KEY, True));
$url = $url.'&Signature=' .$signature;
// $url = $url.'&Signature=' .rawurlencode($signature);
echo "$url\n";
$result = $this->data_api->call_amazon($url);
My call_amazon function is
public function call_amazon($url)
{
$url = AMAZON_URL.$url;
//initialize curl
echo "Caalling url: \n" . $url . "\n";
$ch = curl_init();
//initilize url to set which servvice to call
curl_setopt($ch, CURLOPT_URL, $url);
//to tell curl that post method is used
//tell that retrun value as string
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
//execute service now
$result = curl_exec($ch);
if(empty($result) || $result===FALSE){
return '<customError>
<status>400</status>
<response>false</response>
</customError>';
} else {
echo "$result \n";
//return response
return $result;
}
}
I had checked the docs and examples and signature looks ok to me. Any suggestions?
I am creating a Restful WebService with CakePHP 2 however, i am getting 500 Internal Server Error since i am not able to capture Post Data. The Rest Server is as below:
App::import ( 'Vendor', 'ExchangeFunctions', array ('file'=> 'exchange/exchangefunctions.php'));
class ExchangeController extends AppController
{
public $components = array('RequestHandler');
public
function index()
{
$exchange = new ExchangeFunctions();
$data = $this->request->data('json_decode');
$exchange->username = $_POST['username'];
$exchange->password = $_POST['password'];
$emailList = $exchange->listEmails();
$response = new stdClass();
$response->emailList = $emailList;
foreach($emailList->messages as $listid => $email)
{
$tempEmail = $exchange->getEmailContent(
$email->Id,
$email->ChangeKey,
TRUE,
$_POST['attachmentPath']
);
$response->emails[$tempEmail['attachmentCode']] = $tempEmail;
}
$this->set('response', $response);
$this->set('_serialize','response');
}
}
and the client goes as:
class ApitestController extends AppController
{
Public function index()
{
$this->layout = 'ajax';
$jRequestURLPrefix = 'http://localhost/EWSApi/';
$postUrl = $jRequestURLPrefix."exchange/index.json";
$postData = array(
'username' => 'username',
'password' => 'password',
'attachmentPath'=> $_SERVER['DOCUMENT_ROOT'] . $this->base . DIRECTORY_SEPARATOR . 'emailDownloads' . DIRECTORY_SEPARATOR . 'attachments'
);
$postData = json_encode($postData);
pr($postData);
$ch = curl_init( $postUrl );
$options = array(
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Content-Length: ' . strlen($postData)
),
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POSTFIELDS => $postData,
);
curl_setopt_array( $ch, $options );
$jsonString = curl_exec($ch);
curl_close($ch);
$data = json_decode($jsonString, FALSE);
echo $jsonString;
}
}
Not sure where i am messing up! Please help!
Ok, after a second look there are some more suspicious things. As already mentioned, your CURL request uses GET instead of POST.
$options = array(
...
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $postData,
);
Another thing is that you are encoding the POST data for your CURL call to JSON, but then you are trying to access it on the other side using $_POST, however there won't be anything, POST data would have to be key/value query string formatted in order to appear in $_POST. You have to read php://input instead, which may be what you were trying to do with
$data = $this->request->data('json_decode');
However you must use CakeRequest::input() for that purpose, and of course you must then use the $data variable instead of $_POST
$data = $this->request->input('json_decode');
$exchange->username = $data['username'];
$exchange->password = $data['password'];
....
$tempEmail = $exchange->getEmailContent(
$email->Id,
$email->ChangeKey,
TRUE,
$data['attachmentPath']
);
Also make double sure that your CURL request looks like expected:
$options = array(
...
CURLOPT_POSTFIELDS => $postData,
CURLINFO_HEADER_OUT => true // supported as of PHP 5.1.3
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo '<pre>';
print_r($info);
echo '</pre>';
I'm trying to obtain a request token from Twitter API in order to log in user with his twitter account and I keep getting a 401 response with "Failed to validate oauth signature and token". I'm doing this over PHP. I looked for similar questions but apparently I'm the only one crazy enough to do it from scratch without a library.
In their API documentation they talk about "percent encode" the values sent in the authorization header, I'm doing so with the urlencode() function, not sure if it's right.
To calculate the signature I use hash_hmac( 'SHA1', $signParameters, $hashKey), also not sure if it is the right one to use.
This is the request that gets generated, through cURL:
POST /oauth/request_token HTTP/1.1
Host: api.twitter.com
Accept: */*
Authorization: OAuth oauth_callback="http%3A%2F%2Fwww.soytumascota.com%2Ftwitter%2Fuser.php", oauth_consumer_key="MY_APP_KEY", oauth_nonce="0dde25902bde5f3b280f58ea642047cf", oauth_signature_method="HMAC_SHA1", oauth_timestamp="1334697987", oauth_version="1.0", oauth_signature="8313277875f20cd8a8631966a2ba273a5d13aeda"
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue
I would really appreciate any help you can give, thank you.
EDIT: Here's the code i've written so far.
<?php
DEFINE( 'CONSUMER_KEY', 'MY_APP_KEY' );
DEFINE( 'CONSUMER_SECRET', 'MY_APP_SECRET' );
$url = 'https://api.twitter.com/oauth/request_token';
//setting OAuth parameters
$Oauth = Array();
$Oauth['oauth_callback'] = 'http://www.soytumascota.com/twitter/user.php';
$Oauth['oauth_consumer_key'] = CONSUMER_KEY;
$Oauth['oauth_nonce'] = md5( $Oauth['oauth_callback'] . CONSUMER_KEY . time() );
$Oauth['oauth_signature_method'] = 'HMAC_SHA1';
$Oauth['oauth_timestamp'] = (string) time();
$Oauth['oauth_version'] = '1.0';
//signature and authorization header are calculated inside functions
$Oauth['oauth_signature'] = calculateSignature( 'POST', $url, $Oauth );
$authorization = getAuthorizationHeader( $Oauth );
ksort( $Oauth );
//setting and sending request using cURL
$curl_session = curl_init( $url );
curl_setopt( $curl_session, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl_session, CURLOPT_POST, true );
curl_setopt( $curl_session, CURLINFO_HEADER_OUT, true );
curl_setopt( $curl_session, CURLOPT_HTTPHEADER, Array( 'Authorization: ' . $authorization ) );
$result = curl_exec( $curl_session );
function getAuthorizationHeader( $parameters )
{
$authorization = 'OAuth ';
$j = count( $parameters );
foreach( $parameters as $key => $val )
{
$authorization .= $key . '="' . urlencode( $val ) . '"';
if( $j-- > 1 )
{
$authorization .= ', ';
}
}
return $authorization;
}
function calculateSignature( $method, $url, $parameters, $accessToken = '' )
{
foreach( $parameters as $key => $val )
{
$foo = urlencode( $key );
unset( $parameters[$key] );
$parameters[$foo] = urlencode( $val );
}
ksort( $parameters );
$signBase = '';
$j = count( $parameters );
foreach( $parameters as $key => $val )
{
$signBase .= "{$key}={$val}";
if( $j-- > 1 )
{
$signBase .= '&';
}
}
$signBase = strtoupper( $method ) . '&' . urlencode( $url ) . '&' . urlencode( $signBase );
$signKey = urlencode( CONSUMER_SECRET ) . '&' . urlencode( $accessToken );
$signature = hash_hmac( 'SHA1', $signParameters, $hashKey);
return $signature;
}
First, 'oauth_signature_method' must be 'HMAC-SHA1' (or nothing will work).
About "percent encode", they say in their API documentation https://dev.twitter.com/docs/auth/percent-encoding-parameters they require strings to be encoded according to RFC 3986 so you should use rawurlencode instead of urlencode.
To calculate the signature they say here https://dev.twitter.com/docs/auth/creating-signature that you have to use HMAC-SHA1 hashing algorithm and convert the raw output to base64, something like:
$signature = base64_encode(hash_hmac( 'SHA1', $signBase, $signKey, true));
And finally you may need to add
//no content
curl_setopt( $curl_session, CURLOPT_POSTFIELDS, '');
//no verify certs
curl_setopt( $curl_session, CURLOPT_SSL_VERIFYPEER, FALSE);
to the curl options to get the request working.
I have spent the past couple of hours trying all types of variations but according to the Twitter API this should have worked from step 1!
1 addition I have made to the script below is that I have added in:
$header = array("Expect:");
This I found helped in another question on stackoverflow from getting a denied issue / 100-continue.
Issue:
Failed to validate oauth signature and token is the response EVERY time!!!
Example of my post data:
Array ( [oauth_callback] => http://www.mysite.com//index.php [oauth_consumer_key] => hidden [oauth_nonce] => hidden [oauth_signature_method] => HMAC-SHA1 [oauth_timestamp] => 1301270847 [oauth_version] => 1.0 )
And my header data:
Array ( [0] => Expect: )
Script:
$consumer_key = "hidden";
$consumer_secret = "hidden";
function Post_Data($url,$data,$header){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
$data['oauth_callback'] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
$data['oauth_consumer_key'] = $consumer_key;
$data['oauth_nonce'] = md5(time());
$data['oauth_signature_method'] = "HMAC-SHA1";
$data['oauth_timestamp'] = time();
$data['oauth_version'] = "1.0";
$header = array("Expect:");
$content = Post_Data("http://api.twitter.com/oauth/request_token",$data,$header);
print_r($content);
Can anybody see an obvious mistake that I may be making here? Preferably I would not like to go with somebody elses code as most examples have full classes & massive functions, I am looking for the most simple approach!
Your problem is that you did not include the OAuth signature in your request.
You can read about the concept on this page.
A working implementation can be found here.
I faced same issue, what I was missing is passing header in to the curl request.
As shown in this question, I was also sending the $header = array('Expect:'), which was the problem in my case. I started sending signature in header with other data as below and it solved the case for me.
$header = calculateHeader($parameters, 'https://api.twitter.com/oauth/request_token');
function calculateHeader(array $parameters, $url)
{
// redefine
$url = (string) $url;
// divide into parts
$parts = parse_url($url);
// init var
$chunks = array();
// process queries
foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', urlencode_rfc3986($key) . '="' . urlencode_rfc3986($value) . '"');
// build return
$return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
$return .= implode(',', $chunks);
// prepend name and OAuth part
return $return;
}
function urlencode_rfc3986($value)
{
if(is_array($value)) return array_map('urlencode_rfc3986', $value);
else
{
$search = array('+', ' ', '%7E', '%');
$replace = array('%20', '%20', '~', '%25');
return str_replace($search, $replace, urlencode($value));
}
}