Paypal IPN 沙盒 - IPN 侦听器 - 未验证或无效

Posted

技术标签:

【中文标题】Paypal IPN 沙盒 - IPN 侦听器 - 未验证或无效【英文标题】:Paypal IPN Sandbox - IPN Listener - no verified or invalid 【发布时间】:2013-07-17 02:58:10 【问题描述】:

我已经在开发者中设置了测试账户 Business 和 Personal 来尝试沙盒模式。

我在我的网站上设置了一个付款按钮。我单击按钮并转到贝宝。 测试用户个人账户用于支付。 当我查看 Paypal 商业帐户时,付款已完成并已完成。 重定向到我的网站效果很好。

所以在我看来我应该有一个“工作”系统。

我的 IPN 侦听器未返回已验证或无效。

这是我的听众:

 <?php
 require("../widgets/init.inc.php");

//Test the script is launced
$log_query = mysql_query("INSERT INTO `log` VALUES (' ','zz','ff','rr', 'rr')");                

// Link to PayPal Codes //
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables // 

// 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.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

//For the below line i have tried "www.sandbox.paypal" as well as "www.paypal"
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables //
$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'];
$txnId = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];
$payerEmail = $_POST['payer_email'];
//$id = ($_POST['custom']);

if (!$fp) 

 else 
fputs ($fp, $header . $req);
while (!feof($fp)) 
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) 

if ($payment_status=='Completed') 

//$txnIdCheck = mysql_query("SELECT `txnId` FROM `log` WHERE `txnId`='".$txnId."'");  
//if (mysql_num_rows($txnIdCheck) !=1) 

// enter your email address associated with your paypal account here // 
if ($receiverEmail=='biztester1@mydomain.dk')  

/* when a new premium member makes payment paypal will update our database. The txn_id from paypal, members email address, date of payment and members id we gave them when they joined our site will be inserted into the log table. At the same time the memberAdmin table for the member will be updated by adding a '1' to premium and the date of payment so the new premium member will have access to premium areas of your site. */

//Check if verified is launced          
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','yes','yes','yes', 'yes')");          

//$log_query = mysql_query("INSERT INTO `log` VALUES (' ','".intval($id)."','".$txnId."','".$payerEmail."', now())");                   

//$update_premium = mysql_query("UPDATE `memberAdmin` SET `premium`=1, `premiumDate`=now() WHERE `id`=".intval($id)."");    

       
//


else if (strcmp ($res, "INVALID") == 0)          
//Check if invalid is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','no','no','no', 'no'");   


fclose ($fp);

?>

我已经在 paypal 商业帐户网站上激活了 IPN。 我把paypal返回的信息做成了一个txt文件,看起来是这样的:

==== Thu, 18 Jul 2013 01:34:21 +0200 ====
POST: mc_gross = 0.01
POST: protection_eligibility = Ineligible
POST: payer_id = 73WPPK8HKSW7C
POST: tax = 0.00
POST: payment_date = 15:15:20 Jul 17, 2013 PDT
POST: payment_status = Completed
POST: charset = windows-1252
POST: first_name = Niels
POST: mc_fee = 0.01
POST: notify_version = 3.7
POST: payer_status = verified
POST: business = biztester1@mydomain.dk
POST: quantity = 1
POST: verify_sign = A-ddKAwtxju4TpHGJOGq6c3ewj26AyiHsD.XO90coZ.4rVzOT7VyooKO
POST: payer_email = tester1@mydomain.dk
POST: txn_id = 6WH41489RE087103M
POST: payment_type = instant
POST: last_name = Tester
POST: receiver_email = biztester1@mydomain.dk
POST: payment_fee = 0.01
POST: receiver_id = PCX638B2M7WPA
POST: txn_type = web_accept
POST: item_name = 500Credits
POST: mc_currency = USD
POST: item_number = 1
POST: residence_country = DE
POST: test_ipn = 1
POST: handling_amount = 0.00
POST: transaction_subject = 500Credits
POST: payment_gross = 0.01
POST: shipping = 0.00
POST: ipn_track_id = 2dffcbf8767d3
InvoiceID: 
Custom1: 
Custom2: 
Custom3: 

