带有 fsockopen 的 PayPal IPN 返回 NULL

发布于 2024-12-23 21:33:31 字数 3492 浏览 3 评论 0 原文

我正在尝试在我的 Web 应用程序上设置 PayPal IPN,我从 PayPal 文档中复制了示例 PHP 片段,该片段位于 此处

但是,当我使用 PayPal 的沙箱进行测试时,使用模拟器发送 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 并安装在我的服务器上:

在此处输入图像描述

编辑:刚刚测试 fsockopen< /code> 在端口 80 到 google.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 失败:提供节点名或服务名,或未知)

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¬ify_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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情话难免假 2024-12-30 21:33:31

如果其他人也遇到同样的问题,请尝试使用 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);

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);
淡紫姑娘! 2024-12-30 21:33:31

请小心 $config['csrf_protection'] = TRUE; 这将阻止所有外部帖子,因为它们不会附带 CSRF 令牌,我已经在我的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 变量。

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

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.

贵在坚持 2024-12-30 21:33:31

检查列表

  1. 沙盒网址:“https://www.sandbox.paypal.com/cgi-bin/webscr”;
  2. 就像 @jakub 说 CSRF 必须被禁用,因为你的 paypal 控制器
  3. IPN 不会在本地主机上验证,但是你仍然应该得到 vars。
  4. var_dump(fsockopen('https://www.sandbox.paypal.com/', 443, $errno, $errstr, 30));
  5. var_dump($_POST);

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);
时光清浅 2024-12-30 21:33:31

变量 $errno$errstr 可能保存失败的原因。用你的错误消息回应他们。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文