I have PayPal integrated on my website. There's a form on my site which takes the customer to PayPal to finalise the payment then it returns them to my site. My site then sends a request back to PayPal with the transaction token for PDT so that I can run a few checks then auto-credit my customer's with the product they bought.
The system uses PHP and cURL to send process all this.
When I use: "www.sandbox.paypal.com/cgi-bin/webscr"
Along with the sandbox credentials everything works fine, everything.
Once I change it all to "www.paypal.com/cgi-bin/webscr"
It does not work, My code tells me that the request fails.
My Code:
$pp_hostname = "www.paypal.com";
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-synch';
$tx_token = $_GET['tx'];
$auth_token = "#######-hashed_out_here-########";
$req .= "&tx=$tx_token&at=$auth_token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://$pp_hostname/cgi-bin/webscr");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//set cacert.pem verisign certificate path in curl using 'CURLOPT_CAINFO' field here,
//if your server does not bundled with default verisign certificates.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: $pp_hostname"));
$res = curl_exec($ch);
curl_close($ch);
if(!$res){
$this->twig->error("Request failed.");
}else{
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0) {
for ($i='1'; $i<count($lines);$i++){
$test = explode("=", $lines[$i]);
if(empty($test[1])){
$keyarray[urldecode($test[0])] = '';
}else{
$keyarray[urldecode($test[0])] = urldecode($test[1]);
}
}
//give product
} else if (strcmp ($lines[0], "FAIL") == 0) {
$this->twig->error('Transaction failed!');
}
}
Not sure why I'm having a problem so I don't know how to go about fixing.
My PayPal Account is set up as Business, has PDT and IPN turned on as well as Auto-Return
It appears that I'm receiving HTTP Error, but which I cannot say, if I log the curl_error it simply says " " and if I log the curl_errno I get 0.
I managed to get this fixed. It was due to my server not having the ssl certificates installed, once I did so it worked fine.
Related
I am using paypal payment gateway (currently using sandbox), its working but some time on success auto return showing blank screen?? response url is pretty good, but some times after auto return its showing blank screen.
My code:
after success auto return redirect properly:
http://domainname/client/paypal/success?amt=9.24&cc=USD&item_name=Weight%20Loss%20Diet%20Program&st=Completed&tx=9CX31984H5808205U
after success auto return redirect properly but showing website blank screen:
http://domainname/client/paypal/success?amt=9.24&cc=USD&item_name=Weight%20Loss%20Diet%20Program&st=Completed&tx=9CX31984H5808205U
everything is looking good with code & return url, then why after return sometimes website showing blank screen??
My Code Snippet to execute paypal response:
switch($action){
case "success":
if(isset($_GET['tx']))
{
$tx_token = $_GET['tx'];
$req = 'cmd=_notify-synch';
$auth_token = PDT_IDENTITY_TOKEN;
$req .= "&tx=$tx_token&at=$auth_token";
$ch = curl_init();
if($sandbox==0){
curl_setopt($ch, CURLOPT_URL, "https://www.paypal.com/cgi-bin/webscr"); //Live
}else{
curl_setopt($ch, CURLOPT_URL, "https://www.sandbox.paypal.com/cgi-bin/webscr"); //Sandbox
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//set cacert.pem verisign certificate path in curl using 'CURLOPT_CAINFO' field here,
//if your server does not bundled with default verisign certificates.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
if($sandbox==0){
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: www.paypal.com")); //Live
}else{
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: www.sandbox.paypal.com")); //Sandbox
}
$res = curl_exec($ch);
curl_close($ch);
$lines = explode("\n", trim($res));
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0)
{
for ($i = 1; $i < count($lines); $i++)
{
$temp = explode("=", $lines[$i],2);
$keyarray[urldecode($temp[0])] = urldecode($temp[1]);
}
$invoice_id = $keyarray['invoice'];
$transaction_id = $keyarray['txn_id'];
$payment_status = $keyarray['payment_status'];
if($payment_status=='Completed')
{
........
}
}
}
....
break;
....
}
During PayPal operations, the variables you are using are part of PDT (Paypal data transfer), which is PayPal a/c feature which needs to be enabled. Please check your PayPal a/c PDT settings once.
I am trying to connect to PayPal sandbox using CURL. I've searched both this website and many others trying to find the right answer however, none, and I mean none, have worked for me and I still get the error:
SetExpressCheckout failed: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure ( 35 )
I have the following CURL and PHP installed (It is bought and shared hosting so I cannot upgrade anything).
Curl Verison: 7.36.0
SSL Version: OpenSSL/0.9.8b
PHP Version: 5.4.45
The code I am currently using:
class MyPayPal {
function PPHttpPost($methodName_, $nvpStr_, $PayPalApiUsername, $PayPalApiPassword, $PayPalApiSignature, $PayPalMode) {
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode($PayPalApiUsername);
$API_Password = urlencode($PayPalApiPassword);
$API_Signature = urlencode($PayPalApiSignature);
$paypalmode = ($PayPalMode=='sandbox') ? '.sandbox' : '';
$API_Endpoint = "https://api-3t".$paypalmode.".paypal.com/nvp";
$version = urlencode('109.0');
// Set the curl parameters.
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSLVERSION, 4);
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("<span style='font-family: Verdana'><strong>$methodName_ failed: </strong>".curl_error($ch).'<strong> (</strong> '.curl_errno($ch).' <strong>)</strong></span>');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
}
}
It doesn't matter what I do, I cannot seem to conquer this error. :( Any guidance will be helpful.
Paypal now supports only TLS 1.2 on the sandbox (and in June the same will apply to production systems). If you want to use TLS 1.2 you'll need to upgrade to OpenSSL 1.0.1+ as a minimum, and then you'll be able to set CURLOPT_SSLVERSION to 6 (TLS 1.2). If you want TLS 1.2 to be used automatically during SSL requests, you'll also need to upgrade to PHP 5.5.19+ (this is the ideal solution but many projects are still on older PHP versions).
However, you've said you're on shared hosting and can't upgrade the software yourself...so you're out of luck. My advice would be to get away from whatever hosting provider is still stuck on OpenSSL 0.9.8.
Reference: https://devblog.paypal.com/upcoming-security-changes-notice/
I have PayPal integrated on my website. There's a form on my site which takes the customer to PayPal to finalise the payment then it returns them to my site. My site then sends a request back to PayPal with the transaction token for PDT so that I can run a few checks then auto-credit my customer's with the product they bought.
The system uses PHP and cURL to send process all this.
When I use: "www.sandbox.paypal.com/cgi-bin/webscr"
Along with the sandbox credentials everything works fine, everything.
Once I change it all to "www.paypal.com/cgi-bin/webscr"
It does not work, My code tells me that the request fails.
My Code:
$pp_hostname = "www.paypal.com";
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-synch';
$tx_token = $_GET['tx'];
$auth_token = "#######-hashed_out_here-########";
$req .= "&tx=$tx_token&at=$auth_token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://$pp_hostname/cgi-bin/webscr");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//set cacert.pem verisign certificate path in curl using 'CURLOPT_CAINFO' field here,
//if your server does not bundled with default verisign certificates.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: $pp_hostname"));
$res = curl_exec($ch);
curl_close($ch);
if(!$res){
$this->twig->error("Request failed.");
}else{
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0) {
for ($i='1'; $i<count($lines);$i++){
$test = explode("=", $lines[$i]);
if(empty($test[1])){
$keyarray[urldecode($test[0])] = '';
}else{
$keyarray[urldecode($test[0])] = urldecode($test[1]);
}
}
//give product
} else if (strcmp ($lines[0], "FAIL") == 0) {
$this->twig->error('Transaction failed!');
}
}
Not sure why I'm having a problem so I don't know how to go about fixing.
My PayPal Account is set up as Business, has PDT and IPN turned on as well as Auto-Return
EDIT: Also there isn't an error occurring with the cURL.
OK so if(!($res = curl_exec($ch))) is returning true, i.e its not working
Hello I implemented paypal express checkout API in PHP, On my localhost it successfully running but on Go daddy hosting server it will not displaying anything, It only display one blank page, It dont even go on paypal page nor it will displaying any error message. I guess may be curl request or https response is the problem
Here is my curl request.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
// Turn off the server and peer verification (TrustManager Concept).
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$API_Password&USER=$API_UserName&SIGNATURE=$API_Signature$nvpStr_";
// Set the request as a POST FIELD for curl.
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
// Get response from the server.
$httpResponse = curl_exec($ch);
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();
foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}
}
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
}
return $httpParsedResponseAr;
For more reference this is the code i integrated.
I am sure there is some problem in either curl request or https response please guide me as soon as possible.
Put this at the top of your script.
error_reporting(E_ALL);
ini_set('display_errors', '1');
That will allow you to see the PHP error that is happening.
You may also want to change this...
if(!$httpResponse) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
to...
if($curl_error($ch)) {
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}
The way you have it, if anything at all gets brought back to $httpResponse it would be treated as true. Checking for a curl error there, though, will always output the error message and number if an error with curl does occur.
After many hours of messing about and trying to set up what should be the relatively simple process of sending a payment to www.sandbox.paypal.com and being redirected back to a page on my site with a transaction id in the querystring, I have finally achieved it.
I am now receiving an error message 'FAIL Error 4003'.
Here is the code I am using. It is pretty much the same as the paypal example (all I have done is echo out the responses):
<?php
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-synch';
$tx_token = $_GET['tx'];
$auth_token = "ZdoN6q4GLiRniR2BbOzEEF22GJOWHpVOXRtP7fAhBpvwwm5GyWcTzO_sSSO";
$req .= "&tx=$tx_token&at=$auth_token";
// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
// If possible, securely post back to paypal using HTTPS
// Your PHP server will need to be SSL enabled
// $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
if (!$fp)
{
// HTTP ERROR
echo "HTTP Error";
}
else
{
fputs ($fp, $header . $req);
// read the body data
$res = '';
$headerdone = false;
while (!feof($fp))
{
$line = fgets ($fp, 1024);
if (strcmp($line, "\r\n") == 0) {
// read the header
$headerdone = true;
}
else if ($headerdone)
{
// header has been read. now read the contents
$res .= $line;
echo $line;
}
}
// parse the data
$lines = explode("\n", $res);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0)
{
for ($i=1; $i<count($lines);$i++)
{
list($key,$val) = explode("=", $lines[$i]);
$keyarray[urldecode($key)] = urldecode($val);
}
// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment
$firstname = $keyarray['first_name'];
$lastname = $keyarray['last_name'];
$itemname = $keyarray['item_name'];
$amount = $keyarray['payment_gross'];
echo ("<p><h3>Thank you for your purchase!</h3></p>");
echo ("<b>Payment Details</b><br>\n");
echo ("<li>Name: $firstname $lastname</li>\n");
echo ("<li>Item: $itemname</li>\n");
echo ("<li>Amount: $amount</li>\n");
echo ("");
}
else if (strcmp ($lines[0], "FAIL") == 0) {
echo "Failure: " . $lines[0];
// log for manual investigation
}
}
fclose ($fp);
?>
<br />
Thank you for your payment. Your transaction has been completed, and a receipt for your purchase has been emailed to you. You may log into your account at www.sandbox.paypal.com/ie to view details of this transaction.
I have made sure to confirm the email addresses for both my sandbox merchant and buyer accounts and enabled PDT.
The client is redirected correctly back to my 'thank you' page with the following querystring paramaters - ?tx=4FU63684496248523&st=Pending&amt=29.90&cc=EUR&cm=&item_number=
Has anyone else encountered this error message? If so, what are the usual causes?
The problem was that I was sending my test http request to paypal.com rather than sandbox.paypal.com. The answer was in the FAQ left by Jukebox.
Check the script.When testing Payment Data Transfer (PDT) in the
Sandbox, make sure your PDT script POSTs back information to
www.sandbox.paypal.com. If testing on the Live PayPal site, make sure
the script POSTs data back to www.paypal.com. Currently, all sample
code on the Live and Sandbox sites "point" back to the live PayPal
site.
Hope it helps someone else get up and running quicker than I did. I am now onto my next issue which is the token being returned as empty rather than an error.. sigh..
Make sure your transaction ID is not expired. 4003 PDT error code also comes when your transaction ID is expired.
Here's what solved it for me...
In the Buy Now button, I had a business email address associated with my LIVE PayPal account whereas I need to use the business email address associated with my SANDBOX PayPal account as in:
<input type="hidden" name="business" value="user#host.com">
The value attribute needed to reflect the business email address associated with my sandbox account.
By the way, here's an alternate PHP cURL version of the above script that also does the trick of eliciting a response from PayPal's sandbox:
if (isset($_GET['tx'])) {
$tx = $_GET['tx'];
$identity_token = "INSERT_YOUR_IDENTITY_TOKEN_HERE";
//echo $tx;
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
$nvpString="cmd=_notify-synch".
"&tx=$tx".
"&at=$identity_token";
//echo $nvpString;
//define where the data is going to
$curl = curl_init($url);
//tell cURL to fail if an error occurs
curl_setopt($curl, CURLOPT_FAILONERROR, 1);
//allow for redirects
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
//assign the returned data to a variable
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//set the timeout
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
//use POST
curl_setopt($curl, CURLOPT_POST, 1);
//set the POST data
curl_setopt($curl, CURLOPT_POSTFIELDS, $nvpString);
//execute the transaction
$response = curl_exec($curl);
//show errors
curl_error($curl);
//close the connection
curl_close($curl);
echo '<pre>';
print_r($response);
echo '</pre>';
}//end if (isset($_GET['tx']))
The Identity Token of my test seller account changed without notification. Using the new (correct) Identity Token fixed the problem.
Some more information on Paypal’s PTD can be found here:
http://www.secure-ebook.com/help/payment:paypal:fail_4003
$tx=$_REQUEST['tx'];
$paypal_url='https://www.paypal.com/cgi-bin/webscr?cmd=_notify-synch&tx='.$tx.'&at=token here';
$curl = curl_init($paypal_url);
$data = array(
"cmd" => "_notify-synch",
"tx" => $tx,
"at" => "token here"
);
$data_string = json_encode($data);
curl_setopt ($curl, CURLOPT_HEADER, 0);
curl_setopt ($curl, CURLOPT_POST, 1);
curl_setopt ($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 1);
$headers = array (
'Content-Type: application/x-www-form-urlencoded',
'Host: www.paypal.com',
'Connection: close'
);
curl_setopt ($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt ($curl, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($curl);
$lines = explode("\n", $response);
$keyarray = array();
if (strcmp ($lines[0], "SUCCESS") == 0) {
for ($i=1; $i<count($lines);$i++){
list($key,$val) = explode("=", $lines[$i]);
$keyarray[urldecode($key)] = urldecode($val);
}
$first_name=$keyarray['first_name'];
$last_name=$keyarray['last_name'];
$payment_status=$keyarray['payment_status'];
$business=$keyarray['business'];
$payer_email=$keyarray['payer_email'];
$payment_gross=$keyarray['payment_gross'];
$mc_currency=$keyarray['mc_currency'];
}