PHP/CodeIgniter PayPal IPN 无效验证

Posted

技术标签:

【中文标题】PHP/CodeIgniter PayPal IPN 无效验证【英文标题】:PHP/CodeIgniter PayPal IPN Invalid Validation 【发布时间】:2012-03-08 20:39:36 【问题描述】:

我在 CodeIgniter 2 上构建了一个网站,并且我正在使用 CodeIgniter PayPal Lib。我已经完成了所有必要的事情,现在我可以进行付款了。我收到一个 IPN 数据并将其发送到我的电子邮件。我已经阅读了 PayPal IPN 指南,但在那里找不到解决方案。

到目前为止一切正常,我对结果很满意,但我很担心,因为 PayPal IPN 验证失败,我无法理解问题出在哪里。

当我从沙盒测试站点发送 IPN 测试时,我会收到一个有效的 IPN, 但当我从我的网站付款时,IPN 验证失败。。 p>

我正在记录所有数据,在这两种情况下(有效或无效),付款都是成功的,我有一个“成功!”来自 PayPal 的消息。

我尝试过的事情

    打开/关闭 CSRF 保护 更改编码 (utf-8 | windows-1252) 添加|从我的 PayPal 请求中删除字段

我正在使用的代码

我正在使用的字段

$this->paypal_lib->add_field('business', 'name_1321715512_biz@gmail.com');
$this->paypal_lib->add_field('return', site_url('paypal/success'));
$this->paypal_lib->add_field('cancel_return', site_url('paypal/cancel'));
$this->paypal_lib->add_field('notify_url', site_url('contest/receive_ipn'));
$this->paypal_lib->add_field('item_name', 'Contest Subscribtion Payment (Test)');
$this->paypal_lib->add_field('amount', '30');
$this->paypal_lib->add_field('item_number', Y11-1329469079-12); // Reference number
$this->paypal_lib->add_field('quantity', '1');
$this->paypal_lib->add_field('charset', 'utf8');
$this->paypal_lib->add_field('custom', 1723); //This is an id that I need.  

发帖到 PayPal 进行验证

$post_string.="cmd=_notify-validate";

if (isset($_POST))
    foreach ($_POST as $field=>$value)
         $value = str_replace("\n", "\r\n", $value);
         $value = urlencode(stripslashes($value));
         $post_string .= "&$field=$value";

         $this->ipn_data[$field] = $value; //this is part of the library
    


$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($post_string) . "\r\n\r\n";

$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

验证IPN的代码

fputs ($fp, $header . $post_string);
while (!feof($fp)) 
    $res = fgets ($fp, 1024);
    if (strcmp ($res, "VERIFIED") == 0) 
        // Send me e-mail - Verified
     else if (strcmp ($res, "INVALID") == 0) 
        // Send me e-mail - Invalid
    

fclose($fp);

我还要发布收到的回复

这个是无效的(然后从我的网站发送)

cmd=_notify-validate&mc_gross=30.00&protection_eligibility=Ineligible&address_status=unconfirmed&payer_id=LD9UMUWHD44GY&tax=0.00&address_street=Via+Unit+d%27Italia%2C+5783296&payment_date=02%3A19%3A29+Feb+17%2C+2012+PST&payment_status=Completed&charset=windows-1252&address_zip=80127&first_name=Alexander&mc_fee=1.37&address_country_code=IT&address_name=Alexander+Videnov&notify_version=3.4&custom=1721&payer_status=verified&business=aviden_1321715512_biz%40gmail.com&address_country=Italy&address_city=Napoli&quantity=1&verify_sign=AF1YwvTycK97c-VCwQnfsdzArWAcAqZjskElh-FsmZ0s9HqL9BjFUKVH&payer_email=aviden_1329133801_per%40gmail.com&txn_id=32Y96385XJ0686735&payment_type=instant&last_name=Videnov&address_state=Napoli&receiver_email=aviden_1321715512_biz%40gmail.com&payment_fee=&receiver_id=TQVQ3ASRDBW28&txn_type=web_accept&item_name=Yicca+Contest+Subscribtion+Payment+%28Test%29&mc_currency=EUR&item_number=Y11-1329473936-12&residence_country=IT&test_ipn=1&handling_amount=0.00&transaction_subject=1721&payment_gross=&shipping=0.00&ipn_track_id=35382e1887f00

