php script for in-app purchase - php

i'm doing an application for iPhone/iPad which uses the in-app purchase functionality. On the server side i load a php script for the receipt verification. Here is the content of the script:
<?php
$receipt = json_encode(array("receipt-data" => $_GET["receipt"]));
// NOTE: use "buy" vs "sandbox" in production.
$url = "https://sandbox.itunes.apple.com/verifyReceipt";
$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
curl_setopt($curl_handle, CURLOPT_POST, true);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $receipt);
$response_json = curl_exec($curl_handle);
$response = json_decode($response_json);
curl_close($curl_handle);
print $response->{'status'};
?>
My problem is that the response variable is always empty, i can't receive any response. Also the response_json is empty and i can't understand which is the problem. I think is something server side, but i'm not an expert of php and the server is not under my direct control. Can anyone suggest me a way to resolve the problem or to test which coulod be?
Thank's

If curl_exec() fails, it will return a boolean FALSE. You blindly feed the response to json_decode and assume you'll get something out. Decoding boolean false gives you an empty var. Instead, try this:
...
$response_json = curl_exec($curl_handle);
if ($response_json === FALSE) {
die(curl_error($curl_handle));
}
$response = json_decode($response_json);
...

Related

CURLOPT_RETURNTRANSFER on working on localhost but not working on live server in php

$user_access ='example';
$user_key = 'examplekey';
$payload = json_encode($arr);
$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'example.com/api/users/2');
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($payload)));
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $payload );
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERPWD, $user_access . ":" . $user_key);
if (curl_exec($curl_handle) === FALSE) {
die("Curl Failed: " . curl_error($curl_handle));
} else {
return curl_exec($curl_handle);
};
When I remove the curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); then it is working on both local as well as live server. I do not need the return automatically curl_exec value so that I am using curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
I unable to identify the issue. Please help me
If you checked that you use a likely environment (e.g. PHP-Version, curl_exec not blocked on live server which is the case for some hosters) locally and on your live server than it is most probably that the remote server (the API-Server) is in fact responding differently. This can be that it has access-levels based on ip-address or other things.
In general consider:
You are executing curl_exec() twice: First to check if it's return is FALSE and then again if it was not. Instead store the return value in a variable
Try setting curl_setopt($curl_handle, CURLOPT_VERBOSE, true); so you get more information about potential errors
Using a HTTP-Request Library that handles those things for you, like Guzzle wich brings also good error-handling. After installing it:
$httpClient = new GuzzleHttp\Client();
$response = $client->request('PUT', 'https://example.com/api/users/2', [
'auth' => [$user_access, $user_pass],
'json' => $arr
]);
return $response->getBody();
will handle everything for you.
You should be comparing and handling like below;
$Result = curl_exec($curl_handle);
if($Result === false)die("Curl Failed: " . curl_error($curl_handle)); // Just an error display interceptor
return $Result; // Always return the appropriate response
It is certain in your code that you are trying to wrap this in a function, and this function should always return something. Here we are returning the $Result no matter cURL succeeded or failed, you make an explicit check with the caller to see if your cURL method worked ($cURLFunctionReturnValue === false) and code like that.

PHP - get the returned value with CURL between two sites

I have two PHP sites, an API site (x.php) and another, which calls the API site with CURL (y.php)
The x.php looks like this:
if (isset($_POST['testconnection'])) {
return "ok";
}
And the y.php like this:
$host = "https://there.is.the/x.php";
$command = array (
"testconnection" => "testconnection"
);
$ch=curl_init($host);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($command));
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT,180);
$response = curl_exec($ch);
curl_close($ch);
var_dump($response);
As you can see in the example, I would like to get the return string from x.php in the y.php, but I get an empty string in the answer: string(0) ""
I think it would be: string(2) "ok"
I have replaced the return to echo in x.php but without success.
Sorry if it is a noob question, I'm quite new in curl.
Replace
return "ok";
With
echo "ok";
Your script is exiting with return value, but nothing is output as a response.
A thing to note is that web server must have permissions to access the x.php. Verify that the script is able to execute. Permission problems often result in a blank page.
Tip: Use Postman to test REST APIs. You could shoot the post query against your x.php and see what comes back, eliminating the curl part being wrong.

HTML entity '&times' and php function

