Skip to content

Commit

Permalink
Merge pull request #2 from FIAP-3SOAT-G15/feature/hello-payments-api
Browse files Browse the repository at this point in the history
hellp payments api
  • Loading branch information
wellyfrs authored May 16, 2024
2 parents 7fc45bd + 58a725e commit 60725ae
Show file tree
Hide file tree
Showing 106 changed files with 1,237 additions and 1,795 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN mvn clean package -DskipTests

FROM eclipse-temurin:17-jdk

ARG JAR_FILE=stockapi.jar
ARG JAR_FILE=payments.jar

WORKDIR /opt/app

Expand Down
65 changes: 31 additions & 34 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
version: '3.7'

services:
#api:
# image: stock-api:latest
# container_name: app
# build:
# context: .
# dockerfile: Dockerfile
# depends_on:
# - stock_db
# environment:
# - DB_ENDPOINT=db:5432
# - DB_NAME=selforder
# - DB_USERNAME=selforder
# - DB_PASSWORD=self@Order123!
# - ADMIN_ACCESS_TOKEN=token
# - MOCK_PAYMENT_PROVIDER=true
# - MP_TOKEN=token
# - MP_USER_ID=userId
# - MP_POS_ID=postId
# - MP_WEBHOOK_BASE_URL=webhookBaseUrl
# ports:
# - "8080:8080"
# restart: always
# api:
# image: tech-challenge:latest
# container_name: app
# build:
# context: .
# dockerfile: Dockerfile
# depends_on:
# - db
# environment:
# - DB_ENDPOINT=db:5432
# - DB_NAME=selforder
# - DB_USERNAME=selforder
# - DB_PASSWORD=self@Order123!
# - ADMIN_ACCESS_TOKEN=token
# - MOCK_PAYMENT_PROVIDER=true
# - MP_TOKEN=token
# - MP_USER_ID=userId
# - MP_POS_ID=postId
# - MP_WEBHOOK_BASE_URL=webhookBaseUrl
# ports:
# - "8080:8080"
# restart: always

stock_db:
image: postgres:15.4
container_name: stock_db
volumes:
- stock_db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=stock
- POSTGRES_USER=selforder
- POSTGRES_PASSWORD=self@Order123!
payment_db:
image: amazon/dynamodb-local:latest
ports:
- "5432:5432"
restart: always
- "54000:8000"
environment:
AWS_ACCESS_KEY_ID: "fakekey"
AWS_SECRET_ACCESS_KEY: "fakeaccesskey"
AWS_REGION: us-east-2
command: ["-D\"java.library.path\"=./DynamoDBLocal_lib", "-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"]

volumes:
stock_db:
db:
driver: local
37 changes: 14 additions & 23 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<version>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.fiap</groupId>
<artifactId>stock-api</artifactId>
<artifactId>payments</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>stock-api</name>
<name>payments</name>
<description>API</description>
<properties>
<java.version>17</java.version>
Expand Down Expand Up @@ -44,21 +44,6 @@
<artifactId>hibernate-core</artifactId>
<version>6.1.7.Final</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.4</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>9.22.3</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
Expand All @@ -78,6 +63,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -95,9 +81,14 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>1.12.719</version>
</dependency>
<dependency>
<groupId>io.github.boostchicken</groupId>
<artifactId>spring-data-dynamodb</artifactId>
<version>5.2.5</version>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
Expand Down Expand Up @@ -129,7 +120,7 @@
</dependencies>
</dependencyManagement>
<build>
<finalName>selfordermanagement</finalName>
<finalName>payments</finalName>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
Expand Down Expand Up @@ -291,7 +282,7 @@
<executions>
<execution>
<configuration>
<mainClass>com.fiap.stock.StockApiApp</mainClass>
<mainClass>com.fiap.payments.PaymentsApplication</mainClass>
</configuration>
</execution>
<execution>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.fiap.stock
package com.fiap.payments

import io.swagger.v3.oas.annotations.OpenAPIDefinition
import io.swagger.v3.oas.annotations.info.Contact
import io.swagger.v3.oas.annotations.info.Info
import io.swagger.v3.oas.annotations.servers.Server
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
import org.springframework.boot.runApplication

@SpringBootApplication
@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
@OpenAPIDefinition(
info =
Info(
Expand All @@ -26,8 +27,8 @@ import org.springframework.boot.runApplication
Server(url = "/"),
],
)
class StockApiApp
class PaymentsApp