这是已验证的(从 PayPal 测试站点发送时)

cmd=_notify-validate&test_ipn=1&payment_type=echeck&payment_date=02%3A28%3A24+Feb+17%2C+2012+PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer%40paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John+Smith&address_country=United+States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San+Jose&address_street=123%2C+any+street&business=seller%40paypalsandbox.com&receiver_email=seller%40paypalsandbox.com&receiver_id=TESTSELLERID1&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&txn_type=web_accept&txn_id=242171028&notify_version=2.1&custom=xyz123&invoice=abc1234&charset=windows-1252&verify_sign=An5ns1Kso7MWUdW4ErQKJJJ4qi4-Arge8MWjXZSo7fPSQf3xaqAOjrSH

我注意到的两件事

    我的网站发送的 IPN 请求和沙盒测试站点发送的 IPN 请求之间的字段顺序(请求)不同notify_version 字段存在差异。来自我的网站 (3.4) |来自 PayPal (2.1)

是否有人在验证过程中遇到过同样的问题。有什么我遗漏的东西,或者我可以调试更多的方法吗?

【问题讨论】:

【参考方案1】:

我收到了来自 Paypal 的回复,这可能也与您有关:

现在我们从经验中了解到,在 IPN 验证期间可能难以处理特殊字符。 基本上,我们用于将 IPN 消息发送到您的服务器的字符编码需要由您的 IPN 处理程序在将消息发送回 PayPal 系统进行验证时进行匹配。

通过将帐户的语言编码选项更改为 UTF-8,我们在解决这些问题方面取得了很大成功。

您的操作方法如下: 1. 请登录您的PayPal账户。

    然后点击此链接,您将直接转到语言编码选项:https://www.paypal.com/cgi-bin/webscr?cmd=_profile-language-encoding

    点击“更多选项”按钮。

    将两个下拉菜单都更改为 UTF-8 并点击保存。

如果您在代码中指定了不同的字符编码,请将其也切换为 UTF-8。

【讨论】:

【参考方案2】:

不确定您是否使用自适应支付,但我使用了这个库:http://www.binpress.com/app/paypal-adaptive-payments-pro-codeigniter-library/140,它的效果非常好,而且作者非常乐于助人。

在这里查看我的问题:Paypal IPN Issue with parallel payment。我已经在答案中发布了我的 paypal IPN 代码。

【讨论】:

我在您的帖子中找到了答案。我已将 $post_string.="cmd=_notify-validate"; 更改为 $post_string= 'cmd=_notify-validate&'.file_get_contents("php://input"); 并删除了 foreach 循环。现在 IPN 返回 VERIFIED。我注意到两个请求中的某些字符不同,我可以猜测非法字符是返回 INVALID 的原因。【参考方案3】:

CodeIgniter PayPal Lib 已经过时并且一直存在漏洞。至少根据我的经验。

我所做的并且我会推荐的是,使用官方的 PayPal SDK 并将它们“转换”为 CI。 这相当容易。

您可以在这里找到这些: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/library_download_sdks

还请查看文档: https://www.x.com/developers/paypal/development-integration-guides#ec 没有他们你就活不下去!

【讨论】:

我做了所有必要的更改,但我仍然有无效的响应。我已经修改了所有 PayPal Lib 并用正确的代码替换它,从 paypal 网站获取。同样对于测试,我已经用固定字段对表单进行了硬编码,但仍然没有运气。还有其他建议吗? 我已经用无效请求和验证请求更新了我的帖子。请看一看。

以上是关于PHP/CodeIgniter PayPal IPN 无效验证的主要内容,如果未能解决你的问题,请参考以下文章

我无法在为 PHP CodeIgniter 框架实施 PayPal 库的贝宝自适应支付中添加商品编号、商品价格和数量

php PHP:Codeigniter:IP Geo Scraper

PHP,Codeigniter:如何在Web应用程序中根据用户时区/位置设置日期/时间?

从 URL 中删除 index.php - Codeigniter 2

从 URL 中删除 index.php (CodeIgniter)

PHP | Codeigniter 重定向 |无法修改标头信息