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

Java Paypal中某些IPN消息的响应无效,java,encoding,paypal,paypal-ipn,Java,Encoding,Paypal,Paypal Ipn,我有一个用于Paypal的IPN消息的Java接收器,它在沙箱中工作得非常好。但是在将它设置到真实的Paypal环境之后,我注意到它对大多数消息的响应都是“无效的”(尽管有些支付会得到验证过的响应) 我认为这可能是编码的问题。我读到编码出现在正确的消息中(我看到它有一个名为“charset”的参数,包含该信息),并且在其他地方编码应该设置为“windows-1252”。因此,我从正确的消息中读取字符集,并用该字符集对参数进行编码。在所有收到的消息中,编码为“windows-1252”,但只有少数

我有一个用于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"

PayPal还要求将参数按返回给您的相同顺序发送回去。当我实现其中一个时,我最终从请求读取器将参数读入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);
    }
}
字符串行=null;
BUFEREADER incomingParams=request.getReader();
StringBuilder参数=新建StringBuilder();
而((line=incomingParams.readLine())!=null){
params=params.append(行);
}
字符串[]nvPairs=params.toString().split(“&”);
字符串[]nvPair=null;
字符串值=null;
对于(int i=0;i=1){
如果(nvPair.length>=2){
值=nvPair[1];
}
否则{
value=“”;
}
paramMap.put(nvPair[0],值);
}
}

然后从地图中读取参数,类似于您所做的。另一个注意事项是,我在发回参数时没有对参数进行重新编码,尽管看起来您确实应该这样做。

PayPal还要求参数按照返回给您的相同顺序发回。当我实现其中一个时,我最终从请求读取器将参数读入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);
    }
}
字符串行=null;
BUFEREADER incomingParams=request.getReader();
StringBuilder参数=新建StringBuilder();
而((line=incomingParams.readLine())!=null){
params=params.append(行);
}
字符串[]nvPairs=params.toString().split(“&”);
字符串[]nvPair=null;
字符串值=null;
对于(int i=0;i=1){
如果(nvPair.length>=2){
值=nvPair[1];
}
否则{
value=“”;
}
paramMap.put(nvPair[0],值);
}
}
然后从地图中读取参数,类似于您所做的。另一个注意事项是,我没有在发回时对参数进行重新编码,尽管看起来你确实应该这样做