0

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!

user1070084
  • 383
  • 1
  • 3
  • 11
  • If you use the code exactly as it appears on [this page](https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNImplementation) except replacing the hostnames, does it work? – Francis Avila Nov 29 '11 at 19:54

4 Answers4

6

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.

user1070084
  • 383
  • 1
  • 3
  • 11
1

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

mattauckland
  • 483
  • 1
  • 7
  • 17
1

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!

devios1
  • 36,899
  • 45
  • 162
  • 260
0

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.

Francis Avila
  • 31,233
  • 6
  • 58
  • 96
  • Thanks a lot for the help. I've done as you say and included the following header: $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .= "Host: ssl://www.sandbox.paypal.com\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($postback) . "\r\n\r\n"; As far as I can see this is ok, but the same thing is happening. With the while(!feof($fp)) or the fgets($fp, 1024) it just hangs. Thanks again for your reply! – user1070084 Nov 29 '11 at 19:26
  • That's not the correct formatting of the HOST header. Try using http 1.0 like the paypal example. – Francis Avila Nov 29 '11 at 19:52
  • Thanks again, and apologies if you get a few dumb questions passed your way... I've gone back and copied Paypal's header straight off of their website: $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($postback) . "\r\n\r\n"; with the file pointer still: $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); But I'm still getting the same response with the while(!feof( )) or fgets(). Is there any more info I can include in the header? – user1070084 Nov 29 '11 at 20:49
  • There does not seem to be any example code on that page any more. – Syntax Error Jun 17 '14 at 16:50
  • I also went to check the reference Paypal code page, and it does seem to have been moved/removed. Maybe just CURL from now on? Interested to know if you did get this working though? – David Jul 05 '16 at 08:22