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

报告相同问题?

悬赏问题

  • ¥30 关于#opencv#的问题:使用大疆无人机拍摄水稻田间图像,拼接成tif图片,用什么方法可以识别并框选出水稻作物行
  • ¥15 Python卡尔曼滤波融合
  • ¥20 iOS绕地区网络检测
  • ¥15 python验证码滑块图像识别
  • ¥15 根据背景及设计要求撰写设计报告
  • ¥20 能提供一下思路或者代码吗
  • ¥15 用twincat控制!
  • ¥15 请问一下这个运行结果是怎么来的
  • ¥15 单通道放大电路的工作原理
  • ¥30 YOLO检测微调结果p为1