+
-
-
-
-
\ No newline at end of file
+
diff --git a/migrations/20251015_add_menu_item_id_to_cart.sql b/migrations/20251015_add_menu_item_id_to_cart.sql
new file mode 100644
index 00000000..0d51ca67
--- /dev/null
+++ b/migrations/20251015_add_menu_item_id_to_cart.sql
@@ -0,0 +1,4 @@
+ALTER TABLE cart DROP CONSTRAINT IF EXISTS fk_menu_item;
+ALTER TABLE cart DROP COLUMN IF EXISTS menu_item_id;
+ALTER TABLE cart ADD COLUMN menu_item_id INT;
+ALTER TABLE cart ADD CONSTRAINT fk_menu_item FOREIGN KEY (menu_item_id) REFERENCES menu_items(id);
\ No newline at end of file
diff --git a/migrations/20251015_create_restaurants_and_menu_items_tables.sql b/migrations/20251015_create_restaurants_and_menu_items_tables.sql
new file mode 100644
index 00000000..4819a003
--- /dev/null
+++ b/migrations/20251015_create_restaurants_and_menu_items_tables.sql
@@ -0,0 +1,36 @@
+DROP TABLE IF EXISTS menu_items CASCADE;
+DROP TABLE IF EXISTS restaurants CASCADE;
+
+CREATE TABLE restaurants (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ image_url VARCHAR(255)
+);
+
+CREATE TABLE menu_items (
+ id SERIAL PRIMARY KEY,
+ restaurant_id INT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ price DECIMAL(10, 2) NOT NULL,
+ image_url VARCHAR(255),
+ FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE
+);
+
+-- Insert some sample data for demonstration purposes
+INSERT INTO restaurants (name, description, image_url) VALUES
+('The Gourmet Kitchen', 'A fine dining experience with a modern twist.', 'assets/images/hero.jpg'),
+('Pizza Palace', 'The best pizza in town, made with fresh ingredients.', 'assets/pasted-20251014-230507-170c4564.jpg'),
+('Taco Town', 'Authentic Mexican street tacos and burritos.', 'assets/pasted-20251014-230144-ecd85886.webp');
+
+INSERT INTO menu_items (restaurant_id, name, description, price) VALUES
+(1, 'Steak Frites', 'Juicy steak with a side of crispy french fries.', 25.50),
+(1, 'Salmon en Papillote', 'Salmon baked with herbs and lemon.', 22.00),
+(1, 'Chocolate Lava Cake', 'Warm chocolate cake with a gooey center.', 8.00),
+(2, 'Margherita Pizza', 'Classic pizza with tomato, mozzarella, and basil.', 12.00),
+(2, 'Pepperoni Pizza', 'A crowd-pleaser with spicy pepperoni.', 14.50),
+(2, 'Garlic Bread', 'Toasted bread with garlic butter and herbs.', 5.00),
+(3, 'Carne Asada Tacos', 'Grilled steak tacos with onion and cilantro.', 3.50),
+(3, 'Al Pastor Tacos', 'Marinated pork tacos with pineapple.', 3.50),
+(3, 'Chicken Burrito', 'A large burrito filled with chicken, rice, and beans.', 10.00);
\ No newline at end of file
diff --git a/payment-cancel.php b/payment-cancel.php
index 10bebf0c..577a81b0 100644
--- a/payment-cancel.php
+++ b/payment-cancel.php
@@ -1,16 +1,22 @@
-
-
Payment Canceled
-
Your payment process was canceled. You have not been charged.
-
-
You can return to your cart to review your items or go back to the homepage.
+
+
+
+
Payment Canceled
+
Your payment was canceled. You have not been charged.
+
+
You can continue shopping or go back to your cart.
+
+
Back to Home
+
View Cart
+
-
Back to Cart
-
Back to Home
-
+
\ No newline at end of file
diff --git a/payment-success.php b/payment-success.php
index 00dc527b..e8f05cb8 100644
--- a/payment-success.php
+++ b/payment-success.php
@@ -1,94 +1,79 @@
payment_status == 'paid') {
- // Retrieve metadata
- $metadata = $session->metadata;
- $userId = $metadata->user_id;
- $restaurantId = $metadata->restaurant_id;
- $customerName = $metadata->customer_name;
- $address = $metadata->address;
- $phone = $metadata->phone;
- $totalPrice = $session->amount_total / 100; // Convert from cents
-
- // Check if order already exists for this session to prevent duplicates
- $stmt = $pdoconnection->prepare("SELECT id FROM orders WHERE stripe_session_id = :session_id");
- $stmt->bindParam(':session_id', $sessionId);
- $stmt->execute();
- if ($stmt->fetch()) {
- // Order already processed
- $message = "Your order has already been processed.";
- } else {
- // Create a new order
- $stmt = $pdoconnection->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, delivery_name, delivery_address, delivery_phone, stripe_session_id) VALUES (:user_id, :restaurant_id, :total_price, 'processing', :name, :address, :phone, :session_id)");
- $stmt->bindParam(':user_id', $userId);
- $stmt->bindParam(':restaurant_id', $restaurantId);
- $stmt->bindParam(':total_price', $totalPrice);
- $stmt->bindParam(':name', $customerName);
- $stmt->bindParam(':address', $address);
- $stmt->bindParam(':phone', $phone);
- $stmt->bindParam(':session_id', $sessionId);
- $stmt->execute();
- $orderId = $pdoconnection->lastInsertId();
-
- // Get cart items
- $cartStmt = $pdoconnection->prepare("SELECT * FROM cart WHERE user_id = :user_id");
- $cartStmt->bindParam(':user_id', $userId);
- $cartStmt->execute();
- $cartItems = $cartStmt->fetchAll(PDO::FETCH_ASSOC);
-
- // Move cart items to order_items
- $orderItemStmt = $pdoconnection->prepare("INSERT INTO order_items (order_id, menu_item_id, quantity, price) VALUES (:order_id, :menu_item_id, :quantity, :price)");
- foreach ($cartItems as $item) {
- $priceStmt = $pdoconnection->prepare("SELECT price FROM menu_items WHERE id = :menu_item_id");
- $priceStmt->bindParam(':menu_item_id', $item['menu_item_id']);
- $priceStmt->execute();
- $menuItem = $priceStmt->fetch(PDO::FETCH_ASSOC);
-
- $orderItemStmt->bindParam(':order_id', $orderId);
- $orderItemStmt->bindParam(':menu_item_id', $item['menu_item_id']);
- $orderItemStmt->bindParam(':quantity', $item['quantity']);
- $orderItemStmt->bindParam(':price', $menuItem['price']);
- $orderItemStmt->execute();
- }
-
- // Clear the cart
- $clearCartStmt = $pdoconnection->prepare("DELETE FROM cart WHERE user_id = :user_id");
- $clearCartStmt->bindParam(':user_id', $userId);
- $clearCartStmt->execute();
-
- $message = "Thank you for your order! Your payment was successful and your order (ID: $orderId) is now being processed.";
- }
- } else {
- $message = "Payment was not successful. Please try again.";
- }
- } catch (Exception $e) {
- $message = "An error occurred: " . $e->getMessage();
- }
-} else {
- $message = "Invalid request.";
+if (!isset($_SESSION['user_id'])) {
+ header("Location: login.php");
+ exit();
}
-include 'header.php';
-?>
+if (!isset($_GET['session_id'])) {
+ header("Location: index.php");
+ exit();
+}
-
+$stripe_session_id = $_GET['session_id'];
+$user_id = $_SESSION['user_id'];
+$pdo = db();
-
+\Stripe\Stripe::setApiKey($stripeSecretKey);
+
+try {
+ $checkout_session = \Stripe\Checkout\Session::retrieve($stripe_session_id);
+
+ if ($checkout_session->payment_status == 'paid') {
+ // Fetch cart items and delivery details
+ $stmt = $pdo->prepare("SELECT c.*, mi.price, mi.restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = ?");
+ $stmt->execute([$user_id]);
+ $cart_items = $stmt->fetchAll();
+
+ if (empty($cart_items)) {
+ header("Location: index.php");
+ exit();
+ }
+
+ $total_price = 0;
+ $restaurant_id = null;
+ foreach ($cart_items as $item) {
+ $total_price += $item['price'] * $item['quantity'];
+ $restaurant_id = $item['restaurant_id']; // Assuming all items in cart are from the same restaurant
+ }
+ $delivery_fee = 5.00;
+ $total_price += $delivery_fee;
+
+ // Get delivery details stored in cart
+ $delivery_name = $cart_items[0]['delivery_name'];
+ $delivery_address = $cart_items[0]['delivery_address'];
+ $delivery_phone = $cart_items[0]['delivery_phone'];
+
+ // Create order
+ $stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+ $stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $stripe_session_id, $delivery_name, $delivery_address, $delivery_phone]);
+ $order_id = $pdo->lastInsertId();
+
+ // Insert order items
+ $stmt = $pdo->prepare("INSERT INTO order_items (order_id, menu_item_id, quantity, price) VALUES (?, ?, ?, ?)");
+ foreach ($cart_items as $item) {
+ $stmt->execute([$order_id, $item['menu_item_id'], $item['quantity'], $item['price']]);
+ }
+
+ // Clear cart
+ $stmt = $pdo->prepare("DELETE FROM cart WHERE user_id = ?");
+ $stmt->execute([$user_id]);
+
+ $_SESSION['order_id'] = $order_id;
+ header("Location: order_confirmation.php");
+ exit();
+
+ } else {
+ header("Location: payment-cancel.php");
+ exit();
+ }
+} catch (\Stripe\Exception\ApiErrorException $e) {
+ // Handle Stripe API errors
+ error_log($e->getMessage());
+ header("Location: payment-cancel.php");
+ exit();
+}
\ No newline at end of file
diff --git a/paypal-capture.php b/paypal-capture.php
new file mode 100644
index 00000000..79be9c25
--- /dev/null
+++ b/paypal-capture.php
@@ -0,0 +1,103 @@
+ 'Invalid request.']);
+ exit();
+}
+
+$orderID = $_POST['orderID'];
+$user_id = $_SESSION['user_id'];
+
+// Helper function to get PayPal access token
+function get_paypal_access_token($clientId, $secret, $apiBase) {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, "$apiBase/v1/oauth2/token");
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_USERPWD, "$clientId:$secret");
+ curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
+ $result = curl_exec($ch);
+ curl_close($ch);
+
+ if (empty($result)) return null;
+
+ $json = json_decode($result);
+ return $json->access_token ?? null;
+}
+
+$accessToken = get_paypal_access_token($paypalClientId, $paypalSecret, $paypalApiBase);
+
+if (!$accessToken) {
+ echo json_encode(['error' => 'Could not authenticate with PayPal.']);
+ exit();
+}
+
+// Capture payment
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_URL, "$paypalApiBase/v2/checkout/orders/$orderID/capture");
+curl_setopt($ch, CURLOPT_POST, true);
+curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+curl_setopt($ch, CURLOPT_HTTPHEADER, [
+ "Content-Type: application/json",
+ "Authorization: Bearer $accessToken"
+]);
+
+$result = curl_exec($ch);
+curl_close($ch);
+$details = json_decode($result);
+
+if (isset($details->status) && $details->status == 'COMPLETED') {
+ $pdo = db();
+
+ // Fetch cart items
+ $stmt = $pdo->prepare("SELECT c.*, mi.price, mi.restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = ?");
+ $stmt->execute([$user_id]);
+ $cart_items = $stmt->fetchAll();
+
+ if (empty($cart_items)) {
+ echo json_encode(['error' => 'Your cart is empty.']);
+ exit();
+ }
+
+ $total_price = 0;
+ $restaurant_id = null;
+ foreach ($cart_items as $item) {
+ $total_price += $item['price'] * $item['quantity'];
+ $restaurant_id = $item['restaurant_id'];
+ }
+ $delivery_fee = 5.00;
+ $total_price += $delivery_fee;
+
+ $delivery_name = $_POST['name'];
+ $delivery_address = $_POST['address'];
+ $delivery_phone = $_POST['phone'];
+
+ // Create order
+ $stmt = $pdo->prepare("INSERT INTO orders (user_id, restaurant_id, total_price, status, stripe_session_id, delivery_name, delivery_address, delivery_phone) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+ $stmt->execute([$user_id, $restaurant_id, $total_price, 'paid', $orderID, $delivery_name, $delivery_address, $delivery_phone]);
+ $order_id = $pdo->lastInsertId();
+
+ // Insert order items
+ $stmt = $pdo->prepare("INSERT INTO order_items (order_id, menu_item_id, quantity, price) VALUES (?, ?, ?, ?)");
+ foreach ($cart_items as $item) {
+ $stmt->execute([$order_id, $item['menu_item_id'], $item['quantity'], $item['price']]);
+ }
+
+ // Clear cart
+ $stmt = $pdo->prepare("DELETE FROM cart WHERE user_id = ?");
+ $stmt->execute([$user_id]);
+
+ $_SESSION['order_id'] = $order_id;
+ echo json_encode(['success' => true]);
+
+} else {
+ error_log('PayPal Capture Failed: ' . print_r($details, true));
+ echo json_encode(['error' => 'Payment failed. Please try again.']);
+}