dphfwzn8269 2016-09-13 08:49
浏览 168
已采纳

使用HTTPS的Paypal IPN验证回发

According to new security requirements (2016, 2017 and 2018), it seems that HTTPS will be required for exchange between server and Paypal, during an "IPN". This question is linked to this subject and also this.

How should we adapt this PHP IPN code?

$header .= "POST /cgi-bin/webscr HTTP/1.0
";
$header .= "Host: www.paypal.com:80
";
$header .= "Content-Type: application/x-www-form-urlencoded
";
$header .= "Content-Length: " . strlen($req) . "

";

$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);

$req = 'cmd=_notify-validate';

...

fputs ($fp, $header . $req);

Would replacing the two occurences of www.paypal.com by https://www.paypal.com be enough?

Also, is the fact my shop website is not HTTPS a problem, will this connection be refused?


Here is part of the email received from Paypal:

enter image description here


Edit (2018/06/22), here is the actual IPN code, after applying the accepted answer code. Strangely, I still get: "IPN Verification postback to HTTPS. Update needed: YES". So this means the following code is still not 100% compliant to HTTPS. Why?

<?php
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
  $value = trim(urlencode(stripslashes($value)));
  $req .= "&$key=$value";
}

$header .= "POST /cgi-bin/webscr HTTP/1.0
";
$header .= "Host: www.paypal.com
";
$header .= "Content-Type: application/x-www-form-urlencoded
";
$header .= "Content-Length: " . strlen($req) . "

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

// variables
$item_name = $_POST['item_name'];
$business = $_POST['business'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
// and many more

if (!$fp)
{
  // HTTP ERROR
} else
{
  fputs ($fp, $header . $req);
  while (!feof($fp))
  {
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0)
    {
        // send email to customer, etc.
    }
  }
  fclose ($fp);
}
?>
  • 写回答

6条回答 默认 最新

  • dousou1967 2016-09-13 08:52
    关注

    hostname

    If OpenSSL support is installed, you may prefix the hostname with either ssl:// or tls:// to use an SSL or TLS client connection over TCP/IP to connect to the remote host.

    http://www.php.net/fsockopen

    The port would also need to change to 443. So:

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

    https:// would not work because you're opening a socket, which is a low-level transport. HTTP is an application level protocol on top of that, which the socket doesn't know or care about. At the socket level it's a TLS connection.

    Also, is the fact my shop website is not HTTPS a problem, will this connection be refused?

    What kind of connection a browser has to your server is irrelevant and nobody knows that. You're opening a socket from a PHP program to Paypal, you may as well be doing that directly from the command line without any "HTTP" connection involved at all.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大