fun main(args: Array<String>) {
runApplication<StockApiApp>(*args)
runApplication<PaymentsApp>(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.fiap.payments.adapter.controller

import com.fiap.payments.domain.entities.Payment
import com.fiap.payments.driver.web.PaymentAPI
import com.fiap.payments.usecases.LoadPaymentUseCase
import com.fiap.payments.usecases.SyncPaymentUseCase
import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RestController

@RestController
class PaymentController(
private val loadPaymentUseCase: LoadPaymentUseCase,
private val syncPaymentUseCase: SyncPaymentUseCase
) : PaymentAPI {
private val log = LoggerFactory.getLogger(javaClass)

override fun findAll(): ResponseEntity<List<Payment>> {
return ResponseEntity.ok(loadPaymentUseCase.findAll())
}

override fun getByOrderNumber(orderNumber: Long): ResponseEntity<Payment> {
return ResponseEntity.ok(loadPaymentUseCase.getByOrderNumber(orderNumber))
}

/**
* The server response is important to flag the provider for retries
*/
override fun notify(orderNumber: Long, resourceId: String, topic: String): ResponseEntity<Any> {
// TODO: verify x-signature header by Mercado Pago
log.info("Notification received for order ${orderNumber}: type=${topic} externalId=${resourceId}")

when (topic) {
IPNType.MERCHANT_ORDER.ipnType -> {
syncPaymentUseCase.syncPayment(orderNumber, resourceId)
return ResponseEntity.ok().build()
}
IPNType.PAYMENT.ipnType -> {
val payment = loadPaymentUseCase.getByOrderNumber(orderNumber)
payment.externalOrderGlobalId?.let {
syncPaymentUseCase.syncPayment(orderNumber, it)
return ResponseEntity.ok().build()
}
// returns server error because external order global ID was not previously saved,
// which does not conform with the usual application flow
return ResponseEntity.internalServerError().build()
}
else -> {
// returns bad request because application does not accept this kind of IPN types
return ResponseEntity.badRequest().build()
}
}
}

enum class IPNType(val ipnType: String) {
MERCHANT_ORDER("merchant_order"),
PAYMENT("payment"),
CHARGEBACK("chargebacks"),
POINT_INTEGRATION_IPN("point_integration_ipn"),
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package com.fiap.stock.adapter.controller.configuration
package com.fiap.payments.adapter.controller.configuration

import com.fiap.stock.domain.errors.ErrorType
import com.fiap.stock.domain.errors.SelfOrderManagementException
import com.fiap.payments.domain.errors.ErrorType
import com.fiap.payments.domain.errors.paymentsException
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler

@ControllerAdvice
class ControllerExceptionHandler {
@ExceptionHandler(SelfOrderManagementException::class)
protected fun domainErrorHandler(domainException: SelfOrderManagementException): ResponseEntity<ApiError> {
@ExceptionHandler(paymentsException::class)
protected fun domainErrorHandler(domainException: paymentsException): ResponseEntity<ApiError> {
val apiErrorResponseEntity: ApiErrorResponseEntity =
when (domainException.errorType) {
ErrorType.PRODUCT_ALREADY_EXISTS,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.fiap.payments.adapter.controller.configuration

import com.fiap.payments.PaymentsApp
import com.fiap.payments.adapter.gateway.PaymentGateway
import com.fiap.payments.adapter.gateway.PaymentProviderGateway
import com.fiap.payments.usecases.LoadPaymentUseCase
import com.fiap.payments.usecases.services.PaymentSyncService
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import services.PaymentService

@Configuration
@ComponentScan(basePackageClasses = [PaymentsApp::class])
class ServiceConfig {


@Bean
fun createPaymentService(
paymentRepository: PaymentGateway,
paymentProvider: PaymentProviderGateway,
): PaymentService {
return PaymentService(
paymentRepository,
paymentProvider
)
}

@Bean
fun paymentSyncService(
loadPaymentUseCase: LoadPaymentUseCase,
paymentGateway: PaymentGateway,
paymentProvider: PaymentProviderGateway,
): PaymentSyncService {
return PaymentSyncService(
loadPaymentUseCase,
paymentGateway,
paymentProvider,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.fiap.payments.adapter.gateway

import com.fiap.payments.domain.entities.Payment

interface PaymentGateway {
fun findByOrderNumber(orderNumber: Long): Payment?

fun findAll(): List<Payment>

fun create(payment: Payment): Payment

fun update(payment: Payment): Payment
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.fiap.payments.adapter.gateway

import com.fiap.payments.domain.entities.Order
import com.fiap.payments.domain.entities.PaymentRequest
import com.fiap.payments.domain.valueobjects.PaymentStatus


interface PaymentProviderGateway {
fun createExternalOrder(order: Order): PaymentRequest

fun checkExternalOrderStatus(externalOrderGlobalId: String): PaymentStatus
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.fiap.stock.adapter.gateway
package com.fiap.payments.adapter.gateway

interface TransactionalGateway {
fun <T> transaction(code: () -> T): T
Expand Down
Loading

0 comments on commit 60725ae

Please sign in to comment.