-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: get payment status #73 #105
Conversation
WalkthroughThe updates introduce significant modifications to the payment module of the ByteMeBurger API. Major changes include the removal of Changes
Sequence DiagramssequenceDiagram
participant User
participant API
participant PaymentController
participant PaymentService
participant PaymentRepository
User->>API: POST CreateOrderPayment
API->>PaymentController: CreateOrderPaymentAsync
PaymentController->>PaymentService: CreateOrderPaymentAsync
PaymentService->>PaymentRepository: SavePayment
PaymentRepository-->>PaymentService: Payment (saved)
PaymentService-->>PaymentController: PaymentViewModel (without PaymentType)
PaymentController-->>API: PaymentViewModel (without PaymentType)
API-->>User: PaymentDetails
User->>API: GET GetStatus
API->>PaymentController: GetStatus
PaymentController->>PaymentService: GetPaymentAsync
PaymentService->>PaymentRepository: GetPaymentAsync
PaymentRepository-->>PaymentService: Payment (nullable)
PaymentService-->>PaymentController: Payment (nullable)
PaymentController-->>API: PaymentStatusViewModel
API-->>User: PaymentStatusViewModel
This sequence diagram outlines the main interactions for creating an order payment and retrieving payment status in the updated system. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Outside diff range and nitpick comments (1)
src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (1)
Line range hint
1-113
: TheMercadoPagoService
class is well-designed with a clear focus on interacting with the MercadoPago API. It adheres to SOLID principles, particularly with regards to dependency injection and single responsibility.Continue to ensure that each class in the application maintains a single responsibility and utilizes dependency injection for better testability and maintainability.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (18)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentController.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentStatusViewModel.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentTypeViewModel.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentViewModel.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Application/Services/PaymentService.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/Entities/Payment.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentRepository.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentService.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/ValueObjects/PaymentStatus.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/ValueObjects/PaymentType.cs (1 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (2 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Persistence/Constants.cs (2 hunks)
- src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/PaymentRepositoryDapper.cs (2 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/PaymentControllerTest.cs (1 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/FIAP.TechChallenge.ByteMeBurger.Api.Test.csproj (1 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/Services/PaymentServiceTests.cs (1 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/FIAP.TechChallenge.ByteMeBurger.Persistence.Test.csproj (1 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs (3 hunks)
Files not reviewed due to errors (5)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentViewModel.cs (no review received)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/ValueObjects/PaymentStatus.cs (no review received)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentService.cs (no review received)
- src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentRepository.cs (no review received)
- src/FIAP.TechChallenge.ByteMeBurger.Persistence/Constants.cs (no review received)
Files skipped from review due to trivial changes (5)
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentStatusViewModel.cs
- src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentTypeViewModel.cs
- src/FIAP.TechChallenge.ByteMeBurger.Domain/ValueObjects/PaymentType.cs
- tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/FIAP.TechChallenge.ByteMeBurger.Api.Test.csproj
- tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/FIAP.TechChallenge.ByteMeBurger.Persistence.Test.csproj
Additional context used
Path-based instructions (13)
src/FIAP.TechChallenge.ByteMeBurger.Api/Model/Payment/PaymentViewModel.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Domain/ValueObjects/PaymentStatus.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentService.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Domain/Interfaces/IPaymentRepository.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Domain/Entities/Payment.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Application/Services/PaymentService.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentController.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/Services/PaymentServiceTests.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Persistence/Constants.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/PaymentControllerTest.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.Persistence/Repository/PaymentRepositoryDapper.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.
GitHub Check: build
src/FIAP.TechChallenge.ByteMeBurger.Domain/Entities/Payment.cs
[warning] 26-26:
Non-nullable property 'Type' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
[warning] 26-26:
Non-nullable property 'QrCode' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
[warning] 30-30:
Non-nullable property 'Type' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
Additional comments not posted (8)
src/FIAP.TechChallenge.ByteMeBurger.Domain/Entities/Payment.cs (3)
16-16
: Change from string to enum forPaymentType
enhances type safety and consistency.
24-24
: Update inPaymentStatus
property aligns with the new enum values.
30-38
: Use of default parameter forPaymentType
in the constructor is a good practice for optional values.Tools
GitHub Check: build
[warning] 30-30:
Non-nullable property 'Type' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.src/FIAP.TechChallenge.ByteMeBurger.Application/Services/PaymentService.cs (1)
33-36
: MethodGetPaymentAsync
correctly separates concerns by delegating data fetching to the repository.src/FIAP.TechChallenge.ByteMeBurger.Api/Controllers/PaymentController.cs (1)
32-47
: MethodGetStatus
is well-implemented with proper null handling and clear separation of concerns.tests/FIAP.TechChallenge.ByteMeBurger.Application.Test/Services/PaymentServiceTests.cs (1)
46-65
: Test methodGetPaymentAsync_Success
is well-implemented with thorough checks and proper use of mocking.tests/FIAP.TechChallenge.ByteMeBurger.Api.Test/Controllers/PaymentControllerTest.cs (1)
55-78
: The test methodGetStatus_Success
is well-implemented and aligns with the new functionality inPaymentController
. It correctly asserts the expected behavior of theGetStatus
method, ensuring thePaymentStatusViewModel
is returned as expected.src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (1)
68-68
: The assignment ofPaymentType
toMercadoPago
is consistent with the domain changes noted in the summary.
private PaymentCreateRequest MapPaymentCreateRequest(Order order, PaymentPayerRequest payer, | ||
PaymentAdditionalInfoRequest paymentAdditionalInfoRequest) | ||
=> new() | ||
{ | ||
Description = $"Payment for Order {order.TrackingCode.Value}", | ||
ExternalReference = order.TrackingCode.Value, | ||
Installments = 1, | ||
NotificationUrl = _mercadoPagoOptions.NotificationUrl, | ||
Payer = paymentPayerRequest2, | ||
Payer = payer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method MapPaymentCreateRequest
correctly sets up the payment request. However, the TransactionAmount
is hardcoded to 0.01
, which seems like a placeholder.
Ensure that the TransactionAmount
is dynamically calculated based on the order details rather than being hardcoded. This is crucial for accurate payment processing.
.Create(); | ||
|
||
_mockConnection.SetupDapperAsync(c => | ||
c.QuerySingleOrDefaultAsync<PaymentDAO>(Constants.InsertPaymentQuery, null, null, null, null)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a critical issue in the test for GetPaymentAsync_Success
: the query used should be Constants.GetPaymentQuery
, not Constants.InsertPaymentQuery
. This mistake could lead to incorrect test behavior and false positives.
- c.QuerySingleOrDefaultAsync<PaymentDAO>(Constants.InsertPaymentQuery, null, null, null, null))
+ c.QuerySingleOrDefaultAsync<PaymentDAO>(Constants.GetPaymentQuery, null, null, null, null))
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
c.QuerySingleOrDefaultAsync<PaymentDAO>(Constants.InsertPaymentQuery, null, null, null, null)) | |
c.QuerySingleOrDefaultAsync<PaymentDAO>(Constants.GetPaymentQuery, null, null, null, null)) |
public async Task<Payment?> GetPaymentAsync(string paymentId) | ||
{ | ||
throw new NotImplementedException(); | ||
logger.LogInformation("Getting Payment with ID: {PaymentId}", paymentId); | ||
|
||
var paymentDao = await dbConnection.QuerySingleOrDefaultAsync<PaymentDAO>( | ||
Constants.GetPaymentQuery, | ||
param: new { Id = paymentId } | ||
); | ||
|
||
if (paymentDao is null) | ||
{ | ||
return null; | ||
} | ||
|
||
logger.LogInformation("Payment with ID: {PaymentId} retrieved", paymentId); | ||
return new Payment() | ||
{ | ||
Id = new PaymentId(paymentDao.Id, paymentDao.OrderId), | ||
PaymentType = (PaymentType)paymentDao.PaymentType, | ||
// TODO QrCode = paymentDao.QrCode | ||
Amount = paymentDao.Amount, | ||
Created = paymentDao.Created, | ||
Status = (PaymentStatus)paymentDao.Status | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation of GetPaymentAsync
in PaymentRepositoryDapper
correctly retrieves payment details based on the payment ID. However, the method lacks error handling for potential exceptions during database operations, which could improve robustness.
+ try
{
var paymentDao = await dbConnection.QuerySingleOrDefaultAsync<PaymentDAO>(
Constants.GetPaymentQuery, param: new { Id = paymentId });
if (paymentDao is null)
{
return null;
}
return new Payment()
{
Id = new PaymentId(paymentDao.Id, paymentDao.OrderId),
PaymentType = (PaymentType)paymentDao.PaymentType,
Amount = paymentDao.Amount,
Created = paymentDao.Created,
Status = (PaymentStatus)paymentDao.Status
};
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Failed to retrieve payment with ID: {PaymentId}", paymentId);
+ throw;
+ }
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public async Task<Payment?> GetPaymentAsync(string paymentId) | |
{ | |
throw new NotImplementedException(); | |
logger.LogInformation("Getting Payment with ID: {PaymentId}", paymentId); | |
var paymentDao = await dbConnection.QuerySingleOrDefaultAsync<PaymentDAO>( | |
Constants.GetPaymentQuery, | |
param: new { Id = paymentId } | |
); | |
if (paymentDao is null) | |
{ | |
return null; | |
} | |
logger.LogInformation("Payment with ID: {PaymentId} retrieved", paymentId); | |
return new Payment() | |
{ | |
Id = new PaymentId(paymentDao.Id, paymentDao.OrderId), | |
PaymentType = (PaymentType)paymentDao.PaymentType, | |
// TODO QrCode = paymentDao.QrCode | |
Amount = paymentDao.Amount, | |
Created = paymentDao.Created, | |
Status = (PaymentStatus)paymentDao.Status | |
}; | |
public async Task<Payment?> GetPaymentAsync(string paymentId) | |
{ | |
logger.LogInformation("Getting Payment with ID: {PaymentId}", paymentId); | |
try | |
{ | |
var paymentDao = await dbConnection.QuerySingleOrDefaultAsync<PaymentDAO>( | |
Constants.GetPaymentQuery, | |
param: new { Id = paymentId } | |
); | |
if (paymentDao is null) | |
{ | |
return null; | |
} | |
logger.LogInformation("Payment with ID: {PaymentId} retrieved", paymentId); | |
return new Payment() | |
{ | |
Id = new PaymentId(paymentDao.Id, paymentDao.OrderId), | |
PaymentType = (PaymentType)paymentDao.PaymentType, | |
// TODO QrCode = paymentDao.QrCode | |
Amount = paymentDao.Amount, | |
Created = paymentDao.Created, | |
Status = (PaymentStatus)paymentDao.Status | |
}; | |
} | |
catch (Exception ex) | |
{ | |
logger.LogError(ex, "Failed to retrieve payment with ID: {PaymentId}", paymentId); | |
throw; | |
} | |
} |
|
||
public Payment(PaymentId id) | ||
: base(id) | ||
public Payment() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-nullable properties Type
and QrCode
must be initialized to prevent runtime exceptions.
public Payment()
{
+ Type = default!;
+ QrCode = default!;
}
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public Payment() | |
public Payment() | |
{ | |
Type = default!; | |
QrCode = default!; | |
} |
Tools
GitHub Check: build
[warning] 26-26:
Non-nullable property 'Type' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
[warning] 26-26:
Non-nullable property 'QrCode' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (5 hunks)
- tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- tests/FIAP.TechChallenge.ByteMeBurger.Persistence.Test/Repository/PaymentRepositoryDapperTest.cs
Additional context used
Path-based instructions (1)
src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (1)
Pattern
**/*.cs
: Validate all files and structures against Domain Driven Design, SOLID and Clean Architecture principles.
Additional comments not posted (3)
src/FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway/MercadoPagoService.cs (3)
51-53
: Ensure correct calculation of the total amount.The calculation of
totalAmount
using the sum ofQuantity * UnitPrice
for each item is appropriate and follows standard e-commerce practices.
Line range hint
59-71
: Review the handling of payment status and creation of domain payment object.The method handles the conversion of the MercadoPago payment status to the domain-specific
PaymentStatus
and creates aDomainPayment
object with appropriate properties set. This shows good use of external API data transformation into the domain model.
108-119
: Validate the completeness and correctness of the payment creation request.The
MapPaymentCreateRequest
function properly sets up the payment creation request with all necessary fields, including payment method, transaction amount, and expiration time. This setup is crucial for ensuring that the payment process adheres to the expected standards and requirements.
@@ -21,6 +21,7 @@ namespace FIAP.TechChallenge.ByteMeBurger.MercadoPago.Gateway; | |||
public class MercadoPagoService : IPaymentGateway | |||
{ | |||
private readonly MercadoPagoOptions _mercadoPagoOptions; | |||
private const decimal IntegrationPrice = 0.01M; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider replacing the hardcoded integration price with a dynamic value.
The IntegrationPrice
is set to a constant value of 0.01M
, which is likely a placeholder. For a production environment, it's essential to calculate the price based on the actual order details or settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm keeping this value so I can run tests in production with lower values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@italopessoa, I understand the practicality of using a hardcoded value like 0.01M
for IntegrationPrice
to facilitate testing with lower values in a production environment. To maintain this flexibility while minimizing potential risks, you might consider implementing this as a configurable setting. This way, you can easily switch between test and production values without modifying the codebase, ensuring that test configurations do not inadvertently affect live operations. This approach could enhance both safety and maintainability. If you need help setting this up, feel free to ask!
@@ -94,7 +95,7 @@ private static IEnumerable<PaymentItemRequest> MapPaymentItemRequests(Order orde | |||
Description = item.ProductName, | |||
CategoryId = "food", | |||
Quantity = item.Quantity, | |||
UnitPrice = item.UnitPrice, | |||
UnitPrice = IntegrationPrice, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor to use dynamic unit pricing.
The UnitPrice
is currently set to the hardcoded IntegrationPrice
. This should ideally be replaced with dynamic pricing based on the actual product or service being purchased.
- UnitPrice = IntegrationPrice,
+ UnitPrice = item.Price, // Assuming `item.Price` holds the actual price of the product.
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
UnitPrice = IntegrationPrice, | |
UnitPrice = item.Price, // Assuming `item.Price` holds the actual price of the product. |
No description provided.