如何验证对我指定的 notifyURL 的 PayPal IPN POST 请求确实来自 PayPal?
我并不是说将数据与我之前发送的数据进行比较,而是如何验证此 PayPal 请求来自的服务器/IP 地址确实是有效的?
如何验证对我指定的 notifyURL 的 PayPal IPN POST 请求确实来自 PayPal?
我并不是说将数据与我之前发送的数据进行比较,而是如何验证此 PayPal 请求来自的服务器/IP 地址确实是有效的?
IPN 协议由三个步骤组成:
- PayPal 向您的 IPN 侦听器发送一条消息,通知您该事件
- 您的听众将完整的未更改消息发送回 PayPal;消息必须以相同的顺序包含相同的字段,并以与原始消息相同的方式进行编码
- PayPal 会返回一个单词,如果消息来自 PayPal,则为 VERIFIED,如果与最初发送的消息有任何差异,则为 INVALID
https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
这是我发现的最简单的方法,也是根据 PayPal 建议的。我使用 http_build_query() 从从 paypal 发送到网站的帖子中构造 url。Paypal 文档声明您应该将其发回以进行验证,这就是我们对 file_get_contents 所做的事情。您会注意到我使用 strstr 检查是否存在“已验证”一词,因此我们继续执行该函数,如果不存在则返回 false ...
$verify_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate&' . http_build_query( $_POST );
if( !strstr( file_get_contents( $verify_url ), 'VERIFIED' ) ) return false;
https://gist.github.com/mrded/a596b0d005e84bc27bad
function paypal_is_transaction_valid($data) {
$context = stream_context_create(array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
),
));
$content = file_get_contents('https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate', false, $context);
return (bool) strstr($content, 'VERIFIED');
}
现在需要 HTTP 标头 User-Agent!
$vrf = file_get_contents('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate', false, stream_context_create(array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\nUser-Agent: MyAPP 1.0\r\n",
'method' => 'POST',
'content' => http_build_query($_POST)
)
)));
if ( $vrf == 'VERIFIED' ) {
// Check that the payment_status is Completed
// Check that txn_id has not been previously processed
// Check that receiver_email is your Primary PayPal email
// Check that payment_amount/payment_currency are correct
// process payment
}
这就是我使用的:
if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0)
{
// came from paypal.com (unless your server got r00ted)
}