似乎让这个工作比我认为的要困难得多。

【问题讨论】:

【参考方案1】:

我发现了问题.. 令人烦恼的是 PAYPAL 文档又错了.. 我不明白文档可以说明按下此按钮并按下此按钮.. 当没有这样的按钮时网站...

对于这个问题 - 文档确实说明了错误的方法/不包括所需的完整代码。

问题: $res 返回了这个:

HTTP/1.0 400 Bad Request
Server: BigIP
Connection: close
Content-Length: 19
Invalid Host header

需要补充的是:

$header .= "Host: www.sandbox.paypal.com\r\n";

然后上面的代码如下所示:

// post back to PayPal system to validate //
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

这是我最终使用的完整代码:

<?php
require("../widgets/init.inc.php");         

// Link to PayPal Codes //
// https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables // 

// 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.0\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

// assign posted variables to local variables //
$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'];
$txnId = $_POST['txn_id'];
$receiverEmail = $_POST['receiver_email'];
$payerEmail = $_POST['payer_email'];
//$id = ($_POST['custom']);


if (!$fp) 

 else 
fputs ($fp, $header . $req);
while (!feof($fp)) 
$res = fgets ($fp, 1024);

$log_query_pre = mysql_query("INSERT INTO `log` VALUES (' ','$receiverEmail','$payment_status','$res', 'yes')");    

  if (strcmp ($res, "VERIFIED") == 0) 

if ($payment_status=='Completed') 

//$txnIdCheck = mysql_query("SELECT `txnId` FROM `log` WHERE `txnId`='".$txnId."'");  
//if (mysql_num_rows($txnIdCheck) !=1) 

// enter your email address associated with your paypal account here // 
if ($receiverEmail=='biztester1@mydomain.dk')  

/* when a new premium member makes payment paypal will update our database. The txn_id from paypal, members email address, date of payment and members id we gave them when they joined our site will be inserted into the log table. At the same time the memberAdmin table for the member will be updated by adding a '1' to premium and the date of payment so the new premium member will have access to premium areas of your site. */

//Check if verified is launced          
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','yes','yes','yes', 'yes')");      

//$log_query = mysql_query("INSERT INTO `log` VALUES (' ','".intval($id)."','".$txnId."','".$payerEmail."', now())");                   

//$update_premium = mysql_query("UPDATE `memberAdmin` SET `premium`=1, `premiumDate`=now() WHERE `id`=".intval($id)."");    

       
//


else if (strcmp ($res, "INVALID") == 0)          
//Check if invalid is launced
$log_query_2 = mysql_query("INSERT INTO `log` VALUES (' ','no','no','no', 'no')");  


fclose ($fp);

?>

【讨论】:

谢谢!我整个下午都遇到同样的麻烦。很高兴我找到了这个。令人沮丧的是这是一个文档错误... 谢谢!我遇到了完全相同的问题。 @Niels 我按照上述步骤操作,但 $res 返回 HTTP/1.1 200 OK,我怎样才能得到 VERIFIED 或 INVALID 消息? @evolquez - 它从 $res 输出几行,当第一行是 HTTP/1.1 200 时 - 下一行确定实际的返回消息.. 返回消息是您获得 VERIFIED 消息的地方来自.. 上面的代码仍然适用于贝宝集成,因为它在我的一个网站上在线...... @Niels 我什至没有得到验证,而是 HTTP/1.1 200 和其他 cookie、日期等。知道吗?

以上是关于Paypal IPN 沙盒 - IPN 侦听器 - 未验证或无效的主要内容,如果未能解决你的问题,请参考以下文章

Paypal IPN 在沙盒中有效 直播时无效

PayPal IPN 通知验证正在返回 ASP.NET 的沙盒登录 HTML

在 PayPal Sandbox 中没有收到对侦听器的 IPN 响应

PayPal IPN 侦听器响应

C# 中的 Paypal IPN 侦听器问题

PayPal IPN 侦听器 - SSL 证书握手失败