【发布时间】:2014-09-30 20:24:48
【问题描述】:
我的 Spring 引导服务器中的 Paypal IPN 验证存在问题。我不确定问题出在哪里,如果在服务器端或另一方面,这是Paypal的错。我已经在我的个人资料页面中选择了 UTF-8 作为编码。
主要问题是带有 UTF-8 字符的 IPN,我猜这导致验证失败。
如果我的 Spring 和 Spring 安全服务器中没有 CharacterEncodingFilter,IPN 验证工作正常。 BUT 使其他东西(例如表格)无法以 UTF-8 编码显示,因此这是一个不可接受的解决方案。
当我打印 IPN(没有 CharacterEnconding,因此付款得到验证)我得到的响应(除其他外)时,我觉得很奇怪:
charset=UTF-8
address_name=阿德里安
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 的响应,不是吗?
我真的不知道发生了什么。 谢谢!
【问题讨论】:
标签: spring paypal spring-security paypal-ipn spring-boot