From 137c3f70eac9e3214183029461fcb9eba0c073c5 Mon Sep 17 00:00:00 2001
From: paula_rodriguezslash <paula.rodriguez@slashmobility.com>
Date: Mon, 15 Apr 2024 18:47:24 +0100
Subject: [PATCH] stripe working woop woop

---
 .../BookingMicroservice.csproj                |  1 +
 .../Controllers/BookingController.cs          | 15 ++++++--
 BookingMicroservice/Models/BookingCreation.cs |  1 +
 BookingMicroservice/Program.cs                |  2 ++
 .../Services/BookingService.cs                |  2 +-
 .../Services/IBookingService.cs               |  2 +-
 .../Services/IReservationComplianceService.cs |  2 +-
 .../Services/IStripeService.cs                | 10 ++++++
 .../Services/ReservationComplianceService.cs  |  4 +--
 BookingMicroservice/Services/StripeService.cs | 36 +++++++++++++++++++
 BookingMicroservice/appsettings.json          |  3 ++
 GatewayAPI/Models/BookingCreation.cs          |  2 +-
 12 files changed, 71 insertions(+), 9 deletions(-)
 create mode 100644 BookingMicroservice/Services/IStripeService.cs
 create mode 100644 BookingMicroservice/Services/StripeService.cs

diff --git a/BookingMicroservice/BookingMicroservice.csproj b/BookingMicroservice/BookingMicroservice.csproj
index aac30ec..b0dc162 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 de800b6..1ca7bc7 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,14 +49,20 @@ 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
             {
-                Booking? booking = await reservationComplianceService.TryCreateBookingAsync(bookingCreationModel.FlightId, userId, bookingCreationModel.BookingClass, bookingCreationModel.SeatId);
+                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, bookingCreationModel.PaymentIntentId);
                 if (booking == null)
                     return BadRequest("Error in creating booking");
 
diff --git a/BookingMicroservice/Models/BookingCreation.cs b/BookingMicroservice/Models/BookingCreation.cs
index 0e398b9..976fd9b 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 74cabbd..c2aa2c1 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/BookingService.cs b/BookingMicroservice/Services/BookingService.cs
index 4c7a4fd..f869115 100644
--- a/BookingMicroservice/Services/BookingService.cs
+++ b/BookingMicroservice/Services/BookingService.cs
@@ -30,7 +30,7 @@ namespace BookingMicroservice.Services
             return bookings;
         }
 
-        public Booking CreateBooking(int flightId, int userId, BookingClass bookingClass)
+        public Booking CreateBooking(int flightId, int userId, BookingClass bookingClass, string paymentIntentId)
         {
             Booking booking = new Booking(flightId, userId, bookingClass, null);
 
diff --git a/BookingMicroservice/Services/IBookingService.cs b/BookingMicroservice/Services/IBookingService.cs
index b5bd327..ddb2e27 100644
--- a/BookingMicroservice/Services/IBookingService.cs
+++ b/BookingMicroservice/Services/IBookingService.cs
@@ -4,7 +4,7 @@ namespace BookingMicroservice.Services
 {
     public interface IBookingService
     {
-        Booking CreateBooking(int flightId, int userId, BookingClass bookingClass);
+        Booking CreateBooking(int flightId, int userId, BookingClass bookingClass, string paymentIntentId);
         List<Booking> GetBookings(int? flightId = null, int? userId = null, BookingClass? bookingClass = null);
         Booking? GetBooking(int bookingId);
         void DeleteBooking(int bookingId);
diff --git a/BookingMicroservice/Services/IReservationComplianceService.cs b/BookingMicroservice/Services/IReservationComplianceService.cs
index 7f82720..9264196 100644
--- a/BookingMicroservice/Services/IReservationComplianceService.cs
+++ b/BookingMicroservice/Services/IReservationComplianceService.cs
@@ -4,7 +4,7 @@ namespace BookingMicroservice.Services
 {
     public interface IReservationComplianceService
     {
-        Task<Booking?> TryCreateBookingAsync(int flightId, int userId, BookingClass bookingClass, int? seatId);
+        Task<Booking?> TryCreateBookingAsync(int flightId, int userId, BookingClass bookingClass, int? seatId, string paymentIntentId);
         Task TryBookSeatAsync(int bookingId, int seatId);
 
     }
diff --git a/BookingMicroservice/Services/IStripeService.cs b/BookingMicroservice/Services/IStripeService.cs
new file mode 100644
index 0000000..0c3a097
--- /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/ReservationComplianceService.cs b/BookingMicroservice/Services/ReservationComplianceService.cs
index df3f6a6..8558ef4 100644
--- a/BookingMicroservice/Services/ReservationComplianceService.cs
+++ b/BookingMicroservice/Services/ReservationComplianceService.cs
@@ -18,7 +18,7 @@ namespace BookingMicroservice.Services
             this.flightServiceClient = flightServiceClient;
         }
 
-        public async Task<Booking?> TryCreateBookingAsync(int flightId, int userId, BookingClass bookingClass, int? seatId)
+        public async Task<Booking?> TryCreateBookingAsync(int flightId, int userId, BookingClass bookingClass, int? seatId, string paymentIntentId)
         {
             HttpResponseMessage capacityResponse = await flightServiceClient.GetFlightCapacityAsync(flightId, (int)bookingClass);
             if (!capacityResponse.IsSuccessStatusCode)
@@ -34,7 +34,7 @@ namespace BookingMicroservice.Services
             if (currentBookings >= capacity)
                 throw new BookingException(string.Format(NO_AVAILABLE_SEAT_MSG, bookingClass.ToString().ToLower()));
 
-            Booking booking = bookingService.CreateBooking(flightId, userId, bookingClass);
+            Booking booking = bookingService.CreateBooking(flightId, userId, bookingClass, paymentIntentId);
             if(seatId.HasValue && booking?.Id != null)
             {
                 try
diff --git a/BookingMicroservice/Services/StripeService.cs b/BookingMicroservice/Services/StripeService.cs
new file mode 100644
index 0000000..68963dd
--- /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 7ce4758..a9321d0 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 c313492..d0460cd 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; }
     }
 }
-- 
GitLab