# API Tutorial for OAuth2.0
source: https://developer.mastercard.com/cross-border-services/documentation/tutorials/oauth2-api-sdk-tutorial_unused/index.md

###### Time to complete: *20 minutes*

If you are an Originating Institution contracted with MTS EU or MTS UK, you must connect using [OAuth2.0 Authorization Code flow](https://developer.mastercard.com/cross-border-services/documentation/oauth2-access-token-based-authentication-details/index.md) for Balance APIs and [OAuth2.0 Request Token based flow](https://developer.mastercard.com/cross-border-services/documentation/oauth2-request-token-based-authentication-details/index.md) for all APIs (except Balance API), as the authentication mechanism to ensure compliance with the relevant jurisdiction based Regulatory Technical Standards (either EU or UK) derived from the Revised Payment Services Directive (PSD2).  

## Introduction {#introduction}

This tutorial creates a simple Java program to generate an API client library with OpenAPI Generator and the Mastercard Cross-Border Service APIs Specification. This uses Request Token based OAuth2.0 authentication mechanism to demonstrate how to  

a) make an API call to the Mastercard Cross-Border Services **Payment API** ([EU specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-eu-payment-api/index.md)/ [UK specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-uk-payment-api/index.md)) and   

b) retrieves the payment transaction by making another call to **Retrieve Payment API** ([EU specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-eu-retrieve-payment-api/index.md)/ [UK specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-uk-retrieve-payment-api/index.md)) in the Sandbox environment.

You may extend this to other Cross-Border Services APIs as well.

The tutorial includes generating an API client library with OpenAPI Generator and using the Mastercard Cross-Border Service APIs Specification.

During this tutorial, you will:

1. Add appropriate resources to your project
2. Add proper dependencies
3. Generate the API Client SDK
4. Make API Call

## Step 1: Setting Up {#step-1-setting-up}

### a) Pre-requisites {#a-pre-requisites}

To complete this tutorial, you need:  

* Maven 3.6 or later
* JDK 1.8.0 or later
* IntelliJ IDEA (or any other IDE of your choice)
* [Mastercard Developers Account](https://developer.mastercard.com/) with access to Mastercard Cross-Border Services API and the signing keys generated. You would require the .p12 file, consumer key, keyalias and password from this step to proceed with the below steps. (Click [here](https://developer.mastercard.com/cross-border-services/documentation/tutorials/guide-create-project/index.md) for a step by step guide on account setup.)  
* Mastercard Cross-Border Services Open API specification (Retrieve by clicking on the expandable section on the **Payment API** ([EU specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-eu-payment-api/index.md)/ [UK specification](https://developer.mastercard.com/cross-border-services/documentation/api-ref/psd2-uk-payment-api/index.md)).
* Get the Test mTLS client certificate(.PKCS12 or .PFX file) by contacting Customer Support, to establish mTLS connectivity to connect to APIs.
* Checkout the maven project of Token Generation Utility from : <https://github.com/Mastercard/send-util-crossborder-oauth2>. Build JAR file crossborder-oauth2-1.0-SNAPSHOT.jar and add this jar file in project as dependency.

### b) Create a Maven Project {#b-create-a-maven-project}

In IntelliJ IDEA, create a new Maven project, which sets up your directory structure automatically.  
Provide ArtifactId and Project name.
Here we used the name 'cross_border_services_tutorial'. See below:

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/xb_tutorial_new_prj_1.png)

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/xb_tutorial_new_prj_2.png)

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/xb_tutorial_new_prj_3.png)

### c) Add Resources {#c-add-resources}

Note: #4 and #5 below are only relevant if you want to use Encrypted Request payload, else feel free to skip these two steps.

1. Add the Mastercard Cross-Border Services API specification to your Maven project's resources folder.(Retrieve by clicking on the expandable section on the Payment API)
2. Add the generated p12 file to your Maven project's resources folder. (Generated by creating Sandbox Signing Key within your project in [Mastercard Developers](https://developer.mastercard.com/)
3. Add the Test mTLS client certificate (.PKCS12 or .PFX file) to your Maven project's resources folder.
4. Add the generated Encryption p12 file to your Maven project's resources folder. (Generated by creating Mastercard Encryption Key within your project in [Mastercard Developers](https://developer.mastercard.com/)
5. Add the generated pem file to your Maven project's resources folder. (Downloaded from Client Encryption Keys section).

Your Maven project directory should look as follows:

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/psd2_xb_tutorial_add_resources.png)

