# Integration and Testing
source: https://developer.mastercard.com/transactions-service/documentation/tutorials-and-guides/api-testing-tutorial/index.md

This tutorial walks through the steps required to test the MRS Transactions Service by building an end-to-end application.

## Introduction {#introduction}

This tutorial helps you to create a simple Java application that makes an API call to the MRS Transactions Service in the Sandbox environment.

### What you will learn {#what-you-will-learn}

* How to set up the environment to develop a simple Java application
* How to generate an API client using the [OpenAPI Generator](https://openapi-generator.tech/)
* How to make an API call

### Authentication Options {#authentication-options}

The MRS Transactions Service supports both OAuth 1.0a and OAuth 2.0 authentication methods. This tutorial demonstrates OAuth 1.0a integration using Java. For OAuth 2.0 implementation, refer to:

* [API Basics - Client Authentication](https://developer.mastercard.com/transactions-service/documentation/api-basics/index.md#client-authentication) for an overview of both methods
* [Official Mastercard OAuth 2.0 documentation](https://developer.mastercard.com/platform/documentation/authentication/using-oauth-2-to-access-mastercard-apis/#overview)

Note: The code examples in this tutorial use OAuth 1.0a. If you are using OAuth 2.0, you will need to adapt the authentication configuration to use Bearer token authentication instead of request signing. See the **Making an API Call** section for OAuth 2.0 code examples.

### Estimated time to complete this tutorial {#estimated-time-to-complete-this-tutorial}

* 15-20 minutes

### Prerequisites {#prerequisites}

To complete this tutorial, you will need:

* [JDK 11](https://www.java.com/en/) or later
* An IDE of your choice
* Mastercard Developers account with access to the MRS Transactions API
* MRS Transactions Open API specification (Refer to the [Open Specification](https://developer.mastercard.com/transactions-service/documentation/api-reference/index.md) for details.)

Note: Refer to the [API Reference](https://developer.mastercard.com/transactions-service/documentation/api-reference/index.md) page for more details on each API and related parameters.

## Environment Set up {#environment-set-up}

### 1. Create a Maven Project {#1-create-a-maven-project}

* In the IDE, create a new Maven project which sets your directory structure automatically. ![Create maven project](https://static.developer.mastercard.com/content/transactions-service/img/newmaven.png)
* Provide an ArtifactId and a project name as per your choice. ![Add project name](https://static.developer.mastercard.com/content/transactions-service/img/artifactId.png)

### 2. Add Resources {#2-add-resources}

* Add the Transactions API specification to your Maven project resources folder.
* Add the generated Sandbox key (**.p12 file** ) and encryption cert (**.pem file**) to your Maven project resources folder. (This is generated while creating the project on Mastercard Developers).
* Your Maven project directory structure should appear as: ![Maven structure](https://static.developer.mastercard.com/content/transactions-service/img/mavenstructure.png)

### 3. Update pom.xml file {#3-update-pomxml-file}

* In your IDE, add the [OpenAPI Generator maven plugin](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin) to your project **pom.xml** file. Use the Plugin config as shown below: Note: [OpenAPI Generator](https://openapi-generator.tech/) generates API client libraries using OpenAPI Specification. It provides multiple generators and library templates to support multiple languages and frameworks. We will be using the Java generator for this project.

```XML
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>4.2.2</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/mrs-transactions-api-openapi-v3.yaml</inputSpec>
                <generatorName>java</generatorName>
                <configOptions>
                    <sourceFolder>src/gen/java/main</sourceFolder>
                    <java11>true</java11>
                    <dateLibrary>custom</dateLibrary>
                </configOptions>
                <typeMappings>
                    <typeMapping>Date=String</typeMapping>
                </typeMappings>
            </configuration>
        </execution>
    </executions>
</plugin>
```

* Add the following dependencies to your pom.xml file to add dependencies for the API client library generation and the Mastercard OAuth1 Signer library.

```XML
<properties>
       <!-- Dependencies used by the generated sources -->
       <gson-fire-version>1.8.3</gson-fire-version>
       <swagger-core-version>1.5.22</swagger-core-version>
       <okhttp-version>3.14.2</okhttp-version>
       <gson-version>2.8.5</gson-version>
       <threetenbp-version>1.3.8</threetenbp-version>
       <javax-annotation-version>1.0</javax-annotation-version>
       <junit-version>4.12</junit-version>
   </properties>
 
   <dependencies>
       <dependency>
           <groupId>io.swagger</groupId>
           <artifactId>swagger-annotations</artifactId>
           <version>${swagger-core-version}</version>
       </dependency>
       <dependency>
           <groupId>com.squareup.okhttp3</groupId>
           <artifactId>okhttp</artifactId>
           <version>${okhttp-version}</version>
       </dependency>
       <dependency>
           <groupId>com.squareup.okhttp3</groupId>
           <artifactId>logging-interceptor</artifactId>
           <version>${okhttp-version}</version>
       </dependency>
       <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
           <version>${gson-version}</version>
       </dependency>
       <dependency>
           <groupId>io.gsonfire</groupId>
           <artifactId>gson-fire</artifactId>
           <version>${gson-fire-version}</version>
       </dependency>
       <dependency>
           <groupId>org.threeten</groupId>
           <artifactId>threetenbp</artifactId>
           <version>${threetenbp-version}</version>
       </dependency>
       <dependency>
           <groupId>javax.annotation</groupId>
           <artifactId>jsr250-api</artifactId>
           <version>${javax-annotation-version}</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>${junit-version}</version>
       </dependency>
       <dependency>
           <groupId>com.mastercard.developer</groupId>
           <artifactId>oauth1-signer</artifactId>
           <version>1.2.4</version>
       </dependency>
 
   </dependencies>
```

When using OpenAPI Generator to generate the API client library, you have two options:

* Generate and use the source files on the fly
* Generate and deploy the source files to a Maven repository

<br />

In this tutorial, you will be generating the API client library on the fly, so you include the dependencies that are needed to generate the library. (If you were deploying the source files to a Maven repository, you would only need to include the dependency for that repository.)

In addition, you include the dependency for one of the Mastercard OAuth1 Signer libraries. Mastercard offers OAuth1 Signer Libraries that are developed and maintained by Mastercard's API team, which offer code helpers targeting the HTTP clients used by the different OpenAPI Generator Library templates. The libraries are hosted on [Github](https://github.com/Mastercard?utf8=%E2%9C%93&q=oauth1-signer&type=&language=).

Refer to the following page for more information on [Generating and Configuring a Mastercard API Client](https://developer.mastercard.com/platform/documentation/security-and-authentication/generating-and-configuring-a-mastercard-api-client/#overview).

## Generating the API Client {#generating-the-api-client}

1. Now that you have all the dependencies you need, you can generate the source code. You can navigate to the project root directory within a terminal window and run `mvn clean compile `. ![clean](https://static.developer.mastercard.com/content/transactions-service/img/clean.png)

![install](https://static.developer.mastercard.com/content/transactions-service/img/install.png)
2. Alternatively, you can navigate to the root directory of the project within a terminal window and run mvn clean compile.
![compile](https://static.developer.mastercard.com/content/transactions-service/img/compile.png)

3. A folder named **target** is created within your root directory which contains classes generated for the schemas and API calls defined within the OpenAPI Specification. The generated classes can be found in the target folder as shown below: ![classes](https://static.developer.mastercard.com/content/transactions-service/img/classes.png)

## Making an API Call {#making-an-api-call}

Note: The examples below demonstrate authentication using both **OAuth 1.0a** and **OAuth 2.0**. Choose the section that matches your project configuration.

### OAuth 2.0 (Client Credentials + DPoP) {#oauth-20-client-credentials--dpop}

If your project is configured for OAuth 2.0 authentication, use this flow to authenticate and call the Transactions Service API:

1. Create a signed client assertion (private_key_jwt) using your Mastercard key.
2. Build a DPoP proof JWT for the token request.
3. Request an access token using the Client Credentials Grant.
4. Build a DPoP proof for each API call (include ath claim for access token hash).
5. Call the Transactions API with DPoP-bound access token.

```java
// 1) Create a signed client assertion (private_key_jwt) using your Mastercard key.
String clientAssertion = createClientAssertion(clientId, privateKey, keyId);

// 2) Build a DPoP proof JWT for the token request.
String tokenDpopProof = createDpopProof(tokenEndpoint, "POST", dpopPrivateKey, null);

// 3) Request access token using client_credentials.
String accessToken = tokenClient.requestAccessToken(
    tokenEndpoint,
    clientId,
    clientAssertion,
    tokenDpopProof,
    "client_credentials"
);

// 4) Build a DPoP proof for the API call (include ath claim for access token hash).
String apiDpopProof = createDpopProof(apiEndpoint, "POST", dpopPrivateKey, accessToken);

// 5) Call Transactions API with DPoP-bound access token.
ApiResponse response = apiClient.callTransactionsApi(
    "DPoP " + accessToken,
    apiDpopProof,
    requestBody
);
```

Tip: If your token or API request returns `use_dpop_nonce`, rebuild the DPoP proof using the returned nonce and retry the request. For the full OAuth 2.0 implementation walkthrough, refer to the official [Using OAuth 2.0 to Access Mastercard APIs](https://developer.mastercard.com/platform/documentation/authentication/using-oauth-2-to-access-mastercard-apis/#step-by-step-implementation) guide.

### OAuth 1.0a (RSA Signing) {#oauth-10a-rsa-signing}

If your project is configured for OAuth 1.0a authentication, follow this approach:

1. Under the `src/main/java/` folder path, create a Java file named **ApiClientConfiguration.java**.
2. To make the API call, you need to make your OAuth credentials available to the program for use.

* A PrivateKey is created with the provided credentials for later use.
* AuthenticationUtils is provided by the Mastercard OAuth signing library.

Note: Calling `loadSigningKey` can throw an exception.

```java
 // Read these values from application properties file
   @Value("${mastercard.api.key.alias}")
   private String signingKeyAlias;
 
   @Value("${mastercard.api.keystore.password}")
   private String signingKeyPassword;
 
   @Value("${mastercard.api.p12.path}")
   private String signingKeyPkcs12FileName;
            
   PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyPkcs12FileName, signingKeyAlias, signingKeyPassword);
```

<br />

3. Instantiate a client with your authentication credentials and configuration object as interceptors before you can send it.

```java
  apiClient = new ApiClient();
  apiClient.setBasePath("https://sandbox.api.mastercard.com");
  apiClient.setDebugging(true);

  OkHttpClient.Builder okHttpClientBuilder = apiClient.getHttpClient().newBuilder();
  okHttpClientBuilder.addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey));

  return apiClient.setHttpClient(okHttpClientBuilder.build());
```

Note: For conciseness, only the barebones of what is needed to make the API call is shown above. The full contents of ApiClientConfiguration.java is shown below.

### Contents of ApiClientConfiguration.java {#contents-of-apiclientconfigurationjava}

```java
package com.mastercard.developer.config;
 
import com.mastercard.developer.interceptors.OkHttpOAuth1Interceptor;
import com.mastercard.developer.utils.AuthenticationUtils;
import java.security.PrivateKey;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.openapitools.client.ApiClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
@Service
@Slf4j
public class ApiClientConfiguration {
 
 
    @Value("${mastercard.api.consumer.key}")
    public String consumerKey;
    @Value("${basePath}")
    private String basePath;
    @Value("${mastercard.api.key.alias}")
    private String signingKeyAlias;
 
    @Value("${mastercard.api.keystore.password}")
    private String signingKeyPassword;
 
    @Value("${mastercard.api.p12.path}")
    private String signingKeyPkcs12FileName;
 
    private ApiClient apiClient = null;
 
    public ApiClient getApiClient() {
        createNewApiClient();
        return apiClient;
    }
 
    public ApiClient createNewApiClient() {
        apiClient = new ApiClient();
        try {
 
            PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyPkcs12FileName, signingKeyAlias, signingKeyPassword);
            apiClient.setBasePath(basePath);
            apiClient.setDebugging(true);
            OkHttpClient.Builder okHttpClientBuilder = apiClient.getHttpClient().newBuilder();
 
            okHttpClientBuilder.addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey));
 
            return apiClient.setHttpClient(okHttpClientBuilder.build());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return apiClient;
    }
 
}
```

<br />

4. Now put everything together and you can start using the APIs by making use of the generated classes.

```java
@ApiOperation(value = "transactionSearches API Call", notes = "Fetches the transaction details for a given search criteria. Each account can have multiple Transactions.",
            tags = {"transactions"}
    )
    @PostMapping(value = "/transactions/searches")
    public TransactionsDetails getTransactions(@RequestBody SearchTransactions request) {
        TransactionsDetails transactionsSearchDetails;
        try {
            log.info("Method : transactionSearches, Message : Fetches the transaction details for a given search criteria");
            ApiClient apiClient = apiClientConfiguration.createNewApiClient();
            TransactionsApi transactionsApi = getTransactionsApi(apiClient);
            transactionsSearchDetails = transactionsApi.transactionsSearches(request);
        } catch (ApiException e) {
            throw new InvalidRequest(e.getMessage(), e.getResponseBody());
        }
        log.debug("Method : transactionSearches, Message: Successfully fetched Search result of the transactions");
        return transactionsSearchDetails;
    }
 
    public TransactionsApi getTransactionsApi(ApiClient apiClient) {
        return new TransactionsApi(apiClient);
    }
}
```

Tip: Refer to the following [reference app](https://developer.mastercard.com/transactions-service/documentation/reference-app/index.md) for more details.