I need a function that return me the Timezone of a specific location, so i use the
Google Time Zone API.
function timezoneLookup($lat, $lng){
$url = 'https://maps.googleapis.com/maps/api/timezone/json?location='.$lat.','.$lng.'&timestamp='.time().'&sensor=false';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
The function doesn't work because if i return $url i can see that GET variable "&timestamp=" is transformed into "×tamp=".
If i run the script outside the function it works.
WHY??
----UPDATE----
I resolved the problem, the curl doesn't work with https://, so i add:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
See this for more information PHP cURL Not Working with HTTPS
The function works fine. The reason you're seeing ×tamp= is because &times is being converted to ×. If you view source you'll see the correct url(instead of viewing the converted entity on the web page).
Why ; is not required
There is no problem with this function. If you echo that URL you will get the multiplication sign because it is being filtered through html and recognizing the ascii code. This only happens when you view it though and html viewer (browser), if you view source you will see the original string.
To confirm that this conversion will not occur when passed through curl_setopt(), I ran your code on my server and got an expected result.
echo timezoneLookup(52.2023913, 33.2023913);
function timezoneLookup($lat, $lng){
$url = 'https://maps.googleapis.com/maps/api/timezone/json?location='.$lat.','.$lng.'&timestamp='.time().'&sensor=false';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
Returned...
{ "dstOffset" : 3600, "rawOffset" : 7200, "status" : "OK", "timeZoneId" : "Europe/Kiev", "timeZoneName" : "Eastern European Summer Time" }
If this code is not working for you then it could be a networking issue. Try doing curl with another webpage and see what happens. Also, with a simple api call like this you could easily use file_get_contents()

cURL operation and PHP

I have a frontend code
$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($ch, CURLOPT_URL, $url);
//make the request
$responseJSON = curl_exec($ch);
$response_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response_status == 200) { // success
// remove any "problematic" characters from the json string and then decode
if (debug) {
echo "----finish API of getAPI inside basic_function with status==200---";
echo "<br>";
echo "-------the json response is-------" ; //.$responseJSON;
var_dump($responseJSON);
//print_r($responseJSON);
echo "<br>";
}
return json_decode( preg_replace( '/[\x00-\x1F\x80-\xFF]/', '', $responseJSON ) );
}
and I have a backend code which executed when cURL fired its operation with its URL. The backend code would therefore activated. So, I know cURL is operating.
$output=array (
'status'=>'OK',
'data'=>'12345'
)
$output=json_encode($output)
echo $output;
and $output shown on browser as {"status":"OK","data":"12345"}
However, I gone back to the frontend code and did echo $responseJSON, I got nothing. I thought the output of {"status":"OK","data":"12345"} would gone to the $responseJSON. any idea?
Here's output on Browser, something is very odd! the response_status got 200 which is success even before the parsing of API by the backend code. I expect status =200 and json response after the {"status":"OK","data":"12345"}
=========================================================================================
inside the get API of the basic functions
-------url of cURL is -----http://localhost/test/api/session/login/?device_duid=website&UserName=joe&Password=1234&Submit=Submit
----finish API of getAPI inside basic_function with status==200---
-------the json response is-------string(1153)
"************inside Backend API.php******************
---command of api is--/session/login/
---first element of api is--UserName=joe
--second element of api is---Password=1234
---third element of api is----Submit=Submit
----fourth element of api is---
-------inside session login of api-------------
{"status":"OK","data":"12345"}
Have you tried with curl_setopt($ch, CURLOPT_TIMEOUT, 10); commented?
See what happends if you comment that line.
Also try with the a basic code, if that works, smthing you added later is wrong:
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch, CURLOPT_HEADER, false);
// grab URL and pass it to the browser
curl_exec($ch);
// close cURL resource, and free up system resources
curl_close($ch);
Try var_dump($responseJSON)
If it returns false try
curl_error ( $ch )
Returns a clear text error message for the last cURL operation.
Are you sure your $url is correct?

Why does cURL always return a status code?

I have some PHP code that calls into the cURL library. I'm using it to get JSON data.
I have set cURL opt 'CURLOPT_RETURNTRANSFER' to 1, but still get status code..
Code follows:
<?php
function fetch_page($url)
{
$ch = curl_init();
$array = array(
'include'=>'ayam'
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $array);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close ($ch);
return $result;
}
$return = fetch_page(MY_LINK_URL);
echo json_decode($return);
?>
The code looks totally correct. Try var_dump($result) before returning it to see what it is exactly.
Also, set CURLOPT_HEADER to 1 and check the view source of the output in your browser; both of these can help debug the issue. Edit the question and post the results if so we can help more effectively.
Update: Since you are using HTTPS, also add
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
That looks correct. I actually have the same problem, but when I added
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
it returns json code correctly instead of returning 1(True).
According to the PHP docs,
Returns TRUE on success or FALSE on
failure. However, if the
CURLOPT_RETURNTRANSFER option is set,
it will return the result on success,
FALSE on failure.
So that means you should get
success: the result
failure: FALSE (which is echoed as 0)
Also, if you are fetching JSON, and need to access it, use json_decode() not json_encode().
Well, you should tell us wich url you're pointing (and wich version of php you are running).
I've tried with php 5.3 on "www.google.com" and it worked as expected ($result contains the whole webpage)
Might of had a similar problem:
- cURL on local dev network problem with virtual host naming
Before you close your curl handle output this:
$result = curl_exec ($ch);
print_r(curl_getinfo($ch));
curl_close ($ch);
Here was my solution for getting around the virtual host
// This is your Virtual Hosts name
$request_host = 'dev.project';
// This is the IP
$request_url = '192.168.0.1';
$headers = array("Host: ".$request_host);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $request_url.'?'.$request_args);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
There seems to be a number of reasons why CURLOPT_RETURNTRANSFER can be ignored, and SSL certificate checking is only one of them:
In my case the culprit was CURLOPT_POST which I had set to true. I was expecting to get back a string consisting of the HTTP response header plus the response itself. Instead I was getting status code 1. Go figure. Thankfully I did not need the HTTP header so the solution for me was:
curl_setopt($ch, CURLOPT_HEADER, false);
If I did need the header info, I don't know what I would do. I've wasted an insane amount of time tracking down the problem.
Damn you PHP curl! (waves fist in anger)

Categories