### d) Update pom.xml file {#d-update-pomxml-file}

1. Add the following plugin to your Maven project's pom.xml file to add OpenAPI Generator to your project.
   OpenAPI Generator generates API client libraries from OpenAPI Specifications (formerly known as Swagger files). OpenAPI Generator provides multiple generators and library templates to support multiple languages and frameworks. You will be using the java generator for this project.

   * Plugin

   ```xml
       <build>
       <plugins>
           <plugin>
               <groupId>org.openapitools</groupId>
               <artifactId>openapi-generator-maven-plugin</artifactId>
               <version>3.3.4</version>
               <executions>
                   <execution>
                       <id>Cross-Border Services REST Client</id>
                       <goals>
                           <goal>generate</goal>
                       </goals>
                       <configuration>
                           <inputSpec>${project.basedir}/src/main/resources/cross-border-swagger.yaml</inputSpec>
                           <generatorName>java</generatorName>
                           <configOptions>
                               <sourceFolder>src/gen/java/main</sourceFolder>
                               <hideGenerationTimestamp>true</hideGenerationTimestamp>
                           </configOptions>
                       </configuration>
                   </execution>
               </executions>
           </plugin>
       </plugins>
       </build>
       
   ```

2. Add the following dependencies to your pom.xml file to add dependencies for the API client library generation and the Mastercard OAuth2 Signer library.
   Mastercard offers OAuth2 Signer Libraries which offer code helpers targeting the HTTP clients used by the different OpenAPI Generator Library templates. The libraries are hosted here on [Github](https://github.com/Mastercard?utf8=%E2%9C%93&q=oauth1-signer&type=&language=).

* Dependencies

```xml
  <properties>
      <spring.version>5.2.20.RELEASE</spring.version>
      <slf4j.version>1.7.21</slf4j.version>
      <log4j2.version>2.17.2</log4j2.version>
      <jackson.version>2.13.1</jackson.version>
      <junit.version>4.12</junit.version>
      <javax.ws.rs.version>2.0.1</javax.ws.rs.version>
      <oauth1-signer-version>1.2.4</oauth1-signer-version>
      <apacheAuthZserver.version>1.0.3</apacheAuthZserver.version>
      <apacheAuthZserver.common.version>1.0.2</apacheAuthZserver.common.version>
      <nimbus-jwt>9.21</nimbus-jwt>
      <lombok.version>1.18.22</lombok.version>
      <javaxb-api-version>2.3.1</javaxb-api-version>
      <javaxb-impl-version>2.3.4</javaxb-impl-version>
      <javaxb-anntn-version>1.3.2</javaxb-anntn-version>
      <okhttp-version>2.7.5</okhttp-version>
      <jetty.version>9.4.19.v20190610</jetty.version>
      <httpclient-version>4.5</httpclient-version>
  </properties>
  <dependencies>
      <!-- Below are mandatory dependencies for executing cross border APIs-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- Below dependencies are required for making REST calls -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>javax.ws.rs</groupId>
          <artifactId>javax.ws.rs-api</artifactId>
          <version>${javax.ws.rs.version}</version>
      </dependency>
      <!-- This dependency is used for authentication -->
      <dependency>
          <groupId>com.mastercard.developer</groupId>
          <artifactId>oauth1-signer</artifactId>
          <version>${oauth1-signer-version}</version>
      </dependency>
      <!-- Below dependencies are for executing use cases using JUnit-->
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>${jackson.version}</version>
      </dependency>
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
          <scope>test</scope>
      </dependency>
      <!-- Below dependencies are used for logging of request and response -->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jcl-over-slf4j</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>jul-to-slf4j</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>log4j-over-slf4j</artifactId>
          <version>${slf4j.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-slf4j-impl</artifactId>
          <version>${log4j2.version}</version>
      </dependency>
      <dependency>
          <groupId>com.nimbusds</groupId>
          <artifactId>nimbus-jose-jwt</artifactId>
          <version>${nimbus-jwt}</version>
      </dependency>
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>${lombok.version}</version>
          <scope>provided</scope>
      </dependency>
      <dependency>
          <groupId>org.apache.oltu.oauth2</groupId>
          <artifactId>org.apache.oltu.oauth2.jwt</artifactId>
          <version>${apacheAuthZserver.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.oltu.oauth2</groupId>
          <artifactId>org.apache.oltu.oauth2.common</artifactId>
          <version>${apacheAuthZserver.common.version}</version>
      </dependency>
      <dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>javax.annotation-api</artifactId>
          <version>${javaxb-anntn-version}</version>
      </dependency>
      <dependency>
          <groupId>javax.xml.bind</groupId>
          <artifactId>jaxb-api</artifactId>
          <version>${javaxb-api-version}</version>
      </dependency>
      <dependency>
          <groupId>com.sun.xml.bind</groupId>
          <artifactId>jaxb-impl</artifactId>
          <version>${javaxb-impl-version}</version>
      </dependency>
      <dependency>
          <groupId>com.squareup.okhttp</groupId>
          <artifactId>logging-interceptor</artifactId>
          <version>${okhttp-version}</version>
      </dependency>
      <dependency>
          <groupId>com.squareup.okhttp</groupId>
          <artifactId>okhttp</artifactId>
          <version>${okhttp-version}</version>
      </dependency>
      <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-server</artifactId>
          <version>${jetty.version}</version>
      </dependency>
      <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-util</artifactId>
          <version>${jetty.version}</version>
      </dependency>
      <dependency>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
          <version>${httpclient-version}</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 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.)

## Step 2: Generating the API Client SDK {#step-2-generating-the-api-client-sdk}

### a) Generate Sources {#a-generate-sources}

Now that you have all the dependencies you need, you can generate the sources.

In IntelliJ IDEA, open the window for Maven (View \> Tool Windows \> Maven).
Click the icons for Reimport All Maven Projects and Generate Sources and Update Folders for All Projects:

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/xb_api_tutorial_generate_sources1.png)

### b) Generate the SDK {#b-generate-the-sdk}

You should now be ready to generate the API client library.

In the same menu, navigate to the commands ({Project name} \> Lifecycle), run clean and then compile. Alternatively, you can navigate to the root directory of the project within a terminal window and run mvn clean compile.

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/xb_api_tutorial_generate_sources2.png)

Now, there should be a new folder named target, 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 target folder as shown below.

![](https://static.developer.mastercard.com/content/cross-border-services/documentation/images/tutorial_target_folder.png)

## Step 3: Making API Call (Unencrypted payload) {#step-3-making-api-call-unencrypted-payload}

[See here instructions to make API call with encrypted payload](https://developer.mastercard.com/cross-border-services/documentation/tutorials/psd2-encrypted-api-call-tutorial/index.md)

Create a Java file, called Main.java, at src/main/java/.

Base Path has to be set as per the region:  

++EU Region Base Path++ : <https://sandbox.api.xbs.mastercard.eu>   

++UK Region Base Path++ : <https://sandbox.api.xbs.mastercard.uk>

To make the API call, you need to make your OAuth credentials available to the program as shown below:
* Oauth

```Oauth
String consumerKey = "your consumer key";
String signingKeyFilePath = "/path/to/your/key.p12";
String signingKeyAlias = "your key alias";
String signingKeyPassword = "your password";
PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyFilePath, signingKeyAlias, signingKeyPassword);
```

Next, you instantiate a client that you can set up to sign requests that you send with your authentication credentials.
Note: Request Token generation is included as part of OkHttp2OAuth2RequestTokenInterceptor which will generate a request token based on the provided Consumer Key, P12 File, Signing Key Alias \& Signing Key Password.
* Client_Instantiation

```Client_Instantiation
ApiClient client = new ApiClient();
client.setBasePath("/path/to/your/domainURL");
client.setDebugging(true);
client.setReadTimeout(40000);

