我正在测试使用Web Payments标准和HTML变量将网站集成到Paypal。
我编写了一个简单的PHP脚本来处理IPN通知。
根据Paypal documentation,Paypal服务器响应一个简单的“验证”或“无效”响应,一旦您将收到的数据ping回贝宝。
在我的处理程序中,我正在对这两个关键字进行区分大小写的字符串比较,如果找不到其中任何一个已知关键字,则会将其视为错误。
<?php
$fp = fsockopen ($socket_url, 80, $errno, $errstr, 10);
if (!$fp){
// SOCKET ERROR
return false;
}
else {
fputs ($fp, $header . $req);
$is_ok = false;
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp("VERIFIED",$this->ipn_response)==0) {
//do something ...
}
// if the IPN POST was 'INVALID'
else if (strcmp ($res, "INVALID") == 0) {
fclose ($fp);
return false;
}
else {
echo "Unknown response from Paypal: $res";
fclose ($fp);
return false;
}
}
fclose ($fp);
return true;
}
?>
我的错误消息显示我收到了Paypal的“HTTP / 1.1 200 OK”回复。
Paypal的未知回复: 'HTTP / 1.1 200 OK'
PayPal API是否已更改,或者我做错了什么?
答案 0 :(得分:2)
PayPal的响应位于HTTP响应的正文中。您需要先处理HTTP标头,然后才能进入正文。或者,也可以继续阅读行,直到找到一个空行,下一行将是正文。
答案 1 :(得分:1)
抱歉,我最初的回答非常糟糕:)
fgets只是逐行读取,第一行是HTTP响应。但是,您的代码永远不会提供继续阅读的机会,因为您在处理完第一行后会出现'错误'。
我倾向于用以下内容替换你的while循环:
while (!feof($fp)) {
$res = trim(fgets($fp, 1024));
if (strcmp($res, "VERIFIED")==0) {
//do something ...
}
else if (strcmp($res, "INVALID") == 0) {
fclose ($fp);
return false;
}
}
答案 2 :(得分:1)
正如@Mike所说,你要读全身 - 在你的情况下,你只是测试回复的前1024个字节中是否出现VERIFIED
或INVALID
,这可能是标题。
顺便说一句,您不需要使用fsockopen()
,大多数人都这样做,因为PayPal提供了一个使用它的示例,因此它可以在旧的盒子设置中使用。使用HTTP POST上下文的CURL或file_get_contents
可以很好地完成工作,这是我为 phunction PHP framework 编写的示例:
public static function PayPal($email, $status = 'Completed', $sandbox = false)
{
if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0)
{
$url = ($sandbox !== true) ? '' : '.sandbox';
$result = self::CURL('https://www' . $url . '.paypal.com/cgi-bin/webscr/', array_merge(array('cmd' => '_notify-validate'), $_POST), 'POST');
if ($result == 'VERIFIED')
{
$email = strlen($email) * strcasecmp($email, $_POST['receiver_email']);
$status = strlen($status) * strcasecmp($status, $_POST['payment_status']);
if (($email == 0) && ($status == 0))
{
return true;
}
}
}
return false;
}