我的Spring启动服务器中的Paypal IPN验证存在问题。我不确定问题出在哪里,如果在服务器端或另一方面,这是Paypal的错。我已经在我的个人资料页面中选择了UTF-8作为参与。
主要问题是IPN使用UTF-8字符,这使我的验证失败。
如果我的Spring和Spring安全服务器中没有CharacterEncodingFilter,则IPN验证工作正常。但是其他东西(例如表格)没有用UTF-8编码显示,所以这是一个不可接受的解决方案。
当我打印IPN(没有CharacterEnconding,因此付款得到已验证)我得到的响应(除其他外)时,我发现很奇怪:
charset = UTF-8
ADDRESS_NAME =Adrián
PAYMENT_STATUS =完成
所以Paypal说IPN是UTF-8,但那是我没有收到的。
服务器的编码工作正常,在Spring Security过滤器链之前添加了CharacterEncodingFilter:
@Order(1)
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
FilterRegistration.Dynamic characterEncodingFilter = servletContext
.addFilter("characterEncodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "false");
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
insertFilters(servletContext, new MultipartFilter());
}
}
现在,Paypal的IPN打印节目编程很好:
的charset = UTF-8
如first_name =阿德里安
PAYMENT_STATUS =完成
但Paypal的回复是无效的。
这是我的控制器处理Paypal IPN的帖子:
@RequestMapping(value = "paypalok", method = RequestMethod.POST)
public void processIPN(HttpServletRequest request) {
String PAY_PAL_DEBUG = "https://www.sandbox.paypal.com/cgi-bin/webscr";
String CONTENT_TYPE = "Content-Type";
String MIME_APP_URLENC = "application/x-www-form-urlencoded";
String PARAM_NAME_CMD = "cmd";
String PARAM_VAL_CMD = "_notify-validate";
String PAYMENT_COMPLETED = "Completed";
String paymentStatus = "";
// Create client for Http communication
HttpClient httpClient = HttpClientBuilder.create().build();
// Request configuration can be overridden at the request level.
// They will take precedence over the one set at the client level.
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(40000).setConnectTimeout(40000)
.setConnectionRequestTimeout(40000).build();
HttpPost httppost = new HttpPost(PAY_PAL_DEBUG);
httppost.setHeader(CONTENT_TYPE, MIME_APP_URLENC);
try {
Map<String, String> params = new HashMap<String, String>();
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair(PARAM_NAME_CMD, PARAM_VAL_CMD));
// Process the parameters
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
// String param = names.nextElement();
// String value = request.getParameter(param);
String param = new String (names.nextElement().getBytes ("iso-8859-1"), "UTF-8");
String value = new String (request.getParameter(param).getBytes ("iso-8859-1"), "UTF-8");
nameValuePairs.add(new BasicNameValuePair(param, value));
params.put(param, value);
System.out.println(param + "=" + value);
// Get the payment status
if (param.equalsIgnoreCase("payment_status")) paymentStatus = value;
}
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
if (verifyResponse(httpClient.execute(httppost))) {
// if (paymentStatus.equalsIgnoreCase(PAYMENT_COMPLETED)) do...
return "elovendo/pricing/paymentOk";
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "redirect:/error";
} catch (ClientProtocolException e) {
e.printStackTrace();
return "redirect:/error";
} catch (IOException e) {
e.printStackTrace();
return "redirect:/error";
}
}
private boolean verifyResponse(HttpResponse response) throws IllegalStateException, IOException {
String RESP_VERIFIED = "VERIFIED";
InputStream is = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String responseText = reader.readLine();
is.close();
System.out.println("RESPONSE : " + responseText);
return responseText.equals(RESP_VERIFIED);
}
我用uri编码:
@Configuration
public class WebAppConfiguration {
/** HTTPS and Paging error **/
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setUriEncoding("UTF-8");
}
}
恢复,如果我发送字符UTF-8编码的Paypal验证失败,即使它不应该错误编码。如果我发送错误编码,Paypal的回复就可以了。
我无法使用CharacterEncodingFilter发送IPN的响应错误编码,不是吗?
我真的不知道发生了什么事。 谢谢!
答案 0 :(得分:0)
好吧,我实际上并不知道为什么Paypal发送错误编码的数据,但是一个简单的解决方法就是管理它。
像这样重写CharacterEncodingFilter:
public class CharacterEncodingFilter extends org.springframework.web.filter.CharacterEncodingFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (request != null && !request.getRequestURI().contains("paypalcheck")) {
super.doFilterInternal(request, response, filterChain);
}
else {
filterChain.doFilter(request, response);
}
}
}
引用侦听Paypal的IPN并告诉过滤器不对数据进行编码的控制器URL。
另外,确保过滤器在Spring Security chain之前:
public class SecurityConf extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
http.addFilterBefore(filter, WebAsyncManagerIntegrationFilter.class);
}
}