// For mTLS connection
KeyStore keystore = KeyStore.getInstance("PKCS12");
char[] password= "yourPFXPassword".toCharArray();

keystore.load((new FileInputStream("/path/to/your/.pfx")),password);

SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setKeyStore(keystore);
sslContextFactory.setKeyStorePassword("yourPFXPassword");
sslContextFactory.start();
SSLContext sslContext = sslContextFactory.getSslContext();
SSLSocketFactory sf = sslContext.getSocketFactory();
OkHttpClient httpClient = client.getHttpClient();
httpClient.setSslSocketFactory(sf);
client.addDefaultHeader("Content-Type", "application/json; charset=UTF-8");
client.setHttpClient(httpClient);
        
List<Interceptor> interceptors = client.getHttpClient().networkInterceptors();
interceptors.add(new OkHttp2OAuth2RequestTokenInterceptor(signingKeyFilePath, signingKeyAlias, signingKeyPassword, consumerKey));

PaymentApi paymentApi = new PaymentApi(client);   
```

With your environment set up, you can now start to build a request.
Any nested objects within the Request Body have been assigned a wrapper class each, and so in order to build the request, you will be instantiating multiple objects and ultimately wrapping those with the main request object.

You may store the response in a Response object.
Once you have the response stored, you have different options, but for this tutorial you can simply use toString to print the response body.  

To make it easy to understand, only the snippets needed to make the API call is shown above. The full content of Main.java is shown below.

## Content of Main.java {#content-of-mainjava}

* Main.Java

```Main.Java
package com.mastercard.test;

