You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java模拟Adyen 3D Secure验证POST请求返回500错误求助

解决Java HttpPost调用Adyen 3D Secure返回500错误的问题

我来帮你搞定这个问题——curl能正常返回200和HTML表单,但Java的HttpPost却碰500,十有八九是请求细节上的差异(比如请求头、参数编码)导致的。咱们一步步来复现正确的请求:

第一步:先拆解你的curl请求

首先把你正常工作的curl命令拆解开,比如假设你的命令是这样的(替换成你实际的):

curl -X POST https://test.adyen.com/hpp/3d/validate.shtml \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "MD=your-md-value&PaReq=your-pareq-base64-string&TermUrl=https://your-domain.com/3ds-callback"

接下来要确保Java代码完全复刻这个请求的所有细节。

第二步:Java实现的正确示例(用Apache HttpClient)

Apache HttpClient是Java里最常用的HTTP客户端库,下面是能完美匹配curl请求的代码:

先添加Maven依赖(如果用Maven)

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

完整代码

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;

public class Adyen3DSHandler {
    public static void main(String[] args) {
        // 替换成你实际的Adyen 3DS验证URL
        String adyen3dsUrl = "https://test.adyen.com/hpp/3d/validate.shtml";
        // 替换成你从Adyen获取的MD、PaReq值,以及你的回调URL
        String md = "YOUR_ACTUAL_MD_VALUE";
        String paReq = "YOUR_ACTUAL_PAREQ_BASE64_STRING";
        String termUrl = "https://your-domain.com/3ds-callback";

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost postRequest = new HttpPost(adyen3dsUrl);

            // 关键:模拟curl的请求头,尤其是User-Agent,很多服务器会校验这个
            postRequest.setHeader("User-Agent", "curl/7.68.0"); // 换成你本地curl的版本
            postRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
            // 可选:如果curl里有其他请求头(比如Accept),也要加上
            postRequest.setHeader("Accept", "*/*");

            // 构建表单参数,注意不要手动编码PaReq,UrlEncodedFormEntity会自动处理URL编码
            List<NameValuePair> formParams = new ArrayList<>();
            formParams.add(new BasicNameValuePair("MD", md));
            formParams.add(new BasicNameValuePair("PaReq", paReq));
            formParams.add(new BasicNameValuePair("TermUrl", termUrl));

            // 设置请求实体,指定UTF-8编码避免乱码
            postRequest.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));

            // 执行请求并获取响应
            HttpResponse response = httpClient.execute(postRequest);

            // 输出结果
            System.out.println("状态码:" + response.getStatusLine().getStatusCode());
            String responseHtml = EntityUtils.toString(response.getEntity(), "UTF-8");
            System.out.println("响应内容:" + responseHtml);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第三步:排查常见坑点

如果还是返回500,检查以下几个最容易出错的地方:

  • 请求头缺失:curl默认会带一些请求头(比如User-Agent、Accept),Java HttpPost默认不会,一定要手动加上和curl完全一致的请求头。
  • 参数编码错误:PaReq是Base64编码的XML字符串,不要手动对它做URL编码,UrlEncodedFormEntity会自动处理所有参数的编码,手动编码会导致二次编码,Adyen无法解析。
  • 证书验证问题:测试环境下,Adyen的证书可能不被Java默认信任,curl默认不严格验证证书,所以可以临时关闭Java的证书验证(仅测试用,生产环境绝对不能这么做):
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.ssl.SSLContexts;
    import javax.net.ssl.SSLContext;
    
    // 修改HttpClient的创建方式
    SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial((chain, authType) -> true) // 信任所有证书
            .build();
    
    CloseableHttpClient httpClient = HttpClients.custom()
            .setSSLContext(sslContext)
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
    
  • TermUrl不合法:确保你的TermUrl是在Adyen后台配置允许的域名,否则Adyen会返回错误。

第四步:对比请求细节

如果以上都没问题,用抓包工具(比如Charles、Wireshark)分别抓取curl和Java的请求,对比以下内容:

  1. 所有请求头是否完全一致
  2. 请求体的参数是否完全相同(包括编码后的字符串)
  3. 请求的URL是否完全一致

找出差异点,调整Java代码即可。

内容的提问来源于stack exchange,提问作者Mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:46:24