# Reference Application Tutorial
source: https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/tutorials-and-guides/reference-app-tutorial/index.md

## Overview {#overview}

This tutorial shows you how to generate an API client for the Alerts for Merchants API. You'll build an application that makes an API call to the Alerts service to retrieve details about a specific merchant and transaction.

### What you need {#what-you-need}

* [Mastercard Developers Account](https://developer.mastercard.com/dashboard) with access to the Alerts Merchant API
* A text editor or IDE
* [Apache Maven 3.3+](https://maven.apache.org/download.cgi)
* JDK 17 or newer version
  * Make sure the `JAVA_HOME` environment variable matches the location of your Java installation.

### Generate API keys {#generate-api-keys}

To call these APIs, a consumer key and .p12 files are required from your
[Mastercard Developers](https://developer.mastercard.com/dashboard) project. If you haven't yet done so, first generate the Sandbox credentials that your server uses to communicate with Mastercard and the Alerts for Merchants API client. See our [Quick Start Guide](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/tutorials-and-guides/quick-start-guide/index.md) for the steps required to set up the Sandbox project and download the keys.

## Step-By-Step Guide {#step-by-step-guide}

To complete this tutorial, you can either start from scratch using the [Spring Getting Started](https://spring.io/guides) guides and complete each step, or you can bypass the basic setup steps that are already familiar to you. Either way, you end up with working code.

To skip the basics, do the following:

* Access the source code for this tutorial from this zip file: [alerts-reference.zip](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/uploads/alerts-reference.zip) (275KB)
* Go to [Configure Resources](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/tutorials-and-guides/reference-app-tutorial/index.md#step-2-configure-resources).

### Step 1: Create or import a Maven project {#step-1-create-or-import-a-maven-project}

1. Start by creating a Maven project from scratch or importing an existing project.

   * If creating a project from scratch, in Maven, select **File** \> **New** \> **Project** to create a new Maven project. This sets up your directory structure automatically.
   * If importing the project, then select **File** \> **Open** \> \<*path to extracted alert-reference source code* \>.   

2. Select **Project SDK** , then select **Next**.

3. If not already present, enter a **GroupId** , **ArtifactId** , and **Version**. These are required to configure a Maven project.

4. Select **Next**.

5. Enter a project **Name** , such as *alerts-reference* , and a **Location** .
   ![Create new Maven project for Alerts for Merchants API](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/maven-create-project.png)

6. Select **Create**.

### Step 2: Configure resources {#step-2-configure-resources}

1. If required, download and add the `OpenAPI Specification YAML` file into your Maven project's `resources/swagger` folder: [alert-outcome-specs_inbound.yaml](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/swagger/alert-outcome-specs_inbound.yaml) (13KB).
2. Place the .p12 file on the `{local-file-path}` of your system. The .p12 file was generated when you created the [Sandbox Signing Keys](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/tutorials-and-guides/quick-start-guide/index.md#sandbox-oauth-credentials) within your project in Mastercard Developers.

Your Maven project directory should look like this. (Note that the *.idea* and *.iml* items are generated and used by IntelliJ IDEA):

![Create new Maven project for Alerts for Merchants API](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/maven-project-directory.png)

### Step 3: Update the application configuration {#step-3-update-the-application-configuration}

Edit the `src/main/resources/application.properties` file to update these property values:

* `alerts.cert.path` to `file:configkeys/{p.12 file name}`.

* `alerts.consumer.key`. Use the **CONSUMER KEY** shown in the **Sandbox Keys** and **Production Keys** section of your project page in [Mastercard Developers](https://developer.mastercard.com/dashboard).

* `alerts.keyalias` to the key alias.

* `alerts.keyalias.password` to the password you received from Mastercard when you created your project.

* `alerts.api.base.path` to the appropriate base path. Refer to comments in the `application.properties` file.

### Step 4: Generate an API client project {#step-4-generate-an-api-client-project}

The *pom.xml* file already contains all the details, but if you're creating a project from scratch, then add the following plugin to your project's *pom.xml* file to generate an API client library.

```Maven
<!-- https://mvnrepository.com/artifact/org.openapitools/openapi-generator-maven-plugin -->
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>6.0.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/swagger/alerts-reference-api.yaml</inputSpec>
                <generatorName>java</generatorName>
                <library>okhttp-gson</library>
                <generateApiTests>false</generateApiTests>
                <generateModelTests>false</generateModelTests>
                <configOptions>
                    <sourceFolder>src/gen/java/main</sourceFolder>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
```

Note: If you created your project from scratch, also add the following libraries to the dependencies section of your *pom.xml* file. Otherwise you can use the existing pom file in the project.

```Maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mastercard.ethoca</groupId>
    <artifactId>alerts-reference</artifactId>
    <version>1.0.0</version>
    <name>alerts-reference-app</name>
    <description>Alerts Reference Application</description>
    <packaging>jar</packaging>

    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <swagger-core-version>1.6.11</swagger-core-version>
        <oauth1-signer-version>1.2.3</oauth1-signer-version>
        <gson-fire-version>1.8.5</gson-fire-version>
        <gson-version>2.10.1</gson-version>
        <threetenbp-version>1.3.5</threetenbp-version>
        <junit-version>4.12</junit-version>
        <okhttp-version>4.10.0</okhttp-version>
        <spring-boot-starter-thymeleaf-version>2.7.15</spring-boot-starter-thymeleaf-version>
        <spring-boot-starter-web>2.7.15</spring-boot-starter-web>
        <spring-boot-devtools-version>2.7.15</spring-boot-devtools-version>
        <lombok-version>1.18.28</lombok-version>
        <spring-boot-starter-test-version>2.7.15</spring-boot-starter-test-version>
        <org.apache.oltu.oauth2.client-version>1.0.1</org.apache.oltu.oauth2.client-version>
        <spotbugs-annotations-version>4.2.0</spotbugs-annotations-version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.7.15</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>${spring-boot-starter-thymeleaf-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring-boot-starter-web}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>${lombok-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring-boot-starter-test-version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson-version}</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.7.0</version>
        </dependency>
        <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>io.gsonfire</groupId>
            <artifactId>gson-fire</artifactId>
            <version>${gson-fire-version}</version>
        </dependency>
        <dependency>
            <groupId>com.mastercard.developer</groupId>
            <artifactId>oauth1-signer</artifactId>
            <version>${oauth1-signer-version}</version> <!-- See: https://github.com/Mastercard/oauth1-signer-java/releases -->
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.github.spotbugs</groupId>
            <artifactId>spotbugs-annotations</artifactId>
            <version>${spotbugs-annotations-version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.ant</artifactId>
            <version>0.8.7</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <useIncrementalCompilation>false</useIncrementalCompilation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <!--suppress UnresolvedMavenProperty -->
                    <argLine>${surefireArgLine}</argLine>
                    <reuseForks>false</reuseForks>
                    <excludes>
                        <exclude>**/*IT.java</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <!-- suppress UnresolvedMavenProperty !-->
                    <argLine>${failsafeArgLine}</argLine>
                    <reuseForks>false</reuseForks>
                    <skipITs>${skipITs}</skipITs>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.7</version>
                <configuration>
                    <excludes>
                        <exclude>**/model/*</exclude>
                        <exclude>**/Constants.java</exclude>
                    </excludes>
                </configuration>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-ut.exec</destFile>
                            <propertyName>surefireArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-ut.exec</dataFile>
                            <outputDirectory>${project.build.directory}/jacoco-unit-test-coverage-report</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <destFile>${project.build.directory}/jacoco-int-it.exec</destFile>
                            <propertyName>failsafeArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/jacoco-int-it.exec</dataFile>
                            <outputDirectory>${project.build.directory}/jacoco-integration-test-coverage-report</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>merge-results</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>merge</goal>
                        </goals>
                        <configuration>
                            <fileSets>
                                <fileSet>
                                    <directory>${project.build.directory}</directory>
                                    <includes>
                                        <include>*.exec</include>
                                    </includes>
                                    <excludes>
                                        <exclude>merged.exec</exclude>
                                    </excludes>
                                </fileSet>
                            </fileSets>
                            <destFile>${project.build.directory}/merged.exec</destFile>
                        </configuration>
                    </execution>
                    <execution>
                        <id>create-merged-report</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <dataFile>${project.build.directory}/merged.exec</dataFile>
                            <outputDirectory>${project.build.directory}/jacoco-merged-test-coverage-report</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
            </plugin>
            <plugin>
                <groupId>org.openapitools</groupId>
                <artifactId>openapi-generator-maven-plugin</artifactId>
                <version>6.0.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <inputSpec>${project.basedir}/src/main/resources/swagger/alerts-reference-api.yaml</inputSpec>
                            <generatorName>java</generatorName>
                            <skipValidateSpec>true</skipValidateSpec>
                            <configOptions>
                                <sourceFolder>src/gen/java/main</sourceFolder>
                            </configOptions>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.13</version>
                <configuration>
                    <executable>true</executable>
                    <mainClass>com.mastercard.ethoca.alerts.Application</mainClass>
                    <layout>JAR</layout>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <distributionManagement>
        <repository>
            <id>${distribution.repository.id}</id>
            <url>${distribution.repository.url}</url>
        </repository>
    </distributionManagement>
</project>
```

### Step 5: Generate the API client sources {#step-5-generate-the-api-client-sources}

You now have all the dependencies you need to generate sources. To do this, use one of these methods:

#### Method 1 {#method-1}

1. In IntelliJ IDEA, open the Maven window by selecting **View** \> **Tool Windows** \> **Maven**.
2. Select **Reimport All Maven Projects** and **Generate Sources and Update Folders for All Projects**.

#### Method 2 {#method-2}

1. In the same menu, navigate to the commands by selecting **{Project name}** \> **Lifecycle**.
2. Select **clean and compile** then select **Run Maven Build**.

Alternatively, you can navigate to the root directory of the project within a terminal window and run the `mvn clean compile` command.

After you finish, there should be a new folder named *target* within your root directory. This folder contains classes generated for the schemas and API calls defined within the OpenAPI Specification.

![Target folder](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/target-folder.png)
Note: OpenAPI Generator supports several HTTP clients and frameworks for Java (such as Jersey, OkHttp, RestTemplate, and Retrofit). In this tutorial, we chose to use `okhttp-gson`. Refer to our [Java library on GitHub](https://github.com/Mastercard/oauth1-signer-java#integrating-with-openapi-generator-api-client-libraries) for a list of supported options.

### Step 6: Build and execute {#step-6-build-and-execute}

After you've set the correct properties, you can build the application. Navigate to the project's base directory from a terminal window and run the following command.

`mvn clean package spring-boot:repackage`

After the project builds successfully, you'll see the following content in `${APP_LAUNCH_DIR}/target/`:

```Maven
/                          the ${APP_LAUNCH_DIR}/target/
xxx                                     # other generated resources
alerts-reference-1.0.0.jar              # generated application jar file

xxx/                                  # other build time intermediate directories
xxx                                   # other build time intermediate files
```

To start the application, go to the command prompt and change your working directory to the *alerts-reference* extracted directory that contains the target folder. Then run the following command:

`$: java -jar target/alerts-reference-1.0.0.jar`

You are now running an application that uses the Alerts Merchant API Service.

#### Running the application using an IDE {#running-the-application-using-an-ide}

Select **Application.java** to run it in your IDE.

![Run app in IDE](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/run-application-in-ide.png)

### Send requests to sandbox {#send-requests-to-sandbox}

After successful execution of the application, you can see the home page accessible on `http://localhost:8080/main`. You can now send requests to the sandbox alert service using this UI application.

1. Select **Outcomes** and add the request payload in the text area.

2. Validate a JSON by selecting **Validate**.

   ![Add request payload in Outcomes UI](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/add-request-payload-2.png)
3. If the JSON is valid, you can select **Submit** and the response is shown with the status code.

   **Successful**
   ![Response returned with status code 200](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/response-with-status-code.png)

   **Failed**
   ![Response returned with status code 400](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/response-with-status-code-fail.png)
4. You can choose to **View Request** or **View Response** if you'd like.

   ![View the request and response](https://static.developer.mastercard.com/content/ethoca-alerts-for-merchants/documentation/img/view-request-and-resonse.png)

Here is an example request and response from our provided [test case data](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/testing/index.md).

##### Request {#request}

```JSON
{
    "outcomes": [
        {
            "alertId": "C14XF5HIGYBM883ASUL7VFGCN",
            "outcome": "PARTIALLY_STOPPED",
            "refundStatus": "REFUNDED",
            "refund": {
                "amount": {
                    "value": "22.43",
                    "currencyCode": "USD"
                },
                "type": "REFUND",
                "timestamp": "2023-03-22T18:45:23.123Z",
                "transactionId": "23aer543245678984ew39awse0",
                "acquirerReferenceNumber": "9.876543245678987e+22"
            },
            "amountStopped": {
                "value": "361.56",
                "currencyCode": "USD"
            },
            "comments": "Refunded via transactionId XXX on YYY",
            "actionTimestamp": "2023-03-22T18:45:23.123Z"
        },
        {
            "alertId": "C17XF5HIGYBM883ASUL7VFGCN",
            "outcome": "PARTIALLY_STOPPED",
            "refundStatus": "REFUNDED",
            "refund": {
                "amount": {
                    "value": "361.56",
                    "currencyCode": "USD"
                },
                "type": "REFUND",
                "timestamp": "2023-03-22T18:45:23.123Z",
                "transactionId": "23aer543245678984ew39awse0",
                "acquirerReferenceNumber": "9.876543245678987e+22"
            },
            "amountStopped": {
                "value": "361.56",
                "currencyCode": "USD"
            },
            "comments": "Refunded via transactionId XXX on YYY",
            "actionTimestamp": "2023-03-22T18:45:23.123Z"
        }
    ]
}
```

##### Response {#response}

```JSON
{
	"outcomeResponses": [
		{
			"alertId": "C14XF5HIGYBM883ASUL7VFGCN",
			"status": "SUCCESS"
		},
		{
			"alertId": "C16XF5HIGYBM883ASUL7VFGCN",
			"status": "SUCCESS"
		},
		{
			"alertId": "C17XF5HIGYBM883ASUL7VFGCN",
			"status": "SUCCESS"
		}
	]
}
```

### Configuration for multiple environments {#configuration-for-multiple-environments}

You can configure the application to support multiple environments. If you want to support the sandbox and production environments, and the application will be launched from within `APP_LAUNCH_DIR` (the current directory when launching the application), then you can follow these steps:

1. Copy `${REF_APP_ROOT}/src/main/resources/application.properties` to `${APP_LAUNCH_DIR}/application-sandbox.properties`.

2. Update `${APP_LAUNCH_DIR}/application-sandbox.properties`, according to the inline comments.

3. Run the application as follows:

       cd ${APP_LAUNCH_DIR}
       # java -Dactive.profile=sandbox -jar path/to/alert-reference-1.0.0.jar
       # If APP_LAUNCH_DIR == REF_APP_ROOT, then
       java -Dactive.profile=sandbox -jar target/alert-reference-1.0.0.jar

To run against the prod environment, repeat steps 1 to 3. Replace *sandbox* with *prod* wherever applicable.

## Next Steps {#next-steps}

When ready, you can convert your sandbox keys to production.

* Log into your [Mastercard Developers Account](https://developer.mastercard.com/account/log-in) and navigate to **My Projects**.
* Request Production access for your project, which requires approval from Mastercard and assistance from the [Ethoca Customer Delivery Team](mailto:customerdelivery@ethoca.com).   

You can also check out these other articles for guidance on interacting with the Alerts for Merchants API:

* [API Basics](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/api-basics/index.md)
* [API Reference](https://developer.mastercard.com/ethoca-alerts-for-merchants/documentation/api-reference/index.md)
