worldline

Documentation

Java SDK

Introduction

The Java SDK helps you to communicate with the  Acquiring API . More specifically, it offers a fluent Java API that provides access to all the functionality of the RESTful Acquiring API. Below, we discuss the following topics in detail.

  • Initialization of the SDK

  • Exceptions

  • Logging

  • SSL Certificates

  • Advanced use: Connection pooling

  • Advanced use: Customization of the communication

  • Advanced use: Using system properties

The source code of the SDK is available on  Github . There you can find installation instructions.

The API documentation of the latest version of the SDK is available  here . For a specific major version, replace  latest  with the actual version in format  <major>.x .

Initialization of the Java SDK

All Java code snippets presented in the API Reference assume you have initialized the Java SDK before using them in your Development Environment. This section details how to initialize SDK.

Initializing is simple, and requires only one key task: use our Factory class to create an instance of Client , which contains the actual methods to communicate with the Acquiring API.

The Factory needs the following input information to provide you with an initialized Client :

  • A URI to the property file with your connection configuration

  • The OAuth2 client ID and secret

The property file should contain the following keys:

acquiring.api.integrator=<your company name>
acquiring.api.endpoint.host=api.preprod.acquiring.worldline-solutions.com
acquiring.api.authorizationType=OAuth2
acquiring.api.oauth2.tokenUri=https://auth-test-eu-west-1.aws.bambora.com/connect/token
acquiring.api.connectTimeout=5000 # use -1 for no timeout
acquiring.api.socketTimeout=300000 # use -1 for no timeout
acquiring.api.maxConnections=10 # to support 10 concurrent connections

We recommend you to to keep the timeout values at these values. See  API endpoints  for the possible hosts and token URIs.

If a proxy should be used, the property file should additionally contain the following key(s):

acquiring.api.proxy.uri=<URL to the proxy host including leading http:// or https://>
# omit the following two lines if no proxy authentication is required
acquiring.api.proxy.username=<username for the proxy>
acquiring.api.proxy.password=<password for the proxy>

You can create an instance of  Client  using the  Factory  with this code snippet:

Client client = Factory.createClient(propertiesUrl.toURI(), "oauth2ClientId", "oauth2ClientSecret");

Connection management

The Java SDK by default uses  Apache HttpClient  for setting up connections to the RESTful Server API. Although this works out-of-the-box for most, sometimes its connection pool contains connections that no longer work due to the basic limitations of the blocking I/O model. See section 2.3.3 of  Connection management  for more information.

Therefore, it is recommended to periodically evict expired HTTP connections. With the SDK, this can be done by periodically (e.g. every 10 seconds) calling method  closeExpiredConnections  of a  Client  object.

Because the Java SDK can be used in a multitude of environments, the SDK cannot spawn a thread itself to perform this periodic call. Instead, you should create a scheduled job that runs at a regular interval that performs this cleanup. How this scheduled job should be created depends on the platform that the SDK is used in. Please refer to your platform documentation for instructions on how to create scheduled jobs.

Exceptions

All calls can throw one of the following runtime exceptions:

  • A ValidationException if the request was not correct and couldn't be processed (HTTP status code 400)

  • An AuthorizationException if the request was not allowed or your credentials are incorrect/expired (HTTP status code 401 or 403)

  • An  IdempotenceException  if an idempotent request caused a conflict (HTTP status code 409)

  • A ReferenceException if an object was attempted to be referenced that doesn't exist or has been removed, or there was a conflict (HTTP status code 404, 409 or 410)

  • A PlatformException if something went wrong on the Acquiring platform. The Acquiring platform was unable to process a message from a downstream system, or the service that you're trying to reach is temporary unavailable (HTTP status code 500, 502 or 503)

  • An ApiException if the RESTful Server API returned any other error

Below is an example of how a payment response can be handled:

try {
    ApiPaymentResponse response = client.v1()
            .acquirer(acquiredId)
            .merchants(merchantId)
            .payments()
            .processPayment(request);
} catch (ValidationException e) {
    System.err.println("Input validation error: " + e.getDetail());
} catch (AuthorizationException e) {
    System.err.println("Authorization error: " + e.getDetail());
} catch (ReferenceException e) {
    System.err.println("Incorrect object reference: " + e.getDetail());
} catch (PlatformException e) {
    System.err.println("Error occurred at Worldline or a downstream partner: " + e.getDetail());
} catch (ApiException e) {
    System.err.println("Worldline error:" + e.getStatusCode() + ", " + e.getDetail());
}

Exception overview

The following table is a summary that shows when each of these exceptions will be thrown:

HTTP status code

Meaning

Description

Exception Type

200

Successful

Your request was processed correctly

N/A

201

Created

Your request was processed correctly and a new resource was created. The URI of this created resource is returned in the Location header of the response.

N/A

204

No Content

Your request was processed correctly

N/A

400

Bad Request

Your request is not correct and can't be processed. Please correct the mistake and try again.

ValidationException

403

Not Authorized

You're trying to do something that is not allowed or that you're not authorized to do.

AuthorizationException

404

Not Found

The object you were trying to access could not be found on the server.

ReferenceException

409

Conflict

Your idempotent request resulted in a conflict. The first request has not finished yet.

IdempotenceException

409

Conflict

Your request resulted in a conflict. Either you submitted a duplicate request or you're trying to create something with a duplicate key.

ReferenceException

500

Internal Server Error

Something went wrong on the platform.

PlatformException

502

Bad Gateway

The platform was unable to process a message from a downstream partner/acquirer.

PlatformException

503

Service Unavailable

