# Making an Region(EU/UK) specific API Call with encrypted payload
source: https://developer.mastercard.com/cross-border-services/documentation/tutorials/psd2-encrypted-access-token-api-call-tutorial/index.md

Make sure you have below dependency added to your pom.xml file for Encryption.

        <dependency>
            <groupId>com.mastercard.developer</groupId>
            <artifactId>client-encryption</artifactId>
            <version>1.6.0</version>
        </dependency>

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

To make an API call with encrypted payload, you need to make your OAuth credentials and Encryption keys available to the program to use:
* Oauth

```Oauth
String token = "Bearer <your access token>";
client.addDefaultHeader("Authorization", token);

String decryptionKeyFilePath = "/path/to/your/key.p12";
String decryptionKeyAlias = "your decryption key alias";
String decryptionKeyPassword = "your decryption password";
PrivateKey decryptionKey = EncryptionUtils.loadDecryptionKey(decryptionKeyFilePath, decryptionKeyAlias, decryptionKeyPassword)
String encryptionCertPath = "/path/to/your/CrossBorderServicesEnc.pem";
```

Next, you instantiate a client that you can set up to sign requests that you send with your authentication credentials.
* Client_Instantiation

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

// for mTLS connection (For Sandbox EU/UK domain testing, do not keep below configurations)
KeyStore keystore = KeyStore.getInstance("PKCS12");
char[] password= "yourPfxPassword".toCharArray();

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

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
builder.loadKeyMaterial(keystore, "yourPfxPassword".toCharArray());
SSLContext sslContext = builder.build();

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().interceptors();

List<Interceptor> interceptors = client.getHttpClient().interceptors();
        interceptors.add(new ForceJsonResponseInterceptor());
        JweConfig config = JweConfigBuilder.aJweEncryptionConfig()
                .withEncryptionCertificate(EncryptionUtils.
                        loadEncryptionCertificate("/path/to/your/.pem"))
                .withEncryptionPath("$", "$.encrypted_payload")
                .withEncryptedValueFieldName("data")
                .withDecryptionKey(EncryptionUtils.loadDecryptionKey("/path/to/your/encryption-key.p12"
                        , "yourKeyAlias", "yourPassword"))
                .withDecryptionPath("$.encrypted_payload.data", "$")
                .build();
        interceptors.add(OkHttp2JweInterceptor.from(config));
        client.addDefaultHeader("x-encrypted","true");
RetrieveAccountBalancesApi retrieveAccountBalancesApi = new RetrieveAccountBalancesApi(client);   
        
```

The interceptor that you use to sign requests is also provided by the Mastercard OAuth library.

With your environment set up, you can start to build a request.
Any nested objects within the Request Body have each been assigned a wrapper class, and so in order to build the request, you will be instantiating multiple objects and ultimately wrapping those with the main request object.
You make the Encrypted API call, parse the response payload and store it into 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.
* Main.Java

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

import com.mastercard.developer.encryption.JweConfig;
import com.mastercard.developer.encryption.JweConfigBuilder;
import com.mastercard.developer.interceptors.OkHttp2JweInterceptor;
import com.mastercard.developer.utils.EncryptionUtils;
import org.openapitools.client.api.RetrieveAccountBalancesApi;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.logging.HttpLoggingInterceptor;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.openapitools.client.ApiClient;
import org.openapitools.client.model.*;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.List;

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


        String partnerId = "PSD2_OI_Encrypt"; //"PSD2-OI-Payment"; //"SANDBOX_LISA"

        /*Payment API call*/
        RetrieveAccountBalancesApi retrieveAccountBalancesApi = new RetrieveAccountBalancesApi(getEncryptedAccessTokenApiClient());
        System.out.println("Calling Get All Account Balances");
        Account lstAccounts = retrieveAccountBalancesApi.getAllAccountBalances(partnerId, "true");
        System.out.println("Get All Account Balances response : " + lstAccounts);

    }

    private static ApiClient getEncryptedAccessTokenApiClient() throws Exception {
        ApiClient client = new ApiClient();

        client.setBasePath("/path/to/your/domainURL");
        // Set the Access Token generated using Auth Code
        String token = "Bearer <your access token>";
        client.addDefaultHeader("Authorization", token);
        client.setDebugging(true);
        client.setReadTimeout(40000);

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

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

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        builder.loadKeyMaterial(keystore, "yourPFXPassword".toCharArray());
        SSLContext sslContext = builder.build();

        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().interceptors();
        interceptors.add(new ForceJsonResponseInterceptor());
        JweConfig config = JweConfigBuilder.aJweEncryptionConfig()
                .withEncryptionCertificate(EncryptionUtils.
                        loadEncryptionCertificate(/path/to/your/.pem"))
                .withEncryptionPath("$", "$.encrypted_payload")
                .withEncryptedValueFieldName("data")
                .withDecryptionKey(EncryptionUtils.loadDecryptionKey("/path/to/your/.p12""
                        , "yourKeyAlias", "yourKeyPassword"))
                .withDecryptionPath("$.encrypted_payload.data", "$")
                .build();
        interceptors.add(OkHttp2JweInterceptor.from(config));
        client.addDefaultHeader("x-encrypted","true");
        HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
        logger.setLevel(HttpLoggingInterceptor.Level.BODY);
        interceptors.add(logger);

        return client;
    }

    /**
     * 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();
        }
    }
}
```

[Go Back to API Tutorial](https://developer.mastercard.com/cross-border-services/documentation/tutorials/oauth2-api-sdk-tutorial-access-token/index.md)
