使用fsockopen的PayPal IPN返回NULL

时间:2012-01-04 02:33:04

标签: php codeigniter paypal fsockopen

我正在尝试在我的网络应用程序上设置PayPal IPN,我从PayPal的文档中复制了一个示例PHP代码段here

但是,当我使用PayPal的沙箱进行测试时,使用找到here的模拟器发送IPN。

现在,当PayPal发送IPN时,我会记录IPN的操作和数据,当尝试打开与fsockopen的连接时,当我NULL时,它是var_export

我不明白为什么在fsockopen连接为NULL时代码不再继续使用。

我正在为我的应用程序使用Codeigniter,这是代码失败的一部分:

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);

我使用$error_msg来记录数据,这是记录的示例:

 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

正如您所看到的,$fp在记录数据的最后一行返回NULL。有什么想法发生这种情况吗?

我可以确认我已在我的服务器上启用并安装了OpenSSL:

enter image description here

编辑:刚刚在端口80上测试fsockopengoogle.com,我仍然得到NULL没有错误编号或消息。所以每个URL都会出现这个问题。

编辑#2:通过执行以下操作在我的服务器上测试:

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

遇到PHP错误

     

严重性:警告

     

消息:fsockopen():无法连接   ssl://www.paypal.com/cgi-bin/webscr:443(php_network_getaddresses:   getaddrinfo失败:提供了nodename或servname,或者未知)

4 个答案:

答案 0 :(得分:2)

小心$config['csrf_protection'] = TRUE;这将阻止所有外部POSTS,因为它们不会附带CSRF token,我之前已经使用我的paypal IPN,我需要启用粗略但有效的方式获取回调(在config.php中):

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

我猜这可能是一个问题,你会得到null,因为出于安全原因,CI会审核你的$_POST/$_GET vars,因此不会捕获任何数据。

如果我误解了您的问题并且偏离了轨道,请通过评论告诉我。

答案 1 :(得分:2)

如果其他人遇到同样的问题,请尝试使用HTTPS而不是SSL

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

如果您对Paypals Sandbox的测试使用:

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

答案 2 :(得分:1)

核对清单

  1. 沙箱网址 “https://www.sandbox.paypal.com/cgi-bin/webscr”;
  2. 喜欢@jakub说必须为你的paypal控制器禁用CSRF
  3. IPN不会在localhost上验证,但你仍然应该恢复vars。
  4. var_dump (fsockopen('https://www.sandbox.paypal.com/',443,$ errno,$ errstr,30));
  5. 的var_dump ($ _ POST);

答案 3 :(得分:0)

变量$errno$errstr可能是失败的原因。用你的错误信息回复它们。