# Making an EU Region API Call with encrypted payload
source: https://developer.mastercard.com/cross-border-services/documentation/tutorials/psd2-encrypted-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 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);
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("https://sandbox.api.xbs.mastercard.eu");
client.setDebugging(true);
client.setReadTimeout(40000);
List<Interceptor> interceptors = client.getHttpClient().interceptors();
interceptors.add(new ForceJsonResponseInterceptor());
client.addDefaultHeader("x-encrypted","true"); // This header should be added for all Encryption calls.

JweConfig config = JweConfigBuilder.aJweEncryptionConfig()
            .withEncryptionCertificate(EncryptionUtils.
                    loadEncryptionCertificate(encryptionCertPath))
            .withEncryptionPath("$", "$.encrypted_payload") // This property should be kept as it is.
            .withEncryptedValueFieldName("data") // This property should be kept as it is.
            .withDecryptionKey(decryptionKey)
            .withDecryptionPath("$.encrypted_payload.data", "$") // This property should be kept as it is.
            .build();
interceptors.add(OkHttp2JweInterceptor.from(config)); // This interceptor should be added before OAuth Interceptor.
interceptors.add(new OkHttp2OAuth2Interceptor(signingKeyFilePath, signingKeyAlias, signingKeyPassword, consumerKey));
HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
logger.setLevel(HttpLoggingInterceptor.Level.BODY);
interceptors.add(logger);
PaymentApi paymentApi = new PaymentApi(client);  
```

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

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

```

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.crossborder.api;

import com.mastercard.developer.encryption.EncryptionException;
import com.mastercard.developer.encryption.JweConfig;
import com.mastercard.developer.encryption.JweConfigBuilder;
import com.mastercard.developer.interceptors.OkHttp2JweInterceptor;
import com.mastercard.developer.interceptors.OkHttp2OAuth1Interceptor;
import com.mastercard.developer.interceptors.OkHttpFieldLevelEncryptionInterceptor;
import com.mastercard.developer.utils.AuthenticationUtils;
import com.mastercard.developer.utils.EncryptionUtils;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.logging.HttpLoggingInterceptor;
import org.openapitools.client.ApiClient;
import org.openapitools.client.api.PaymentApi;
import org.openapitools.client.api.RetrievePaymentApi;
import org.openapitools.client.model.AdditionalData;
import org.openapitools.client.model.Address;
import org.openapitools.client.model.DataField;
import org.openapitools.client.model.FxType;
import org.openapitools.client.model.GovernmentIds;
import org.openapitools.client.model.PaymentAmount;
import org.openapitools.client.model.PaymentRequest;
import org.openapitools.client.model.PaymentRequestWrapper;
import org.openapitools.client.model.PaymentWrapper;
import org.openapitools.client.model.Recipient;
import org.openapitools.client.model.RetrievePaymentWrapper;
import org.openapitools.client.model.Reverse;
import org.openapitools.client.model.Sender;
import interceptor.OkHttp2OAuth2Interceptor;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;

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


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

        /*Payment API call*/
        PaymentApi paymentApi = new PaymentApi(getEncryptedApiClient());
        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*/
        System.out.println("Calling Retrieve Payment");
        RetrievePaymentApi retrievePayment = new RetrievePaymentApi(getEncryptedApiClient());
        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 ApiClient getEncryptedApiClient() throws GeneralSecurityException, IOException, EncryptionException {
        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("https://sandbox.api.xbs.mastercard.eu");
        client.setDebugging(true);
        client.setReadTimeout(40000);
        List<Interceptor> interceptors = client.getHttpClient().interceptors();
        interceptors.add(new ForceJsonResponseInterceptor());
        JweConfig config = JweConfigBuilder.aJweEncryptionConfig()
                    .withEncryptionCertificate(EncryptionUtils.
                            loadEncryptionCertificate("/path/to/your/cert.pem"))
                    .withEncryptionPath("$", "$.encrypted_payload")
                    .withEncryptedValueFieldName("data")
                    .withDecryptionKey(EncryptionUtils.loadDecryptionKey("/path/to/your/encryption-key.p12"
                            , "keyalias", "keystorepwd1"))
                    .withDecryptionPath("$.encrypted_payload.data", "$")
                    .build();
        interceptors.add(OkHttp2JweInterceptor.from(config));
        client.addDefaultHeader("x-encrypted","true");
        interceptors.add(new OkHttp2OAuth2Interceptor(signingKeyFilePath, signingKeyAlias, signingKeyPassword, consumerKey));
        HttpLoggingInterceptor logger = new HttpLoggingInterceptor();
        logger.setLevel(HttpLoggingInterceptor.Level.BODY);
        interceptors.add(logger);
        return client;
    }

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

```

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