diff --git a/.docker/db/scripts/1_create_account_management_db.sql b/.docker/db/scripts/1_create_account_management_db.sql
index b90aa18027cfa6753b677b80cd98a846c53b091f..61285b82315567a7d903faca4ba0cb7e6e5fbff2 100644
--- a/.docker/db/scripts/1_create_account_management_db.sql
+++ b/.docker/db/scripts/1_create_account_management_db.sql
@@ -31,6 +31,7 @@ CREATE TABLE IF NOT EXISTS scheduled_payment
     source_account_id      BIGINT,
     target_account_id      BIGINT,
     amount                 DECIMAL,
+    currency_code          VARCHAR(3),
     recurrence_type        VARCHAR(50),
     recurrence_payment_day INTEGER
 );
diff --git a/.docker/db/scripts/1_create_transaction_db.sql b/.docker/db/scripts/1_create_transaction_db.sql
index 40a610c02c8d2627ff0852fd7329d86cd213e452..03191b75450e85570ebfda3f85145e222995c92d 100644
--- a/.docker/db/scripts/1_create_transaction_db.sql
+++ b/.docker/db/scripts/1_create_transaction_db.sql
@@ -5,7 +5,7 @@ SET SEARCH_PATH TO bank_transaction;
 
 CREATE TABLE IF NOT EXISTS proc_transaction
 (
-    proc_uuid  UUID PRIMARY KEY,
+    trans_uuid UUID PRIMARY KEY,
     acc_source VARCHAR(255),
     acc_target VARCHAR(255),
     type       VARCHAR(255),
@@ -14,3 +14,10 @@ CREATE TABLE IF NOT EXISTS proc_transaction
     detail_msg VARCHAR(255)
 );
 
