2011-01-31 114 views
8

如何验证PayPal IPN POST请求到我指定的notifyURL确实来自PayPal?确认IPN呼叫来自PayPal?

我并不是指将数据与之前发送的数据进行比较,但我如何验证此PayPal请求来自的服务器/ IP地址确实是有效的?

+0

这里列出了验证,其中IPN后回来的方法来自并非万无一失,并没有真正让你更安全比你已经是。按照PayPal的建议实施最佳做法。如果他们没有安全感,PayPal将面临更大的问题,因为他们的整个品牌都建立在用户的信任基础之上。 – Brad 2011-02-14 02:19:56

回答

16

的IPN协议包含3个 步骤:

  1. PayPal发送您的IPN侦听器 消息,通知您事件的
  2. 您的侦听器将完整 不变的消息回PayPal;所述 消息必须包含相同的字段 以相同的顺序和在 相同的方式,原始消息
  3. PayPal发送一个字后面,这 要么VERIFIED如果消息 发源与PayPal或无效的,如果被编码 有什么是 最初发送

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro

+0

谢谢,我知道这一点,我正是这样做......但我怎样才能双倍确定它的PayPal调用我的IPN监听器? (您已复制粘贴的第1步)? – siliconpi 2011-01-31 07:11:46

+0

是否有你需要的理由?毕竟,上面概述的3个步骤过程的全部要点是,别人不可能调用您的IPN侦听器,并仍然获得VERIFIED响应。 – Amber 2011-01-31 07:12:43

+0

我不是100%熟悉man-in-the-the-middle类型的攻击,但我想更强有力的验证,要求来自PayPal将更加谨慎...... – siliconpi 2011-01-31 10:54:16

1

如果我没有记错,日任何差异e贝宝为其IPN呼叫使用静态IP。

因此,检查正确的IP应该工作。

或者,您可以使用gethostbyaddrgethostbyname

-1

这是what I use

if (preg_match('~^(?:.+[.])?paypal[.]com$~', gethostbyaddr($_SERVER['REMOTE_ADDR'])) > 0) 
{ 
    // came from paypal.com (unless your server got r00ted) 
} 
11

这是我发现做到这一点,也为百付宝提出的最简单方法。我使用http_build_query()来构建从贝宝发送到网站的帖子中的网址。贝宝文档声明,您应该将其发送回来进行验证,这就是我们用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; 
2

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'); 
} 
3

HTTP头现在需要用户代理!

$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 
}