Paypal 中某些 IPN 消息的响应无效

发布于 2025-01-04 20:28:53 字数 2308 浏览 0 评论 0原文

我有一个用于 Paypal IPN 消息的 Java 接收器,它在沙箱中运行得很好。但在将其设置为真实的 Paypal 环境后,我注意到大多数消息都会得到“无效”响应(尽管有些付款会得到已验证的响应)。

认为这可能是编码问题。我读到编码来自正确的消息(我看到它有一个名为“charset”的参数,其中包含该信息)并且在其他地方编码应设置为“windows-1252”。因此,我从正确的消息中读取字符集,并使用该字符集对参数进行编码。在所有消息中,收到的编码是“windows-1252”,但只有少数响应“已验证”(其余均为无效)。如果我重新发送帐户中 IPN 历史记录中的“无效”消息,它们将再次被视为无效。

有人知道可能会发生什么吗?

谢谢。

String paypalURL = "https://www.paypal.com/cgi-bin/webscr";

// read post from PayPal system and add 'cmd'
Enumeration en = request.getParameterNames();
String str = "cmd=_notify-validate";
String charset = request.getParameter("charset"); //this gets windows-1252

while(en.hasMoreElements()){
    String paramName = (String)en.nextElement();
    String paramValue = request.getParameter(paramName);
    str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, charset); 
}
// post back to PayPal system to validate
// NOTE: change http: to https: in the following URL to verify using SSL (for increased security).
// using HTTPS requires either Java 1.4 or greater, or Java Secure Socket Extension (JSSE)
// and configured for older versions.
URL u;
u = new URL(paypalURL);
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(); //It's always INVALID - It should be "VERIFIED"
in.close();

// assign posted variables to local variables
//String itemName = request.getParameter("item_name");
//String itemNumber = request.getParameter("item_number");
//String quantity = request.getParameter("quantity");
String paymentStatus = request.getParameter("payment_status");
String paymentAmount = request.getParameter("mc_gross");
String paymentCurrency = request.getParameter("mc_currency");
String txnId = request.getParameter("txn_id");
String receiverEmail = request.getParameter("receiver_email");
//String payerEmail = request.getParameter("payer_email");
String username = request.getParameter("custom");
//check notification validation

if(res.equals("VERIFIED")) {  //It's always INVALID - It should be "VERIFIED"

I have a Java receiver for IPN messages of Paypal and it worked perfectly in the Sandbox. But after setting it to the real Paypal environment I have noticed that it gets the response "INVALID" for most of the messages (though some payments get the VERIFIED response).

I have thought that it may be a problem of encoding. I read that the encoding came in the proper message (I've seen it has a param called "charset" with that information) and somewhere else that the encoding should be set to "windows-1252". So I'm reading the charset from the proper message and encoding the params with that charset. In all the messages the encoding received is "windows-1252" but only a few has a response "VERIFIED" (the rest are INVALID). If I resend the "INVALID" messages from the IPN History in the account they are said as INVALID again.

Doe anyone has any idea of what may be happening?

Thanks.

String paypalURL = "https://www.paypal.com/cgi-bin/webscr";

// read post from PayPal system and add 'cmd'
Enumeration en = request.getParameterNames();
String str = "cmd=_notify-validate";
String charset = request.getParameter("charset"); //this gets windows-1252

while(en.hasMoreElements()){
    String paramName = (String)en.nextElement();
    String paramValue = request.getParameter(paramName);
    str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, charset); 
}
// post back to PayPal system to validate
// NOTE: change http: to https: in the following URL to verify using SSL (for increased security).
// using HTTPS requires either Java 1.4 or greater, or Java Secure Socket Extension (JSSE)
// and configured for older versions.
URL u;
u = new URL(paypalURL);
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(); //It's always INVALID - It should be "VERIFIED"
in.close();

// assign posted variables to local variables
//String itemName = request.getParameter("item_name");
//String itemNumber = request.getParameter("item_number");
//String quantity = request.getParameter("quantity");
String paymentStatus = request.getParameter("payment_status");
String paymentAmount = request.getParameter("mc_gross");
String paymentCurrency = request.getParameter("mc_currency");
String txnId = request.getParameter("txn_id");
String receiverEmail = request.getParameter("receiver_email");
//String payerEmail = request.getParameter("payer_email");
String username = request.getParameter("custom");
//check notification validation

if(res.equals("VERIFIED")) {  //It's always INVALID - It should be "VERIFIED"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

尤怨 2025-01-11 20:28:53

PayPal 还要求按照参数发送给您的顺序发回参数。当我实现其中之一时,我最终从请求读取器ala将参数读入LinkedHashMap

String line = null;
BuferedReader incomingParams = request.getReader();
StringBuilder params = new StringBuilder();
while ((line = incomingParams.readLine()) != null) {
    params = params.append(line);
}

String[] nvPairs = params.toString().split("&");
String[] nvPair = null;
String value = null;
for (int i = 0; i < nvPairs.length; ++i) {
    nvPair = nvPairs[i].split("=");
    if (nvPair != null && nvPair.length >= 1) {
        if (nvPair.length >= 2) { 
            value = nvPair[1];
        }
        else {
            value = "";
        }
        paramMap.put(nvPair[0], value);
    }
}

,然后从映射中读回参数,与您所做的类似。另一件需要注意的是,我在发回时没有重新编码参数,尽管看起来你应该这样做。

PayPal also requires that parameters be sent back in the same order as they came to you. When I implemented one of these, I ended up reading the parameters into a LinkedHashMap from the request reader ala

String line = null;
BuferedReader incomingParams = request.getReader();
StringBuilder params = new StringBuilder();
while ((line = incomingParams.readLine()) != null) {
    params = params.append(line);
}

String[] nvPairs = params.toString().split("&");
String[] nvPair = null;
String value = null;
for (int i = 0; i < nvPairs.length; ++i) {
    nvPair = nvPairs[i].split("=");
    if (nvPair != null && nvPair.length >= 1) {
        if (nvPair.length >= 2) { 
            value = nvPair[1];
        }
        else {
            value = "";
        }
        paramMap.put(nvPair[0], value);
    }
}

and then reading the parameters back out of the map similarly to what you have done. One other note is that I didn't re-encode the params as I sent the back, though certainly seems like you should.

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