This repository has been archived by the owner on Dec 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into refactor/folder-struc…
…ture-clean-architecture
- Loading branch information
Showing
44 changed files
with
1,024 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
curl -X POST \ | ||
'https://api.mercadopago.com/pos'\ | ||
-H 'Content-Type: application/json' \ | ||
-H "Authorization: Bearer $MERCADOPAGO_PRIVATE_ACCESS_TOKEN" \ | ||
-d '{ | ||
"category": 5611203, | ||
"external_id": "STORE00001POS001", | ||
"external_store_id": "STORE00001", | ||
"fixed_amount": true, | ||
"name": "First POS", | ||
"store_id": 62212711 | ||
}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
curl -X POST \ | ||
'https://api.mercadopago.com/users/1910105219/stores'\ | ||
-H 'Content-Type: application/json' \ | ||
-H "Authorization: Bearer $MERCADOPAGO_PRIVATE_ACCESS_TOKEN" \ | ||
-d '{ | ||
"business_hours": { | ||
"monday": [ | ||
{ | ||
"open": "08:00", | ||
"close": "23:00" | ||
} | ||
], | ||
"tuesday": [ | ||
{ | ||
"open": "08:00", | ||
"close": "23:00" | ||
} | ||
], | ||
"wednesday": [ | ||
{ | ||
"open": "08:00", | ||
"close": "23:00" | ||
} | ||
], | ||
"thursday": [ | ||
{ | ||
"open": "08:00", | ||
"close": "23:00" | ||
} | ||
], | ||
"friday": [ | ||
{ | ||
"open": "08:00", | ||
"close": "23:00" | ||
} | ||
], | ||
"saturday": [ | ||
{ | ||
"open": "13:00", | ||
"close": "22:00" | ||
} | ||
], | ||
"sunday": [ | ||
{ | ||
"open": "13:00", | ||
"close": "22:00" | ||
} | ||
] | ||
}, | ||
"external_id": "STORE00001", | ||
"location": { | ||
"street_number": "1106", | ||
"street_name": "Av. Paulista", | ||
"city_name": "São Paulo", | ||
"state_name": "São Paulo", | ||
"latitude": -23.5640485, | ||
"longitude": -46.6526571, | ||
"reference": "" | ||
}, | ||
"name": "Fastfood FIAP" | ||
}' |
94 changes: 94 additions & 0 deletions
94
src/main/java/br/com/fiap/grupo30/fastfood/adapters/out/mercadopago/MercadoPagoAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package br.com.fiap.grupo30.fastfood.adapters.out.mercadopago; | ||
|
||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.OrderDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoPaymentDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoQrCodeDTO; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.net.URI; | ||
import java.net.http.HttpClient; | ||
import java.net.http.HttpRequest; | ||
import java.net.http.HttpResponse; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class MercadoPagoAdapter { | ||
|
||
@Value("${integrations.mercadopago.base-url}") | ||
private String baseUrl; | ||
|
||
@Value("${integrations.mercadopago.public-key}") | ||
private String publicKey; | ||
|
||
@Value("${integrations.mercadopago.access-token}") | ||
private String privateAccessToken; | ||
|
||
@Value("${integrations.mercadopago.app-user-id}") | ||
private Long appUserId; | ||
|
||
@Value("${integrations.mercadopago.point-of-sale-id}") | ||
private String pointOfSaleId; | ||
|
||
@Value("${integrations.mercadopago.notifications-url}") | ||
private String notificationsUrl; | ||
|
||
@Value("${integrations.mercadopago.payment-collection.user-id}") | ||
private String userIdForPaymentCollection; | ||
|
||
private final MercadoPagoRequestBuilder requestBuilder; | ||
|
||
public MercadoPagoAdapter(MercadoPagoRequestBuilder requestBuilder) { | ||
this.requestBuilder = requestBuilder; | ||
} | ||
|
||
public MercadoPagoQrCodeDTO createQrCodeForPaymentCollection(OrderDTO order) throws Exception { | ||
String resourceUrlTemplate = | ||
"https://api.mercadopago.com/instore/orders/qr/seller/collectors/%s/pos/%s/qrs"; | ||
String resourceUrl = String.format(resourceUrlTemplate, appUserId, pointOfSaleId); | ||
|
||
var requestBody = | ||
this.requestBuilder.buildQrCodePaymentCollectionRequest(order, notificationsUrl); | ||
|
||
ObjectMapper mapper = new ObjectMapper(); | ||
String serializedRequestBody = mapper.writeValueAsString(requestBody); | ||
|
||
try (HttpClient client = HttpClient.newHttpClient()) { | ||
HttpRequest request = | ||
HttpRequest.newBuilder() | ||
.uri(URI.create(resourceUrl)) | ||
.header("Authorization", String.format("Bearer %s", privateAccessToken)) | ||
.header("Content-type", "application/json") | ||
.PUT(HttpRequest.BodyPublishers.ofString(serializedRequestBody)) | ||
.build(); | ||
|
||
HttpResponse<String> response = | ||
client.send(request, HttpResponse.BodyHandlers.ofString()); | ||
MercadoPagoQrCodeDTO result = | ||
mapper.readValue(response.body(), MercadoPagoQrCodeDTO.class); | ||
|
||
return result; | ||
} | ||
} | ||
|
||
public MercadoPagoPaymentDTO getPayment(String paymentId) throws Exception { | ||
String resourceUrlTemplate = "https://api.mercadopago.com/v1/payments/%s"; | ||
String resourceUrl = String.format(resourceUrlTemplate, paymentId); | ||
|
||
try (HttpClient client = HttpClient.newHttpClient()) { | ||
HttpRequest request = | ||
HttpRequest.newBuilder() | ||
.uri(URI.create(resourceUrl)) | ||
.header("Authorization", String.format("Bearer %s", privateAccessToken)) | ||
.header("Content-type", "application/json") | ||
.GET() | ||
.build(); | ||
|
||
HttpResponse<String> response = | ||
client.send(request, HttpResponse.BodyHandlers.ofString()); | ||
MercadoPagoPaymentDTO result = | ||
new ObjectMapper().readValue(response.body(), MercadoPagoPaymentDTO.class); | ||
|
||
return result; | ||
} | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...java/br/com/fiap/grupo30/fastfood/adapters/out/mercadopago/MercadoPagoRequestBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package br.com.fiap.grupo30.fastfood.adapters.out.mercadopago; | ||
|
||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.OrderDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoCashOutDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoCreateQrCodeForPaymentCollectionRequestDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoOrderItemDTO; | ||
import java.time.Instant; | ||
import java.util.Date; | ||
import java.util.stream.Stream; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class MercadoPagoRequestBuilder { | ||
public MercadoPagoCreateQrCodeForPaymentCollectionRequestDTO | ||
buildQrCodePaymentCollectionRequest(OrderDTO order, String notificationsUrl) { | ||
String orderId = order.getOrderId().toString(); | ||
MercadoPagoCreateQrCodeForPaymentCollectionRequestDTO requestBody = | ||
new MercadoPagoCreateQrCodeForPaymentCollectionRequestDTO(); | ||
requestBody.setTitle(String.format("Pedido %s", orderId)); | ||
requestBody.setDescription(String.format("Pedido da lanchonete fastfood")); | ||
requestBody.setExpirationDate(Date.from(Instant.now().plusSeconds(3600))); | ||
requestBody.setExternalReference(orderId); | ||
requestBody.setTotalAmount(order.getTotalPrice()); | ||
requestBody.setNotificationUrl(notificationsUrl); | ||
|
||
MercadoPagoCashOutDTO cashOut = new MercadoPagoCashOutDTO(); | ||
cashOut.setAmount(order.getTotalPrice()); | ||
|
||
MercadoPagoOrderItemDTO[] items = | ||
Stream.of(order.getItems()) | ||
.map( | ||
(ourOrderItem) -> { | ||
MercadoPagoOrderItemDTO theirOrderItem = | ||
new MercadoPagoOrderItemDTO(); | ||
theirOrderItem.setTitle(ourOrderItem.getProduct().getName()); | ||
theirOrderItem.setDescription( | ||
ourOrderItem.getProduct().getDescription()); | ||
theirOrderItem.setCategory( | ||
ourOrderItem.getProduct().getCategory().getName()); | ||
theirOrderItem.setQuantity(ourOrderItem.getQuantity()); | ||
theirOrderItem.setUnitPrice( | ||
ourOrderItem.getProduct().getPrice()); | ||
theirOrderItem.setUnitMeasure("unit"); | ||
theirOrderItem.setTotalAmount(ourOrderItem.getTotalPrice()); | ||
return theirOrderItem; | ||
}) | ||
.toArray(MercadoPagoOrderItemDTO[]::new); | ||
requestBody.setItems(items); | ||
|
||
return requestBody; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
.../com/fiap/grupo30/fastfood/domain/usecases/payment/CollectOrderPaymentViaCashUseCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package br.com.fiap.grupo30.fastfood.domain.usecases.payment; | ||
|
||
import br.com.fiap.grupo30.fastfood.infrastructure.persistence.entities.OrderEntity; | ||
import br.com.fiap.grupo30.fastfood.infrastructure.persistence.repositories.JpaOrderRepository; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.CollectPaymentViaCashRequest; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.OrderDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.exceptions.ResourceNotFoundException; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class CollectOrderPaymentViaCashUseCase { | ||
private final JpaOrderRepository orderRepository; | ||
|
||
@Autowired | ||
public CollectOrderPaymentViaCashUseCase(JpaOrderRepository orderRepository) { | ||
this.orderRepository = orderRepository; | ||
} | ||
|
||
public OrderDTO execute(Long orderId, CollectPaymentViaCashRequest payment) { | ||
OrderEntity order = | ||
this.orderRepository | ||
.findById(orderId) | ||
.orElseThrow(() -> new ResourceNotFoundException("Order not found")); | ||
|
||
order.setPaymentCollected(payment.getAmount()); | ||
|
||
return this.orderRepository.save(order).toDTO(); | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
...ap/grupo30/fastfood/domain/usecases/payment/CollectOrderPaymentViaMercadoPagoUseCase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package br.com.fiap.grupo30.fastfood.domain.usecases.payment; | ||
|
||
import br.com.fiap.grupo30.fastfood.adapters.out.mercadopago.MercadoPagoAdapter; | ||
import br.com.fiap.grupo30.fastfood.infrastructure.persistence.entities.OrderEntity; | ||
import br.com.fiap.grupo30.fastfood.infrastructure.persistence.repositories.JpaOrderRepository; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoPaymentDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.MercadoPagoPaymentStatus; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.mercadopago.events.MercadoPagoActionEventDTO; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.exceptions.PaymentProcessingFailedException; | ||
import br.com.fiap.grupo30.fastfood.presentation.presenters.exceptions.ResourceNotFoundException; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class CollectOrderPaymentViaMercadoPagoUseCase { | ||
private final JpaOrderRepository orderRepository; | ||
private final MercadoPagoAdapter mercadoPagoAdapter; | ||
|
||
@Autowired | ||
public CollectOrderPaymentViaMercadoPagoUseCase( | ||
JpaOrderRepository orderRepository, MercadoPagoAdapter mercadoPagoAdapter) { | ||
this.orderRepository = orderRepository; | ||
this.mercadoPagoAdapter = mercadoPagoAdapter; | ||
} | ||
|
||
public void execute(MercadoPagoActionEventDTO mercadoPagoPaymentEvent) { | ||
try { | ||
MercadoPagoPaymentDTO payment = | ||
this.mercadoPagoAdapter.getPayment(mercadoPagoPaymentEvent.getData().getId()); | ||
|
||
OrderEntity order = | ||
this.orderRepository | ||
.findById(Long.parseLong(payment.getExternalReference())) | ||
.orElseThrow(() -> new ResourceNotFoundException("Order not found")); | ||
|
||
if (MercadoPagoPaymentStatus.APPROVED.getValue().equals(payment.getStatus())) { | ||
order.setPaymentCollected(payment.getTransactionAmount()); | ||
} else { | ||
order.setPaymentRejected(); | ||
} | ||
|
||
this.orderRepository.save(order); | ||
|
||
} catch (Exception e) { | ||
throw new PaymentProcessingFailedException("Could not process payment collection", e); | ||
} | ||
} | ||
} |
Oops, something went wrong.