Paypal 沙箱 IPN 返回 INVALID

发布于 2024-08-05 11:59:13 字数 2906 浏览 8 评论 0原文

我正在尝试使用 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&notify_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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

逆流 2024-08-12 11:59:13

无效”消息是由于以下原因造成的:

  • 检查您是否将您的回复发布到正确的 URL,即 https://www.sandbox.paypal.com/cgi-bin/webscrhttps://www.paypal.com/cgi-bin/webscr,具体取决于您是否在沙盒中进行测试分别居住。
  • 验证您对测试 IPN 消息的响应是否包含与测试消息完全相同的变量和值,并且它们的顺序与测试消息中的顺序相同。最后,验证原始变量前面是否有 cmd=_notify-validate 变量。
  • 确保您对响应字符串进行编码,并使用与测试 IPN 消息相同的字符编码。 (例如,我可以看到他使用带有变音符号的字母和其他符号,如“/”等)。
    关于最后一点,商家可以尝试更改其PayPal帐户中使用的编码语言,具体步骤如下:

    1. 登录您的 PayPal 帐户
    2. 点击“个人资料”
    3. 点击“我的销售偏好”标签
    4. 点击“PayPal 按钮语言编码”(位于页面末尾)
    5. 点击“其他选项”
    6. 从下拉菜单中选择:UTF-8
    7. 为第二个选项选择相同的字符集,该选项与 IPN 相关
    8. 点击“保存”

如果问题仍然存在,我们建议检查正在使用的脚本,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:

  • Check that your are posting your response to the correct URL, which is https://www.sandbox.paypal.com/cgi-bin/webscr or https://www.paypal.com/cgi-bin/webscr, depending on whether you are testing in the Sandbox or you are live, respectively.
  • Verify that your response to the test IPN message contains exactly the same variables and values as the test message and that they are in the same order as in the test message. Finally, verify that the original variables are preceded by a cmd=_notify-validate variable.
  • 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:

    1. Login on you PayPal account
    2. Click on Profile
    3. Click on “My Selling Preferences” tab
    4. Click on “PayPal Button Language Encoding” (at the end of the page)
    5. Click on "Other Options"
    6. Select from the drop down menu: UTF-8
    7. Choose the same charset also for the second option, which is related to IPN
    8. Click “Save”

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

墨落画卷 2024-08-12 11:59:13

我很确定要发送到的 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)

孤独陪着我 2024-08-12 11:59:13

谢谢你们的回复。
哦哦我终于解决了。

实际上在通知 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.

笑叹一世浮沉 2024-08-12 11:59:13

请记住贝宝的沙箱具有完全不同的凭据。您必须拥有开发帐户并登录开发面板才能使用沙箱。

Remember paypal's sandbox has completely different credentials. You must have development account and be logged into development panel to use sandbox.

南笙 2024-08-12 11:59:13

如果您正在通过 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

初与友歌 2024-08-12 11:59:13

在让 Paypal IPN 正常工作之前,我遇到了多个层层叠加的问题 - 它一直返回 INVALID,但不幸的是,并没有具体说明我出错的部分。

我错了:

沙箱 - 如果您使用沙箱,您需要使用整个沙箱环境。它需要在 Paypal Sandbox 网站上创建一个新的独立帐户。它在您的常规帐户下设置的 Sandbox API 凭据还不够。然后,您使用该单独的 Paypal 帐户在 Paypal Sandbox 网站上提交虚假交易,并观察它们在 Sandbox 端点上遇到 IPN。在设置 API 访问时,对第二个帐户的需求并不明显或明确。此外,在 Sandbox 和 Live 之间切换不仅需要切换 URL,还需要切换凭据。因此,一个简单的编译标志交替字符串并不能消除它。

实时 - 如果您使用实时环境,许多事情都会妨碍您。对于我们来说,Paypal花了很长时间才向我们开放“商业”访问权限。在启用之前,它不会通过 API 向我们提供任何内容。当我们最初申请时,我们被断然拒绝,没有任何解释或解决时间表。一个月后,接受付款(没有 API 来让我们及时了解这些付款)后,它似乎就神奇地开始工作了。

代码示例 - Paypal 提供的代码示例已过时,并且存在一些明显的问题。下面是一个使用现代 TPL/async 的示例:

// Send the verification back to Paypal in the format Paypal requested
var verif = (HttpWebRequest)WebRequest.Create(ipnVerifyUrl);
verif.Method = "POST";
verif.ContentType = "application/x-www-form-urlencoded";
var param = req.BinaryRead(req.TotalBytes);
var sRequest = Encoding.ASCII.GetString(param);
sRequest = "cmd=_notify-validate&" + sRequest;
verif.ContentLength = sRequest.Length;

using (var streamOut = new StreamWriter(verif.GetRequestStream(), Encoding.ASCII))
{
    await streamOut.WriteAsync(sRequest);
}

// Send it
using (var re = await verif.GetResponseAsync())
{
    var s = await HttpWebRequestAsync.GetFullResponseStringAsync((HttpWebResponse)re);
    // Log the response (s)
}

除了此代码实际工作之外(这正是我们在生产中所拥有的,删除了一些日志库调用),此代码在等待网络时不会冻结线程。
等待允许线程在网络执行其操作时离开,无论是向 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:

// Send the verification back to Paypal in the format Paypal requested
var verif = (HttpWebRequest)WebRequest.Create(ipnVerifyUrl);
verif.Method = "POST";
verif.ContentType = "application/x-www-form-urlencoded";
var param = req.BinaryRead(req.TotalBytes);
var sRequest = Encoding.ASCII.GetString(param);
sRequest = "cmd=_notify-validate&" + sRequest;
verif.ContentLength = sRequest.Length;

using (var streamOut = new StreamWriter(verif.GetRequestStream(), Encoding.ASCII))
{
    await streamOut.WriteAsync(sRequest);
}

// Send it
using (var re = await verif.GetResponseAsync())
{
    var s = await HttpWebRequestAsync.GetFullResponseStringAsync((HttpWebResponse)re);
    // Log the response (s)
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文