3

I'm trying to set up the PayPal IPN on my web application, I copied from PayPal's documentation on an example PHP snippet which is found here.

However, when I'm testing with the PayPal's sandbox, sending an IPN with the simulator which is found here.

Now, when PayPal sends the IPN, I log the actions and data of the IPN, when trying to open an connection with fsockopen, it is NULL when I do var_export on it.

I don't understand why it's not going any further with the code when the fsockopen connection is NULL.

I'm using Codeigniter for my application, and this is the part of the code that fails:

if($this->uri->segment(3) == 'ipn')
{
    $error_msg = '';

    $error_msg .= " initiated ";

    $req = 'cmd=_notify-validate';

    $error_msg .= " \n\n req: " . var_export($req, true);

    foreach($this->input->post() as $key => $value) 
    {
        $value = urlencode(stripslashes($value));
        $req .= "&" . $key . "=" . $value;
    }

    $error_msg .= " \n\n req: " . var_export($req, true);

    $header = '';
    $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";

    $error_msg .= " \n\n headers: " . var_export($header, true);

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

    $error_msg .= " \n\n fp: " . var_export($fp, true);

I use $error_msg to log the data, this is an example what is logged:

 initiated  

 req: 'cmd=_notify-validate' 

 req: 'cmd=_notify-validate&test_ipn=1&payment_type=echeck&payment_date=17%3A30%3A40+Jan+03%2C+2012+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name=something&item_number=DX4WYSur44CQICgO2lC%2FB10NmdaiPNH3xPZXQNAlfrEqpse0xnime22zaNXDFgbRrOL4Xsz4emkhqFw4JhOSHzCtaHt9%2B0p9p8xW6R71PVbFXNyEVjkPeHNdQm32PJg&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&txn_type=web_accept&txn_id=4014130&notify_version=2.1&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=An5ns1Kso7MWUdW4ErQKJJJ4qi4-AN8d2a.xggmx9Dn4AgHpvPHJHTAp' 

 headers: 'POST /cgi-bin/webscr HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 969

' 

 fp: NULL

As you can see $fp is returning NULL on the last line of the logged data. Is there any idea why this is happening?

I can confirm I have OpenSSL enabled and installed on my server:

enter image description here

EDIT: Just tested fsockopen on port 80 to google.com, I still get NULL with no error number or message. So this problems occurs to every URL.

EDIT #2: Tested on my server by doing this:

fsockopen('ssl://www.paypal.com/cgi-bin/webscr', 443, $errno, $errstr, 30)

A PHP Error was encountered

Severity: Warning

Message: fsockopen(): unable to connect to ssl://www.paypal.com/cgi-bin/webscr:443 (php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known)

MacMac
  • 34,294
  • 55
  • 151
  • 222
  • Is openSSL support enabled on your server? – subroutines Jan 04 '12 at 04:17
  • Use `var_dump` to check instead of `var_export` as `var_export` returns "a parsable string representation of a variable". So in short, there's nothing wrong with your code. – subroutines Jan 05 '12 at 03:47
  • check if outbound connections can be created by your server. try pinging google.com from the command line. It may be a firewall issue. – Maxim Krizhanovsky Jan 08 '12 at 16:11
  • From the documentation: If the value returned in errno is 0 and the function returned FALSE, it is an indication that the error occurred before the connect() call. This is most likely due to a problem initializing the socket. – Maxim Krizhanovsky Jan 08 '12 at 16:12
  • @Darhazer Pinging google.com seems fine. What should to fix fsockopen? – MacMac Jan 10 '12 at 19:39
  • please enable error_reporting / display_errors and check for any warning, produced by fsockopen – Maxim Krizhanovsky Jan 10 '12 at 21:05
  • 2
    You should pass only ssl://www.paypal.com only to fsockopen, the rest goes to the GET http header. Only the host, without path should be provided. Please retry with the original code – Maxim Krizhanovsky Jan 10 '12 at 22:36

4 Answers4

3

If anyone else is having the same problem, try using HTTPS instead of SSL

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

And if your testing on Paypals Sandbox use:

$fp = fsockopen ('https://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
manniL
  • 7,157
  • 7
  • 46
  • 72
Nexpulse
  • 31
  • 4
2

Be careful of $config['csrf_protection'] = TRUE; this will block all external POSTS as they will not come with a CSRF token, I've had this with my paypal IPN before, I needed to enable a crude but effective way to get the callback (in config.php):

if(stripos($_SERVER["REQUEST_URI"],'/paypal') === FALSE) {
  // disable CSRF for the /paypal 
    $config['csrf_protection'] = TRUE;
} else {
    $config['csrf_protection'] = FALSE;
}

I'm guessing this could be an issue, you would get null as no data would be captured as CI reviews your $_POST/$_GET vars for security reasons.

If I misunderstood your question and am way off track, just let me know via a comment.

Jakub
  • 20,418
  • 8
  • 65
  • 92
2

Check List

  1. sandbox url: "https://www.sandbox.paypal.com/cgi-bin/webscr";
  2. like @jakub says CSRF must be disabled for your paypal controller
  3. IPN wont validate on localhost, however you should still get vars back.
  4. var_dump(fsockopen ('https://www.sandbox.paypal.com/', 443, $errno, $errstr, 30));
  5. var_dump($_POST);
Philip
  • 4,592
  • 2
  • 20
  • 28
  • `var_dump(fsockopen..` return `resource(6) of type (stream)` , but my code still didn't works . – Salem May 12 '22 at 17:36
0

The variables $errno and $errstr probably hold the reason for the failure. Echo them out with your error message.

SpoonNZ
  • 3,780
  • 1
  • 20
  • 25
  • I get `0` for `$errno` and `''` for `$errstr` when using `var_export` on them. – MacMac Jan 04 '12 at 13:55
  • It's peculiar. That suggests no error. The other odd thing is when there's an error, fsockopen should return `false` not `null`. Can you try opening a connection on port 80 (just to google.com or something) to help troubleshoot. – SpoonNZ Jan 04 '12 at 21:04
  • Hmm, `google.com` at port `80` still returns `NULL` with no error number and message. – MacMac Jan 08 '12 at 16:02