import com.mastercard.oauth2.requesttoken.interceptor.OkHttp2OAuth2RequestTokenInterceptor;
import com.mastercard.developer.utils.AuthenticationUtils;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.CardedRateApi;
import org.openapitools.client.api.PaymentApi;
import org.openapitools.client.api.RetrievePaymentApi;
import org.openapitools.client.model.*;
import interceptor.OkHttp2OAuth2Interceptor;
import java.io.IOException;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) throws Exception {

        ApiClient client = new ApiClient();

        String consumerKey = "your consumer key";
        String signingKeyFilePath = "/path/to/your/key.p12";
        String signingKeyAlias = "your key alias";
        String signingKeyPassword = "your password";
        PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyFilePath, signingKeyAlias, signingKeyPassword);

        client.setBasePath("/path/to/your/domainURL");
        client.setDebugging(true);
        client.setReadTimeout(40000);
        
        // form mTLS connection
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        char[] password= "yourPFXPassword".toCharArray();
        
        keystore.load((new FileInputStream("/path/to/your/.pfx")),password);
        
        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
        sslContextFactory.setKeyStore(keystore);
        sslContextFactory.setKeyStorePassword("yourPFXPassword");
        sslContextFactory.start();
        SSLContext sslContext = sslContextFactory.getSslContext();
        SSLSocketFactory sf = sslContext.getSocketFactory();
        OkHttpClient httpClient = client.getHttpClient();
        httpClient.setSslSocketFactory(sf);
        client.addDefaultHeader("Content-Type", "application/json; charset=UTF-8");
        client.setHttpClient(httpClient);
        
        List<Interceptor> interceptors = client.getHttpClient().networkInterceptors();
        interceptors.add(new OkHttp2OAuth2RequestTokenInterceptor(signingKeyFilePath, signingKeyAlias, signingKeyPassword, consumerKey));

        String partnerId = "your_partner_id";  // example: "BEL_MASEND5ged2"

        /*Payment API call*/
        PaymentApi paymentApi = new PaymentApi(client);
        System.out.println("Calling Make Payment");
        PaymentRequestWrapper paymentRequestWrapper = getPaymentRequest(); // Populate payment request
        PaymentWrapper remitResponse = paymentApi.payment(partnerId,paymentRequestWrapper);
        System.out.println("Make payment response : " + remitResponse);

        /*Retrieve Payment API call*/
        RetrievePaymentApi retrievePayment = new RetrievePaymentApi(client);
        System.out.println("Calling Retrieve Payment");
        String ref = "061574074811229"; //Can be obtained by remitResponse.getPayment().getTransactionReference();
        RetrievePaymentWrapper response = retrievePayment.transactionStatus(partnerId, ref);
        System.out.println("Retrieve Payment response: " +response);
    }

    private static PaymentRequestWrapper getPaymentRequest() {

        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setTransactionReference(String.valueOf(System.currentTimeMillis()));
        paymentRequest.setSenderAccountUri("tel:+254108989");
        paymentRequest.setRecipientAccountUri("ewallet:paypal_user011");
        /* Amount information */
        PaymentAmount amount = new PaymentAmount();
        amount.setAmount("200");
        amount.setCurrency("INR");
        paymentRequest.setPaymentAmount(amount);
        paymentRequest.setPaymentOriginationCountry("ARE");

        FxType quoteType = new FxType();
        Reverse reverseFees = new Reverse();
        reverseFees.setSenderCurrency("USD");
        quoteType.setReverse(reverseFees);
        paymentRequest.setFxType(quoteType);
        paymentRequest.setBankCode("NP021");
        paymentRequest.setPaymentType("P2B");

        /*Sender Information */
        Sender senderData = new Sender();
        senderData.setFirstName("Pat");
        senderData.setLastName("Rose");
        senderData.setNationality("IND");
        Address senderAddress = new Address();
        senderAddress.setLine1("53 Main Street");
        senderAddress.setLine2("5A");
        senderAddress.setCity("Pune");
        senderAddress.setCountrySubdivision("MH");
        senderAddress.setCountry("IND");
        senderAddress.setPostalCode("411001");
        senderData.setAddress( senderAddress);

        GovernmentIds idData1 = new GovernmentIds();
        List<GovernmentIds> governmentIds = new ArrayList<>();
        idData1.setGovernmentIdUri("ppn:123456789;expiration-date=2019-05-27;issue-date=2011-07-12;country=USA");
        governmentIds.add(idData1);
        senderData.setGovernmentIds(governmentIds);
        senderData.setDateOfBirth("1985-06-24");
        paymentRequest.setSender(senderData);

        /*Recipient information */
        Recipient recipientData = new Recipient();
        recipientData.setEmail("test@gmail.com");
        recipientData.setNationality("USA");
        recipientData.setOrganizationName("WU");
        Address recipientAddress = new Address();
        recipientAddress.setLine1("123 MainStreet");
        recipientAddress.setLine2("5A");
        recipientAddress.setCity("Arlington");
        recipientAddress.setCountrySubdivision("VA");
        recipientAddress.setCountry("USA");
        recipientAddress.setPostalCode("22207");
        recipientData.setAddress(recipientAddress);
        paymentRequest.setRecipient(recipientData);

        /* Additional Data */
        List <DataField> fields = new ArrayList<>();
        DataField dataField1 = new DataField();
        dataField1.setName("501");dataField1.setValue("1234222222");
        DataField dataField2 = new DataField();
        dataField2.setName("503");dataField2.setValue("12362");
        AdditionalData additionalField = new AdditionalData();
        additionalField.setDataField(fields);
        paymentRequest.setAdditionalData(additionalField);

        paymentRequest.setSourceOfIncome("Bank");
        paymentRequest.setReceivingBankName("Royal Exchange");
        paymentRequest.setReceivingBankBranchName("Quad Cities");
        paymentRequest.setPaymentFileIdentifier("1233241223");
        PaymentRequestWrapper wrapper = new PaymentRequestWrapper();
        wrapper.setPaymentrequest(paymentRequest);
        return wrapper;
    }

    /**Add "Format=JSON" to the request for the service/gateway to return a JSON response.*/
    private static class ForceJsonResponseInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            String withJsonFormatUrl = withJsonFormat(originalRequest.uri().toString());
            Request newRequest = originalRequest.newBuilder().url(withJsonFormatUrl).build();
            return chain.proceed(newRequest);
        }

        private String withJsonFormat(String uri) {
            StringBuilder newUri = new StringBuilder(uri);
            newUri.append(uri.contains("?") ? "&" : "?");
            newUri.append("Format=JSON");
            return newUri.toString();
        }
    }
}

```

Note: Well Done! 👏. You have successfully completed the tutorial on how to generate the SDK and connect to the Mastercard Cross-Border Payment API in sandbox using the SDK.

## Further Reading {#further-reading}

* [Using OAuth 1.0a to Access Mastercard APIs](https://developer.mastercard.com/platform/documentation/using-oauth-1a-to-access-mastercard-apis).

* [OpenAPI Generator](https://openapi-generator.tech/)

* [Getting Started with APIs using OAuth2.0](https://developer.mastercard.com/cross-border-services/documentation/api-basics/getting-started-oauth2/index.md)