The service that you're trying to reach is temporarily unavailable. Please try again later.

PlatformException

other

Unexpected error

An unexpected error has occurred

ApiException

Logging

The Java SDK supports logging of requests, responses and exceptions of the API communication.

In order to start using the logging feature, an implementation of the CommunicatorLogger interface should be provided. The SDK provides two example implementations for logging to System.out ( SysOutCommunicatorLogger ) and logging to a java.util.logging.Logger ( JdkCommunicatorLogger ).

Logging can be enabled by calling the enableLogging method on a Client object, and providing the logger as an argument. The logger can subsequently be disabled by calling the disableLogging method.

When logged messages contain sensitive data, this data is obfuscated.

The following code exemplifies the use of adding a logger:

Client client = Factory.createClient(propertiesUrl.toURI(), "oauth2ClientId", "oauth2ClientSecret");

CommunicatorLogger logger = new JdkCommunicatorLogger(Logger.getLogger(...), Level.INFO);
client.enableLogging(logger);
//... Do some calls
client.disableLogging();

Installing SSL certificates

Not all versions of Java support the SSL certificates of the Acquiring platform out-of-the-box. If a CommunicationException wrapped around a  javax.net.ssl.SSLHandshakeException    is thrown when trying to communicate with the Server API, you must manually install an SSL certificate. Following is the procedure for most Java implementations:

  1. Open  the correct API Endpoint   in your browser; ignore the 404 error.

  2. Export the root certificate (Trustwave / SecureTrust CA) from your browser to a  Base64 encoded X.509 (*.CER)  file.

  3. From the command line, go to the  /lib/security directory  of the JRE to use and execute the following command:


    
    keytool -import -keystore cacerts -alias securetrustca -file <path to exported certificate>

    

The default password for OpenJDK and Oracle's JDK and JRE is  changeit  . For other vendors, please check the vendor's documentation. When prompted to trust the certificate, type  yes  and press  Enter  .

Advanced use: Connection pooling

A Client created using the Factory class from a properties file or CommunicatorConfiguration object will use its own connection pool. If multiple clients should share a single connection pool, the Factory class should be used to first create a shared Communicator , then to create Client instances that use that Communicator :

Communicator communicator = Factory.createCommunicator(propertiesUrl.toURI(), "oauth2ClientId", "oauth2ClientSecret");
// create one or more clients using the shared communicator
Client client = Factory.createClient(communicator);

Instead of closing these  Client  instances, you should instead close the  Communicator  when it is no longer needed. This will close all  Client  instances that use the  Communicator .

Connection management

Just like  Client Communicator  also has method  closeExpiredConnections  that can be used to evict expired HTTP connections. You can call this method on the  Communicator  instead of on any of the  Client  instances. The effect will be the same.

Advanced use: Customization of the communication

A Client uses a Communicator to communicate with the RESTful Server API. A Communicator contains all the logic to transform a request object to a HTTP request and a HTTP response to a response object. If needed, you can extend this class. To instantiate a Client that uses your own implementation of Communicator you can use the following code snippet:

Communicator communicator = new YourCommunicator();
Client client = Factory.createClient(communicator

However, for most customizations you do not have to extend  Communicator . The functionality of the  Communicator  is built on the following:

  • The RESTful Server API endpoint URI.

  • Connection , which represents one or more HTTP connections to the Worldline server.

  • An  Authenticator , which is used to sign your requests.

  • MetadataProvider , which constructs the header with metadata of your server that is sent in requests for BI and fraud prevention purposes.

  • Marshaller , which is used to marshal and unmarshal request and response objects to and from JSON.

For your convenience, a  CommunicatorBuilder  is provided to easily replace one or more of these components. For example, to instantiate a  Client  that uses your own implementation of  Connection , you can use the following code snippet:

Connection connection = new YourConnection();
Communicator communicator  = Factory.createCommunicatorBuilder(propertiesUrl.toURI(), "oauth2ClientId", "oauth2ClientSecret")
        .withConnection(connection)
        .build();
Client client = Factory.createClient(communicator);

Connection management

Calling  closeExpiredConnections  on a  Client  or a  Communicator  object only works if the  Connection  implements  PooledConnection , otherwise these methods do nothing. If you write a custom  Connection  that uses a pool of HTTP connections, implement  PooledConnection  instead.

Logging

To facilitate implementing logging in a custom  Connection , the SDK provides utility classes  RequestLogMessageBuilder  and  ResponseLogMessageBuilder . These can be used to easily construct request and response messages. For instance:

// In the below code, logger is the CommunicatorLogger set using enableLogging.
// Note that it may be null if enableLogging is not called.
String requestId = UUID.randomUUID().toString();
RequestLogMessageBuilder requestLogMessageBuilder =
    new RequestLogMessageBuilder(requestId, method, uri);
// add request headers to requestLogMessageBuilder
// if present, set the request body on requestLogMessageBuilder
logger.log(requestLogMessageBuilder.getMessage());
long startTime = System.currentTimeMillis();
// send the request
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
int statusCode = ...;
// note: the duration is optional
ResponseLogMessageBuilder responseLogMessageBuilder =
    new ResponseLogMessageBuilder(requestId, statusCode, duration);
// add response headers to responseLogMessageBuilder
// if present, set the response body on responseLogMessageBuilder
logger.log(responseLogMessageBuilder.getMessage());

Advanced use: Using system properties

Proxy

The SDK provides basic support for HTTP proxies by specifying the proxy in the property file used for initializing the SDK. If this is not sufficient it is also possible to use  Java's proxying mechanism  instead. Note that  java.net.Authenticator  is needed for authentication.