diff --git a/BookingMicroservice/Controllers/BookingController.cs b/BookingMicroservice/Controllers/BookingController.cs index 71d73923f50a9fd4a9d09948bc7489e31d2a9f8f..0a2584ea2955302d68389d4bf7053104fea6df70 100644 --- a/BookingMicroservice/Controllers/BookingController.cs +++ b/BookingMicroservice/Controllers/BookingController.cs @@ -142,6 +142,7 @@ namespace BookingMicroservice.Controllers } } + [Authorize] [HttpPost("create-payment-intent")] public async Task<IActionResult> CreatePaymentIntent([FromBody] PaymentIntentCreateRequest request) { diff --git a/client/src/components/BookingList/BookingCard/BookingCard.tsx b/client/src/components/BookingList/BookingCard/BookingCard.tsx index 4b14a613fb22ce34a7a5f95d7b05aec4a0477c6f..60d2ffca26ac011b8384fe4f8c947f6dfcf5b430 100644 --- a/client/src/components/BookingList/BookingCard/BookingCard.tsx +++ b/client/src/components/BookingList/BookingCard/BookingCard.tsx @@ -24,7 +24,6 @@ function BookingCard({ flight }: IBookingCard) { price: isEconomy ? flight.economyPrice : flight.businessPrice }; try { - //await bookFlight(bookingInfo); alert("Flight booked successfully, navigating to payments page..."); navigate('/booking/payment-form', { state: { bookingInfo } }); } catch (error) { diff --git a/client/src/components/PaymentForm/PaymentForm.tsx b/client/src/components/PaymentForm/PaymentForm.tsx index 0c4eb50e42a61dca6ff82004cd3eeee552f16d38..9afb97afe2fccbb9991553133d353d1c51cb8db2 100644 --- a/client/src/components/PaymentForm/PaymentForm.tsx +++ b/client/src/components/PaymentForm/PaymentForm.tsx @@ -1,9 +1,9 @@ import React, { useState, useEffect } from 'react'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useNavigate } from "react-router-dom"; import Api from "../../helpers/Api"; import { CardElement, useStripe, useElements, Elements } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; -import axios from 'axios'; +import {bookFlight} from "../../services/BookingList/BookingOrder"; import './PaymentForm.scss'; const stripePromise = loadStripe('pk_test_51P5UhOExQclpActcEGkHdut1X1k6uQnEXQ2cKKTD5l9FS9a1TyB2ap1lRSQXZt35Dpd7mh8gHOwFyVb4TiqpZfJr00bDRrD4vF'); @@ -12,6 +12,7 @@ const PaymentForm = () => { const stripe = useStripe(); const elements = useElements(); const location = useLocation(); + const navigate = useNavigate(); const [loading, setLoading] = useState(false); const [bookingInfo, setBookingInfo] = useState(null); const [message, setMessage] = useState(""); @@ -24,38 +25,62 @@ const PaymentForm = () => { }, [location]); useEffect(() => { - if (!bookingInfo || clientSecret) return; - + if (!stripe || !bookingInfo) return; + const fetchClientSecret = async () => { try { - let price = bookingInfo.price; - let priceInCents = price * 100; - const form = { items: [{ price: priceInCents }] }; - const response = await Api.post("Booking/create-payment-intent", form); + const form = { items: [{ price: bookingInfo.price * 100 }] }; + const response = await Api.post("Booking/create-payment-intent", form, { withCredentials: true }); setClientSecret(response.data.clientSecret); - setLoading(false); } catch (error) { console.error('Failed to retrieve client secret:', error); - setLoading(false); + setMessage("Failed to retrieve Stripe secret key"); } }; - + fetchClientSecret(); - }, [bookingInfo, clientSecret]); + }, [stripe, bookingInfo]); const handleSubmit = async (event) => { event.preventDefault(); - if (!stripe || !elements || !clientSecret) { console.log('Stripe.js has not yet loaded or client secret not available.'); return; } + + setLoading(true); + try { + const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, { + payment_method: { + card: elements.getElement(CardElement), + }, + }); + + if (error) { + setMessage(`Payment failed: ${error.message}`); + } else if (paymentIntent && paymentIntent.status === 'succeeded') { + setMessage("Payment succeeded!"); + + const updatedBookingInfo = { + ...bookingInfo, + paymentIntentId: paymentIntent.id + }; + + setBookingInfo(updatedBookingInfo); + + await bookFlight(updatedBookingInfo); + alert("Flight booked successfully!"); + navigate('/customer/bookings'); - setLoading(true); - - - - setLoading(false); + } else { + setMessage(`Payment processed but check status: ${paymentIntent.status}`); + } + } catch (error) { + console.error('Payment confirmation failed:', error); + setMessage("An error occurred while confirming the payment."); + } finally { + setLoading(false); + } }; return ( @@ -63,7 +88,10 @@ const PaymentForm = () => { <form onSubmit={handleSubmit} className="payment-form"> <h3 id="form-heading">Last step!</h3> <p id="form-description">Enter your payment info below.</p> - <CardElement className="StripeElement" /> + <CardElement className="StripeElement" onChange={event => { + setDisabled(event.empty); + setMessage(event.error ? event.error.message : ""); + }} /> <button type="submit" className="button" disabled={!stripe || loading}> {loading ? 'Processing...' : 'Pay'} </button>