Php PayPal IPN和fsockopen

Php PayPal IPN和fsockopen,php,paypal,paypal-ipn,fsockopen,Php,Paypal,Paypal Ipn,Fsockopen,我不能使用cURL,安装在我的web主机上的无法更改的版本不支持TLS 我现在正在尝试使用fsockopen,看看是否能够使用IPN 它只是挂起,浏览器抛出连接超时 PHP7,已启用开放式ssl <?php header('HTTP/1.1 200 OK'); $item_name = $_POST['item_name']; $item_number = $_POST['item_number']; $payment_statu

我不能使用cURL,安装在我的web主机上的无法更改的版本不支持TLS

我现在正在尝试使用fsockopen,看看是否能够使用IPN

它只是挂起,浏览器抛出连接超时

PHP7,已启用开放式ssl

<?php
    header('HTTP/1.1 200 OK'); 

    $item_name        = $_POST['item_name'];
    $item_number      = $_POST['item_number'];
    $payment_status   = $_POST['payment_status'];
    $payment_amount   = $_POST['mc_gross'];
    $payment_currency = $_POST['mc_currency'];
    $txn_id           = $_POST['txn_id'];
    $receiver_email   = $_POST['receiver_email'];
    $payer_email      = $_POST['payer_email'];

    $req = 'cmd=_notify-validate';               // Add 'cmd=_notify-validate' to beginning of the acknowledgement
    foreach ($_POST as $key => $value) {         // Loop through the notification NV pairs
        $value = urlencode(stripslashes($value));  // Encode these values
        $req  .= "&$key=$value";                   // Add the NV pairs to the acknowledgement
    }

    // Set up the acknowledgement request headers
    $header  = "POST /cgi-bin/webscr HTTP/1.1\r\n";                    // HTTP POST request
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

    // Open a socket for the acknowledgement request
     $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

    // Send the HTTP POST request back to PayPal for validation
    fputs($fp, $header . $req);

    while (!feof($fp)) {                     // While not EOF

    $res = trim(fgets ($fp, 1024));

    if (strcmp ($res, "VERIFIED") == 0) {  // Response contains VERIFIED - process notification

      file_put_contents('./log_'.date("j.n.Y").'.txt', 'VERIFIED', FILE_APPEND);
    } 
    else if (strcmp ($res, "INVALID") == 0) { Response contains INVALID - reject notification
        file_put_contents('./log_'.date("j.n.Y").'.txt', 'INVALID', FILE_APPEND);
    }
  }
  //close
  fclose($fp);
?>

$res
在请求-响应之间循环,每次读取1024字节,在最后一次迭代时将其保留为空

如果您试图通过循环将
$res
变量记录到某个地方,您只需逐行找到响应,例如

HTTP/1.0 302 Found 
Location: https://www.sandbox.paypal.com
Server: BigIP
Connection: close 

这不是解决问题,而是。。只是一个想法。:)

谢谢你的发帖!我遇到了一个类似的问题,IPN被发送,我的服务器使用fsocket对其进行了验证,代码被执行以写入数据库,但PayPal在多次重试后仍报告“交付状态”为“失败”,导致数据库中出现重复。查看您的代码后,我发现我一直在编写的教程遗漏了这一行,导致PayPal的请求超时,而不是显示200:

    $header .= "Connection: close\r\n";

我遇到了同样的问题,沙盒返回了一个空结果。我的代码类似于Tsukasa提供的更新2

我不得不将sandbox.paypal.com更改为ipnbp.sandbox.paypal.com,并在其前面加上ssl。fsocket调用如下所示:

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

如果您的服务器环境不支持TLS,则意味着它必须非常旧。10岁以上。如果他们不能让你进入一个新的服务器,它有一个更新的运行TLS的环境,我强烈建议你切换主机。好的,我解决了我的问题,但是现在$res总是空的。我没有得到验证或无效的回复。
    $header .= "Connection: close\r\n";
$fp = fsockopen ('ssl://ipnbp.sandbox.paypal.com', 443, $errno, $errstr, 30);