我已经尝试编写一个小的PayPal IPN 处理程序,但是在使用 IPN 模拟器 https://developer.paypal.com/webapps/developer/applications/ipn_simulator 时,我总是得到"无效"。我不确定我发回的 URL 是否正确。我已经看过这个主题的一些要点,但它们似乎都有点冗长。他们关于此的文档在这里 https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNIntro/#protocol_and_arch,我认为我已经遵循了协议的所有步骤。任何帮助不胜感激
<?php
/**
* Validates a PayPal IPN notification
* @param array $req The $_POST variable for the request
* @return String Returns the validity: 'VALID' or 'INVALID'
*/
function verifyPayPalIPN($req) {
// Base URL for the php validation
$baseURL = 'https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate';
// Loop through the POST parameters to
// create the validaton URL
$postVars = '';
foreach ($req as $key => $value) {
$postVars .= $key . '=' . urlencode($value) . '&';
}
// Strip the last & off of the URL
$postVars = substr($postVars, 0, -1);
// Send the request to PayPal to confirm
// whether the request to the script is
// from PayPal
$requestValidity = system("curl --data '$postVars' $baseURL");
return $requestValidity;
}
file_put_contents('/tmp/result.txt', verifyPayPalIPN($_POST));
?>
cmd=_notify-validate
应该是postVars字符串的一部分
$baseURL = 'https://www.paypal.com/cgi-bin/webscr';
// Loop through the POST parameters to
// create the validaton URL
$postVars = 'cmd=_notify-validate';
foreach ($req as $key => $value) {
$postVars .= $key . '=' . urlencode($value) . '&';
}
我过去使用的代码是这样的:
$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";
$fp = fsockopen ("ssl://www.paypal.com", 443, $errno, $errstr, 30);
if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {
} else if (strcmp ($res, "INVALID") == 0) {
}
}
fclose($fp);
}
另请注意端口号 443
首先,检查您的付费环境和验证环境是否相同(sandbox
或production
),如果不是,则说您的客户在production
环境中支付了订单,但随后您的PHP代码尝试请求sandbox
环境端点来验证IPN请求,那么它将始终以无效结尾