I am using cURL and PHP to make a request to a test API to return a list of users but I get the following error:
PHP Notice: Trying to get property 'id' of non-object
Not sure where I am going wrong.
Here is my code
<?php
// I am using the JSONPlaceholder website as a test API
$url = 'https://jsonplaceholder.typicode.com/users';
// Initial a new cURL session
$request = curl_init($url);
// Return request as string
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
// Run cURL / execute http request
$response = curl_exec($request);
// Close the cURL resource
curl_close($request);
if ($response === false) {
print "Could not make successful request\n";
} else {
$response = json_decode($response);
print $response->id . "\n";
print $response->name . "\n";
print $response->username . "\n";
}
?>
you have to loop through the response:
if ($response === false) {
print "Could not make successful request\n";
} else {
$response = json_decode($response);
foreach ($response as $item) {
print $item->id . "\n";
print $item->name . "\n";
print $item->username . "\n";
}
}
I am totally new to this hotelbed API, is there anybody done before please guide me how to get result from this API using Codeigniter frame work?
I have tried their code, but I couldn't:
<?php
$apiKey = " ";
$Secret = " ";
$signature = hash("sha256", $apiKey.$Secret.time());
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/status";
//echo "Your API Key is: " . $apiKey . "";
//echo "Your X-Signature is: " . $signature . "";
try
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $endpoint,
CURLOPT_HTTPHEADER => ['Accept:application/json' , 'Api-key:'.$apiKey.'', 'X-Signature:'.$signature.'']
));
$resp = curl_exec($curl);
if (!curl_errno($curl)) {
switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
case 200: # OK
echo "Server JSON Response:" . $resp;
break;
default:
echo 'Unexpected HTTP code: ', $http_code, "\n";
echo $resp;
}
}
curl_close($curl);
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}
?>
I ran this code and it was fine for me:
Server JSON Response:{"auditData":{"timestamp":"2017-11-09 10:25:04.503"},"status":"OK"}
It must be a problem with your setup. Have you uncommented php_curl & php_openssl in your php.ini? What server are you using?
Is the "Server JSON Response:" even printing at all?
Maybe try running an availability request and see if you are getting the same problem (https://github.com/hotelbeds-sdk/hotel-api-sdk-php/issues/107#issuecomment-342760756)
Here below i have attached my api request
$apiKey = "XXXX";
$Secret = "XXX";
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/hotels";
$request = new http\Client\Request("POST",
$endpoint,
[ "Api-Key" => $apiKey,
"X-Signature" => $signature,
"Accept" => "application/xml" ]);
try
{ $client = new http\Client;
$client->enqueue($request)->send();
$response = $client->getResponse();
if ($response->getResponseCode() != 200) {
printf("%s returned '%s' (%d)\n",
$response->getTransferInfo("effective_url"),
$response->getInfo(),
$response->getResponseCode()
);
} else {
printf($response->getBody());
}
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}'
getting following error
Uncaught Error: Class 'http\Client\Request' not found in
You need to add a use statement.
use http\Client\Request;
$request = new Request(blah blah);
Of course I assume you are using Composer autoloader. If not, you will also need to require_once() the file.
You can try using cURL instead of pecl_http. Here is an example:
<?php
// Your API Key and secret
$apiKey = "yourApiKey";
$Secret = "yourSecret";
// Signature is generated by SHA256 (Api-Key + Secret + Timestamp (in seconds))
$signature = hash("sha256", $apiKey.$Secret.time());
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/status";
echo "Your API Key is: " . $apiKey . "<br>";
echo "Your X-Signature is: " . $signature . "<br><br>";
// Example of call to the API
try
{
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $endpoint,
CURLOPT_HTTPHEADER => ['Accept:application/json' , 'Api-key:'.$apiKey.'', 'X-Signature:'.$signature.'']
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Check HTTP status code
if (!curl_errno($curl)) {
switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
case 200: # OK
echo "Server JSON Response:<br>" . $resp;
break;
default:
echo 'Unexpected HTTP code: ', $http_code, "\n";
echo $resp;
}
}
// Close request to clear up some resources
curl_close($curl);
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}
?>
Just make sure that first you uncomment ;extension=php_curl.dll in your php.ini file and restart your server.
We are planning to update our examples in the developer portal because some are outdated or not well documented.
Hi I am trying to integrate First data payment gateway integration in soap request method using php. I have downloaded the working sample code from first data but when i am trying to submit a payment with the sample code they gave it is throwing me an error.
The entire php code is
<?php
class SoapClientHMAC extends SoapClient {
public function __doRequest($request, $location, $action, $version, $one_way = NULL) {
global $context;
$hmackey = "***********************"; // <-- Insert your HMAC key here
$keyid = "*****"; // <-- Insert the Key ID here
$hashtime = date("c");
$hashstr = "POST\ntext/xml; charset=utf-8\n" . sha1($request) . "\n" . $hashtime . "\n" . parse_url($location,PHP_URL_PATH);
$authstr = base64_encode(hash_hmac("sha1",$hashstr,$hmackey,TRUE));
if (version_compare(PHP_VERSION, '5.3.11') == -1) {
ini_set("user_agent", "PHP-SOAP/" . PHP_VERSION . "\r\nAuthorization: GGE4_API " . $keyid . ":" . $authstr . "\r\nx-gge4-date: " . $hashtime . "\r\nx-gge4-content-sha1: " . sha1($request));
} else {
stream_context_set_option($context,array("http" => array("header" => "authorization: GGE4_API " . $keyid . ":" . $authstr . "\r\nx-gge4-date: " . $hashtime . "\r\nx-gge4-content-sha1: " . sha1($request))));
}
return parent::__doRequest($request, $location, $action, $version, $one_way);
}
public function SoapClientHMAC($wsdl, $options = NULL) {
global $context;
$context = stream_context_create();
$options['stream_context'] = $context;
return parent::SoapClient($wsdl, $options);
}
}
$trxnProperties = array(
"User_Name"=>"",
"Secure_AuthResult"=>"",
"Ecommerce_Flag"=>"",
"XID"=>"",
"ExactID"=>$_POST["ddlPOS_ExactID"], //Payment Gateway
"CAVV"=>"",
"Password"=>"********", //Gateway Password
"CAVV_Algorithm"=>"",
"Transaction_Type"=>$_POST["ddlPOS_Transaction_Type"],//Transaction Code I.E. Purchase="00" Pre-Authorization="01" etc.
"Reference_No"=>$_POST["tbPOS_Reference_No"],
"Customer_Ref"=>$_POST["tbPOS_Customer_Ref"],
"Reference_3"=>$_POST["tbPOS_Reference_3"],
"Client_IP"=>"", //This value is only used for fraud investigation.
"Client_Email"=>$_POST["tb_Client_Email"], //This value is only used for fraud investigation.
"Language"=>$_POST["ddlPOS_Language"], //English="en" French="fr"
"Card_Number"=>$_POST["tbPOS_Card_Number"], //For Testing, Use Test#s VISA="4111111111111111" MasterCard="5500000000000004" etc.
"Expiry_Date"=>$_POST["ddlPOS_Expiry_Date_Month"] . $_POST["ddlPOS_Expiry_Date_Year"],//This value should be in the format MM/YY.
"CardHoldersName"=>$_POST["tbPOS_CardHoldersName"],
"Track1"=>"",
"Track2"=>"",
"Authorization_Num"=>$_POST["tbPOS_Authorization_Num"],
"Transaction_Tag"=>$_POST["tbPOS_Transaction_Tag"],
"DollarAmount"=>$_POST["tbPOS_DollarAmount"],
"VerificationStr1"=>$_POST["tbPOS_VerificationStr1"],
"VerificationStr2"=>"",
"CVD_Presence_Ind"=>"",
"Secure_AuthRequired"=>"",
"Currency"=>"",
"PartialRedemption"=>"",
// Level 2 fields
"ZipCode"=>$_POST["tbPOS_ZipCode"],
"Tax1Amount"=>$_POST["tbPOS_Tax1Amount"],
"Tax1Number"=>$_POST["tbPOS_Tax1Number"],
"Tax2Amount"=>$_POST["tbPOS_Tax2Amount"],
"Tax2Number"=>$_POST["tbPOS_Tax2Number"],
//"SurchargeAmount"=>$_POST["tbPOS_SurchargeAmount"], //Used for debit transactions only
//"PAN"=>$_POST["tbPOS_PAN"] //Used for debit transactions only
);
$client = new SoapClientHMAC("https://api.demo.globalgatewaye4.firstdata.com/transaction/v12/wsdl");
$trxnResult = $client->SendAndCommit($trxnProperties);
if(#$client->fault){
// there was a fault, inform
print "<B>FAULT: Code: {$client->faultcode} <BR />";
print "String: {$client->faultstring} </B>";
$trxnResult["CTR"] = "There was an error while processing. No TRANSACTION DATA IN CTR!";
}
//Uncomment the following commented code to display the full results.
echo "<H3><U>Transaction Properties BEFORE Processing</U></H3>";
echo "<TABLE border='0'>\n";
echo " <TR><TD><B>Property</B></TD><TD><B>Value</B></TD></TR>\n";
foreach($trxnProperties as $key=>$value){
echo " <TR><TD>$key</TD><TD>:$value</TD></TR>\n";
}
echo "</TABLE>\n";
echo "<H3><U>Transaction Properties AFTER Processing</U></H3>";
echo "<TABLE border='0'>\n";
echo " <TR><TD><B>Property</B></TD><TD><B>Value</B></TD></TR>\n";
foreach($trxnResult as $key=>$value){
$value = nl2br($value);
echo " <TR><TD valign='top'>$key</TD><TD>:$value</TD></TR>\n";
}
echo "</TABLE>\n";
// kill object
unset($client);
?>
When i submit the payment my page comes to this particular code and the error it throws is
Fatal error: Uncaught SoapFault exception: [HTTP] in C:\wamp\www\Fd\php\process.php:49 Stack trace: #0 C:\wamp\www\Fd\php\process.php(49): SoapClient->__doRequest('<?xml version="...', 'https://api.dem...', 'http://secure2....', 1, 0) #1 [internal function]: SoapClientHMAC->__doRequest('<?xml version="...', 'https://api.dem...', 'http://secure2....', 1, 0) #2 C:\wamp\www\Fd\php\process.php(104): SoapClient->__call('SendAndCommit', Array) #3 C:\wamp\www\Fd\php\process.php(104): SoapClientHMAC->SendAndCommit(Array) #4 {main} thrown in C:\wamp\www\Fd\php\process.php on line 48.
And the line 48 is
return parent::__doRequest($request, $location, $action, $version, $one_way);
I couldn't really figure out what this error is. Googled and tried various solutions but no success.Also I have both the soap and openssl enabled in my php server if that is of any help.
Thanks in advance for any help.
A little bit too late but anyways... just dump that garbage SOAP code, heres my early stage JSON and CURL version
<?php
class FirstData
{
protected $host = "api.demo.globalgatewaye4.firstdata.com";
protected $protocol = "https://";
protected $uri = "/transaction/v12";
/*Modify this acording to your firstdata api stuff*/
protected $hmackey = "XXXXXXXXXXXXXXXXXXXXXXX";
protected $keyid = "XXXXX";
protected $gatewayid = "XX000-00";
protected $password = "XXXXXXX";
public function request()
{
$location = $this->protocol . $this->host . $this->uri;
$request = array(
'transaction_type' => "00",
'amount' => 10.00,
'cc_expiry' => "0415",
'cc_number' => '4111111111111111',
'cardholder_name' => 'Test',
'reference_no' => '23',
'customer_ref' => '11',
'reference_3' => '234',
'gateway_id' => $this->gatewayid,
'password' => $this->password,
);
$content = json_encode($request);
var_dump($content);
$gge4Date = strftime("%Y-%m-%dT%H:%M:%S", time()) . 'Z';
$contentType = "application/json";
$contentDigest = sha1($content);
$contentSize = sizeof($content);
$method = "POST";
$hashstr = "$method\n$contentType\n$contentDigest\n$gge4Date\n$this->uri";
$authstr = 'GGE4_API ' . $this->keyid . ':' . base64_encode(hash_hmac("sha1", $hashstr, $this->hmackey, true));
$headers = array(
"Content-Type: $contentType",
"X-GGe4-Content-SHA1: $contentDigest",
"X-GGe4-Date: $gge4Date",
"Authorization: $authstr",
"Accept: $contentType"
);
//Print the headers we area sending
var_dump($headers);
//CURL stuff
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $location);
//Warning ->>>>>>>>>>>>>>>>>>>>
/*Hardcoded for easier implementation, DO NOT USE THIS ON PRODUCTION!!*/
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
//Warning ->>>>>>>>>>>>>>>>>>>>
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
//This guy does the job
$output = curl_exec($ch);
//echo curl_error($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = $this->parseHeader(substr($output, 0, $header_size));
$body = substr($output, $header_size);
curl_close($ch);
//Print the response header
var_dump($header);
/* If we get any of this X-GGe4-Content-SHA1 X-GGe4-Date Authorization
* then the API call is valid */
if (isset($header['authorization']))
{
//Ovbiously before we do anything we should validate the hash
var_dump(json_decode($body));
}
//Otherwise just debug the error response, which is just plain text
else
{
echo $body;
}
}
private function parseHeader($rawHeader)
{
$header = array();
//http://blog.motane.lu/2009/02/16/exploding-new-lines-in-php/
$lines = preg_split('/\r\n|\r|\n/', $rawHeader);
foreach ($lines as $key => $line)
{
$keyval = explode(': ', $line, 2);
if (isset($keyval[0]) && isset($keyval[1]))
{
$header[strtolower($keyval[0])] = $keyval[1];
}
}
return $header;
}
}
$firstdata = new FirstData();
$firstdata->request();
I tried SOAP with no success, finally had to switch to JSON.
#KukoBit's answer worked for me. Only problem was the date string which is expected in GMT. I solved it by calculating date as follows:
$gge4Date = strftime("%Y-%m-%dT%H:%M:%S", time() - (int) substr(date('O'), 0, 3)*60*60) . 'Z';
Hope this helps.
ps. I know this should be a comment, but due to points restrictions, I cannot.
Just a heads up for those who keep getting 'Unauthorized Request. Bad or missing credentials.' .
MAKE SURE you are NOT using your PRODUCTION credentials for DEMO environment. They will not work. Stop pulling your hair out :)
all you have to do is, goto
https://firstdata.zendesk.com/entries/21510561-first-data-global-gateway-e4sm-demo-accounts
Signup for a free demo. you will generate your hmac, and get your other data there , just like you do in production.
$client = new SoapClientHMAC("https://api.demo.globalgatewaye4.firstdata.com/transaction/v12/wsdl");
remove ".demo" => "https://api.globalgatewaye4.firstdata.com/transaction/v12/wsdl"
You use live access in api first data
I have using a version of GoCardless's API in PHP to process payments on my website. However when their API returns an error I would like to display the user more effective errors.
I have got half way there but I was wondering if there is anyway I could do the following:
If I have the following error:
Array ( [error] => Array ( [0] => The resource has already been confirmed ) )
Is there anyway to extract just the The resource has already been confirmed part with PHP?
My Code:
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $e->getMessage() . '</code></p>';
}
Thanks.
UPDATE 1:
Code that triggers the exception:
$http_response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_response_code < 200 || $http_response_code > 300) {
// Create a string
$message = print_r(json_decode($result, true), true);
// Throw an exception with the error message
throw new GoCardless_ApiException($message, $http_response_code);
}
UPDATE 2 :-> print_r($e->getMessage()) Output:
Array ( [error] => Array ( [0] => The resource has already been confirmed ) )
The method $e->getMessage() appears to return an array with an index 'error' wich is an array again that contains the message text. If you ask me this is bad API design
However you can access the message text like this:
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$message = $e->getMessage();
$error = $message['error'];
print '<h2>Payment Error</h2>
<p>Server Returned : <code><' . $error[0] . "</code></p>";
}
If you look into the GoCardless_ApiException class code you'll see that there's a getResponse() method that you could use to access the error element of the response array...
$try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$response = $e->getResponse();
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $response['error'][0] . "</code></p>";
}
I discovered the problem, the output from $e->getMessage() was a plain string, NOT an array.
So I edited the Request.php file to the following:
$http_response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_response_code < 200 || $http_response_code > 300) {
// Create a string <<-- THE PROBLEM -->>
// $message = print_r(json_decode($result, true), true);
$message_test = json_decode($result, true);
// Throw an exception with the error message
// OLD - throw new GoCardless_ApiException($message, $http_response_code);
throw new GoCardless_ApiException($message_test[error][0], $http_response_code);
}
and then my php file :
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$message = $e->getMessage();
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $message . "</code></p>";
}
and the page outputs:
Payment Error
Server Returned : The resource has already been confirmed