Paypal 沙箱 IPN 返回 INVALID
我正在尝试使用 servlet 进行 IPN 回调。我使用的代码是由 paypal 提供的,用于验证 ipn 数据。但每次我收到无效响应时。
这是代码:
Enumeration en = req.getParameterNames();
String str = "cmd=_notify-validate";
while (en.hasMoreElements()) {
String paramName = (String) en.nextElement();
String paramValue = req.getParameter(paramName);
//str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue,"UTF-8"); // for UTF-8 i set the encode format in my account as UTF-8
//str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue,"ISO-8859-1");// for ISO-8859-1 i set the encode format in my account as ISO-8859-1
str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue); //default as provided by paypal
}
URL u = new URL("http://www.sandbox.paypal.com/cgi-bin/webscr");
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.println(str);
pw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String res = in.readLine();
in.close();
if (res.equals("VERIFIED") || !res.equals("VERIFIED")) {
//Update database...
} else if (res.equals("INVALID")) {
//INVALID
}
我已经检查了贝宝提供的所有三种可能性,以防贝宝返回无效,如下所示:
1)缺少参数 - 因为我发送所有参数,所以没有缺少参数的问题
2)无效的URL。 - 我正在使用沙箱,因此 URL 为: http://www.sandbox.paypal.com/ cgi-bin/webscr
3) 字符编码。 - 尝试使用与贝宝帐户设置参数编码相同的字符编码。
我使用以下参数发送回贝宝的请求:
cmd=_notify-validate&last_name=User&test_ipn=1&address_name=Test+User&txn_type=web_accept&receiver_email=sellr1_1252495907_biz%40gmail.com&residence_country=US&address_city=San+Jose& payment_gross=& payment_date =01%3A55%3A04+Sep+26%2C+2009+PDT&address_zip=95131& payment_status=已完成&address_street=1+Main+St&first_name=测试&payer_email=buyer1_1252495751_per%40gmail.com&protection_eligibility=合格&payer_id =BXBKS22JQCUWL&verify_sign=AOMkeg7ofCL7FJfioyWA19uCxD4XAgZirsjiGh8cUy1fd2YAqBwOkkst& payment_type=instant&business=sellr1_1252495907_biz%40gmail.com&address_country_code=US&mc_fee= 0.64&address_status=已确认&transaction_subject=True+Up&数量=1¬ify_version=2.8&mc_currency=EUR& ;custom=&address_state=CA& payment_fee=&handling_amount=0.00&payer_status=verified&shipping=0.00&item_name=True+Up&tax=0.00&用户名=hannonj&charset=windows-1252&item_number= 567&mc_gross=10.00&txn_id=7F456350BS7942738&receiver_id=MASSU6BSR9SC2&address_country=美国+美国
请问,有人可以指导我正确的方向吗?我不明白代码、URL 或其他任何内容有什么问题。我尝试了所有的可能性。请帮我。
I am trying IPN callback, using servlet. The code I am using is provided by paypal for verifying the ipn data. But every time i getting a INVALID response.
Here is the code:
Enumeration en = req.getParameterNames();
String str = "cmd=_notify-validate";
while (en.hasMoreElements()) {
String paramName = (String) en.nextElement();
String paramValue = req.getParameter(paramName);
//str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue,"UTF-8"); // for UTF-8 i set the encode format in my account as UTF-8
//str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue,"ISO-8859-1");// for ISO-8859-1 i set the encode format in my account as ISO-8859-1
str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue); //default as provided by paypal
}
URL u = new URL("http://www.sandbox.paypal.com/cgi-bin/webscr");
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.println(str);
pw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String res = in.readLine();
in.close();
if (res.equals("VERIFIED") || !res.equals("VERIFIED")) {
//Update database...
} else if (res.equals("INVALID")) {
//INVALID
}
I have checked all three possibilities provided by paypal in case paypal return INVALID as follow:
1) Missing Parameters - As I am send all the parameters no issue of missing parameters
2) Invalid URL. - I am using sandbox so URL is : http://www.sandbox.paypal.com/cgi-bin/webscr
3) Character encoding. - Tried with character encoding same as paypal account setting parameter encoding.
the request I am sending back to paypal using following parameters:
cmd=_notify-validate&last_name=User&test_ipn=1&address_name=Test+User&txn_type=web_accept&receiver_email=sellr1_1252495907_biz%40gmail.com&residence_country=US&address_city=San+Jose&payment_gross=&payment_date=01%3A55%3A04+Sep+26%2C+2009+PDT&address_zip=95131&payment_status=Completed&address_street=1+Main+St&first_name=Test&payer_email=buyer1_1252495751_per%40gmail.com&protection_eligibility=Eligible&payer_id=BXBKS22JQCUWL&verify_sign=AOMkeg7ofCL7FJfioyWA19uCxD4XAgZirsjiGh8cUy1fd2YAqBwOkkst&payment_type=instant&business=sellr1_1252495907_biz%40gmail.com&address_country_code=US&mc_fee=0.64&address_status=confirmed&transaction_subject=True+Up&quantity=1¬ify_version=2.8&mc_currency=EUR&custom=&address_state=CA&payment_fee=&handling_amount=0.00&payer_status=verified&shipping=0.00&item_name=True+Up&tax=0.00&username=hannonj&charset=windows-1252&item_number=567&mc_gross=10.00&txn_id=7F456350BS7942738&receiver_id=MASSU6BSR9SC2&address_country=United+States
Please , can any one direct me to proper direction? I am not getting what is wrong the code or the URL or anything else. I tried all the possibilities. Please help me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
“无效”消息是由于以下原因造成的:
确保您对响应字符串进行编码,并使用与测试 IPN 消息相同的字符编码。 (例如,我可以看到他使用带有变音符号的字母和其他符号,如“/”等)。
关于最后一点,商家可以尝试更改其PayPal帐户中使用的编码语言,具体步骤如下:
如果问题仍然存在,我们建议检查正在使用的脚本,PayPal 在以下位置提供了一些 IPN 代码示例: https://github .com/paypal/ipn-code-samples
有关其他信息,我包含链接:https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNTesting/#id091GFE00WY4
An “INVALID” message is due to the following reasons:
Ensure that you are encoding your response string and are using the same character encoding as used by the test IPN message. (for example, I can see that he is using letters with umlaut and other symbols like “/”, etc).
With regard to the last point, the merchant can try to change the encoding language in use in his PayPal account, following the steps below:
If the issue persists, we recommend to review the script in use, PayPal has some IPN code samples available at: https://github.com/paypal/ipn-code-samples
For additional information I include the link: https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNTesting/#id091GFE00WY4
我很确定要发送到的 URL 只是“www.sandbox.paypal.com”,请参阅 Sandbox 用户指南的第 4 章,这就是我为自己的代码添加的内容(顺便说一句,对于 live,它是也只是“www.paypal.com”,用于他们的 示例代码)
I'm pretty sure the URL to send to is just "www.sandbox.paypal.com", see chapter 4 of Sandbox User Guide, and well, this is what I put for my own code (incidentally, for live, it is also just "www.paypal.com", for their sample code)
谢谢你们的回复。
哦哦我终于解决了。
实际上在通知 URL 中我还添加了一个用户名参数。 Paypal 希望 IPN 的参数值与返回到 servlet 的参数值相同。(您可以通过 req.getParameterNames() 获取它)。因为我有额外的用户名参数,这是贝宝不知道的。 Paypal 返回无效。
Thank you guys for your reply.
ohhh I solved it at last.
Actually in notify URL I also added a username parameter. Paypal want the parameter values for IPN same as it return to the servlet.(You can get it as req.getParameterNames()). As I have username parameter extra, which is not known to paypal. Paypal was returning INVALID.
请记住贝宝的沙箱具有完全不同的凭据。您必须拥有开发帐户并登录开发面板才能使用沙箱。
Remember paypal's sandbox has completely different credentials. You must have development account and be logged into development panel to use sandbox.
如果您正在通过 SSL 测试 Paypal IPN,则必须在端口 443 上使用 ssl://www.sandbox.paypal.com
If you're testing Paypal IPN over SSL, you will have to use ssl://www.sandbox.paypal.com on the port 443
在让 Paypal IPN 正常工作之前,我遇到了多个层层叠加的问题 - 它一直返回 INVALID,但不幸的是,并没有具体说明我出错的部分。
我错了:
沙箱 - 如果您使用沙箱,您需要使用整个沙箱环境。它需要在 Paypal Sandbox 网站上创建一个新的独立帐户。它在您的常规帐户下设置的 Sandbox API 凭据还不够。然后,您使用该单独的 Paypal 帐户在 Paypal Sandbox 网站上提交虚假交易,并观察它们在 Sandbox 端点上遇到 IPN。在设置 API 访问时,对第二个帐户的需求并不明显或明确。此外,在 Sandbox 和 Live 之间切换不仅需要切换 URL,还需要切换凭据。因此,一个简单的编译标志交替字符串并不能消除它。
实时 - 如果您使用实时环境,许多事情都会妨碍您。对于我们来说,Paypal花了很长时间才向我们开放“商业”访问权限。在启用之前,它不会通过 API 向我们提供任何内容。当我们最初申请时,我们被断然拒绝,没有任何解释或解决时间表。一个月后,接受付款(没有 API 来让我们及时了解这些付款)后,它似乎就神奇地开始工作了。
代码示例 - Paypal 提供的代码示例已过时,并且存在一些明显的问题。下面是一个使用现代 TPL/async 的示例:
除了此代码实际工作之外(这正是我们在生产中所拥有的,删除了一些日志库调用),此代码在等待网络时不会冻结线程。
等待允许线程在网络执行其操作时离开,无论是向 Paypal 写入验证请求,还是接收返回的响应,这两者都可能需要很长时间。
I ran into multiple problems layered on top of each other before I could get Paypal IPN working - it kept returning INVALID but was not specific about which part I was getting wrong, unfortunately.
Things I got wrong:
Sandbox - if you use the Sandbox you need to use the entire Sandbox environment. It requires creating a new, separate account on the Paypal Sandbox website. The Sandbox API credentials it sets up under your regular account are not enough. You then use that separate Paypal account to file fake transactions on the Paypal Sandbox website, and watch them come across IPN on the Sandbox endpoint. The need for this second account is not obvious or clear at all in setting up API access. Also, switching between Sandbox and Live requires more than switching the URL, you need to switch the credentials. So a simple compile flag alternating a string isn't going to cut it.
Live - if you use the Live environment a number of things will get in your way. For us, it took a long time for Paypal to open up "Business" access to us. It wouldn't provide us anything over the API until that was enabled. When we initially applied we were flatly denied with no explanation or timeline to resolve it. A month later ish of taking payments (with no API to keep us up to date with those payments) it seemed to just magically start working.
Code example - the code example provided by Paypal is outdated, and has some clear issues. Here's an example that uses modern TPL/async:
Besides this code actually working (This is exactly what we have in Production, with some of our logging library calls stripped out), this code won't freeze a thread while waiting on network.
The awaits allow the thread to step away while the network does its thing, both in writing the verification request to Paypal, and in receiving the response back, both of which could be a long time.