Paypal IPN Script, issue with feof and fgets

2020-08-02 07:11发布

问题:

I've been having issues with my Paypal IPN listener script for a couple of days now. For those of you who are unfamiliar with the Paypal IPN system, basically Paypal sends your script with a message about the transaction, which you send back with a couple of bits added. If Paypal receives the correct reply, it'll reply with 'VERIFIED', and if not it'll say 'INVALID'.

I initially thought that the problem I was experiencing was with the 'fsockopen' command: $fp=fsockopen('ssl://sandbox.paypal.com', 443, $errno, $errstr, 30); However, having reduced all of my code to pretty much just this line, it seems to connect ok. The problem comes in with the 'feof' and 'fgets' commands. The script just hangs up, and I don't know why. I've essentially copied the code suggested on the Paypal IPN Listener website, so I assumed that it would work! If you could help me understand why feof or fgets are causing it to stall then your help would be much appreciated.

Here's the full script:

$postback = 'cmd=_notify-validate'; //doesn't matter what these include for now
$header='abc';

//Script has been activated, create debug
$filename = 'debug/debug1_script.txt';
$filehandle=fopen($filename, 'w');
fwrite($filehandle,$postback);
fclose($filehandle);


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

//no connection, create debug file
if(!$fp){
    $filename = 'debug/debug2_fpfail.txt';
    $filehandle=fopen($filename, 'w');
    fwrite($filehandle, $errstr.'('.$errno.')');
    fclose($filehandle);
    die();
}


//post data back
fputs($fp, $header . $postback);

//create debug file
$filename = 'debug/debug3_postback.txt';
$filehandle=fopen($filename, 'w');
fwrite($filehandle, $header.$postback);
fclose($filehandle);


//script hangs with either of the two following lines included
while(!feof($fp)){
    $res=fgets($fp,1024);
}

Many thanks in advance!

回答1:

So I think I found a solution, which was instead of using the

while(!feof())

and

fgets()

combo, I used this:

$res=stream_get_contents($fp, 1024);

Worked first time! Now I can get on with my life.



回答2:

To anyone arriving here by Google, don't forget to include "Connection: Close" in your headers! Otherwise the host will keep the connection open until it times out!



回答3:

If anyone else has the same issue, CURL seems to be the recommend choice for IPN by PayPal.

Check out there code sample on Github at: https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php



回答4:

The connection back to paypal from your $fp socket must be an http POST. feof() hangs because paypal never hears a full HTTP request, so it never sends anything back--it just keeps listening until you give up.

You need the extra stuff (the finished $header and $req variables) in the example code on this paypal IPN page.

I would rewrite this to use CURL if you can, instead of raw sockets, so you don't have to format the complete http request and read a raw http response.