Use a computer

For full performance and fluidity, please open Pay Engineers on a desktop or laptop. On mobile, the experience is limited — especially authenticated sections and advanced tools after login.

java

Java HttpClient sample

A Java 11+ example built on the standard library HttpClient, showing authentication, timeout configuration, response handling and where to store processor credentials in a typical Spring application.

Why the built-in HttpClient

Java 11 introduced java.net.http.HttpClient as part of the standard library, which is usually sufficient for calling published compliance endpoints without adding Apache HttpClient or OkHttp as a dependency — useful in environments with strict dependency review processes, which is common in banking and PSP backends.

Configuration

Store the base URL and API key in externalized configuration (Spring application.yml, environment variables, or a secrets manager) — never as constants in source:

processor:
  base-url: ${PROCESSOR_BASE_URL:https://sandbox.example.com}
  api-key: ${PROCESSOR_API_KEY}

Java example

HttpClient client = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(10))
    .build();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(baseUrl + "/v1/ping"))
    .header("Authorization", "Bearer " + apiKey)
    .header("Accept", "application/json")
    .timeout(Duration.ofSeconds(10))
    .GET()
    .build();

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

if (response.statusCode() >= 400) {
    throw new ProcessorException(
        "Processor returned HTTP " + response.statusCode() + ": " + response.body()
    );
}

JsonNode data = objectMapper.readTree(response.body());

Async usage

For services handling significant throughput, prefer sendAsync and compose with CompletableFuture rather than blocking a request-handling thread per outbound call:

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(this::handleResponse)
    .exceptionally(this::handleFailure);

Error handling

Separate three failure modes in your exception hierarchy: java.net.http.HttpTimeoutException for slow upstreams, java.io.IOException/java.net.ConnectException for connectivity issues (DNS, TLS, refused connections), and a domain-specific exception for HTTP-level error responses (4xx/5xx). Logging the processor's error code (usually present in the JSON body) alongside the HTTP status makes support tickets far faster to resolve.

Security notes

  • Do not disable hostname verification or trust-all certificate managers to work around TLS issues in any environment, including sandbox — fix the underlying trust store instead.
  • Keep api-key out of application.yml if that file is committed to version control; reference it via an environment variable or a secrets manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) instead.
  • Set both connectTimeout and a per-request timeout — a client that only sets one can still hang indefinitely on a slow response body.