PayPal沙盒IPN验证始终返回INVALID

5
我谷歌了这个问题并尝试了所有建议,但都没有成功。
我尝试了这段代码:https://developer.paypal.com/docs/classic/ipn/ht_ipn/,但它不起作用。只是复制粘贴并删除旧的magick_quotes路由程序。
我尝试了这段代码:http://samples.geekality.net/view-source.php?file=ipn/ipn_handler.class.php,但它也不起作用。
在所有情况下,我尝试做以下操作:
$req = 'cmd=_notify-validate&' . file_get_contents('php://input');

为了确保我向IPN发送的信息与其发送给我的信息完全一致,我使用了调试代理(Fiddler)并保存了IPN发送给我以及我发送给IPN的信息。请求体是逐字节相同的,除了我的请求前面有cmd=_notify-validate&字符串。
是的,我检查过我使用了正确的沙箱URL。以下是整个请求体:
IPN发送给我的内容:(我只是用XXX替换了个人数据)
POST http://localhost.loc/en/payment/success/1 HTTP/1.1
Host: localhost.loc
Connection: keep-alive
Content-Length: 921
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4

mc_gross=1.00&protection_eligibility=Ineligible&payer_id=5XNKM66NSDKC4&tax=0.00&payment_date=05%3A34%3A11+Jun+01%2C+2015+PDT&payment_status=Completed&charset=utf-8&first_name=XXX&mc_fee=0.33&notify_version=3.8&custom=topup%3A262262%3A1%3A1433162020&payer_status=verified&business=XXX&quantity=1&payer_email=XXX&verify_sign=AG58dBsn5g2z8O8NEjotbuJGP14PAIpZ4k26VL8IyhaDPkcDRj002Keq&memo=hmgvjgjhgfjhfggjhfjtfgjh&txn_id=4CN141026K278934Y&payment_type=instant&last_name=XXX&receiver_email=XXX&payment_fee=0.33&receiver_id=DCMXPXGX4QX6J&txn_type=web_accept&item_name=Account+top+up&mc_currency=USD&item_number=Account+262262+top+up&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=topup%3A262262%3A1%3A1433162020&payment_gross=1.00&shipping=0.00&auth=ANSTBwT3znll-gJQZO2cLoV5QJFW9v8W.FqyWxffdtI0L-9mfsoe2xRL44M86Sn2XtYGtcqG4Fjjel1kdYZyxpQ

我发送给IPN的内容:

POST https://www.sandbox.paypal.com/cgi-bin/webscr HTTP/1.1
Host: www.sandbox.paypal.com
Accept: */*
Content-Length: 942
Content-Type: application/x-www-form-urlencoded

cmd=_notify-validate&mc_gross=1.00&protection_eligibility=Ineligible&payer_id=5XNKM66NSDKC4&tax=0.00&payment_date=05%3A34%3A11+Jun+01%2C+2015+PDT&payment_status=Completed&charset=utf-8&first_name=XXX&mc_fee=0.33&notify_version=3.8&custom=topup%3A262262%3A1%3A1433162020&payer_status=verified&business=XXX&quantity=1&payer_email=XXX&verify_sign=AG58dBsn5g2z8O8NEjotbuJGP14PAIpZ4k26VL8IyhaDPkcDRj002Keq&memo=hmgvjgjhgfjhfggjhfjtfgjh&txn_id=4CN141026K278934Y&payment_type=instant&last_name=XXX&receiver_email=XXX&payment_fee=0.33&receiver_id=DCMXPXGX4QX6J&txn_type=web_accept&item_name=Account+top+up&mc_currency=USD&item_number=Account+262262+top+up&residence_country=US&test_ipn=1&handling_amount=0.00&transaction_subject=topup%3A262262%3A1%3A1433162020&payment_gross=1.00&shipping=0.00&auth=ANSTBwT3znll-gJQZO2cLoV5QJFW9v8W.FqyWxffdtI0L-9mfsoe2xRL44M86Sn2XtYGtcqG4Fjjel1kdYZyxpQ

有人能帮我看看我做错了什么吗? 谢谢。


你应该将你的编辑迁移到你自己的问题的答案上 :-) - Marty
2个回答

3

我只能用脏话来形容PayPal!!!!!问题出在……(鼓声响起……塔丹!)在charset字段中!不是说它的值必须与IPN发送给你的相同,而是要用大写字母!IPN以小写字母发送!因此,您必须修改IPN数据才能成功验证它,无论手册如何告诉我们将数据返回“原样”。这是PayPal的bug吗?

所以我的最终工作代码是:(使用HTTP_Request2)

protected function verifyPostData() {
    $this->request->setBody('cmd=_notify-validate&' . str_replace('=utf-8', '=UTF-8', file_get_contents('php://input')));
    $response = $this->request->send();
    if ($response->getStatus() != 200) {
        throw new \RuntimeException("Transaction data verification request failed with code {$response->getStatus()}");
    }
    $content = trim($response->getBody());
    return ($content == 'VERIFIED');
}

我是如何做到的:我发送了PDT请求以获取交易数据。然后,我对比了PDT和IPN数据的每个字段。PDT没有一些IPN字段,如authverify_signtest_ipn。但所有其他字段似乎必须相同。唯一的区别在于charset字段的字符大小写。然后,我尝试验证修改后的数据,出乎意料地成功了!

0
这是一个最近的PayPal bug,当客户完成付款并点击“点击此处返回…”而不是等待几秒钟时,传递给您网站上的PDT脚本的参数会以小写形式发送。
这也会破坏大小写敏感或编码的cm/custom参数等内容。
显然,PayPal已经意识到了这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接