+CREATE TABLE IF NOT EXISTS proc_reg
+(
+    proc_uuid   UUID PRIMARY KEY,
+    status_when TIMESTAMP,
+    status      VARCHAR(255),
+    status_info VARCHAR(255)
+);
\ No newline at end of file
diff --git a/.docker/db/scripts/2_generate_account_management_db.sql b/.docker/db/scripts/2_generate_account_management_db.sql
index b061fe00fb6b74d78e6927a1c5e300ce08d2fcc5..2f473f8352c8b6491090bf016226cd4ae85c1684 100644
--- a/.docker/db/scripts/2_generate_account_management_db.sql
+++ b/.docker/db/scripts/2_generate_account_management_db.sql
@@ -20,10 +20,10 @@ VALUES (3656018305580485508, 'a5dc3241-71c9-4594-8a07-083c9c2b7b1c', 1, 1000, 0,
        (994, 'ACC4', 1, 1000, 1, 'CZK');
 
 
-INSERT INTO scheduled_payment (id, source_account_id, target_account_id, amount, recurrence_type, recurrence_payment_day)
+INSERT INTO scheduled_payment (id, source_account_id, target_account_id, amount, currency_code, recurrence_type, recurrence_payment_day)
 VALUES
-    (991, 2, 3, 100, 0, 2),
-    (992, 2, 3, 200, 0, 3),
-    (993, 3, 2, 1200, 1, 15);
+    (991, 2, 3, 100, 'EUR', 0, 2),
+    (992, 2, 3, 200, 'EUR', 0, 3),
+    (993, 3, 2, 1200, 'EUR', 1, 15);
 
 
diff --git a/.docker/db/scripts/2_generate_transaction_db.sql b/.docker/db/scripts/2_generate_transaction_db.sql
index 25302370fb20ba0a032e5078884b7557731c478a..bf1b81cad26f8433f771ce4a4c03bc3c6067518c 100644
--- a/.docker/db/scripts/2_generate_transaction_db.sql
+++ b/.docker/db/scripts/2_generate_transaction_db.sql
@@ -2,7 +2,7 @@ SET SEARCH_PATH TO bank_transaction;
 
 -- INSERT starting data
 
-INSERT INTO proc_transaction (proc_uuid, acc_source, acc_target, type, amount, curr_code, detail_msg)
+INSERT INTO proc_transaction (trans_uuid, acc_source, acc_target, type, amount, curr_code, detail_msg)
 VALUES ('00000000-0000-0000-0000-000000000001', '123456789', '987654321', 'TRANSFER', 100.00, 'USD', 'Dummy transfer 1'),
        ('00000000-0000-0000-0000-000000000002', '987654321', '123456789', 'DEPOSIT', 200.00, 'EUR', 'Dummy deposit 1'),
        ('00000000-0000-0000-0000-000000000003', '111111111', '222222222', 'WITHDRAWAL', 300.00, 'GBP', 'Dummy withdrawal 1'),
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/application/controller/AccountController.java b/account-management/src/main/java/cz/muni/pa165/banking/application/controller/AccountController.java
index 6df625abb9b54a7e11a41367cb1ddd971c9b04a3..dc2ed112fbc7c33a38667b730d73edf4aa1c0df5 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/application/controller/AccountController.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/application/controller/AccountController.java
@@ -1,16 +1,14 @@
 package cz.muni.pa165.banking.application.controller;
 
 import cz.muni.pa165.banking.account.management.AccountApi;
-import cz.muni.pa165.banking.account.management.dto.AccountDto;
-import cz.muni.pa165.banking.account.management.dto.NewAccountDto;
-import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentDto;
-import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentsDto;
+import cz.muni.pa165.banking.account.management.dto.*;
 import cz.muni.pa165.banking.application.facade.AccountFacade;
-import cz.muni.pa165.banking.exception.EntityNotFoundException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.time.LocalDate;
+
 @RestController
 public class AccountController implements AccountApi {
     
@@ -37,13 +35,13 @@ public class AccountController implements AccountApi {
 
     @Override
     public ResponseEntity<ScheduledPaymentsDto> getScheduledPayments(String accountNumber) {
-        ScheduledPaymentsDto payments;
-        try{
-            payments = accountFacade.findScheduledPaymentsByNumber(accountNumber);
-        }
-        catch (EntityNotFoundException  e){
-            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-        }
+        ScheduledPaymentsDto payments = accountFacade.findScheduledPaymentsByNumber(accountNumber);
+        return ResponseEntity.ok(payments);
+    }
+
+    @Override
+    public ResponseEntity<ScheduledPaymentsDto> getScheduledPaymentsOf(LocalDate date) {
+        ScheduledPaymentsDto payments = accountFacade.scheduledPaymentsOfDay(date);
         return ResponseEntity.ok(payments);
     }
 
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/application/controller/UserController.java b/account-management/src/main/java/cz/muni/pa165/banking/application/controller/UserController.java
index 261ba6df0f3c6e7cd4ae6660319e6e0197829934..9c2bfb02981aefc5e2852ebc5464dd3f5f289660 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/application/controller/UserController.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/application/controller/UserController.java
@@ -4,7 +4,6 @@ import cz.muni.pa165.banking.account.management.UserApi;
 import cz.muni.pa165.banking.account.management.dto.NewUserDto;
 import cz.muni.pa165.banking.account.management.dto.UserDto;
 import cz.muni.pa165.banking.application.facade.UserFacade;
-import cz.muni.pa165.banking.exception.EntityNotFoundException;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.RestController;
@@ -25,13 +24,7 @@ public class UserController implements UserApi{
 
     @Override
     public ResponseEntity<UserDto> findUserById(Long userId) {
-        UserDto user;
-        try{
-            user = userFacade.findById(userId);
-        }
-        catch (EntityNotFoundException e){
-            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
-        }
+        UserDto user = userFacade.findById(userId);
         return ResponseEntity.ok(user);
     }    
     
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/application/facade/AccountFacade.java b/account-management/src/main/java/cz/muni/pa165/banking/application/facade/AccountFacade.java
index f8e1a774987685927aeaeea7f33f5023a4876cec..9b6077cd7be1b0bf72b56fa407ba3f85b2640867 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/application/facade/AccountFacade.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/application/facade/AccountFacade.java
@@ -1,9 +1,6 @@
 package cz.muni.pa165.banking.application.facade;
 
-import cz.muni.pa165.banking.account.management.dto.AccountDto;
-import cz.muni.pa165.banking.account.management.dto.NewAccountDto;
-import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentDto;
-import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentsDto;
+import cz.muni.pa165.banking.account.management.dto.*;
 import cz.muni.pa165.banking.application.mapper.DtoMapper;
 import cz.muni.pa165.banking.application.service.AccountService;
 import cz.muni.pa165.banking.domain.account.Account;
@@ -12,7 +9,9 @@ import cz.muni.pa165.banking.exception.EntityNotFoundException;
 import cz.muni.pa165.banking.exception.UnexpectedValueException;
 import org.springframework.stereotype.Component;
 
+import java.time.LocalDate;
 import java.util.Currency;
+import java.util.List;
 
 
 @Component
@@ -60,4 +59,13 @@ public class AccountFacade {
     public AccountDto findByAccountNumber(String accountNumber) {
         return mapper.map(accountService.findByNumber(accountNumber));
     }
+
+    public ScheduledPaymentsDto scheduledPaymentsOfDay(LocalDate date) {
+        List<ScheduledPayment> payments = accountService.scheduledPaymentsOfDay(date);
+        ScheduledPaymentsDto result = new ScheduledPaymentsDto();
+        result.setScheduledPayments(payments.stream()
+                .map(mapper::map)
+                .toList());
+        return result;
+    }
 }
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java b/account-management/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
index 9c7eb93419aaff60a532dd77907173c90dfdf92f..088749afdc9b203eb2f7aabaa31a9fe2f5bc60f5 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
@@ -45,6 +45,8 @@ public interface DtoMapper {
         return result;
     }
     
+    ScheduledPaymentDto map(ScheduledPayment scheduledPayment);
+    
     ScheduledPaymentType map(RecurrenceType type);
 
     RecurrenceType map(ScheduledPaymentType type);
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/application/service/AccountService.java b/account-management/src/main/java/cz/muni/pa165/banking/application/service/AccountService.java
index af6d7ec26d4a059a7ba42445e4aff873552ff721..7966ac928fa96e72dc37f10086edfbcc5c6aba97 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/application/service/AccountService.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/application/service/AccountService.java
@@ -6,15 +6,16 @@ import cz.muni.pa165.banking.domain.account.repository.AccountRepository;
 import cz.muni.pa165.banking.domain.scheduled.ScheduledPayment;
 import cz.muni.pa165.banking.domain.scheduled.ScheduledPaymentProjection;
 import cz.muni.pa165.banking.domain.scheduled.recurrence.Recurrence;
+import cz.muni.pa165.banking.domain.scheduled.recurrence.RecurrenceQuerySpecificationBuilder;
 import cz.muni.pa165.banking.domain.scheduled.recurrence.RecurrenceType;
 import cz.muni.pa165.banking.domain.scheduled.repository.ScheduledPaymentRepository;
 import cz.muni.pa165.banking.domain.user.repository.UserRepository;
 import cz.muni.pa165.banking.exception.EntityNotFoundException;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -74,6 +75,7 @@ public class AccountService {
         newScheduledPayment.setSourceAccountId(senderAccount.getId());
         newScheduledPayment.setTargetAccountId(receiverAccount.getId());
         newScheduledPayment.setAmount(amount);
+        newScheduledPayment.setCurrencyCode(senderAccount.getCurrency().getCurrencyCode());
 
         Recurrence recurrence = new Recurrence();
         recurrence.setType(recurrenceType);
@@ -109,4 +111,7 @@ public class AccountService {
                 .toList();
     }
 
+    public List<ScheduledPayment> scheduledPaymentsOfDay(LocalDate date) {
+        return scheduledPaymentsRepository.findAll(RecurrenceQuerySpecificationBuilder.forDay(date));
+    }
 }
diff --git a/account-management/src/main/java/cz/muni/pa165/banking/domain/scheduled/ScheduledPayment.java b/account-management/src/main/java/cz/muni/pa165/banking/domain/scheduled/ScheduledPayment.java
index 67aeaa580470bf646a0f7518726dce3e1f50a426..ce7404d5380bb1bbe889ee4b445d749844de8cb8 100644
--- a/account-management/src/main/java/cz/muni/pa165/banking/domain/scheduled/ScheduledPayment.java
+++ b/account-management/src/main/java/cz/muni/pa165/banking/domain/scheduled/ScheduledPayment.java
@@ -22,6 +22,9 @@ public class ScheduledPayment {
     
     private BigDecimal amount;
 
+    @Column(name = "currency_code")
+    private String currencyCode;
+    
     @Embedded
     @AttributeOverrides({
             @AttributeOverride(name = "type", column = @Column(name = "recurrence_type")),
@@ -65,6 +68,14 @@ public class ScheduledPayment {
         this.amount = amount;
     }
 
+    public String getCurrencyCode() {
+        return currencyCode;
+    }
+
+    public void setCurrencyCode(String currencyCode) {
+        this.currencyCode = currencyCode;
+    }
+
     public Recurrence getRecurrence() {
         return recurrence;
     }
diff --git a/account-query/src/main/java/cz/muni/pa165/banking/domain/report/StatisticalReport.java b/account-query/src/main/java/cz/muni/pa165/banking/domain/report/StatisticalReport.java
index ad06ee984adec9c4f43f2ae2e5d0034b5f65fee0..815a98879dc6cb91399cff31ff0c259fc814141c 100644
--- a/account-query/src/main/java/cz/muni/pa165/banking/domain/report/StatisticalReport.java
+++ b/account-query/src/main/java/cz/muni/pa165/banking/domain/report/StatisticalReport.java
@@ -19,7 +19,7 @@ public class StatisticalReport {
 
     private final TransactionStatistics withdrawalAmount = new TransactionStatistics(TransactionType.WITHDRAW);
 
-    private final TransactionStatistics crossAccountAmount = new TransactionStatistics(TransactionType.CROSS_ACCOUNT_PAYMENT);
+    private final TransactionStatistics crossAccountAmount = new TransactionStatistics(TransactionType.TRANSFER);
 
     private final TransactionStatistics creditAmount = new TransactionStatistics(TransactionType.CREDIT);
 
@@ -49,7 +49,7 @@ public class StatisticalReport {
             case REFUND -> refundAmount.AddAmount(transaction.getAmount());
             case DEPOSIT -> depositAmount.AddAmount(transaction.getAmount());
             case WITHDRAW -> withdrawalAmount.AddAmount(transaction.getAmount());
-            case CROSS_ACCOUNT_PAYMENT -> crossAccountAmount.AddAmount(transaction.getAmount());
+            case TRANSFER -> crossAccountAmount.AddAmount(transaction.getAmount());
         }
     }
 
diff --git a/account-query/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java b/account-query/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
index 2a1fb15b87e63a153fb22f837940e0b2bf5b7e6d..5d0988c86783f5f2da92ae27e580ff3c7b5ba064 100644
--- a/account-query/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
+++ b/account-query/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
@@ -11,7 +11,7 @@ public enum TransactionType {
 
     CREDIT,
 
-    CROSS_ACCOUNT_PAYMENT,
+    TRANSFER,
 
     REFUND
 
diff --git a/account-query/src/test/java/cz/muni/pa165/banking/domain/report/StatisticalReportTest.java b/account-query/src/test/java/cz/muni/pa165/banking/domain/report/StatisticalReportTest.java
index 1a56a8f4b0b34e30a3de7c6de4a2bb432a9d48cb..1b0418837ed7bac0a9a8baa4bdf49017c4320e9b 100644
--- a/account-query/src/test/java/cz/muni/pa165/banking/domain/report/StatisticalReportTest.java
+++ b/account-query/src/test/java/cz/muni/pa165/banking/domain/report/StatisticalReportTest.java
@@ -21,7 +21,7 @@ class StatisticalReportTest {
         Transaction tr3 = new Transaction(TransactionType.WITHDRAW, BigDecimal.ONE, OffsetDateTime.now(), new UUID(2, 2));
         Transaction tr5 = new Transaction(TransactionType.REFUND, BigDecimal.ONE, OffsetDateTime.now(), new UUID(2, 2));
         Transaction tr6 = new Transaction(TransactionType.DEPOSIT, BigDecimal.ONE, OffsetDateTime.now(), new UUID(2, 2));
-        Transaction tr7 = new Transaction(TransactionType.CROSS_ACCOUNT_PAYMENT, BigDecimal.ONE, OffsetDateTime.now(), new UUID(2, 2));
+        Transaction tr7 = new Transaction(TransactionType.TRANSFER, BigDecimal.ONE, OffsetDateTime.now(), new UUID(2, 2));
         report = new StatisticalReport(List.of(tr1, tr2, tr3, tr5, tr6, tr7));
     }
     @Test
@@ -59,7 +59,7 @@ class StatisticalReportTest {
         //Act
         TransactionStatistics statistics = report.getCrossAccountAmount();
         //Assert
-        assertThat(statistics.getType()).isEqualTo(TransactionType.CROSS_ACCOUNT_PAYMENT);
+        assertThat(statistics.getType()).isEqualTo(TransactionType.TRANSFER);
     }
     @Test
     public void whenGetAllStatsThenStatsOfAllTypesReturned(){
diff --git a/m2m-banking-api/account-management-api/openapi.yaml b/m2m-banking-api/account-management-api/openapi.yaml
index d2472c8698bfb7f9ae5adc9432241cdb24c67f14..18dc08b5a88034ae3478891cae54719840e15cde 100644
--- a/m2m-banking-api/account-management-api/openapi.yaml
+++ b/m2m-banking-api/account-management-api/openapi.yaml
@@ -129,6 +129,7 @@ components:
         - senderAccountNumber
         - receiverAccountNumber
         - amount
+        - currencyCode
         - type
         - day
       properties:
@@ -140,6 +141,8 @@ components:
           type: number
           format: decimal
           description: amount of money to send
+        currencyCode:
+          type: string
         type:
           $ref: '#/components/schemas/ScheduledPaymentType'
         day:
@@ -309,3 +312,25 @@ paths:
                 $ref: '#/components/schemas/ScheduledPaymentDto'
         "400":
           description: NOK
+  
+  /scheduled:
+    get:
+      tags:
+        - Account
+      summary: Scheduled payments of a day
+      operationId: getScheduledPaymentsOf
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              type: string
+              format: date
+              nullable: false
+      responses:
+        "200":
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ScheduledPaymentsDto'
\ No newline at end of file
diff --git a/m2m-banking-api/account-query-api/openapi.yaml b/m2m-banking-api/account-query-api/openapi.yaml
index 344ed566183609927723e57bc97646414b7b7065..1560488aea29fa5759c3b2ffc8fde8d219eef69a 100644
--- a/m2m-banking-api/account-query-api/openapi.yaml
+++ b/m2m-banking-api/account-query-api/openapi.yaml
@@ -17,7 +17,7 @@ components:
   schemas:
     TransactionType:
       type: string
-      enum: [ WITHDRAW, DEPOSIT, CREDIT, CROSS_ACCOUNT_PAYMENT, REFUND ]
+      enum: [ WITHDRAW, DEPOSIT, CREDIT, TRANSFER, REFUND ]
       description: type of transaction
     Transaction:
       title: A transaction
diff --git a/m2m-banking-api/transaction-api/openapi.yaml b/m2m-banking-api/transaction-api/openapi.yaml
index f44f9df748c9906e8b22027be1e05fb0b00526a9..d4bd661243056aa2e18d568f31dd93d02b813a7e 100644
--- a/m2m-banking-api/transaction-api/openapi.yaml
+++ b/m2m-banking-api/transaction-api/openapi.yaml
@@ -62,6 +62,28 @@ paths:
         '404':
           description: Resource or process by UUID not found
 
+  /transaction/v1/scheduled/trigger:
+    post:
+      tags:
+        - Transaction
+      operationId: executeSchedulePayments
+      summary: Trigger scheduled payments
+      description: |
+        Manual execution of scheduled payments for a given date.
+        The input date is optional, if none is provided then the current day is used.
+      parameters:
+        - in: query
+          name: date
+          schema:
+            type: string
+            format: date
+          required: false
+      responses: 
+        '200':
+          description: Executed
+        '500':
+          description: Failure
+
   /transaction/v1/revert:
     post:
       tags:
@@ -89,6 +111,119 @@ paths:
           description: Process found by UUID but not in expected state (PROCESSED)
         '404':
           description: Resource or process by UUID not found
+  
+  /process/v1/{uuid}/status:
+    get:
+      tags:
+        - Process
+      operationId: getProcessStatus
+      summary: Process Status
+      description: |
+        Method finds an existing process for a transaction request, returning all information about it's state
+        and further information regarding errors.
+      parameters:
+        - in: path
+          name: uuid
+          required: true
+          schema:
+            type: string
+            format: uuid
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ProcessStatusDto'
+        '404':
+          description: Process by UUID not found
+  
+  /processes/v1/{status}:
+    get:
+      tags: 
+        - Process
+      operationId: getProcessesOfState
+      summary: Processes in a state
+      description: Find a collection of Processes in a defined state
+      parameters:
+        - in: path
+          name: status
+          required: true
+          schema:
+            $ref: '#/components/schemas/StatusDto'
+      responses:
+        '200':
+          description: OK
+          content: 
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ProcessStatusListDto'
+  
+  /processes/v1/resolve/threshold:
+    get:
+      tags:
+        - Process
+      operationId: getDefaultThreshold
+      summary: Process resolution date threshold
+      description: Get the default threshold used by the system to mark unresolved processes as failed
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ThresholdDto'
+  
+  /processes/v1/resolve:
+    get:
+      tags:
+        - Process
+      operationId: getUnresolvedProcesses
+      summary: Unresolved processes
+      description: | 
+        Get a collection of unresolved processes to a given date. If no date is provided, the default threshold is used. 
+      parameters:
+        - in: query
+          name: date
+          schema:
+            type: string
+            format: date
+          required: false
+      responses: 
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ProcessStatusListDto'
+    patch:
+      tags:
+        - Process
+      operationId: resolveProcesses
+      summary: Fail unresolved processes
+      description: |
+        Mark unresolved processes as failed. The input date marks as the threshold below which processes
+        in the state CREATED or PENDING shall be marked as resolved by failure. The provided date must be
+        before the current day. If no date is provided, the default threshold is used.
+        Method returns a collection of Process UUID's, which have been resolved.
+      parameters:
+        - in: query
+          name: date
+          schema:
+            type: string
+            format: date
+          required: false
+      responses:
+        '200':
+          description: OK
+          content:
+            application/json:
+              schema:
+                type: array
+                items: 
+                  type: string
+                  format: uuid
+
 
 components: 
   schemas: 
@@ -99,6 +234,7 @@ components:
         - DEPOSIT
         - TRANSFER
         - SCHEDULED
+        - REFUND
       description: Enumaration defining a type for a transaction. Each type may have different certain implementations and validations.
       
     AccountDto:
@@ -156,4 +292,43 @@ components:
       allOf:
         - $ref: '#/components/schemas/ProcessDto'
         - $ref: '#/components/schemas/TransactionDto'
-        
\ No newline at end of file
+    
+    StatusDetailDto:
+      type: object
+      properties: 
+        created:
+          type: string
+          format: date-time
+        status:
+          $ref: '#/components/schemas/StatusDto'
+        information:
+          type: string
+      
+    ProcessStatusDto:
+      type: object
+      properties:
+        identifier:
+          type: string
+          format: uuid
+        status:
+          $ref: '#/components/schemas/StatusDetailDto'
+
+    ProcessStatusListDto:
+      type: object
+      properties: 
+        when:
+          type: string
+          format: date-time
+        processes:
+          type: array
+          items: 
+            $ref: '#/components/schemas/ProcessStatusDto'
+            
+    ThresholdDto:
+      type: object
+      properties:
+        message:
+          type: string
+        currentThreshold:
+          type: string
+          format: date
\ No newline at end of file
diff --git a/transaction-processor/.todo-list b/transaction-processor/.todo-list
deleted file mode 100644
index d425db5eed299212dc9db86d756977e27c3555cf..0000000000000000000000000000000000000000
--- a/transaction-processor/.todo-list
+++ /dev/null
@@ -1,10 +0,0 @@
-- externalize openapi contract into separate artifact
-- handler for cross-account transaction
-- exchange rate API for currency conversion
-- custom exception classes
-- handler for exceptions -> Controller Advice
-- implementation for status and rollback/revert of transaction
-
-
-- TESTS TESTS TESTS
-- review within teammates projects / branches (bude toho dost asi zejo)
\ No newline at end of file
diff --git a/transaction-processor/pom.xml b/transaction-processor/pom.xml
index 003a95d0efb68b5d8eab782c2201b3dca314a50e..32b296ccaab1bc14c5166ab4cfe993cb093bc468 100644
--- a/transaction-processor/pom.xml
+++ b/transaction-processor/pom.xml
@@ -88,11 +88,6 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-tx</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.mapstruct</groupId>
-            <artifactId>mapstruct-processor</artifactId>
-            <version>${org.mapstruct.version}</version>
-        </dependency>
 
         <!--   DB     -->
         <dependency>
@@ -124,6 +119,13 @@
             <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
             <version>2.3.0</version>
         </dependency>
+        
+        <!--   Test utils   -->
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     
     <build>
@@ -247,6 +249,11 @@
                     </execution>
                 </executions>
             </plugin>
+            <!-- run integration tests in "mvn verify" phase -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/AsyncMessagingConfiguration.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/AsyncMessagingConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..7146acc5621a547e260540d86fceab6af9af9b65
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/AsyncMessagingConfiguration.java
@@ -0,0 +1,20 @@
+package cz.muni.pa165.banking.application.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+@Configuration
+public class AsyncMessagingConfiguration {
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(5);
+        executor.setMaxPoolSize(10);
+        executor.setThreadNamePrefix("Async-");
+        executor.initialize();
+        return executor;
+    }
+    
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/ExchangeRateInitializer.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/ExchangeRateInitializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..8cff4df537ee02f65bfb276b16f110045be517f1
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/configuration/ExchangeRateInitializer.java
@@ -0,0 +1,39 @@
+package cz.muni.pa165.banking.application.configuration;
+
+import cz.muni.pa165.banking.domain.money.exchange.ExchangeRateService;
+import jakarta.annotation.PostConstruct;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.Currency;
+import java.util.List;
+
+@Component
+public class ExchangeRateInitializer {
+    
+    private final Logger logger = LoggerFactory.getLogger(ExchangeRateInitializer.class);
+    
+    private final ExchangeRateService exchangeRateService;
+
+    @Value("#{'${banking.apps.rates.initial.currencies}'.split(',')}")
+    private List<String> currencies;
+    
+    public ExchangeRateInitializer(ExchangeRateService exchangeRateService) {
+        this.exchangeRateService = exchangeRateService;
+    }
+    
+    @PostConstruct
+    void initialize() {
+        for (String currency : currencies) {
+            try {
+                // ignore result, just call service to trigger mechanism to cache data
+                exchangeRateService.getRate(Currency.getInstance(currency), Currency.getInstance(currency));
+            } catch (Exception e) {
+                logger.warn(String.format("Initializing exchange rates for %s failed. API might be unavailable!", currency));
+            }
+        }
+    }
+    
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/ProcessController.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/ProcessController.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a77544dab2fae1e7af813b35cc5a92c74dc7a19
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/ProcessController.java
@@ -0,0 +1,49 @@
+package cz.muni.pa165.banking.application.controller;
+
+import cz.muni.pa165.banking.application.facade.ProcessFacade;
+import cz.muni.pa165.banking.transaction.processor.ProcessApi;
+import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusDto;
+import cz.muni.pa165.banking.transaction.processor.dto.ProcessStatusListDto;
+import cz.muni.pa165.banking.transaction.processor.dto.StatusDto;
+import cz.muni.pa165.banking.transaction.processor.dto.ThresholdDto;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.UUID;
+
+@RestController
+public class ProcessController implements ProcessApi {
+    
+    private final ProcessFacade processFacade;
+
+    public ProcessController(ProcessFacade processFacade) {
+        this.processFacade = processFacade;
+    }
+
+    @Override
+    public ResponseEntity<ThresholdDto> getDefaultThreshold() {
+        return ResponseEntity.ok(processFacade.getDefaultThreshold());
+    }
+
+    @Override
+    public ResponseEntity<ProcessStatusDto> getProcessStatus(UUID uuid) {
+        return ResponseEntity.ok(processFacade.getProcessStatus(uuid));
+    }
+
+    @Override
+    public ResponseEntity<ProcessStatusListDto> getProcessesOfState(StatusDto status) {
+        return ResponseEntity.ok(processFacade.getProcessesOfState(status));
+    }
+
+    @Override
+    public ResponseEntity<ProcessStatusListDto> getUnresolvedProcesses(LocalDate date) {
+        return ResponseEntity.ok(processFacade.getUnresolvedProcesses(date));
+    }
+
+    @Override
+    public ResponseEntity<List<UUID>> resolveProcesses(LocalDate date) {
+        return ResponseEntity.ok(processFacade.resolveProcesses(date));
+    }
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/TransactionController.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/TransactionController.java
index af908faf0d588d58dce85daa6baf617e1dae317c..7cf6096ce8c7deafd6d15677d472791d83afe15a 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/TransactionController.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/controller/TransactionController.java
@@ -1,6 +1,7 @@
 package cz.muni.pa165.banking.application.controller;
 
 import cz.muni.pa165.banking.application.facade.TransactionFacade;
+import cz.muni.pa165.banking.application.service.ScheduledPaymentService;
 import cz.muni.pa165.banking.transaction.processor.TransactionApi;
 import cz.muni.pa165.banking.transaction.processor.dto.ProcessDetailDto;
 import cz.muni.pa165.banking.transaction.processor.dto.ProcessDto;
@@ -8,15 +9,19 @@ import cz.muni.pa165.banking.transaction.processor.dto.TransactionDto;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
+import java.time.LocalDate;
 import java.util.UUID;
 
 @RestController
 public class TransactionController implements TransactionApi {
     
     private final TransactionFacade facade;
+    
+    private final ScheduledPaymentService scheduledPaymentService;
 
-    public TransactionController(TransactionFacade facade) {
+    public TransactionController(TransactionFacade facade, ScheduledPaymentService scheduledPaymentService) {
         this.facade = facade;
+        this.scheduledPaymentService = scheduledPaymentService;
     }
 
 
@@ -38,4 +43,12 @@ public class TransactionController implements TransactionApi {
         return ResponseEntity.ok(revertingProcess);
     }
 
+    @Override
+    public ResponseEntity<Void> executeSchedulePayments(LocalDate date) {
+        if (date == null) {
+            date = LocalDate.now();
+        }
+        scheduledPaymentService.executeScheduledPayments(date);
+        return ResponseEntity.ok(null);
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/ProcessFacade.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/ProcessFacade.java
new file mode 100644
index 0000000000000000000000000000000000000000..5dfbc2257d46c01748cfc53b8a94ac8d5914371d
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/facade/ProcessFacade.java
@@ -0,0 +1,91 @@
+package cz.muni.pa165.banking.application.facade;
+
+import cz.muni.pa165.banking.application.service.ProcessService;
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.transaction.processor.dto.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.util.List;
+import java.util.UUID;
+
+@Component
+public class ProcessFacade {
+
+    @Value("${process.resolution.threshold}")
+    private int thresholdDays;
+
+    private final ProcessService service;
+
+    public ProcessFacade(ProcessService service) {
+        this.service = service;
+    }
+
+    public ThresholdDto getDefaultThreshold() {
+        return new ThresholdDto()
+                .message("The default threshold is set to be " + thresholdDays + " days ago.")
+                .currentThreshold(defaultThreshold());
+    }
+
+    public ProcessStatusDto getProcessStatus(UUID uuid) {
+        Process process = service.findByUuid(uuid);
+        return map(process);
+    }
+
+    public ProcessStatusListDto getProcessesOfState(StatusDto statusDto) {
+        OffsetDateTime now = OffsetDateTime.now();
+        Status status = Status.valueOf(statusDto.name());
+        List<Process> processes = service.processesWithStatus(status);
+
+        return new ProcessStatusListDto()
+                .when(now)
+                .processes(
+                        processes.stream()
+                                .map(this::map)
+                                .toList()
+                );
+    }
+
+    public ProcessStatusListDto getUnresolvedProcesses(LocalDate threshold) {
+        OffsetDateTime now = OffsetDateTime.now();
+        
+        if (threshold == null) {
+            threshold = defaultThreshold();
+        }
+        List<Process> processes = service.unresolvedProcessesToDate(threshold);
+
+        return new ProcessStatusListDto()
+                .when(now)
+                .processes(
+                        processes.stream()
+                                .map(this::map)
+                                .toList()
+                );
+    }
+
+    public List<UUID> resolveProcesses(LocalDate threshold) {
+        if (threshold == null) {
+            threshold = defaultThreshold();
+        }
+        return service.resolveProcesses(threshold);
+    }
+
+    private LocalDate defaultThreshold() {
+        return LocalDate.now().minusDays(thresholdDays);
+    }
+    
+    
+    private ProcessStatusDto map(Process process) {
+        return new ProcessStatusDto()
+                .identifier(process.getUuid())
+                .status(new StatusDetailDto()
+                        .created(process.getWhen().atOffset(ZoneOffset.UTC))
+                        .status(StatusDto.valueOf(process.getStatus().name()))
+                        .information(process.getInformation()));
+    }
+
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
index 91672d333dce23118e744ee9bafa6b0692817b1c..61a32d648c66532bb44338244270563cc036bc22 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/mapper/DtoMapper.java
@@ -36,18 +36,18 @@ public interface DtoMapper {
     default ProcessDto map(Process source) {
         ProcessDto dto = new ProcessDto();
         
-        dto.setIdentifier(source.uuid());
+        dto.setIdentifier(source.getUuid());
         dto.setStatus(map(source.getStatus()));
-        dto.setInfo(source.getStatusInformation());
+        dto.setInfo(source.getInformation());
         
         return dto;
     }
     
     default ProcessDetailDto map(Process process, Transaction transaction) {
         ProcessDetailDto dto = new ProcessDetailDto();
-        dto.identifier(process.uuid());
+        dto.identifier(process.getUuid());
         dto.status(map(process.getStatus()));
-        dto.info(process.getStatusInformation());
+        dto.info(process.getInformation());
         dto.source(map(transaction.getSource()));
         
         if (transaction.getTarget() != null) {
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/MessagingService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/MessagingService.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc38675999d1da2621818ef013418abbb58c478a
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/MessagingService.java
@@ -0,0 +1,40 @@
+package cz.muni.pa165.banking.application.messaging;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+@Service
+public class MessagingService {
+
+    private final Logger logger = LoggerFactory.getLogger(MessagingService.class);
+    
+    private final ProcessListener processListener;
+    
+    private final Queue<String> queue = new ConcurrentLinkedQueue<>();
+
+    public MessagingService(ProcessListener processListener) {
+        this.processListener = processListener;
+    }
+
+    public void addToQueue(String message) {
+        queue.add(message);
+        triggerRead();
+    }
+
+    @Async
+    void triggerRead() {
+        String message = queue.poll();
+        try {
+            processListener.onReceived(message);
+        } catch (JsonProcessingException e) {
+            logger.error("Error while processing message");
+        }
+    }
+
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessListener.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessListener.java
index d6bf974e6db5935d3006487872558fd08a0d2726..896cb904bebbc898371c3c4919ac58d35340e860 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessListener.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessListener.java
@@ -1,5 +1,7 @@
 package cz.muni.pa165.banking.application.messaging;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import cz.muni.pa165.banking.application.service.ProcessHandlerService;
 import cz.muni.pa165.banking.domain.messaging.ProcessRequest;
 import org.springframework.stereotype.Service;
@@ -7,18 +9,20 @@ import org.springframework.stereotype.Service;
 @Service
 public class ProcessListener {
     
-    private final ProcessHandlerService service;
+    private final ObjectMapper objectMapper;
+    
+    private final ProcessHandlerService processHandlerService;
 
-    public ProcessListener(ProcessHandlerService service) {
-        this.service = service;
+    public ProcessListener(ObjectMapper objectMapper, ProcessHandlerService processHandlerService) {
+        this.objectMapper = objectMapper;
+        this.processHandlerService = processHandlerService;
     }
 
-
-    // TODO Milestone-2/3, add messaging RabbitMq dependencies
-//    @RabbitListener(queues = "${messaging.exchange:process-request}")
-    public void onReceived(ProcessRequest message) {
+    public void onReceived(String message) throws JsonProcessingException {
         System.out.println(message);
-        service.handle(message);
+        
+        ProcessRequest request = objectMapper.readValue(message, ProcessRequest.class);
+        processHandlerService.handle(request);
     }
     
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java
index 44cdc381f250ed25160a6138efbbb89cf074ac8a..ff6cb7887ba981c17aa3a5b13b602b403dc14060 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/messaging/ProcessProducer.java
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import cz.muni.pa165.banking.domain.messaging.MessageProducer;
 import cz.muni.pa165.banking.domain.messaging.ProcessRequest;
 import cz.muni.pa165.banking.exception.ServerError;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.util.Map;
@@ -12,18 +11,14 @@ import java.util.Map;
 @Service
 public class ProcessProducer implements MessageProducer {
     
-    // TODO Milestone-2/3, add messaging RabbitMq dependencies
-//    private final RabbitTemplate template;
+    private final MessagingService messagingService;
     
     private final ObjectMapper mapper;
     
-    @Value("${messaging.exchange:process-request}")
-    private String EXCHANGE_NAME;
-
-    public ProcessProducer(ObjectMapper mapper) {
+    public ProcessProducer(MessagingService messagingService, ObjectMapper mapper) {
+        this.messagingService = messagingService;
         this.mapper = mapper;
     }
-
     
     @Override
     public void send(ProcessRequest data) {
@@ -39,7 +34,7 @@ public class ProcessProducer implements MessageProducer {
                     )
             );
         }
-//        template.convertAndSend(EXCHANGE_NAME, "", dataAsJsonString); 
+        messagingService.addToQueue(dataAsJsonString);
     }
     
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/AccountApiProxy.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/AccountApiProxy.java
new file mode 100644
index 0000000000000000000000000000000000000000..32a821ea408d90dbc09cb12634a0bd04feecd9e7
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/AccountApiProxy.java
@@ -0,0 +1,8 @@
+package cz.muni.pa165.banking.application.proxy;
+
+import cz.muni.pa165.banking.account.management.AccountApi;
+import org.springframework.cloud.openfeign.FeignClient;
+
+@FeignClient(url = "${banking.apps.management.url}", name = "AccountApi")
+public interface AccountApiProxy extends AccountApi {
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/Dummy.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/Dummy.java
deleted file mode 100644
index f832677ac863837007b4204d933050a48432f934..0000000000000000000000000000000000000000
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/Dummy.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package cz.muni.pa165.banking.application.proxy;
-
-import cz.muni.pa165.banking.account.query.CustomerServiceApi;
-import jakarta.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-@Service
-public class Dummy {
-    
-    @Autowired
-    private CustomerServiceApi customerServiceApi;
-    
-    @PostConstruct
-    public void test() {
-        var jj = customerServiceApi.getBalance("id1");
-        System.out.println("jozo");
-    }
-    
-}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/ExchangeRatesApi.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/ExchangeRatesApi.java
deleted file mode 100644
index 62e21b8cfc298e1426dc6df7719376b443ad0600..0000000000000000000000000000000000000000
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/ExchangeRatesApi.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package cz.muni.pa165.banking.application.proxy;
-
-// some proxy for a REST API, which contains real-time data about the currency rates
-// e.g. https://exchangeratesapi.io/
-// https://nordicapis.com/10-apis-for-currency-exchange-rates/
-public interface ExchangeRatesApi {
-    
-    // TODO nejake methods po vybere a nastudovani API
-    
-}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/SystemServiceApiProxy.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/SystemServiceApiProxy.java
new file mode 100644
index 0000000000000000000000000000000000000000..abe170cf37833e1cc22f0630e7e499634a0bf119
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/SystemServiceApiProxy.java
@@ -0,0 +1,8 @@
+package cz.muni.pa165.banking.application.proxy;
+
+import cz.muni.pa165.banking.account.query.SystemServiceApi;
+import org.springframework.cloud.openfeign.FeignClient;
+
+@FeignClient(url = "${banking.apps.query.url}", name = "SystemServiceApi")
+public interface SystemServiceApiProxy extends SystemServiceApi {
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRateResponseProcessor.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRateResponseProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5f4ba4daa30f50a81492d364a6dfd19a1d7cea0
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRateResponseProcessor.java
@@ -0,0 +1,46 @@
+package cz.muni.pa165.banking.application.proxy.rate;
+
+import cz.muni.pa165.banking.exception.UnexpectedValueException;
+
+import java.math.BigDecimal;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ExchangeRateResponseProcessor {
+    
+    public static Map<Currency, BigDecimal> process(Map<String, Object> response) {
+        if (!response.get("result").equals("success")) {
+            throw new UnexpectedValueException("Exchange rate API unavailable");
+        }
+
+        Map<String, Object> rates = (Map<String, Object>) response.get("conversion_rates");
+        
+        Map<Currency, BigDecimal> result = new HashMap<>();
+        for (String currencyCode : rates.keySet()) {
+            Currency currency;
+            try {
+                currency = Currency.getInstance(currencyCode);
+            } catch (Exception e) {
+                continue;
+            }
+            Object value = rates.get(currencyCode);
+            
+            BigDecimal rate;
+            if (value instanceof Integer val) {
+                rate = BigDecimal.valueOf(val);
+            } else if (value instanceof Double val) {
+                rate = BigDecimal.valueOf(val);
+            } else {
+                String strVal = value.toString();
+                double val = Double.parseDouble(strVal);
+                rate = BigDecimal.valueOf(val);
+            }
+            
+            result.put(currency, rate);
+        }
+        
+        return result;
+    }
+    
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRatesApi.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRatesApi.java
new file mode 100644
index 0000000000000000000000000000000000000000..f95e7581bf8b50a2ecce57a636848be9eee54228
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/proxy/rate/ExchangeRatesApi.java
@@ -0,0 +1,16 @@
+package cz.muni.pa165.banking.application.proxy.rate;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.Map;
+
+// https://app.exchangerate-api.com
+@FeignClient(name = "ExchangeRateApi", url = "${banking.apps.rates.url}")
+public interface ExchangeRatesApi {
+    
+    @GetMapping("/latest/{currency}")
+    Map<String, Object> getRatesOfCurrency(@RequestParam String currency);
+    
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryImpl.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryImpl.java
index 8d13fe11d21ad2ff03b54b8c1b0f139b40fa1460..e2bfb30fa23170147295ac2b403486bb97fa7882 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryImpl.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryImpl.java
@@ -2,31 +2,51 @@ package cz.muni.pa165.banking.application.repository;
 
 import cz.muni.pa165.banking.domain.process.Process;
 import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.exception.EntityNotFoundException;
 import org.springframework.stereotype.Repository;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.time.*;
+import java.util.*;
 
 @Repository
 public class ProcessRepositoryImpl implements ProcessRepository {
     
-    // TODO until app has no DB connection -> Milestone2
-    private final Map<UUID, Process> inmemoryDb = new HashMap<>();
+    private final ProcessRepositoryJpa repository;
+
+    public ProcessRepositoryImpl(ProcessRepositoryJpa repository) {
+        this.repository = repository;
+    }
 
     @Override
     public boolean idExists(UUID uuid) {
-        return inmemoryDb.containsKey(uuid);
+        return repository.existsById(uuid);
     }
 
     @Override
     public Process findById(UUID uuid) {
-        return inmemoryDb.get(uuid);
+        Optional<Process> process = repository.findById(uuid);
+        if (process.isEmpty()) {
+            throw new EntityNotFoundException(String.format("Process with UUID %s not found", uuid));
+        }
+        return process.get();
     }
 
     @Override
     public void save(Process process) {
-        inmemoryDb.put(process.uuid(), process);
+        repository.save(process);
+    }
+
+    @Override
+    public List<Process> findProcessOfStatus(Status status) {
+        return repository.findAllWithStatus(status);
+    }
+
+    @Override
+    public List<Process> findProcessesOfStatusUptoDate(Status status, LocalDate localDate) {
+        LocalDateTime endOfDay = localDate.atTime(LocalTime.MAX);
+        Instant instant = endOfDay.toInstant(ZoneOffset.UTC);
+        return repository.findByStatusAndDateBeforeEqual(status, instant);
     }
 
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpa.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpa.java
new file mode 100644
index 0000000000000000000000000000000000000000..7437ca16690f211b70a32e81031d822b37016d71
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpa.java
@@ -0,0 +1,21 @@
+package cz.muni.pa165.banking.application.repository;
+
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.time.Instant;
+import java.util.List;
+import java.util.UUID;
+
+public interface ProcessRepositoryJpa extends JpaRepository<Process, UUID> {
+    
+    @Query("SELECT p FROM Process p WHERE p.currentStatus.status = :status")
+    List<Process> findAllWithStatus(@Param("status") Status status);
+    
+    @Query("SELECT p FROM Process p WHERE p.currentStatus.status = :status AND p.currentStatus.when <= :date")
+    List<Process> findByStatusAndDateBeforeEqual(@Param("status") Status status, @Param("date") Instant date);
+
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/AccountServiceImpl.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/AccountServiceImpl.java
index a65602e495288f5f6f501cd3534608dfd332ce10..bf5f658d0c6a09be9272ac9f91633109da26b2db 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/AccountServiceImpl.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/AccountServiceImpl.java
@@ -1,5 +1,9 @@
 package cz.muni.pa165.banking.application.service;
 
+import cz.muni.pa165.banking.account.management.AccountApi;
+import cz.muni.pa165.banking.account.management.dto.AccountDto;
+import cz.muni.pa165.banking.account.query.CustomerServiceApi;
+import cz.muni.pa165.banking.account.query.SystemServiceApi;
 import cz.muni.pa165.banking.domain.account.Account;
 import cz.muni.pa165.banking.domain.remote.AccountService;
 import cz.muni.pa165.banking.domain.transaction.TransactionType;
@@ -7,31 +11,54 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.util.Currency;
+import java.util.Objects;
 import java.util.UUID;
 
 @Service
 public class AccountServiceImpl implements AccountService {
     
-    // TODO add proxies to other services of teammates and calls with validations
-    //  -> Milestone2
+    private final AccountApi accountApi;
     
+    private final CustomerServiceApi publicBalanceApi;
+    
+    private final SystemServiceApi privateBalanceApi;
+
+    public AccountServiceImpl(AccountApi accountApi, CustomerServiceApi publicBalanceApi, SystemServiceApi privateBalanceApi) {
+        this.accountApi = accountApi;
+        this.publicBalanceApi = publicBalanceApi;
+        this.privateBalanceApi = privateBalanceApi;
+    }
+
     @Override
     public Currency getAccountCurrency(Account account) {
-        return Currency.getInstance("EUR");
+        AccountDto accountDto = accountApi.findByAccountNumber(account.getAccountNumber()).getBody();
+        Objects.requireNonNull(accountDto);
+        return Currency.getInstance(accountDto.getCurrency());
     }
 
     @Override
     public boolean isValid(Account account) {
-        return true;
+        AccountDto accountDto = accountApi.findByAccountNumber(account.getAccountNumber()).getBody();
+        return accountDto != null;
     }
 
     @Override
     public boolean accountHasSufficientFunds(Account account, BigDecimal amount) {
-        return true;
+        BigDecimal currentBalance = publicBalanceApi.getBalance(account.getAccountNumber()).getBody();
+        return Objects.requireNonNull(currentBalance).compareTo(amount) >= 0;
     }
 
     @Override
-    public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information) {
-
+    public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account) {
+        privateBalanceApi.addTransactionToBalance(
+                account.getAccountNumber(),
+                amount,
+                processUuid,
+                convertType(transactionType)
+        );
+    }
+    
+    private cz.muni.pa165.banking.account.query.dto.TransactionType convertType(TransactionType type) {
+        return cz.muni.pa165.banking.account.query.dto.TransactionType.valueOf(type.name());
     }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ExchangeRateServiceImpl.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ExchangeRateServiceImpl.java
index fb0786f00141256104b45ed72d121537d958b834..4a0c3cad66afc4f126bee51e2567ba3a30b300e9 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ExchangeRateServiceImpl.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ExchangeRateServiceImpl.java
@@ -1,25 +1,34 @@
 package cz.muni.pa165.banking.application.service;
 
+import cz.muni.pa165.banking.application.proxy.rate.ExchangeRateResponseProcessor;
+import cz.muni.pa165.banking.application.proxy.rate.ExchangeRatesApi;
 import cz.muni.pa165.banking.domain.money.exchange.ExchangeRateService;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.util.Currency;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 @Service
 public class ExchangeRateServiceImpl implements ExchangeRateService {
     
-    // TODO call external API containing current information about exchange rates -> Milestone2
-    //  either actual API containing real data, or custom 'mock' API containing static data
-
-//    private final ExchangeRatesApi proxy;
+    private final ExchangeRatesApi exchangeRatesApi;
+    
+    Map<Currency, Map<Currency, BigDecimal>> exchangeRates = new ConcurrentHashMap<>();
 
-//    public ExchangeRateServiceImpl(ExchangeRatesApi proxy) {
-//        this.proxy = proxy;
-//    }
+    public ExchangeRateServiceImpl(ExchangeRatesApi exchangeRatesApi) {
+        this.exchangeRatesApi = exchangeRatesApi;
+    }
 
     @Override
     public BigDecimal getRate(Currency base, Currency target) {
-        return BigDecimal.ONE;
+        if (!exchangeRates.containsKey(base)) {
+            Map<String, Object> response = exchangeRatesApi.getRatesOfCurrency(base.getCurrencyCode());
+            exchangeRates.put(base, ExchangeRateResponseProcessor.process(response));
+        }
+        
+        return exchangeRates.get(base).get(target);
     }
+
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ProcessService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ProcessService.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf193f1ceb45e75bd0fd2a841cad01a76802833f
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ProcessService.java
@@ -0,0 +1,69 @@
+package cz.muni.pa165.banking.application.service;
+
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessOperations;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import cz.muni.pa165.banking.exception.UnexpectedValueException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+@Service
+public class ProcessService {
+    
+    private final ProcessRepository processRepository;
+
+    public ProcessService(ProcessRepository processRepository) {
+        this.processRepository = processRepository;
+    }
+    
+    public Process findByUuid(UUID uuid) {
+        return processRepository.findById(uuid);
+    }
+    
+    @Transactional(readOnly = true)
+    public List<Process> processesWithStatus(Status status) {
+        return processRepository.findProcessOfStatus(status);
+    }
+
+    @Transactional(readOnly = true)
+    public List<Process> unresolvedProcessesToDate(LocalDate threshold) {
+        List<Process> result = new ArrayList<>();
+        
+        result.addAll(processRepository.findProcessesOfStatusUptoDate(Status.CREATED, threshold));
+        result.addAll(processRepository.findProcessesOfStatusUptoDate(Status.PENDING, threshold));
+        
+        return result;
+    }
+    
+    @Transactional
+    public List<UUID> resolveProcesses(LocalDate localDate) {
+        LocalDate now = LocalDate.now();
+        if (!localDate.isBefore(now)) {
+            throw new UnexpectedValueException("Threshold should be atleast one day ago. Cannot resolve processes from today or the future");
+        }
+        
+        List<Process> staleProcesses = new ArrayList<>();
+        staleProcesses.addAll(processRepository.findProcessesOfStatusUptoDate(Status.CREATED, localDate));
+        staleProcesses.addAll(processRepository.findProcessesOfStatusUptoDate(Status.PENDING, localDate));
+
+        StatusInformation resolvedInfo = new StatusInformation(Instant.now(), Status.FAILED, "Resolved stale process as FAILED by system");
+        
+        List<UUID> resolved = new ArrayList<>();
+        for (Process process : staleProcesses) {
+            try {
+                ProcessOperations.changeState(process, resolvedInfo);
+                processRepository.save(process);
+                resolved.add(process.getUuid());
+            } catch (Exception ignored){}
+        }
+        
+        return resolved;
+    }
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ScheduledPaymentService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ScheduledPaymentService.java
new file mode 100644
index 0000000000000000000000000000000000000000..958ae04b3cde48317db1649a693ad5b163cb4d82
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/ScheduledPaymentService.java
@@ -0,0 +1,85 @@
+package cz.muni.pa165.banking.application.service;
+
+import cz.muni.pa165.banking.account.management.AccountApi;
+import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentDto;
+import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentsDto;
+import cz.muni.pa165.banking.domain.account.Account;
+import cz.muni.pa165.banking.domain.messaging.MessageProducer;
+import cz.muni.pa165.banking.domain.money.Money;
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessFactory;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
+import cz.muni.pa165.banking.domain.transaction.Transaction;
+import cz.muni.pa165.banking.domain.transaction.TransactionType;
+import cz.muni.pa165.banking.exception.ServerError;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.Currency;
+import java.util.Objects;
+
+@Service
+public class ScheduledPaymentService {
+
+    private final Logger LOGGER = LoggerFactory.getLogger(ScheduledPaymentService.class);
+
+    private final AccountApi accountApi;
+
+    private final ProcessTransactionRepository processTransactionRepository;
+
+    private final ProcessRepository processRepository;
+
+    private final MessageProducer messageProducer;
+
+    ScheduledPaymentService(AccountApi accountApi,
+                            ProcessTransactionRepository processTransactionRepository,
+                            ProcessRepository processRepository,
+                            MessageProducer messageProducer) {
+        this.accountApi = accountApi;
+        this.processTransactionRepository = processTransactionRepository;
+        this.processRepository = processRepository;
+        this.messageProducer = messageProducer;
+    }
+
+    @Scheduled(cron = "${scheduled-payments.cron.expression}")
+    public void autoExecute() {
+        LocalDate now = LocalDate.now();
+        executeScheduledPayments(now);
+    }
+    
+    public void executeScheduledPayments(LocalDate date) {
+        ResponseEntity<ScheduledPaymentsDto> response = accountApi.getScheduledPaymentsOf(date);
+        if (!response.getStatusCode().is2xxSuccessful()) {
+            throw new ServerError("Call to Account Management service unsuccessful.");
+        }
+
+        ProcessFactory factory = new ProcessFactory(processTransactionRepository, processRepository);
+        ScheduledPaymentsDto payments = Objects.requireNonNull(response.getBody());
+        for (ScheduledPaymentDto payment : payments.getScheduledPayments()) {
+            Transaction newTransaction = transactionForScheduledPayment(payment);
+            Process process = factory.create(newTransaction, messageProducer);
+            LOGGER.info("[Create Scheduled Payment Process] %s" + process.getUuid());
+        }
+
+        LOGGER.info("Finished creating processes for scheduled payments.");
+    }
+
+    private Transaction transactionForScheduledPayment(ScheduledPaymentDto payment) {
+        Account source = new Account(payment.getSenderAccount());
+        Account target = new Account(payment.getReceiverAccount());
+        Money money = new Money(payment.getAmount(), Currency.getInstance(payment.getCurrencyCode()));
+        return new Transaction(
+                source,
+                target,
+                TransactionType.SCHEDULED,
+                money,
+                "Automatic execution of scheduled payment"
+        );
+    }
+
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionProcessesService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionProcessesService.java
index 193e9bb9990af42ff22dd616b0ff0a96c60c8825..c591a76735629e5410768bb638888367e30b3f54 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionProcessesService.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/application/service/TransactionProcessesService.java
@@ -1,7 +1,6 @@
 package cz.muni.pa165.banking.application.service;
 
-import cz.muni.pa165.banking.application.messaging.ProcessProducer;
-import cz.muni.pa165.banking.domain.money.Money;
+import cz.muni.pa165.banking.domain.messaging.MessageProducer;
 import cz.muni.pa165.banking.domain.process.Process;
 import cz.muni.pa165.banking.domain.process.ProcessFactory;
 import cz.muni.pa165.banking.domain.process.ProcessTransaction;
@@ -27,9 +26,11 @@ public class TransactionProcessesService {
 
     private final ProcessRepository processRepository;
     
-    private final ProcessProducer processProducer;
+    private final MessageProducer processProducer;
 
-    public TransactionProcessesService(ProcessTransactionRepository processTransactionRepository, ProcessRepository processRepository, ProcessProducer processProducer) {
+    public TransactionProcessesService(ProcessTransactionRepository processTransactionRepository,
+                                       ProcessRepository processRepository,
+                                       MessageProducer processProducer) {
         this.processTransactionRepository = processTransactionRepository;
         this.processRepository = processRepository;
         this.processProducer = processProducer;
@@ -40,7 +41,7 @@ public class TransactionProcessesService {
         ProcessFactory factory = new ProcessFactory(processTransactionRepository, processRepository);
         Process process = factory.create(newTransaction, processProducer);
         
-        LOGGER.info("[Create Process] %s" + process.uuid());
+        LOGGER.info("[Create Process] %s" + process.getUuid());
         
         return process;
     }
@@ -70,24 +71,22 @@ public class TransactionProcessesService {
         ProcessTransaction processTransaction = processTransactionRepository.findTransactionByProcessId(uuid);
         
         if (!processTransaction.getType().equals(TransactionType.TRANSFER) || processTransaction.getType().equals(TransactionType.SCHEDULED)) {
-            LOGGER.error("[Revert Process] Process " + uuid + " not of type CROSS_ACCOUNT/SCHEDULED, unable to revert");
-            throw new UnexpectedValueException("Unable to revert transaction not type of CROSS_ACCOUNT or SCHEDULED!");
+            LOGGER.error("[Revert Process] Process " + uuid + " not of type TRANSFER/SCHEDULED, unable to revert");
+            throw new UnexpectedValueException("Unable to revert transaction not type of TRANSFER or SCHEDULED!");
         }
 
-        Money original = processTransaction.getMoney();
-        Money reverted = new Money(original.getAmount().negate(), original.getCurrency());
         Transaction revertingTransaction = new Transaction(
                 processTransaction.getTarget(),
                 processTransaction.getSource(),
-                processTransaction.getType(),
-                reverted,
+                TransactionType.REFUND,
+                processTransaction.getMoney(),
                 String.format("Admin reversal of executed %s transaction {%s}", processTransaction.getType(), uuid)
         );
         
         ProcessFactory factory = new ProcessFactory(processTransactionRepository, processRepository);
         Process revertingProcess = factory.create(revertingTransaction, processProducer);
 
-        LOGGER.info(String.format("[Revert Process] Created new process {%s} in order to revert process {%s}", revertingProcess.uuid(), uuid));   
+        LOGGER.info(String.format("[Revert Process] Created new process {%s} in order to revert process {%s}", revertingProcess.getUuid(), uuid));   
         
         return revertingProcess;
     }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/account/Account.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/account/Account.java
index 08fb772787a4ca38f2c8a3406f150da4bcaaf3cd..5be7d59855b014a9858b94c188033c86d822a6a5 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/account/Account.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/account/Account.java
@@ -1,5 +1,7 @@
 package cz.muni.pa165.banking.domain.account;
 
+import java.util.Objects;
+
 public class Account {
     
     private String accountNumber;
@@ -19,4 +21,24 @@ public class Account {
     public void setAccountNumber(String accountNumber) {
         this.accountNumber = accountNumber;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Account account = (Account) o;
+        return Objects.equals(getAccountNumber(), account.getAccountNumber());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getAccountNumber());
+    }
+
+    @Override
+    public String toString() {
+        return "Account{" +
+                "accountNumber='" + accountNumber + '\'' +
+                '}';
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java
index dece4563799f49937d07416f49319310d3a9adf4..f70a6996f917e6456f0c4f7ad87478139bd02037 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/messaging/ProcessRequest.java
@@ -2,10 +2,24 @@ package cz.muni.pa165.banking.domain.messaging;
 
 import cz.muni.pa165.banking.domain.transaction.TransactionType;
 
+import java.util.Objects;
 import java.util.UUID;
 
 public record ProcessRequest(UUID uuid, TransactionType type) {
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ProcessRequest request = (ProcessRequest) o;
+        return Objects.equals(uuid, request.uuid) && type == request.type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(uuid, type);
+    }
+
     @Override
     public String toString() {
         return "ProcessRequest{" +
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/Money.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/Money.java
index d3382ff80c9e952180b88708516f238b0f63cfdf..e6dc93e83c15d6d735beb3616e3380b1105518bb 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/Money.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/money/Money.java
@@ -2,6 +2,7 @@ package cz.muni.pa165.banking.domain.money;
 
 import java.math.BigDecimal;
 import java.util.Currency;
+import java.util.Objects;
 
 public class Money {
 
@@ -32,4 +33,25 @@ public class Money {
     public void setCurrency(String currencyCode) {
         this.currency = Currency.getInstance(currencyCode);
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Money money = (Money) o;
+        return Objects.equals(getAmount(), money.getAmount()) && Objects.equals(getCurrency(), money.getCurrency());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getAmount(), getCurrency());
+    }
+
+    @Override
+    public String toString() {
+        return "Money{" +
+                "amount=" + amount +
+                ", currency=" + currency +
+                '}';
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/Process.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/Process.java
index 54a372aa205e15fe19e4b28fc64e59eea41c15dc..b9aae5b469307e295686230058e10daa6f590697 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/Process.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/Process.java
@@ -2,43 +2,81 @@ package cz.muni.pa165.banking.domain.process;
 
 import cz.muni.pa165.banking.domain.process.status.Status;
 import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import jakarta.persistence.Entity;
 
 import java.time.Instant;
+import java.util.Objects;
 import java.util.UUID;
 
-// @Entity
+@Entity
 public class Process {
     
-    private final UUID uuid;
+    private UUID uuid;
     
     private StatusInformation currentStatus;
     
-    Process() {
-        uuid = UUID.randomUUID();
-        currentStatus = new StatusInformation(Instant.now(), Status.CREATED, "Process created, waiting for processing.");
+    public static Process createNew() {
+        Process process = new Process();
+        process.uuid = UUID.randomUUID();
+        process.currentStatus = new StatusInformation(Instant.now(), Status.CREATED, "Process created, waiting for processing.");
+        
+        return process;
     }
 
+    @Deprecated // hibernate
+    public Process() {}
+
     /**
      * Return a copy of Process UUID, ensuring the UUID is not modified or replaced. 
      */
-    public UUID uuid() {
+    public UUID getUuid() {
         return UUID.fromString(uuid.toString());
     }
+
+    @Deprecated // hibernate
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid;
+    }
     
     public Instant getWhen() {
-        return currentStatus.when();
+        return currentStatus.getWhen();
     }
     
     public Status getStatus() {
-        return currentStatus.status();
+        return currentStatus.getStatus();
     }
     
-    public String getStatusInformation() {
-        return currentStatus.information();
+    public String getInformation() {
+        return currentStatus.getInformation();
     }
-    
+
+    @Deprecated // hibernate
+    public StatusInformation getCurrentStatus() {
+        return currentStatus;
+    }
+    @Deprecated // hibernate
     void setCurrentStatus(StatusInformation information) {
         currentStatus = information;
     }
-    
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Process process = (Process) o;
+        return Objects.equals(getUuid(), process.getUuid()) && Objects.equals(getCurrentStatus(), process.getCurrentStatus());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getUuid(), getCurrentStatus());
+    }
+
+    @Override
+    public String toString() {
+        return "Process{" +
+                "uuid=" + uuid +
+                ", currentStatus=" + currentStatus +
+                '}';
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java
index e59971349af79754a883328e7dce361f8bdd7a8b..66f2ff741138adfb85336467148984c02b384654 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessFactory.java
@@ -23,7 +23,7 @@ public class ProcessFactory {
 
 
     public Process create(Transaction transaction, MessageProducer messageProducer) {
-        Process newProcess = new Process();
+        Process newProcess = Process.createNew();
         processRepository.save(newProcess);
 
         ProcessTransaction assignedTransaction = new ProcessTransaction(
@@ -32,11 +32,11 @@ public class ProcessFactory {
                 transaction.getType(),
                 transaction.getMoney(),
                 transaction.getDetail(),
-                newProcess.uuid()
+                newProcess.getUuid()
         );
         processTransactionRepository.save(assignedTransaction);
         
-        messageProducer.send(new ProcessRequest(newProcess.uuid(), transaction.getType()));
+        messageProducer.send(new ProcessRequest(newProcess.getUuid(), transaction.getType()));
         
         return newProcess;
     }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessTransaction.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessTransaction.java
index fd98d790e5c26965a11c0b6d19638520ce444ffb..44876ab7f4e390e6f33e061e35eb677cd98513cb 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessTransaction.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/ProcessTransaction.java
@@ -6,6 +6,7 @@ import cz.muni.pa165.banking.domain.transaction.Transaction;
 import cz.muni.pa165.banking.domain.transaction.TransactionType;
 import jakarta.persistence.Entity;
 
+import java.util.Objects;
 import java.util.UUID;
 
 @Entity
@@ -36,4 +37,23 @@ public class ProcessTransaction extends Transaction {
     public void setUuid(UUID uuid) {
         this.uuid = uuid;
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ProcessTransaction that)) return false;
+        return Objects.equals(getUuid(), that.getUuid());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getUuid());
+    }
+
+    @Override
+    public String toString() {
+        return "ProcessTransaction{" +
+                "uuid=" + uuid +
+                "} " + super.toString();
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java
index aa9a66a41ee1d6487858dc5fe0e7b83caefb0c46..a6233dcd811ab6e814ef73475824e101a7533f0b 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/DepositHandler.java
@@ -27,7 +27,7 @@ class DepositHandler extends ProcessHandler {
             throw new UnexpectedValueException(String.format("Unable to deposit of provided currency (%s) as the account's currency is '%s'", money.getCurrency(), accountCurrency));    
         }
         
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.DEPOSIT, money.getAmount(), account, processTransaction.getDetail());
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.DEPOSIT, money.getAmount(), account);
     }
 
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java
index d076f2fb03cddfd644224122c8656e08176e8c26..513795b3f840b40697ef19a3ff1ace3a0e110570 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandler.java
@@ -58,11 +58,11 @@ abstract class ProcessHandler {
         if (process.getStatus().equals(Status.FAILED)) {
             throw new UnexpectedValueException(
                     "Process already closed, ended with failure",
-                    "Failure information: " + process.getStatusInformation()
+                    "Failure information: " + process.getInformation()
             );
         }
         if (process.getStatus().equals(Status.PROCESSED)) {
-            throw new UnexpectedValueException("Process already finalized, ended successfully", process.getStatusInformation());
+            throw new UnexpectedValueException("Process already finalized, ended successfully", process.getInformation());
         }
     }
 
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java
index 5d5811c58eb8de1a929b11e9543a5487ae4ccf7c..44bc263be8d0920e8f35adc3738b5f9e5e2fb96d 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerGateway.java
@@ -24,8 +24,9 @@ public class ProcessHandlerGateway {
         ProcessHandler handler = switch (type) {
             case WITHDRAWAL -> new WithdrawHandler();
             case DEPOSIT -> new DepositHandler();
-            case TRANSFER -> new CrossAccountHandler();
+            case TRANSFER -> new TransferHandler();
             case SCHEDULED -> new ScheduledHandler();
+            case REFUND -> new RefundHandler();
         };
         
         handler.handle(processUuid, processRepository, processTransactionRepository, accountService, currencyConverter);
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/RefundHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/RefundHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..63775a546616c42231ffff4b81565d6969afe98e
--- /dev/null
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/RefundHandler.java
@@ -0,0 +1,35 @@
+package cz.muni.pa165.banking.domain.process.handler;
+
+
+import cz.muni.pa165.banking.domain.account.Account;
+import cz.muni.pa165.banking.domain.money.CurrencyConverter;
+import cz.muni.pa165.banking.domain.money.Money;
+import cz.muni.pa165.banking.domain.process.ProcessTransaction;
+import cz.muni.pa165.banking.domain.remote.AccountService;
+import cz.muni.pa165.banking.domain.transaction.TransactionType;
+
+import java.math.BigDecimal;
+import java.util.Currency;
+
+public class RefundHandler extends ProcessHandler {
+
+    @Override
+    void evaluate(ProcessTransaction processTransaction, AccountService accountService, CurrencyConverter currencyConverter) {
+        Account source = processTransaction.getSource();
+        validateAccount(source, accountService);
+
+        Account target = processTransaction.getTarget();
+        validateAccount(target, accountService);
+
+        Money money = processTransaction.getMoney();
+        Currency sourceAccountCurrency = accountService.getAccountCurrency(source);
+        BigDecimal sourceAmount = currencyConverter.convertTo(money.getCurrency(), sourceAccountCurrency, money.getAmount());
+
+        Currency targetAccountCurrency = accountService.getAccountCurrency(target);
+        BigDecimal targetAmount = currencyConverter.convertTo(money.getCurrency(), targetAccountCurrency, money.getAmount());
+        targetAmount = targetAmount.multiply(BigDecimal.valueOf(-1L));
+
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.REFUND, sourceAmount, source);
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.REFUND, targetAmount, target);
+    }
+}
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandler.java
index cdf8e167b43f2ef707b12905d9d5e5d924b79779..63cb2107ca1ad02240a64e31bb0a5d4db4b6fb4d 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandler.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandler.java
@@ -14,7 +14,7 @@ import java.util.Currency;
 /**
  * Handler for transaction of type ${@link cz.muni.pa165.banking.domain.transaction.TransactionType#SCHEDULED}.
  * Customer may send a specified amount of money to a foreign account automatically by setting a scheduled payment.
- * The implementation resembles ${@link CrossAccountHandler#evaluate} with minor variations.
+ * The implementation resembles ${@link TransferHandler#evaluate} with minor variations.
  */
 public class ScheduledHandler extends ProcessHandler {
     
@@ -46,8 +46,8 @@ public class ScheduledHandler extends ProcessHandler {
             targetAmount = currencyConverter.convertTo(currency, targetAccountCurrency, targetAmount);
         }
 
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.SCHEDULED, sourceAmount, source, processTransaction.getDetail());
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.SCHEDULED, targetAmount, target, processTransaction.getDetail());
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.SCHEDULED, sourceAmount, source);
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.SCHEDULED, targetAmount, target);
     }
 
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/TransferHandler.java
similarity index 91%
rename from transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandler.java
rename to transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/TransferHandler.java
index 9dc80feb1e318d7a9472937190eee3380383cfaa..aaa1621895a7c50e27ba310ff46ec47af635fe11 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandler.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/TransferHandler.java
@@ -17,7 +17,7 @@ import java.util.Currency;
  * not have to be the same. The amount of money is calculated via ${@link cz.muni.pa165.banking.domain.money.CurrencyConverter}
  * using the target account's currency.
  */
-public class CrossAccountHandler extends ProcessHandler {
+public class TransferHandler extends ProcessHandler {
     
     @Override
     void evaluate(ProcessTransaction processTransaction, AccountService accountService, CurrencyConverter currencyConverter) {
@@ -55,8 +55,8 @@ public class CrossAccountHandler extends ProcessHandler {
             targetAmount = currencyConverter.convertTo(currency, targetAccountCurrency, targetAmount);
         }
         
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.TRANSFER, sourceAmount, source, processTransaction.getDetail());
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.TRANSFER, targetAmount, target, processTransaction.getDetail());
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.TRANSFER, sourceAmount, source);
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.TRANSFER, targetAmount, target);
     }
 
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java
index d57c3bf9c9e0162a92977de2b8abbc4cbfc348aa..2f8ef3751acf38b41accd9aafa747831b6fd31ce 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandler.java
@@ -40,7 +40,7 @@ public class WithdrawHandler extends ProcessHandler {
 
         BigDecimal calculatedAmount = money.getAmount().multiply(BigDecimal.valueOf(-1L));
 
-        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.WITHDRAWAL, calculatedAmount, account, processTransaction.getDetail());
+        accountService.publishAccountChange(processTransaction.getUuid(), TransactionType.WITHDRAWAL, calculatedAmount, account);
     }
 
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/repository/ProcessRepository.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/repository/ProcessRepository.java
index 12b56e54bbe890a148cbf3095ea7d3cb35f6b3ad..07a75bba7dbd6febb5906880e4fbac335ccbb9d7 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/repository/ProcessRepository.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/repository/ProcessRepository.java
@@ -1,7 +1,10 @@
 package cz.muni.pa165.banking.domain.process.repository;
 
 import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.status.Status;
 
+import java.time.LocalDate;
+import java.util.List;
 import java.util.UUID;
 
 public interface ProcessRepository {
@@ -12,4 +15,8 @@ public interface ProcessRepository {
     
     void save(Process process);
     
+    List<Process> findProcessOfStatus(Status status);
+    
+    List<Process> findProcessesOfStatusUptoDate(Status status, LocalDate localDate);
+    
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/status/StatusInformation.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/status/StatusInformation.java
index ddc7d46aefe93fe94dd396e26ff0bc911c693f28..713c83696a96c4a53a84c7382c7e8de24fe65621 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/status/StatusInformation.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/process/status/StatusInformation.java
@@ -1,6 +1,70 @@
 package cz.muni.pa165.banking.domain.process.status;
 
+import jakarta.persistence.Embeddable;
+
 import java.time.Instant;
+import java.util.Objects;
+
+@Embeddable
+public final class StatusInformation {
+    private Instant when;
+    private Status status;
+    private String information;
+
+    public StatusInformation(Instant when, Status status, String information) {
+        this.when = when;
+        this.status = status;
+        this.information = information;
+    }
+
+    @Deprecated // hibernate
+    public StatusInformation() {}
+
+    public Instant getWhen() {
+        return when;
+    }
+
+    public void setWhen(Instant when) {
+        this.when = when;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public String getInformation() {
+        return information;
+    }
+
+    public void setInformation(String information) {
+        this.information = information;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) return true;
+        if (obj == null || obj.getClass() != this.getClass()) return false;
+        var that = (StatusInformation) obj;
+        return Objects.equals(this.when, that.when) &&
+                Objects.equals(this.status, that.status) &&
+                Objects.equals(this.information, that.information);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(when, status, information);
+    }
+
+    @Override
+    public String toString() {
+        return "StatusInformation[" +
+                "when=" + when + ", " +
+                "status=" + status + ", " +
+                "information=" + information + ']';
+    }
 
-public record StatusInformation(Instant when, Status status, String information) {
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/remote/AccountService.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/remote/AccountService.java
index 010f2731127f4ef98981d9f4f745a227cf1aa6ff..37ebc5d9ef9464705b43946fa18e10199835cd02 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/remote/AccountService.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/remote/AccountService.java
@@ -30,6 +30,6 @@ public interface AccountService {
     /**
      *  Publish transaction results to update balance of account within processed transaction
      */
-    void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information);
+    void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account);
     
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/Transaction.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/Transaction.java
index 35a7d1742f363bcd8753e546fbf1045b97e5b4c7..e363c572df66bd3a36dd8a4939b6818c7e846381 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/Transaction.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/Transaction.java
@@ -3,6 +3,8 @@ package cz.muni.pa165.banking.domain.transaction;
 import cz.muni.pa165.banking.domain.account.Account;
 import cz.muni.pa165.banking.domain.money.Money;
 
+import java.util.Objects;
+
 public class Transaction {
     
     private Account source;
@@ -20,7 +22,8 @@ public class Transaction {
         // Hibernate
     }
     
-    public Transaction(Account source, Account target, TransactionType type, Money amount, String detail) {
+    public Transaction(Account source, Account target,
+                       TransactionType type, Money amount, String detail) {
         this.source = source;
         this.target = target;
         this.type = type;
@@ -73,4 +76,26 @@ public class Transaction {
         this.detail = detail;
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof Transaction that)) return false;
+        return Objects.equals(getSource(), that.getSource()) && Objects.equals(getTarget(), that.getTarget()) && getType() == that.getType() && Objects.equals(getMoney(), that.getMoney()) && Objects.equals(getDetail(), that.getDetail());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getSource(), getTarget(), getType(), getMoney(), getDetail());
+    }
+
+    @Override
+    public String toString() {
+        return "Transaction{" +
+                "source=" + source +
+                ", target=" + target +
+                ", type=" + type +
+                ", money=" + money +
+                ", detail='" + detail + '\'' +
+                '}';
+    }
 }
diff --git a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
index 1158d407d47d69a9f84f45467fe6a2dba672f922..7b826bacbf8740d48f026a8145cb86c491d62670 100644
--- a/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
+++ b/transaction-processor/src/main/java/cz/muni/pa165/banking/domain/transaction/TransactionType.java
@@ -8,6 +8,8 @@ public enum TransactionType {
 
     TRANSFER,
     
-    SCHEDULED
+    SCHEDULED,
+    
+    REFUND
     
 }
diff --git a/transaction-processor/src/main/resources/application.yaml b/transaction-processor/src/main/resources/application.yaml
index 2dc85c373a9d07b3ebca98472350bbea9a9f0c20..19aeabac8d731275c9b84f87b86ef2103aada346 100644
--- a/transaction-processor/src/main/resources/application.yaml
+++ b/transaction-processor/src/main/resources/application.yaml
@@ -1,8 +1,12 @@
 db:
   hostname: localhost
-spring:
-  application:
-    name: Transaction-Processor
+scheduled-payments:
+  cron:
+    expression: "00 7 * * *"
+process:
+  resolution:
+    threshold: 7
+
 banking:
   apps:
     management:
@@ -13,11 +17,19 @@ banking:
       host: localhost
       port: 8081
       url: ${banking.apps.query.host}:${banking.apps.query.port}
-    
+    rates:
+      api-key: 5f40db3a892e886bda8a6967
+      url: https://v6.exchangerate-api.com/v6/${banking.apps.rates.api-key}
+      initial:
+        currencies: CZK, EUR, USD
+
+spring:
+  application:
+    name: Transaction-Processor  
   datasource:
     url: jdbc:postgresql://${db.hostname}:5432/banking
     driver-class-name: org.postgresql.Driver
     username: ACC_TRANSACTION
     password: transactionAccPasswd
   jpa:
-    mapping-resources: hibernate/Transaction.hbm.xml
+    mapping-resources: hibernate/Transaction.hbm.xml, hibernate/Process.hbm.xml
diff --git a/transaction-processor/src/main/resources/hibernate/Process.hbm.xml b/transaction-processor/src/main/resources/hibernate/Process.hbm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f810cd53ffad63338c2ec7bf3acbbd3ce8f4bb98
--- /dev/null
+++ b/transaction-processor/src/main/resources/hibernate/Process.hbm.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD//EN"
+        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+    <class name="cz.muni.pa165.banking.domain.process.Process" table="proc_reg">
+
+        <cache usage="read-write"/>
+
+        <id name="uuid"
+            column="proc_uuid"
+            type="java.util.UUID"/>
+
+        <component
+                name="currentStatus"
+                class="cz.muni.pa165.banking.domain.process.status.StatusInformation"
+        >
+            <property
+                    name="when"
+                    column="status_when"
+                    type="java.time.Instant"
+            />
+            <property
+                    name="status"
+                    column="status">
+                <type name="org.hibernate.type.EnumType">
+                    <param name="enumClass">cz.muni.pa165.banking.domain.process.status.Status</param>
+                    <param name="useNamed">true</param>
+                </type>
+            </property>
+
+            <property
+                    name="information"
+                    column="status_info"
+                    type="java.lang.String"
+            />
+        </component>
+
+    </class>
+
+</hibernate-mapping>
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/integration/ProcessControllerIT.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/integration/ProcessControllerIT.java
new file mode 100644
index 0000000000000000000000000000000000000000..c97aecfda45f64ae4984cfbb2fc1cb33e08cbf71
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/integration/ProcessControllerIT.java
@@ -0,0 +1,103 @@
+package cz.muni.pa165.banking.application.integration;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import cz.muni.pa165.banking.application.repository.ProcessRepositoryJpa;
+import cz.muni.pa165.banking.application.service.ProcessService;
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessOperations;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import java.time.*;
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+@AutoConfigureDataJpa
+public class ProcessControllerIT {
+    
+    @Autowired
+    private MockMvc mockMvc;
+    
+    @Autowired
+    private ProcessService service;
+    
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    private static final Instant instant = LocalDateTime.of(2024, Month.APRIL, 24, 12, 0, 0).toInstant(ZoneOffset.UTC);
+    
+    @BeforeAll
+    public static void initDb(@Autowired ProcessRepositoryJpa repository) {
+        repository.save(Process.createNew());
+        repository.save(Process.createNew());
+
+        Process processed1 = Process.createNew();
+        ProcessOperations.changeState(processed1, new StatusInformation(instant, Status.PENDING, "PENDING"));
+        repository.save(processed1);
+
+        Process processed2 = Process.createNew();
+        ProcessOperations.changeState(processed2, new StatusInformation(instant, Status.PENDING, "PENDING"));
+        repository.save(processed2);
+
+        LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+        LocalDateTime newDateTime = currentDateTime.minusDays(10);
+        Instant tenDaysAgo = newDateTime.toInstant(ZoneOffset.UTC);
+
+        Process processed4 = Process.createNew();
+        ProcessOperations.changeState(processed4, new StatusInformation(tenDaysAgo, Status.CREATED, "CREATED"));
+        repository.save(processed4);
+
+        Process processed5 = Process.createNew();
+        ProcessOperations.changeState(processed5, new StatusInformation(tenDaysAgo, Status.PENDING, "PENDING"));
+        repository.save(processed5);
+    }
+
+    @Test
+    public void resolveStaleProcesses() throws Exception {
+        LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+        LocalDateTime newDateTime = currentDateTime.minusDays(1);
+        LocalDate yesterday = newDateTime.toLocalDate();
+        
+        List<Process> staleProcesses = service.unresolvedProcessesToDate(yesterday);
+        for (Process process : staleProcesses) {
+            assertNotEquals(Status.FAILED, process.getStatus());
+        }
+        List<UUID> staleProcessIds = staleProcesses.stream()
+                .map(Process::getUuid)
+                .toList();
+
+        MvcResult response = mockMvc.perform(patch("/processes/v1/resolve")
+                        .param("date", yesterday.toString())
+                        .contentType(MediaType.APPLICATION_JSON))
+                .andExpect(status().isOk())
+                .andReturn();
+        
+        String jsonResponse = response.getResponse().getContentAsString();
+        List<UUID> resolvedProcessIds = objectMapper.readValue(jsonResponse, new TypeReference<>() {});
+        assertEquals(staleProcessIds.size(), resolvedProcessIds.size());
+        assertTrue(resolvedProcessIds.containsAll(staleProcessIds));
+        
+        for (UUID uuid : resolvedProcessIds) {
+            Process process = service.findByUuid(uuid);
+            assertEquals(Status.FAILED, process.getStatus());
+            assertEquals("Resolved stale process as FAILED by system", process.getInformation());
+        }
+    }
+    
+}
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpaTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpaTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..273a714cf1f48b1d72465b59d408418067d522ca
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/repository/ProcessRepositoryJpaTest.java
@@ -0,0 +1,94 @@
+package cz.muni.pa165.banking.application.repository;
+
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessOperations;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import java.time.*;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@ExtendWith(SpringExtension.class)
+@DataJpaTest
+public class ProcessRepositoryJpaTest {
+    
+    @Autowired
+    private ProcessRepositoryJpa repository;
+    
+    private static final Instant instant = LocalDateTime.of(2024, Month.APRIL, 24, 12, 0, 0).toInstant(ZoneOffset.UTC);
+    
+    
+    @BeforeAll
+    public static void initDb(@Autowired ProcessRepositoryJpa repository) {
+        repository.save(Process.createNew());
+        repository.save(Process.createNew());
+        repository.save(Process.createNew());
+        
+        Process processed1 = Process.createNew();
+        ProcessOperations.changeState(processed1, new StatusInformation(instant, Status.PROCESSED, "done"));
+        repository.save(processed1);
+        
+        Process processed2 = Process.createNew();
+        ProcessOperations.changeState(processed2, new StatusInformation(instant, Status.PROCESSED, "done"));
+        repository.save(processed2);
+        
+        Process processed3 = Process.createNew();
+        ProcessOperations.changeState(processed3, new StatusInformation(instant, Status.PROCESSED, "done"));
+        repository.save(processed3);
+
+        LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+        LocalDateTime newDateTime = currentDateTime.minusDays(1);
+        Instant yesterday = newDateTime.toInstant(ZoneOffset.UTC);
+        
+        Process processed4 = Process.createNew();
+        ProcessOperations.changeState(processed4, new StatusInformation(yesterday, Status.PROCESSED, "done"));
+        repository.save(processed4);
+        
+        Process processed5 = Process.createNew();
+        ProcessOperations.changeState(processed5, new StatusInformation(yesterday, Status.PROCESSED, "done"));
+        repository.save(processed5);
+    }
+    
+    @Test
+    public void findAllWithStatusCreated() {
+        List<Process> createdProcesses = repository.findAllWithStatus(Status.CREATED);
+
+        assertEquals(3, createdProcesses.size());
+
+        Set<Status> statuses = createdProcesses.stream()
+                .map(Process::getStatus)
+                .collect(Collectors.toSet());
+        assertEquals(1, statuses.size());
+        assertTrue(statuses.contains(Status.CREATED));
+    }
+    
+    @Test
+    public void findProcessedProcessesFromYesterday() {
+        LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+        LocalDateTime newDateTime = currentDateTime.minusDays(1);
+        Instant yesterday = newDateTime.toInstant(ZoneOffset.UTC);
+        
+        List<Process> processedYesterday = repository.findByStatusAndDateBeforeEqual(Status.PROCESSED, yesterday);
+        assertEquals(2, processedYesterday.size());
+    }
+
+    @Test
+    public void findCreatedProcessesFromYesterday() {
+        LocalDateTime currentDateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+        LocalDateTime newDateTime = currentDateTime.minusDays(1);
+        Instant yesterday = newDateTime.toInstant(ZoneOffset.UTC);
+
+        List<Process> processedYesterday = repository.findByStatusAndDateBeforeEqual(Status.CREATED, yesterday);
+        assertEquals(0, processedYesterday.size());
+    }
+}
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/AccountServiceImplTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/AccountServiceImplTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf107f607d340ec80801e2f0cac54216146ab0e1
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/AccountServiceImplTest.java
@@ -0,0 +1,89 @@
+package cz.muni.pa165.banking.application.service;
+
+import cz.muni.pa165.banking.account.management.AccountApi;
+import cz.muni.pa165.banking.account.management.dto.AccountDto;
+import cz.muni.pa165.banking.account.query.CustomerServiceApi;
+import cz.muni.pa165.banking.account.query.SystemServiceApi;
+import cz.muni.pa165.banking.domain.account.Account;
+import cz.muni.pa165.banking.domain.transaction.TransactionType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.ResponseEntity;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class AccountServiceImplTest {
+
+    @Mock
+    private AccountApi accountApi;
+
+    @Mock
+    private CustomerServiceApi publicBalanceApi;
+
+    @Mock
+    private SystemServiceApi privateBalanceApi;
+
+    @InjectMocks
+    private AccountServiceImpl accountService;
+
+    @Test
+    void getAccountCurrency_shouldCallAccountApi() {
+        Account account = new Account("12345");
+        AccountDto accountDto = new AccountDto();
+        accountDto.setCurrency("USD");
+
+        when(accountApi.findByAccountNumber(account.getAccountNumber())).thenReturn(ResponseEntity.ok(accountDto));
+
+        accountService.getAccountCurrency(account);
+
+        verify(accountApi, times(1)).findByAccountNumber(account.getAccountNumber());
+    }
+
+    @Test
+    void isValid_shouldCallAccountApi() {
+        Account account = new Account("12345");
+        AccountDto accountDto = new AccountDto();
+
+        when(accountApi.findByAccountNumber(account.getAccountNumber())).thenReturn(ResponseEntity.ok(accountDto));
+
+        accountService.isValid(account);
+
+        verify(accountApi, times(1)).findByAccountNumber(account.getAccountNumber());
+    }
+
+    @Test
+    void accountHasSufficientFunds_shouldCallPublicBalanceApi() {
+        Account account = new Account("12345");
+        BigDecimal amount = BigDecimal.TEN;
+
+        when(publicBalanceApi.getBalance(account.getAccountNumber())).thenReturn(ResponseEntity.ok(BigDecimal.ONE));
+
+        accountService.accountHasSufficientFunds(account, amount);
+
+        verify(publicBalanceApi, times(1)).getBalance(account.getAccountNumber());
+    }
+
+    @Test
+    void publishAccountChange_shouldCallPrivateBalanceApi() {
+        UUID processUuid = UUID.randomUUID();
+        TransactionType transactionType = TransactionType.DEPOSIT;
+        BigDecimal amount = BigDecimal.TEN;
+        Account account = new Account("12345");
+
+        accountService.publishAccountChange(processUuid, transactionType, amount, account);
+
+        verify(privateBalanceApi, times(1)).addTransactionToBalance(
+                account.getAccountNumber(),
+                amount,
+                processUuid,
+                cz.muni.pa165.banking.account.query.dto.TransactionType.DEPOSIT
+        );
+    }
+}
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ProcessServiceTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ProcessServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d310cb391b8af76fda45208f88d1e6ce02afc76
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ProcessServiceTest.java
@@ -0,0 +1,87 @@
+package cz.muni.pa165.banking.application.service;
+
+
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.exception.UnexpectedValueException;
+import org.awaitility.reflect.WhiteboxImpl;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class ProcessServiceTest {
+
+    @Mock
+    private ProcessRepository processRepository;
+
+    @InjectMocks
+    private ProcessService processService;
+
+    @Test
+    void findByUuid_shouldCallProcessRepository() {
+        UUID uuid = UUID.randomUUID();
+
+        processService.findByUuid(uuid);
+
+        verify(processRepository, times(1)).findById(uuid);
+    }
+
+    @Test
+    void processesWithStatus_shouldCallProcessRepository() {
+        Status status = Status.CREATED;
+
+        processService.processesWithStatus(status);
+
+        verify(processRepository, times(1)).findProcessOfStatus(status);
+    }
+
+    @Test
+    void unresolvedProcessesToDate_shouldCallProcessRepository() {
+        LocalDate threshold = LocalDate.now();
+
+        processService.unresolvedProcessesToDate(threshold);
+
+        verify(processRepository, times(1)).findProcessesOfStatusUptoDate(Status.CREATED, threshold);
+        verify(processRepository, times(1)).findProcessesOfStatusUptoDate(Status.PENDING, threshold);
+    }
+
+    @Test
+    void resolveProcesses_failOnInvalidThreshold() {
+        LocalDate localDate = LocalDate.now();
+
+        UnexpectedValueException e = assertThrows(
+                UnexpectedValueException.class,
+                () -> processService.resolveProcesses(localDate)
+        );
+        
+        String cause = WhiteboxImpl.getInternalState(e, "cause");
+        assertEquals("Threshold should be atleast one day ago. Cannot resolve processes from today or the future", cause);
+    }
+
+    @Test
+    void resolveProcesses_shouldCallProcessRepository() {
+        LocalDate localDate = LocalDate.now().minusDays(2);
+        
+        Process p1 = Process.createNew();
+        Process p2 = Process.createNew();
+        when(processRepository.findProcessesOfStatusUptoDate(Status.CREATED, localDate)).thenReturn(List.of(p1));
+        when(processRepository.findProcessesOfStatusUptoDate(Status.PENDING, localDate)).thenReturn(List.of(p2));
+        
+        processService.resolveProcesses(localDate);
+
+        verify(processRepository, times(2)).findProcessesOfStatusUptoDate(any(), any());
+        verify(processRepository, times(1)).save(p1);
+        verify(processRepository, times(1)).save(p2);
+    }
+}
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ScheduledPaymentServiceTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ScheduledPaymentServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e64b6565a5a9a2cd009ef155c7e756b8b285b928
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/ScheduledPaymentServiceTest.java
@@ -0,0 +1,84 @@
+package cz.muni.pa165.banking.application.service;
+
+import cz.muni.pa165.banking.account.management.AccountApi;
+import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentDto;
+import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentType;
+import cz.muni.pa165.banking.account.management.dto.ScheduledPaymentsDto;
+import cz.muni.pa165.banking.domain.messaging.MessageProducer;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
+import cz.muni.pa165.banking.exception.ServerError;
+import org.awaitility.reflect.WhiteboxImpl;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class ScheduledPaymentServiceTest {
+
+    @Mock
+    private AccountApi accountApi;
+
+    @Mock
+    private ProcessTransactionRepository processTransactionRepository;
+
+    @Mock
+    private ProcessRepository processRepository;
+
+    @Mock
+    private MessageProducer messageProducer;
+
+    @InjectMocks
+    private ScheduledPaymentService scheduledPaymentService;
+
+    @Test
+    void executeScheduledPayments_shouldCreateProcessesForScheduledPayments() {
+        LocalDate date = LocalDate.now();
+        ScheduledPaymentsDto validScheduledPaymentsDto = new ScheduledPaymentsDto();
+        
+        validScheduledPaymentsDto.addScheduledPaymentsItem(
+                new ScheduledPaymentDto(BigDecimal.ONE, "EUR", ScheduledPaymentType.MONTHLY, 1)
+        );
+        validScheduledPaymentsDto.addScheduledPaymentsItem(
+                new ScheduledPaymentDto(BigDecimal.ONE, "EUR", ScheduledPaymentType.MONTHLY, 1)
+        );
+        validScheduledPaymentsDto.addScheduledPaymentsItem(
+                new ScheduledPaymentDto(BigDecimal.ONE, "EUR", ScheduledPaymentType.MONTHLY, 1)
+        );
+
+        when(accountApi.getScheduledPaymentsOf(date)).thenReturn(ResponseEntity.ok(validScheduledPaymentsDto));
+
+        scheduledPaymentService.executeScheduledPayments(date);
+
+        verify(processRepository, times(3)).save(any());
+        verify(processTransactionRepository, times(3)).save(any());
+        verify(messageProducer, times(3)).send(any());
+    }
+
+    @Test
+    void executeScheduledPayments_shouldThrowServerErrorForInvalidResponse() {
+        LocalDate date = LocalDate.now();
+
+        when(accountApi.getScheduledPaymentsOf(date)).thenReturn(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
+
+        ServerError err = assertThrows(
+                ServerError.class,
+                () -> scheduledPaymentService.executeScheduledPayments(date)
+        );
+        String cause = WhiteboxImpl.getInternalState(err, "cause");
+        assertEquals("Call to Account Management service unsuccessful.", cause);
+
+        verify(processRepository, never()).save(any());
+    }
+
+}
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/TransactionProcessesServiceTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/TransactionProcessesServiceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6014746d3982a47b94226418c3bcafa6f05e7aa9
--- /dev/null
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/application/service/TransactionProcessesServiceTest.java
@@ -0,0 +1,95 @@
+package cz.muni.pa165.banking.application.service;
+
+import cz.muni.pa165.banking.domain.account.Account;
+import cz.muni.pa165.banking.domain.messaging.MessageProducer;
+import cz.muni.pa165.banking.domain.money.Money;
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessOperations;
+import cz.muni.pa165.banking.domain.process.ProcessTransaction;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import cz.muni.pa165.banking.domain.transaction.Transaction;
+import cz.muni.pa165.banking.domain.transaction.TransactionType;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.math.BigDecimal;
+import java.time.Instant;
+import java.util.Currency;
+import java.util.UUID;
+
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class TransactionProcessesServiceTest {
+
+    @Mock
+    private ProcessTransactionRepository processTransactionRepository;
+
+    @Mock
+    private ProcessRepository processRepository;
+
+    @Mock
+    private MessageProducer processProducer;
+
+    @InjectMocks
+    private TransactionProcessesService transactionProcessesService;
+
+    @Test
+    void createProcessForTransaction_shouldCreateProcess() {
+        Transaction newTransaction = new Transaction();
+
+        transactionProcessesService.createProcessForTransaction(newTransaction);
+
+        verify(processRepository, times(1)).save(any());
+        verify(processTransactionRepository, times(1)).save(any());
+        verify(processProducer, times(1)).send(any());
+    }
+
+    @Test
+    void findProcess_shouldCallProcessRepository() {
+        UUID uuid = UUID.randomUUID();
+
+        transactionProcessesService.findProcess(uuid);
+
+        verify(processRepository, times(1)).findById(uuid);
+    }
+
+    @Test
+    void findProcessTransaction_shouldCallProcessTransactionRepository() {
+        UUID uuid = UUID.randomUUID();
+
+        transactionProcessesService.findProcessTransaction(uuid);
+
+        verify(processTransactionRepository, times(1)).findTransactionByProcessId(uuid);
+    }
+
+    @Test
+    void revertProcess_shouldCreateRevertingProcess() {
+        UUID uuid = UUID.randomUUID();
+        Process process = Process.createNew();
+        ProcessOperations.changeState(process, new StatusInformation(Instant.now(), Status.PROCESSED, "done"));
+        ProcessTransaction processTransaction = new ProcessTransaction();
+        processTransaction.setUuid(process.getUuid());
+        processTransaction.setSource(new Account("123"));
+        processTransaction.setTarget(new Account("321"));
+        processTransaction.setType(TransactionType.TRANSFER);
+        processTransaction.setMoney(new Money(BigDecimal.ONE, Currency.getInstance("EUR")));
+        Transaction revertingTransaction = new Transaction();
+
+        when(processRepository.findById(uuid)).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(uuid)).thenReturn(processTransaction);
+
+        transactionProcessesService.revertProcess(uuid);
+
+        verify(processRepository, times(1)).findById(any());
+        verify(processTransactionRepository, times(1)).findTransactionByProcessId(any());
+        verify(processRepository, times(1)).save(any());
+        verify(processProducer, times(1)).send(any());
+    }
+}
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessFactoryTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessFactoryTest.java
index a1264aa501c86cd84b55ac2ec095a412123b2988..7994b660d5350a67863b10acb6465e44abb3b0f3 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessFactoryTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessFactoryTest.java
@@ -95,7 +95,7 @@ class ProcessFactoryTest {
         verify(processTransactionRepository).save(argumentCaptor.capture());
         ProcessTransaction captured = argumentCaptor.getValue();
 
-        assertEquals(createdProcess.uuid(), captured.getUuid());
+        assertEquals(createdProcess.getUuid(), captured.getUuid());
     }
 
 
@@ -103,23 +103,20 @@ class ProcessFactoryTest {
     void transactionRequestCreated() {
         ProcessTransactionRepository processTransactionRepository = mock(ProcessTransactionRepository.class);
         ProcessRepository processRepository = mock(ProcessRepository.class);
-        MessageProducer messageProducer = new MessageProducerSpy();
+        MessageProducerSpy messageProducer = new MessageProducerSpy();
 
         ProcessFactory processFactory = new ProcessFactory(processTransactionRepository, processRepository);
         Process createdProcess = processFactory.create(transaction, messageProducer);
 
-        UUID sentUuid = WhiteboxImpl.getInternalState(messageProducer, "receivedUuid");
-        TransactionType sentType = WhiteboxImpl.getInternalState(messageProducer, "receivedType");
-
-        assertEquals(createdProcess.uuid(), sentUuid);
-        assertEquals(TransactionType.DEPOSIT, sentType);
+        assertEquals(createdProcess.getUuid(), messageProducer.receivedUuid);
+        assertEquals(TransactionType.DEPOSIT, messageProducer.receivedType);
     }
 
-    private class MessageProducerSpy implements MessageProducer {
+    private static class MessageProducerSpy implements MessageProducer {
 
-        private UUID receivedUuid;
+        public UUID receivedUuid;
 
-        private TransactionType receivedType;
+        public TransactionType receivedType;
 
         @Override
         public void send(ProcessRequest data) {
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessMock.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessMock.java
index 8cbf9dee8a40fe311c5263311d9621267869694b..143d073017059023b096c261eafb6440749b067d 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessMock.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessMock.java
@@ -1,9 +1,23 @@
 package cz.muni.pa165.banking.domain.process;
 
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+
+import java.time.Instant;
+import java.util.UUID;
+
 public class ProcessMock extends Process {
     
+    private final UUID uuid;
+    
     public ProcessMock() {
         super();
+        this.uuid = UUID.randomUUID();
+        this.setCurrentStatus(new StatusInformation(Instant.now(), Status.CREATED, "Process created, waiting for processing."));
     }
     
+    @Override
+    public UUID getUuid() {
+        return this.uuid;
+    }
 }
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessOperationsTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessOperationsTest.java
index 7505ecb9373589a9515a3e13f57a8ddb55e742da..61593a14e6f039ade5c177f81e79e3ffcb0e1601 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessOperationsTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/ProcessOperationsTest.java
@@ -12,7 +12,7 @@ class ProcessOperationsTest {
 
     @Test
     void changeState() {
-        Process process = new Process();
+        Process process = Process.createNew();
 
         StatusInformation newStatus = new StatusInformation(
                 Instant.now(),
@@ -22,8 +22,8 @@ class ProcessOperationsTest {
         
         ProcessOperations.changeState(process, newStatus);
         
-        assertEquals(newStatus.when(), process.getWhen());
-        assertEquals(newStatus.status(), process.getStatus());
-        assertEquals(newStatus.information(), process.getStatusInformation());
+        assertEquals(newStatus.getWhen(), process.getWhen());
+        assertEquals(newStatus.getStatus(), process.getStatus());
+        assertEquals(newStatus.getInformation(), process.getInformation());
     }
 }
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/DepositHandlerTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/DepositHandlerTest.java
index 4bcddcc4a4a03b8533243e5b8a995d9d9ae39efc..da39d6016439a52512a3777f8494620de632044a 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/DepositHandlerTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/DepositHandlerTest.java
@@ -31,27 +31,25 @@ import static org.mockito.Mockito.when;
 class DepositHandlerTest {
 
     private boolean published = false;
-    
-    private static Account account;
+
     private static Process process;
-    private static ProcessTransaction processTransaction;
     private static ProcessRepository processRepository;
     private static ProcessTransactionRepository processTransactionRepository;
     private static ProcessHandler depositHandler;
     private static CurrencyConverter converter;
 
     @BeforeAll
-    static void init() {        
-        account = new Account("ACC");
+    static void init() {
+        Account account = new Account("ACC");
         process = new ProcessMock();
-        processTransaction = new ProcessTransaction(account, null, TransactionType.DEPOSIT, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction processTransaction = new ProcessTransaction(account, null, TransactionType.DEPOSIT, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
         depositHandler = new DepositHandler();
         processRepository = mock(ProcessRepository.class);
         processTransactionRepository = mock(ProcessTransactionRepository.class);
         converter = new CurrencyConverterStub(null);
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
     }
     
     @BeforeEach
@@ -65,7 +63,7 @@ class DepositHandlerTest {
 
         assertThrows(
                 EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -76,7 +74,7 @@ class DepositHandlerTest {
         
         assertThrows(
                 UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -84,7 +82,7 @@ class DepositHandlerTest {
     @Test
     void depositMoneySuccessful() {
         AccountService accountService = new AccountServiceStub(true, Currency.getInstance("EUR"));
-        depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter);
+        depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter);
 
         assertEquals(Status.PROCESSED, process.getStatus());
         assertTrue(published);
@@ -129,7 +127,7 @@ class DepositHandlerTest {
         }
 
         @Override
-        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information) {
+        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account) {
             published = true;
         }
     }
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerTest.java
index fc420748d9e08a0c2f557c1f8b3b364ef55ba088..52263512cd53695dcc8ffcad06b42d8c74006272 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ProcessHandlerTest.java
@@ -51,7 +51,7 @@ class ProcessHandlerTest {
         ProcessOperations.changeState(process, new StatusInformation(null, Status.FAILED, "N/A"));
         assertThrows(
                 UnexpectedValueException.class,
-                () -> genericHandler.handle(process.uuid(), processRepository, null, null, null)
+                () -> genericHandler.handle(process.getUuid(), processRepository, null, null, null)
         );
     }
 
@@ -62,17 +62,17 @@ class ProcessHandlerTest {
         ProcessOperations.changeState(process, new StatusInformation(null, Status.PROCESSED, "N/A"));
         assertThrows(
                 UnexpectedValueException.class,
-                () -> genericHandler.handle(process.uuid(), processRepository, null, null, null)
+                () -> genericHandler.handle(process.getUuid(), processRepository, null, null, null)
         );
     }
 
     @Test
     void processNotLinkedToTransactionRequest() {
         Process process = createProcess();
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(null);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(null);
         assertThrows(
                 EntityNotFoundException.class,
-                () -> genericHandler.handle(process.uuid(), processRepository, processTransactionRepository, null, null)
+                () -> genericHandler.handle(process.getUuid(), processRepository, processTransactionRepository, null, null)
         );
     }
     
@@ -90,7 +90,7 @@ class ProcessHandlerTest {
         
         assertThrows(
                 RuntimeException.class,
-                () -> failingHandler.handle(process.uuid(), processRepository, processTransactionRepository, null, null)
+                () -> failingHandler.handle(process.getUuid(), processRepository, processTransactionRepository, null, null)
         );
 
         assertEquals(Status.FAILED, process.getStatus());
@@ -101,20 +101,20 @@ class ProcessHandlerTest {
         Process process = createProcess();
         ofProcess(process);
 
-        genericHandler.handle(process.uuid(), processRepository, processTransactionRepository, null, null);
+        genericHandler.handle(process.getUuid(), processRepository, processTransactionRepository, null, null);
         assertEquals(Status.PROCESSED, process.getStatus());
     }
 
 
     private Process createProcess() {
         Process process = new ProcessMock();
-        when(processRepository.findById(process.uuid())).thenReturn(process);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
         return process;
     }
     
     private ProcessTransaction ofProcess(Process process) {
-        ProcessTransaction result = new ProcessTransaction(new Account("ACC_1"), null, TransactionType.DEPOSIT, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(result);
+        ProcessTransaction result = new ProcessTransaction(new Account("ACC_1"), null, TransactionType.DEPOSIT, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(result);
         return result;
     }
 }
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandlerTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandlerTest.java
index 24b1013c4dc887699f8e18b10a2fa3a3618382a7..802a490381e0c9cbe6695c3c6d2975106f1fe919 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandlerTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/ScheduledHandlerTest.java
@@ -51,14 +51,14 @@ class ScheduledHandlerTest {
     void nonexistingFirstAccountValidation() {
         AccountService accountService = new AccountServiceStub(false, false,null, false);
         Process process = new ProcessMock();
-        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
         
         assertThrows(
                 EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -67,14 +67,14 @@ class ScheduledHandlerTest {
     void twoSameAccountsValidation() {
         AccountService accountService = new AccountServiceStub(true, false,null, false);
         Process process = new ProcessMock();
-        ProcessTransaction processTransaction = new ProcessTransaction(account1, account1, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction processTransaction = new ProcessTransaction(account1, account1, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
 
         assertThrows(
                 UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -83,14 +83,14 @@ class ScheduledHandlerTest {
     void nonexistingSecondAccountValidation() {
         AccountService accountService = new AccountServiceStub(true, false,null, false);
         Process process = new ProcessMock();
-        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
         
         assertThrows(
                 EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -99,12 +99,12 @@ class ScheduledHandlerTest {
     void crossAccountTransactionSuccessful() {
         AccountService accountService = new AccountServiceStub(true, true, null, true);
         Process process = new ProcessMock();
-        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
 
-        depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter);
+        depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter);
 
         assertEquals(Status.PROCESSED, process.getStatus());
         assertTrue(published1);
@@ -157,7 +157,7 @@ class ScheduledHandlerTest {
         }
 
         @Override
-        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information) {
+        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account) {
             if (account.equals(account1)) {
                 published1 = true;
             } else {
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandlerTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/TransferHandlerTest.java
similarity index 74%
rename from transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandlerTest.java
rename to transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/TransferHandlerTest.java
index 2551bd4a91df78468d6ea6f7cb846545a19f1704..357e351209f18c0b39c46b19d9dfb32b0249d108 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/CrossAccountHandlerTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/TransferHandlerTest.java
@@ -1,208 +1,207 @@
-package cz.muni.pa165.banking.domain.process.handler;
-
-import cz.muni.pa165.banking.domain.account.Account;
-import cz.muni.pa165.banking.domain.money.CurrencyConverter;
-import cz.muni.pa165.banking.domain.money.Money;
-import cz.muni.pa165.banking.domain.money.exchange.ExchangeRateService;
-import cz.muni.pa165.banking.domain.process.Process;
-import cz.muni.pa165.banking.domain.process.ProcessMock;
-import cz.muni.pa165.banking.domain.process.ProcessOperations;
-import cz.muni.pa165.banking.domain.process.ProcessTransaction;
-import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
-import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
-import cz.muni.pa165.banking.domain.process.status.Status;
-import cz.muni.pa165.banking.domain.process.status.StatusInformation;
-import cz.muni.pa165.banking.domain.remote.AccountService;
-import cz.muni.pa165.banking.domain.transaction.TransactionType;
-import cz.muni.pa165.banking.exception.EntityNotFoundException;
-import cz.muni.pa165.banking.exception.UnexpectedValueException;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.math.BigDecimal;
-import java.util.Currency;
-import java.util.UUID;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-class CrossAccountHandlerTest {
-
-    private boolean published1 = false;
-    private boolean published2 = false;
-
-    private static Account account1;
-    private static Account account2;
-    private static Process process;
-    private static ProcessTransaction processTransaction;
-    private static ProcessRepository processRepository;
-    private static ProcessTransactionRepository processTransactionRepository;
-    private static ProcessHandler depositHandler;
-    private static CurrencyConverter converter;
-
-    @BeforeAll
-    static void init() {
-        account1 = new Account("ACC1");
-        account2 = new Account("ACC2");
-        process = new ProcessMock();
-        processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
-        depositHandler = new CrossAccountHandler();
-        processRepository = mock(ProcessRepository.class);
-        processTransactionRepository = mock(ProcessTransactionRepository.class);
-        converter = new CurrencyConverterStub(null);
-
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
-    }
-
-    @BeforeEach
-    void prepare() {
-        ProcessOperations.changeState(process, new StatusInformation(null, Status.CREATED, null));
-    }
-
-    @Test
-    void nonexistingFirstAccountValidation() {
-        AccountService accountService = new AccountServiceStub(false, false,null, false);
-
-        assertThrows(
-                EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
-        );
-        assertEquals(Status.FAILED, process.getStatus());
-    }
-
-
-    @Test
-    void nonexistingSecondAccountValidation() {
-        AccountService accountService = new AccountServiceStub(true, false,null, false);
-        
-        assertThrows(
-                EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
-        );
-        assertEquals(Status.FAILED, process.getStatus());
-    }
-
-
-    @Test
-    void negativeAmountInTransaction() {
-        AccountService accountService = new AccountServiceStub(true, true, null, false);
-        Process process = new ProcessMock();
-        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE.negate(), Currency.getInstance("EUR")), "", process.uuid());
-
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
-
-        assertThrows(
-                UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
-        );
-        assertEquals(Status.FAILED, process.getStatus());
-    }
-
-    @Test
-    void zeroAmountInTransaction() {
-        AccountService accountService = new AccountServiceStub(true, true, null, false);
-        Process process = new ProcessMock();
-        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ZERO, Currency.getInstance("EUR")), "", process.uuid());
-        
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
-        
-        assertThrows(
-                UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
-        );
-        assertEquals(Status.FAILED, process.getStatus());
-    }
-
-    @Test
-    void insufficientBalanceForTransaction() {
-        AccountService accountService = new AccountServiceStub(true, true, null, false);
-        Process process = new ProcessMock();
-        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
-
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
-
-        assertThrows(
-                UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
-        );
-        assertEquals(Status.FAILED, process.getStatus());
-    }
-    
-    @Test
-    void crossAccountTransactionSuccessful() {
-        AccountService accountService = new AccountServiceStub(true, true, null, true);
-        Process process = new ProcessMock();
-        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
-
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
-
-        depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter);
-        
-        assertEquals(Status.PROCESSED, process.getStatus());
-        assertTrue(published1);
-        assertTrue(published2);
-    }
-    
-    
-    private static class CurrencyConverterStub extends CurrencyConverter {
-
-        public CurrencyConverterStub(ExchangeRateService exchangeRateApi) {
-            super(exchangeRateApi);
-        }
-
-        @Override
-        public BigDecimal convertTo(Currency source, Currency target, BigDecimal amount) {
-            return amount;
-        }
-    }
-
-    private class AccountServiceStub implements AccountService {
-
-        private final boolean isValid1;
-        private final boolean isValid2;
-        private final Currency currency;
-        private final boolean sufficientFunds;
-
-        private AccountServiceStub(boolean isValid1, boolean isValid2, Currency currency, boolean sufficientFunds) {
-            this.isValid1 = isValid1;
-            this.isValid2 = isValid2;
-            this.currency = currency;
-            this.sufficientFunds = sufficientFunds;
-        }
-
-        @Override
-        public Currency getAccountCurrency(Account account) {
-            return currency;
-        }
-
-        @Override
-        public boolean isValid(Account account) {
-            if (account.equals(account1)) {
-                return isValid1;
-            }
-            return isValid2;
-        }
-
-        @Override
-        public boolean accountHasSufficientFunds(Account account, BigDecimal amount) {
-            return sufficientFunds;
-        }
-
-        @Override
-        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information) {
-            if (account.equals(account1)) {
-                published1 = true;
-            } else {
-                published2 = true;
-            }
-        }
-    }
-    
+package cz.muni.pa165.banking.domain.process.handler;
+
+import cz.muni.pa165.banking.domain.account.Account;
+import cz.muni.pa165.banking.domain.money.CurrencyConverter;
+import cz.muni.pa165.banking.domain.money.Money;
+import cz.muni.pa165.banking.domain.money.exchange.ExchangeRateService;
+import cz.muni.pa165.banking.domain.process.Process;
+import cz.muni.pa165.banking.domain.process.ProcessMock;
+import cz.muni.pa165.banking.domain.process.ProcessOperations;
+import cz.muni.pa165.banking.domain.process.ProcessTransaction;
+import cz.muni.pa165.banking.domain.process.repository.ProcessRepository;
+import cz.muni.pa165.banking.domain.process.repository.ProcessTransactionRepository;
+import cz.muni.pa165.banking.domain.process.status.Status;
+import cz.muni.pa165.banking.domain.process.status.StatusInformation;
+import cz.muni.pa165.banking.domain.remote.AccountService;
+import cz.muni.pa165.banking.domain.transaction.TransactionType;
+import cz.muni.pa165.banking.exception.EntityNotFoundException;
+import cz.muni.pa165.banking.exception.UnexpectedValueException;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.util.Currency;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class TransferHandlerTest {
+
+    private boolean published1 = false;
+    private boolean published2 = false;
+
+    private static Account account1;
+    private static Account account2;
+    private static Process process;
+    private static ProcessRepository processRepository;
+    private static ProcessTransactionRepository processTransactionRepository;
+    private static ProcessHandler depositHandler;
+    private static CurrencyConverter converter;
+
+    @BeforeAll
+    static void init() {
+        account1 = new Account("ACC1");
+        account2 = new Account("ACC2");
+        process = new ProcessMock();
+        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
+        depositHandler = new TransferHandler();
+        processRepository = mock(ProcessRepository.class);
+        processTransactionRepository = mock(ProcessTransactionRepository.class);
+        converter = new CurrencyConverterStub(null);
+
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
+    }
+
+    @BeforeEach
+    void prepare() {
+        ProcessOperations.changeState(process, new StatusInformation(null, Status.CREATED, null));
+    }
+
+    @Test
+    void nonexistingFirstAccountValidation() {
+        AccountService accountService = new AccountServiceStub(false, false,null, false);
+
+        assertThrows(
+                EntityNotFoundException.class,
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
+        );
+        assertEquals(Status.FAILED, process.getStatus());
+    }
+
+
+    @Test
+    void nonexistingSecondAccountValidation() {
+        AccountService accountService = new AccountServiceStub(true, false,null, false);
+        
+        assertThrows(
+                EntityNotFoundException.class,
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
+        );
+        assertEquals(Status.FAILED, process.getStatus());
+    }
+
+
+    @Test
+    void negativeAmountInTransaction() {
+        AccountService accountService = new AccountServiceStub(true, true, null, false);
+        Process process = new ProcessMock();
+        ProcessTransaction processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE.negate(), Currency.getInstance("EUR")), "", process.getUuid());
+
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
+
+        assertThrows(
+                UnexpectedValueException.class,
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
+        );
+        assertEquals(Status.FAILED, process.getStatus());
+    }
+
+    @Test
+    void zeroAmountInTransaction() {
+        AccountService accountService = new AccountServiceStub(true, true, null, false);
+        Process process = new ProcessMock();
+        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ZERO, Currency.getInstance("EUR")), "", process.getUuid());
+        
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
+        
+        assertThrows(
+                UnexpectedValueException.class,
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
+        );
+        assertEquals(Status.FAILED, process.getStatus());
+    }
+
+    @Test
+    void insufficientBalanceForTransaction() {
+        AccountService accountService = new AccountServiceStub(true, true, null, false);
+        Process process = new ProcessMock();
+        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
+
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
+
+        assertThrows(
+                UnexpectedValueException.class,
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
+        );
+        assertEquals(Status.FAILED, process.getStatus());
+    }
+    
+    @Test
+    void crossAccountTransactionSuccessful() {
+        AccountService accountService = new AccountServiceStub(true, true, null, true);
+        Process process = new ProcessMock();
+        ProcessTransaction  processTransaction = new ProcessTransaction(account1, account2, TransactionType.TRANSFER, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
+
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
+
+        depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter);
+        
+        assertEquals(Status.PROCESSED, process.getStatus());
+        assertTrue(published1);
+        assertTrue(published2);
+    }
+    
+    
+    private static class CurrencyConverterStub extends CurrencyConverter {
+
+        public CurrencyConverterStub(ExchangeRateService exchangeRateApi) {
+            super(exchangeRateApi);
+        }
+
+        @Override
+        public BigDecimal convertTo(Currency source, Currency target, BigDecimal amount) {
+            return amount;
+        }
+    }
+
+    private class AccountServiceStub implements AccountService {
+
+        private final boolean isValid1;
+        private final boolean isValid2;
+        private final Currency currency;
+        private final boolean sufficientFunds;
+
+        private AccountServiceStub(boolean isValid1, boolean isValid2, Currency currency, boolean sufficientFunds) {
+            this.isValid1 = isValid1;
+            this.isValid2 = isValid2;
+            this.currency = currency;
+            this.sufficientFunds = sufficientFunds;
+        }
+
+        @Override
+        public Currency getAccountCurrency(Account account) {
+            return currency;
+        }
+
+        @Override
+        public boolean isValid(Account account) {
+            if (account.equals(account1)) {
+                return isValid1;
+            }
+            return isValid2;
+        }
+
+        @Override
+        public boolean accountHasSufficientFunds(Account account, BigDecimal amount) {
+            return sufficientFunds;
+        }
+
+        @Override
+        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account) {
+            if (account.equals(account1)) {
+                published1 = true;
+            } else {
+                published2 = true;
+            }
+        }
+    }
+    
 }
\ No newline at end of file
diff --git a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandlerTest.java b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandlerTest.java
index 66dffd2694ae5ab84e2b57f3ab4ccd2a7adb16ef..10b13732189324ceaacbc04632e2644a8c7db682 100644
--- a/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandlerTest.java
+++ b/transaction-processor/src/test/java/cz/muni/pa165/banking/domain/process/handler/WithdrawHandlerTest.java
@@ -32,9 +32,7 @@ class WithdrawHandlerTest {
 
     private boolean published = false;
 
-    private static Account account;
     private static Process process;
-    private static ProcessTransaction processTransaction;
     private static ProcessRepository processRepository;
     private static ProcessTransactionRepository processTransactionRepository;
     private static ProcessHandler depositHandler;
@@ -42,16 +40,16 @@ class WithdrawHandlerTest {
 
     @BeforeAll
     static void init() {
-        account = new Account("ACC");
+        Account account = new Account("ACC");
         process = new ProcessMock();
-        processTransaction = new ProcessTransaction(account, null, TransactionType.WITHDRAWAL, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.uuid());
+        ProcessTransaction processTransaction = new ProcessTransaction(account, null, TransactionType.WITHDRAWAL, new Money(BigDecimal.ONE, Currency.getInstance("EUR")), "", process.getUuid());
         depositHandler = new WithdrawHandler();
         processRepository = mock(ProcessRepository.class);
         processTransactionRepository = mock(ProcessTransactionRepository.class);
         converter = new CurrencyConverterStub(null);
 
-        when(processRepository.findById(process.uuid())).thenReturn(process);
-        when(processTransactionRepository.findTransactionByProcessId(process.uuid())).thenReturn(processTransaction);
+        when(processRepository.findById(process.getUuid())).thenReturn(process);
+        when(processTransactionRepository.findTransactionByProcessId(process.getUuid())).thenReturn(processTransaction);
     }
 
     @BeforeEach
@@ -65,7 +63,7 @@ class WithdrawHandlerTest {
 
         assertThrows(
                 EntityNotFoundException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -76,7 +74,7 @@ class WithdrawHandlerTest {
 
         assertThrows(
                 UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -87,7 +85,7 @@ class WithdrawHandlerTest {
 
         assertThrows(
                 UnexpectedValueException.class,
-                () -> depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter)
+                () -> depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter)
         );
         assertEquals(Status.FAILED, process.getStatus());
     }
@@ -96,7 +94,7 @@ class WithdrawHandlerTest {
     void withdrawTransactionSuccessful() {
         AccountService accountService = new AccountServiceStub(true, Currency.getInstance("EUR"), true);
         
-        depositHandler.handle(process.uuid(), processRepository, processTransactionRepository, accountService, converter);
+        depositHandler.handle(process.getUuid(), processRepository, processTransactionRepository, accountService, converter);
         
         assertEquals(Status.PROCESSED, process.getStatus());
         assertTrue(published);
@@ -143,7 +141,7 @@ class WithdrawHandlerTest {
         }
 
         @Override
-        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account, String information) {
+        public void publishAccountChange(UUID processUuid, TransactionType transactionType, BigDecimal amount, Account account) {
             published = true;
         }
     }
diff --git a/transaction-processor/src/test/resources/application.properties b/transaction-processor/src/test/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..af598f20e5222b5689c61d4f36ff29ca5174aacb
--- /dev/null
+++ b/transaction-processor/src/test/resources/application.properties
@@ -0,0 +1,6 @@
+spring.h2.console.enabled=true
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=user
+spring.datasource.password=password
+spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
\ No newline at end of file