# Customer Onboarding Guide source: https://developer.mastercard.com/india-online-dispute-resolution/documentation/onboarding-guide/index.md This tutorial will explain how to create a simple API client. ## Environment setup {#environment-setup} 1. Create a Maven project. * In the IDE, create a new Maven project (for example, **IndiaOnlineDisputeResolutionTutorial**) which sets your directory structure automatically. * Provide an **ArtifactId** and a project name as per your choice. 2. Add resources. * Add the IODR [API specification](https://developer.mastercard.com/india-online-dispute-resolution/documentation/api-reference/index.md#apis) to your resources folder of Maven project. * Add the generated sandbox key, Mastercard encryption key, and encryption certificate to your Maven project resources folder. This is generated while creating the project on Mastercard Developers. * Your Maven project directory structure appears: ![add_resource1](https://static.developer.mastercard.com/content/india-online-dispute-resolution/uploads/add_resource1.png) 3. Update the pom.xml file. ```XML org.openapitools openapi-generator-maven-plugin 5.2.1 IODR API REST Client generate ${project.basedir}/src/main/resources/india-online-dispute-resolution-api-swagger.yaml java false false src/gen/java/main true java8 Date=LocalDate ``` * Add the following dependencies to your pom.xml file to generate the API client library and the Mastercard OAuth1 Signer library. The Mastercard OAuth1 Signer library provides code helpers for HTTP clients used for various OpenAPI Generator Library templates. **Dependencies** ```XML 17 2.5.3 1.18.16 4.9.1 3.11 1.3.2 1.5.1 1.8.2 4.13.1 2.8.6 1.8.5 1.6.2 1.3.2 UTF-8 com.mastercard.developers.iodr 0.2.1 17 17 org.springframework.boot spring-boot-starter-web ${spring.boot.version} org.springframework.boot spring-boot-devtools ${spring.boot.version} runtime true org.springframework.data spring-data-commons 2.5.0 com.squareup.okhttp3 okhttp ${okhttp-version} com.squareup.okhttp3 logging-interceptor ${okhttp-version} com.google.code.gson gson ${gson-version} io.gsonfire gson-fire ${gson-fire-version} org.apache.commons commons-lang3 ${commons-lang3-version} javax.annotation javax.annotation-api ${javax-annotation-version} com.mastercard.developer oauth1-signer ${oauth1-signer-version} com.mastercard.developer client-encryption ${client-encryption-version} io.swagger swagger-annotations ${swagger-core-version} com.google.code.findbugs jsr305 3.0.2 org.openapitools jackson-databind-nullable ${jackson-databind-nullable-version} commons-io commons-io 2.6 log4j log4j 1.2.14 runtime junit junit 4.13.2 test org.springframework.boot spring-boot-starter-test test com.vaadin.external.google android-json org.junit.jupiter junit-jupiter-engine org.mockito mockito-junit-jupiter org.mockito mockito-inline 3.0.0 test ``` For more information, refer [Generating and Configuring a Mastercard API Client](https://developer.mastercard.com/platform/documentation/security-and-authentication/generating-and-configuring-a-mastercard-api-client/#overview). ## Setting up the project {#setting-up-the-project} 1. Navigate to the root directory of the project within a terminal window and run `mvn clean install`. ![maven_comm_clean2](https://static.developer.mastercard.com/content/india-online-dispute-resolution/uploads/maven_comm_clean2.png) 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. ![iodr_target_jar1](https://static.developer.mastercard.com/content/india-online-dispute-resolution/uploads/iodr_target_jar1.png) 2. Following are the steps to create a sample project with an open API generator. a. Create a Java file **IODRApiClient.java** at src/main/java/. b. To make the API call, add the following OAuth credentials in **IODRApiClient.java** . c. Create a java test file **IODRApiTest.java** at src/test/java/. **OAuth** ```java String consumerKey = ""; String signingKeyFilePath = "./src/main/resources/client p12 file name downloaded on project creation>.p12"; String encryptionCertPath = "./src/main/resources/.pem"; String mcKeyFilePath = "./src/main/resources/.p12"; String signingKeyAlias = ""; String mcKeyAlias = ""; String mcKeyPassword = ""; PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyFilePath, signingKeyAlias, signingKeyPassword); ``` **Content of IODRApiClient.java** ```java package com.mastercard.odr; import java.security.PrivateKey; import java.security.cert.Certificate; import com.mastercard.developer.interceptors.OkHttpJweInterceptor; import com.mastercard.developer.interceptors.OkHttpOAuth1Interceptor; import com.mastercard.developer.utils.AuthenticationUtils; import com.mastercard.developer.utils.EncryptionUtils; import com.mastercard.developer.encryption.JweConfig; import com.mastercard.developer.encryption.JweConfigBuilder; import org.springframework.stereotype.Service; @Service public class IODRApiClient { public ApiClient getApiClient(boolean enableEncryption) throws Exception { ApiClient client = new ApiClient(); String consumerKey = ""; String signingKeyFilePath = "./src/main/resources/client p12 file name downloaded on project creation>.p12"; String encryptionCertPath = "./src/main/resources/.pem"; String mcKeyFilePath = "./src/main/resources/.p12"; String signingKeyAlias = ""; String signingKeyPassword = ""; String mcKeyAlias = ""; String mcKeyPassword = ""; PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyFilePath, signingKeyAlias, signingKeyPassword); client.setBasePath("https://mtf.api.mastercard.co.in/iodr"); client.setDebugging(true); if (enableEncryption) { client.setHttpClient(client.getHttpClient().newBuilder() .addInterceptor(new OkHttpJweInterceptor(getEncryptionDecryptionConfig(encryptionCertPath,mcKeyFilePath, mcKeyAlias, mcKeyPassword))) .addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey)).build()); } else { client.setHttpClient(client.getHttpClient().newBuilder() .addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey)).build()); } return client; } private JweConfig getEncryptionDecryptionConfig(String encryptionCertPath, String keyFile, String keyAlias, String password) { JweConfig config = null; try { Certificate encryptionCertificate = EncryptionUtils.loadEncryptionCertificate(encryptionCertPath); PrivateKey key = EncryptionUtils.loadDecryptionKey(keyFile, keyAlias, password); config = JweConfigBuilder.aJweEncryptionConfig().withEncryptionCertificate(encryptionCertificate) .withEncryptionPath("$", "$").withEncryptedValueFieldName("encryptedValue") .withDecryptionKey(key).withDecryptionPath("$.encryptedValue", "$") .build(); } catch (Exception e) { System.out.println(e); } return config; } } ``` **Content of IODRApiTest.java** ```java package com.mastercard.odr; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.openapitools.client.api.IodrApi; import org.openapitools.client.model.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.UUID; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { IODRApiClient.class }) public class IODRApiTest { @Autowired IODRApiClient iodrApiClient; IodrApi iodrApi; IodrApi iodrApiClientForEncryptionDecryption; @Before public void setUp() throws Exception { iodrApi = new IodrApi(iodrApiClient.getApiClient(false)); iodrApiClientForEncryptionDecryption = new IodrApi(iodrApiClient.getApiClient(true)); } @Test public void testCreateComplaintsAPIWithPositiveScenario() throws Exception { try { String requestId = UUID.randomUUID().toString(); CreateComplaint createComplaintRequestPayload = getCreateComplaintRequest(); System.out.println("Calling create a new complaint API Positive Scenario with requestID "+requestId +" and request payload "+ createComplaintRequestPayload); Complaint createComplaintResponse = iodrApiClientForEncryptionDecryption.createComplaint(requestId, createComplaintRequestPayload); Assert.assertEquals("Complaint created successfully.", createComplaintResponse.getDescription()); System.out.println("Calling create a new complaint API response : "+ createComplaintResponse); } catch (Exception e) { System.out.println("Create a new complaint API Call failed with error msg : "+ e.getMessage()); Assert.assertNotNull(e.getMessage()); } } @Test public void testCreateComplaintsAPIWithNegativeScenario() throws Exception { try { String requestId = UUID.randomUUID().toString(); CreateComplaint createComplaintRequestPayload = getCreateComplaintRequest(); createComplaintRequestPayload.setCardNumber(""); System.out.println("Calling create a new complaint API with Negative Scenario requestID : "+requestId+ " and request payload : {}"+ createComplaintRequestPayload.toString()); Complaint createComplaintResponse = iodrApiClientForEncryptionDecryption.createComplaint(requestId, createComplaintRequestPayload); System.out.println("Calling create a new complaint API response with Negative Scenario : " + createComplaintResponse.toString()); } catch (Exception e) { System.out.println("Create a new complaint API Call failed with error msg with Negative Scenario: " + e); Assert.assertNotNull(e.getMessage()); } } @Test public void testValidateTransactionStatusWithPositiveScenario() { try { String requestId = UUID.randomUUID().toString(); IODRTransactionValidation iodrTransactionValidationRequestPayload = getValidateTransactionRequest(); System.out.println("Calling validate transaction details API with requestID : " + requestId + " and request payload : " + iodrTransactionValidationRequestPayload.toString()); Detail validateTransactionDetails = iodrApiClientForEncryptionDecryption.validateTransaction(requestId, iodrTransactionValidationRequestPayload); System.out.println("Calling validate transaction details API response : " + validateTransactionDetails.toString()); } catch (Exception e) { System.out.println("Validate transaction details API Call failed with error msg " + e); Assert.assertNotNull(e); } } @Test public void testValidateTransactionStatusWithNegativeScenario() { try { String requestId = UUID.randomUUID().toString(); IODRTransactionValidation iodrTransactionValidationRequestPayload = getValidateTransactionRequest(); iodrTransactionValidationRequestPayload.setAcquirerICA(""); System.out.println("Calling validate transaction details API with requestID : " + requestId + " and request payload : " + iodrTransactionValidationRequestPayload.toString()); Detail validateTransactionDetails = iodrApiClientForEncryptionDecryption.validateTransaction(requestId, iodrTransactionValidationRequestPayload); System.out.println("Calling validate transaction details API response : " + validateTransactionDetails.toString()); } catch (Exception e) { System.out.println("Validate transaction details API Call failed with error msg " + e); Assert.assertNotNull(e); } } @Test public void testGetTransactionStatusWithPositiveScenario() { try { String trackingNumber = "OUD0AT0UAKDO"; System.out.println("Calling get transaction status API with trackingNumber : " + trackingNumber); Status transactionDetailStatus = iodrApiClientForEncryptionDecryption.getTransactionStatus(trackingNumber); System.out.println("Calling get transaction status API response : " + transactionDetailStatus.toString()); } catch (Exception e) { System.out.println("Get transaction status API Call failed with error msg "+e); Assert.assertNotNull(e); } } @Test public void testGetTransactionStatusWithNegativeScenario() { try { String trackingNumber = "OUD0AT0UAKDP"; System.out.println("Calling get transaction status API with trackingNumber : " + trackingNumber); Status transactionDetailStatus = iodrApiClientForEncryptionDecryption.getTransactionStatus(trackingNumber); System.out.println("Calling get transaction status API response : " + transactionDetailStatus.toString()); } catch (Exception e) { System.out.println("Get transaction status API Call failed with error msg "+e); Assert.assertNotNull(e); } } @Test public void testUpdateComplaintsByUserAPIWithPositiveScenario() { try { String requestId = UUID.randomUUID().toString(); UpdateComplaintByUser updateComplaintByUser = getUpdateComplaintByUserRequest(); System.out.println("Calling update a complaint by issuer API with requestID : "+ requestId+" and request payload :"+ updateComplaintByUser.toString()); Complaint complaintUpdateByIssuer = iodrApi.updateComplaint(requestId, updateComplaintByUser); System.out.println("Calling update a complaint by issuer API response :"+ complaintUpdateByIssuer.toString()); } catch (Exception e) { System.out.println(e); Assert.assertNotNull(e); } } @Test public void testUpdateComplaintsByUserAPIWithNegativeScenario() { try { String requestId = UUID.randomUUID().toString(); UpdateComplaintByUser updateComplaintByUser = getUpdateComplaintByUserRequest(); updateComplaintByUser.setTrackingNumber("ABX"); System.out.println("Calling update a complaint by issuer API with requestID "+ requestId+" and request payload "+updateComplaintByUser); Complaint complaintUpdateByIssuer = iodrApi.updateComplaint(requestId, updateComplaintByUser); System.out.println("Calling update a complaint by issuer API response :" + complaintUpdateByIssuer.toString()); } catch (Exception e) { System.out.println(e); Assert.assertNotNull(e); } } @Test public void testFetchComplaintBySerachCriteriaAPIWithPositiveScenario() { try { String requestId = UUID.randomUUID().toString(); FetchComplaintsBySearchCriteria fetchComplaintsBySearchCriteria = getComplaintsBySeachParamRequest(); System.out.println("Calling get a complaint Details API with requestID : " + requestId + " and request payload : " + fetchComplaintsBySearchCriteria.toString()); Search complaintSearchResponse = iodrApiClientForEncryptionDecryption.getComplaintsBySearchParam(requestId, fetchComplaintsBySearchCriteria); System.out.println("Calling get a complaint Details API response : " + complaintSearchResponse.toString()); } catch (Exception e) { System.out.println(e); Assert.assertNotNull(e); } } @Test public void testFetchComplaintBySerachCriteriaAPIWithNegativeScenario() { try { String requestId = UUID.randomUUID().toString(); FetchComplaintsBySearchCriteria fetchComplaintsBySearchCriteria = getComplaintsBySeachParamRequest(); fetchComplaintsBySearchCriteria.setSearchValue(""); System.out.println("Calling get a complaint Details API with requestID : " + requestId + " and request payload : " + fetchComplaintsBySearchCriteria.toString()); Search complaintSearchResponse = iodrApiClientForEncryptionDecryption.getComplaintsBySearchParam(requestId, fetchComplaintsBySearchCriteria); System.out.println("Calling get a complaint Details API response : " + complaintSearchResponse.toString()); } catch (Exception e) { System.out.println(e); Assert.assertNotNull(e); } } private CreateComplaint getCreateComplaintRequest() { CreateComplaint createComplaint = new CreateComplaint(); createComplaint.setComplaintType(CreateComplaint.ComplaintTypeEnum.ATM); createComplaint.setTransactionDate("2025-03-06"); createComplaint.setCardNumber("530837881010"); createComplaint.setTransactionAmount("9999.98"); return createComplaint; } // Validate Transaction Details API by Issuer Request payload private IODRTransactionValidation getValidateTransactionRequest() { IODRTransactionValidation iodrTransactionValidation = new IODRTransactionValidation(); iodrTransactionValidation.setTrackingNumber("OUD0AT0UAKDO"); iodrTransactionValidation.setRetrievalReferenceNumber("435465768995"); iodrTransactionValidation.setBanknetReferenceNumber("234354739"); iodrTransactionValidation.setApprovalCode("A1R4D8"); iodrTransactionValidation.setAcquirerICA("00000023162"); return iodrTransactionValidation; } // Update Complaint By Issuer or Acquirer API Request payload private UpdateComplaintByUser getUpdateComplaintByUserRequest() { UpdateComplaintByUser updateComplaintByIssuer = new UpdateComplaintByUser(); updateComplaintByIssuer.setComments("Complaint status updated"); updateComplaintByIssuer.setComplaintStatus(UpdateComplaintByUser.ComplaintStatusEnum.UNDER_INVESTIGATION); updateComplaintByIssuer.setTrackingNumber("OUD0AT0UAKDO"); return updateComplaintByIssuer; } // Get Complaint Details by Search criteria by Issuer or Acquirer private FetchComplaintsBySearchCriteria getComplaintsBySeachParamRequest() { FetchComplaintsBySearchCriteria fetchComplaintsBySearchCriteria = new FetchComplaintsBySearchCriteria(); fetchComplaintsBySearchCriteria.searchType(FetchComplaintsBySearchCriteria.SearchTypeEnum.DEFAULT); return fetchComplaintsBySearchCriteria; } } ``` 3. Once the project setup is completed, compile and run the project. Note: You have successfully completed the tutorial on how to generate the SDK and connect to the IODR API in Sandbox using the SDK. ## Encryption and decryption {#encryption-and-decryption} If the endpoint you are calling requires [encryption or decryption](https://developer.mastercard.com/platform/documentation/security-and-authentication/securing-sensitive-data-using-payload-encryption/), you need to configure an interceptor to encrypt the request payload or decrypt the response body. To configure the interceptor, load the certificate: * create the configuration object for encryption and decryption. ```java private JweConfig getEncryptionDecryptionConfig(String encryptionCertPath, String keyFile, String keyAlias, String password) { JweConfig config = null; try { Certificate encryptionCertificate = EncryptionUtils.loadEncryptionCertificate(encryptionCertPath); PrivateKey key = EncryptionUtils.loadDecryptionKey(keyFile, keyAlias, password); config = JweConfigBuilder.aJweEncryptionConfig().withEncryptionCertificate(encryptionCertificate) .withEncryptionPath("$", "$").withEncryptedValueFieldName("encryptedValue") .withDecryptionKey(key).withDecryptionPath("$.encryptedValue", "$") .build(); } catch (Exception e) { System.out.println(e); } return config; } ``` * Instantiate `IodrApi` with `getApiClient` with `enabledEncryptionDecryption` as true. ```Java IodrApi iodrApiClientForEncryptionDecryption = new IodrApi(getApiClient(true)); ``` * Use the following method to get the `ApiClient`. ```Java public ApiClient getApiClient(boolean enableEncryption) throws Exception { ApiClient client = new ApiClient(); String consumerKey = ""; String signingKeyFilePath = "./src/main/resources/client p12 file name downloaded on project creation>.p12"; String encryptionCertPath = "./src/main/resources/.pem"; String mcKeyFilePath = "./src/main/resources/.p12"; String signingKeyAlias = ""; String signingKeyPassword = ""; String mcKeyAlias = ""; String mcKeyPassword = ""; PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyFilePath, signingKeyAlias, signingKeyPassword); client.setBasePath("https://mtf.api.mastercard.co.in/iodr"); client.setDebugging(true); if (enableEncryption) { client.setHttpClient(client.getHttpClient().newBuilder() .addInterceptor(new OkHttpJweInterceptor(getEncryptionDecryptionConfig(encryptionCertPath,mcKeyFilePath, mcKeyAlias, mcKeyPassword))) .addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey)).build()); } else { client.setHttpClient(client.getHttpClient().newBuilder() .addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey)).build()); } return client; } ``` ### Generate a unique Request-ID {#generate-a-unique-request-id} The Request-ID header identifies each API request. This helps in tracking and logging failed requests, debug, and trace issues. Use the UUID class in Java to generate a random UUID. ```java import java.util.UUID; public class RequestIdGenerator { public static String generateRequestId() { return UUID.randomUUID().toString(); } } ``` Note: For a walkthrough of the first Sandbox call, see [Make your first Sandbox request](https://developer.mastercard.com/india-online-dispute-resolution/documentation/quick-start-guide/index.md#step-3-make-your-first-sandbox-request).