We help IT Professionals succeed at work.

how to use CURL instead of fsockopen

allanch08
allanch08 asked
on
Hi,

I have the following IPN listener set up in the page to which I send my clients after they've clicked on a buy now button and paid for their music in Paypal. Although the payment_status variable comes back as completed, I keep getting into the following error:

Notice: Undefined variable: header in /myserver/myweb.com/new_web/thankyou.php on line 47
We cannot verify your purchase. Please contact admin@test.com

The result of the payment verification is always invalid.

I've though of using curl but because because I'm using a template and my object oriented programming skills are zero, I have no idea how to use it. The fsockopen function seems to be much more straight forward and my webhost has confirmed that fsockopen is supported but  allow_url_fopen isn't and that's where they suggested curl. any thoughts on what could be going wrong? Please ignore my rudimentary scripting skills...

 
<?php 

error_reporting(E_ALL); 
ini_set('display_errors', true); 

include ("includes/header.inc");
include ("includes/config.inc");

if (isset($_GET['txn_id'])&&($_GET['item_name'])){

	$txn_id = $_GET['txn_id'];
	$item_name = $_GET['item_name'];

	$query3 = "SELECT * FROM downloads WHERE txn_id='$txn_id'";
	$result3 = mysql_query($query3) or die(mysql_error());

	while ($row3 = mysql_fetch_assoc($result3)) {

	$count=$row3['count'];

	}

	if($count == 5){
	echo "<div class=\"errortext\">We\'re sorry, you have downloaded this track 5 times</div>";

	}else{
	$count++;

	$query4 = "UPDATE downloads SET count='$count' WHERE id='$download_id'";
	$result4 = mysql_query($query4) or die(mysql_error());
	}

}elseif(isset($_GET['id'])&& ($_GET['id']=='5723')){

// read the post from PayPal system and add 'cmd'

	$req = 'cmd=_notify-validate';

	foreach ($_POST as $key => $value) {
	$value = urlencode(stripslashes($value));
	$req .= "&$key=$value";

	}

// 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 ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables
	
	$item_name = $_POST['item_name'];
	$payment_status = $_POST['payment_status'];
	$txn_id = $_POST['txn_id'];
	$payer_email = $_POST['payer_email'];
	$payment_amount = $_POST['mc_gross'];
	$receiver_email = $_POST['receiver_email'];

//$item_number = $_POST['item_number'];
//$payment_currency = $_POST['mc_currency'];

	if (!$fp) {

// HTTP ERROR
	echo "<div class=\"errortext\">http error</div>";

	}else{

	fputs ($fp, $header . $req);

	while (!feof($fp)) {
	$res = fgets ($fp, 1024);

		if (strcmp ($res, "VERIFIED") == 0) {
	
			if ($payment_status=="Denied"){ 
	
			echo "<div class=\"errortext\">your payment has been denied</div>";
	
			}elseif ($payment_status=="Pending"){ 
	
			echo "<div class=\"errortext\">your payment is pending.</div>";
	
			}elseif (($_POST['payment_status']=='Completed') && ($_POST['receiver_email'] == 'paypal@myweb.com') &&  ($_POST('payment_amount')=='1.50')){ 
			
			$query8 = "SELECT txn_id FROM downloads WHERE txn_id = '".$_POST['txn_id']."'";
			$result8 = mysql_query($query8) or die(mysql_error());
	
				if (mysql_num_rows($result8)==0){
	
				$query0 = "SELECT * FROM tracks WHERE name = '$item_name'";
				$result0 = mysql_query($query0) or die(mysql_error());
	
				while ($row0 = mysql_fetch_assoc($result0)){
				
				$track_id = $row0['id'];
				$path = $row0['path'];
	
				}
	
				$query5 = "INSERT INTO downloads (count,txn_id) VALUES ('0','$txn_id')";
				$result5 = mysql_query($query5) or die(mysql_error());
				
				$query6 = "SELECT id FROM downloads WHERE txn_id = '$txn_id'";
				$result6 = mysql_query($query6) or die(mysql_error());
				$row6 = mysql_fetch_array($result6); 
				
				$download_id = $row6[0];
				
				$query7 = "INSERT INTO downloads2tracks (download_id,track_id) VALUES ('$download_id','$track_id')";
				$result7 = mysql_query($query7) or die(mysql_error());
	
				echo "<a href=\"download.php?file='.$item_name.mp3.'\">Download file</a>"; 
	
				$subject = "Digital Download Delivery from myweb.com";
				$body = "testing 123 http://www.myweb.com/new_web/thankyou.php?txn_id=$txn_id&file=$item_name.mp3";
				
				
				}else{
	
				echo "<div class=\"errortext\">transaction id exists</div>";
				
				}
			}
	
		}elseif (strcmp ($res, "INVALID") == 0) {
	
	// log for manual investigation
	
		echo "<div class=\"errortext\">We cannot verify your purchase. Please contact test@test.com</div>";
		
		}
	}
	fclose ($fp);
	}
}else{

echo "<div class=\"errortext\">invalid access to page</div>";

}

?>

Open in new window

Comment
Watch Question

For the paypal fsockopen function to work, your server must have SSL support installed. Do

<?php
phpinfo();
?>

and scan the output for "OpenSSL support"

Author

Commented:
Thanks, I checked that and it is enabled but I keep getting $res as INVALID and undefined $header. Any other ideas? I'm at a loss.
Engineering Manager
Commented:

$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";  //Change this to

the dot operator is removed.

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";  //this

Your error will be solved, since $header is not already defined in your script, you are getting this error.


The $header error referred to above is only a NOTICE and PHP will create $header as an empty variable so fixing it will make no difference.

However, looking at your code I notice you have a line

$req = 'cmd=_notify-validate';

which has a spurious "=" in it. Amend it to

$req = 'cmd_notify-validate';

and retest.
Ignore that last post.... talking rubbish. It's an odd syntax but it is right according to paypal.
YOu have

$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

which is a test environment rather than

$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

which is live. Is that what you intend? Are you in test mode for this?

Commented:
Hi allanch08,

Change the following line in your code:
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

to:

$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);

Once done, test it and let me know the results. In case of an error warnings/errors post me the code which is on the line that the warning indicated.

You don't have to be in live mode to be able to confirm the payment. It's a very good thing that you are testing this in the sandbox. I strongly suggest you don't switch to live version unless this warning/error is fixed.

Author

Commented:
thanks for the help!!!