IPN 验证回发到 HTTPS

  • 本文关键字:HTTPS 验证 IPN php paypal
  • 更新时间 :
  • 英文 :


我的PHP代码当前使用以下代码回发到PayPal。如何更新此标准以满足即将生效的新支付安全标准?

$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) 
{
  $value = urlencode(stripslashes($value));
  $req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
if (!$fp) 
{
  //an error occurred...
} 
else 
{
  fputs ($fp, $header . $req);
  while (!feof($fp)) 
  {
    $res = fgets ($fp, 1024);
    if(strcmp ($res, "VERIFIED") == 0) 
    {
      //all is well...
    }
  }
}

若要启用 IPN 验证回发到 HTTPS,请按如下所示更改代码,

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

PayPal建议在生产环境中使用 ipnpb.paypal.com 终结点。

此外,您需要将 HTTP/1.0 更改为 HTTP/1.1 以符合PayPal升级。

您需要提交的标头,

$header = "POST /cgi-bin/webscr HTTP/1.1rn";
$header .= "Host: www.paypal.comrn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen( $req ) . "rn";
$header .= "Connection: closernrn";

对于沙盒更改,

 $header .= "Host: www.paypal.comrn";

$header .= "Host: www.sandbox.paypal.comrn";

上面建议的新代码现在有机会进行测试。

这不起作用:

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) 
{
  $value = urlencode(stripslashes($value));
  $req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.1rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen( 'tls://ipnpb.paypal.com', 443, $errno, $errstr, 30);

这是有效的:

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) 
{
  $value = urlencode(stripslashes($value));
  $req .= "&$key=$value";
}
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
如何使用HTTP/1.0并发布到

www.paypal.com 而不是使用HTTP/1.1并发布到 tls://ipnpb.paypal.com?

有几件事需要做:

  • 你仍然在HTTP/1.0;你需要切换到HTTP/1.1。
  • 您需要切换到使用 TLS。

现在大多数PHP设置都应该安装cURL,所以最简单的办法就是使用cURL。 为此,代码的最后四行将更改为以下内容:

$curl = curl_init( 'https://ipnpb.paypal.com/cgi-bin/webscr' );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, $req );
$response = curl_exec( $curl );
if( 'VERIFIED' == trim( $response ) ) {
  // IPN verified by PayPal
}

我在PayPal IPN 验证和使用此代码时遇到了类似的问题

回发到PayPal系统进行验证

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);

如果我正确理解解决方案,新代码应如下所示

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.1rn";
$header .= "Host: ipnpb.paypal.comrn";
$header .= "Connection: closern";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
$fp = fsockopen( 'tls://ipnpb.paypal.com', 443, $errno, $errstr, 30);

最新更新