diff --git a/BookingMicroservice/BookingMicroservice.csproj b/BookingMicroservice/BookingMicroservice.csproj index aac30ec61683d673dfb036a93dd6bf5fc43013a9..b0dc1629551990500350dfd58d6f748d3ebf057a 100644 --- a/BookingMicroservice/BookingMicroservice.csproj +++ b/BookingMicroservice/BookingMicroservice.csproj @@ -18,6 +18,7 @@ </PackageReference> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" /> + <PackageReference Include="Stripe.net" Version="44.1.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" /> </ItemGroup> diff --git a/BookingMicroservice/Controllers/BookingController.cs b/BookingMicroservice/Controllers/BookingController.cs index a8aabdeffd43c409782b18f03074583cd54cbca2..77150c643b32ab9807a43b5f67069ae2e135fc05 100644 --- a/BookingMicroservice/Controllers/BookingController.cs +++ b/BookingMicroservice/Controllers/BookingController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; + namespace BookingMicroservice.Controllers { [ApiController] @@ -13,11 +14,13 @@ namespace BookingMicroservice.Controllers { private readonly IReservationComplianceService reservationComplianceService; private readonly IBookingService bookingService; + private readonly IStripeService stripeService; - public BookingController(IReservationComplianceService reservationComplianceService, IBookingService bookingService) + public BookingController(IReservationComplianceService reservationComplianceService, IBookingService bookingService, IStripeService stripeService) { this.reservationComplianceService = reservationComplianceService; this.bookingService = bookingService; + this.stripeService = stripeService; } [Authorize] @@ -46,13 +49,19 @@ namespace BookingMicroservice.Controllers [HttpPost()] public async Task<IActionResult> MakeBooking([FromBody] BookingCreation bookingCreationModel) { - // TODO: add stripe handling + string? userIdValue = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; if (!int.TryParse(userIdValue, out int userId)) return BadRequest("Unable to get User Id from Token"); try { + bool isPaymentSuccessful = await stripeService.VerifyPaymentIntent(bookingCreationModel.PaymentIntentId); + if (!isPaymentSuccessful) + { + return BadRequest("Payment verification failed."); + } + Booking? booking = await reservationComplianceService.TryCreateBookingAsync(bookingCreationModel.FlightId, userId, bookingCreationModel.BookingClass, bookingCreationModel.SeatId); if (booking == null) return BadRequest("Error in creating booking"); diff --git a/BookingMicroservice/Models/BookingCreation.cs b/BookingMicroservice/Models/BookingCreation.cs index 0e398b9d3e6c6e9eff874335902c683ccaf1f42c..976fd9bd604fe9e832c575afa6aed22129088f32 100644 --- a/BookingMicroservice/Models/BookingCreation.cs +++ b/BookingMicroservice/Models/BookingCreation.cs @@ -5,5 +5,6 @@ public required int FlightId { get; set; } public required BookingClass BookingClass { get; set; } public int? SeatId { get; set; } + public required string PaymentIntentId { get; set; } } } diff --git a/BookingMicroservice/Program.cs b/BookingMicroservice/Program.cs index 74cabbd729d2e59148649da179c50c918bf9dc0d..c2aa2c1631803da388913b75b1d2f611c8940046 100644 --- a/BookingMicroservice/Program.cs +++ b/BookingMicroservice/Program.cs @@ -13,6 +13,7 @@ builder.Services.AddHttpContextAccessor(); builder.Services.AddTransient<RequestCookieHandler>(); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddLogging(); builder.Services.AddSwaggerGen(); builder.Services.AddDbContext<ApplicationDbContext>(options => @@ -59,6 +60,7 @@ builder.Services.AddHttpClient<IFlightServiceClient, FlightServiceClient>(client builder.Services.AddScoped<IBookingService, BookingService>(); builder.Services.AddScoped<IReservationComplianceService, ReservationComplianceService>(); +builder.Services.AddScoped<IStripeService, StripeService>(); var app = builder.Build(); diff --git a/BookingMicroservice/Services/IStripeService.cs b/BookingMicroservice/Services/IStripeService.cs new file mode 100644 index 0000000000000000000000000000000000000000..0c3a0975033b5d9ec786fc54caa8c051cc1a44ba --- /dev/null +++ b/BookingMicroservice/Services/IStripeService.cs @@ -0,0 +1,10 @@ +using BookingMicroservice.Models; +using Stripe; + +namespace BookingMicroservice.Services +{ + public interface IStripeService + { + Task<bool> VerifyPaymentIntent(string paymentIntentId); + } +} \ No newline at end of file diff --git a/BookingMicroservice/Services/StripeService.cs b/BookingMicroservice/Services/StripeService.cs new file mode 100644 index 0000000000000000000000000000000000000000..68963ddf55794bf57b3de7cb95532fdabc7f7def --- /dev/null +++ b/BookingMicroservice/Services/StripeService.cs @@ -0,0 +1,36 @@ +using BookingMicroservice.Models; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using Stripe; +using System; +using System.Threading.Tasks; + +namespace BookingMicroservice.Services +{ + public class StripeService : IStripeService + { + private readonly ILogger<StripeService> _logger; + + public StripeService(ILogger<StripeService> logger, IConfiguration configuration) + { + _logger = logger; + StripeConfiguration.ApiKey = configuration["Stripe:SecretKey"]; + } + + public async Task<bool> VerifyPaymentIntent(string paymentIntentId) + { + var service = new PaymentIntentService(); + try + { + var paymentIntent = await service.GetAsync(paymentIntentId); + _logger.LogInformation($"Payment Intent Status: {paymentIntent.Status}"); + return paymentIntent.Status == "succeeded"; + } + catch (StripeException ex) + { + _logger.LogError($"Error verifying payment intent: {ex.Message}"); + throw new Exception("Failed to verify payment intent: " + ex.Message); + } + } + } +} diff --git a/BookingMicroservice/appsettings.json b/BookingMicroservice/appsettings.json index 7ce4758e8bacea93b6bfa282c518089174e34fb3..a9321d0a03d6d8ed9b2835edff262cbcb0cdc8f9 100644 --- a/BookingMicroservice/appsettings.json +++ b/BookingMicroservice/appsettings.json @@ -16,5 +16,8 @@ }, "FlightMicroservice": { "BaseUrl": "http://localhost:5175" + }, + "Stripe": { + "SecretKey": "sk_test_51P5UhOExQclpActcAn0yMrhaHESmCjtM69JOhjmo4B5AK67WwZn317QZmbunbuanwytn3xxhgVh6wfxEONorblgl00rQbt1YZk" } } diff --git a/GatewayAPI/Models/BookingCreation.cs b/GatewayAPI/Models/BookingCreation.cs index c3134926859c658ace68b0dc5806c7c398270dc8..d0460cd3c54288628ef1837b7cec5362fcd39f3f 100644 --- a/GatewayAPI/Models/BookingCreation.cs +++ b/GatewayAPI/Models/BookingCreation.cs @@ -5,6 +5,6 @@ public required int FlightId { get; set; } public required int BookingClass { get; set; } public int? SeatId { get; set; } - + public required string PaymentIntentId { get; set; } } }