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

Tomcat Java Servlet实现Apple Pay商户验证及HTTPClient证书传输方法

Absolutely! You can use a Tomcat Java Servlet to handle Apple Pay merchant verification—this is fully feasible, and we can adapt your PHP cURL logic to Java's HttpClient ecosystem with just a few key steps.

Step-by-Step Implementation

The core requirement is sending a signed POST request to Apple’s validation endpoint, which requires authenticating with your SSL certificate and private key. Here’s how to do it in a Java Servlet:

1. Prepare Your PEM Files for Java

Java typically works with keystores (PKCS12 or JKS) instead of raw PEM files. The easiest way is to convert your certificate and private key into a PKCS12 keystore using OpenSSL:

openssl pkcs12 -export -in your-production-cert.pem -inkey your-production-key.pem -out apple-pay-keystore.p12 -name "apple-pay-identity"

You’ll be prompted to set a password for the keystore—save this, as you’ll need it in your code.

Alternatively, if you want to load raw PEM files directly, you can use the BouncyCastle library, but the keystore approach is simpler for standard Java HttpClient usage.

2. Modern Java HttpClient (Java 11+)

If you’re using Java 11 or newer, the built-in java.net.http.HttpClient is the way to go. Here’s a complete Servlet example:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.KeyStore;
import java.security.SecureRandom;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/apple-pay/verify-merchant")
public class ApplePayMerchantVerificationServlet extends HttpServlet {
    // Apple's production validation URL (use sandbox URL for testing)
    private static final String APPLE_VALIDATION_URL = "https://apple-pay-gateway.apple.com/paymentservices/startSession";
    // Path to your PKCS12 keystore (place this in WEB-INF for security)
    private static final String KEYSTORE_PATH = "/WEB-INF/apple-pay-keystore.p12";
    private static final String KEYSTORE_PASSWORD = "your-keystore-password";
    private static final String KEY_PASSWORD = "your-keystore-password"; // Same as keystore unless you set a separate one

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            // Load the PKCS12 keystore from the web app's resources
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(getServletContext().getResourceAsStream(KEYSTORE_PATH), KEYSTORE_PASSWORD.toCharArray());

            // Initialize KeyManagerFactory to use our keystore
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, KEY_PASSWORD.toCharArray());

            // Create a custom SSL context with our identity
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());

            // Build HttpClient with the custom SSL context
            HttpClient httpClient = HttpClient.newBuilder()
                    .sslContext(sslContext)
                    .build();

            // Prepare the request body (matches your PHP payload)
            String requestBody = "{\"merchantIdentifier\":\"merchant.com.blah.shop\", \"domainName\":\"shop.blah.com\", \"displayName\":\"Blah Shop\"}";

            // Build and send the POST request
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(APPLE_VALIDATION_URL))
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                    .build();

            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

            // Forward Apple's response back to the client
            resp.setContentType("application/json");
            resp.setStatus(response.statusCode());
            resp.getWriter().write(response.body());
        } catch (Exception e) {
            throw new ServletException("Failed to process Apple Pay merchant verification", e);
        }
    }
}

3. Apache HttpClient (For Java 8 or Older)

If you’re stuck on an older Java version, use Apache HttpClient. First add these Maven dependencies:

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

Then the Servlet code:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.KeyStore;

@WebServlet("/apple-pay/verify-merchant")
public class ApplePayMerchantVerificationServlet extends HttpServlet {
    private static final String APPLE_VALIDATION_URL = "https://apple-pay-gateway.apple.com/paymentservices/startSession";
    private static final String KEYSTORE_PATH = "/WEB-INF/apple-pay-keystore.p12";
    private static final String KEYSTORE_PASSWORD = "your-keystore-password";

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            // Load PKCS12 keystore
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(getServletContext().getResourceAsStream(KEYSTORE_PATH), KEYSTORE_PASSWORD.toCharArray());

            // Create SSL context with our keystore
            SSLContext sslContext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, KEYSTORE_PASSWORD.toCharArray())
                    .build();

            // Create SSL socket factory for HttpClient
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext);

            // Build HttpClient
            HttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslSocketFactory)
                    .build();

            // Prepare POST request
            HttpPost postRequest = new HttpPost(APPLE_VALIDATION_URL);
            postRequest.setHeader("Content-Type", "application/json");
            String requestBody = "{\"merchantIdentifier\":\"merchant.com.blah.shop\", \"domainName\":\"shop.blah.com\", \"displayName\":\"Blah Shop\"}";
            postRequest.setEntity(new StringEntity(requestBody));

            // Execute request and get response
            HttpResponse httpResponse = httpClient.execute(postRequest);
            HttpEntity responseEntity = httpResponse.getEntity();
            String responseBody = EntityUtils.toString(responseEntity);

            // Send response back to client
            resp.setContentType("application/json");
            resp.setStatus(httpResponse.getStatusLine().getStatusCode());
            resp.getWriter().write(responseBody);
        } catch (Exception e) {
            throw new ServletException("Apple Pay merchant verification failed", e);
        }
    }
}
Important Notes
  • Security: Always store your keystore in the WEB-INF directory (not accessible via public URLs) and avoid hardcoding passwords in production—use environment variables or a secure configuration system instead.
  • Sandbox vs Production: Use Apple’s sandbox validation URL (https://apple-pay-gateway-sandbox.apple.com/paymentservices/startSession) for testing.
  • Error Handling: Add checks for HTTP status codes (Apple returns 200 for success) and parse error responses from Apple to handle cases like invalid merchant identifiers.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:57:08