From 2c8c9bfe04325d1ade59aa59675f93322e312d8c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 15 Oct 2025 01:01:54 +0000 Subject: [PATCH] V7 --- cart_actions.php | 92 +++++------ checkout.php | 124 ++++++++++++-- create_stripe_session.php | 79 ++++----- includes/api_keys.php | 12 +- menu.php | 155 +++++------------- .../20251015_add_menu_item_id_to_cart.sql | 4 + ...eate_restaurants_and_menu_items_tables.sql | 36 ++++ payment-cancel.php | 24 ++- payment-success.php | 155 ++++++++---------- paypal-capture.php | 103 ++++++++++++ 10 files changed, 459 insertions(+), 325 deletions(-) create mode 100644 migrations/20251015_add_menu_item_id_to_cart.sql create mode 100644 migrations/20251015_create_restaurants_and_menu_items_tables.sql create mode 100644 paypal-capture.php diff --git a/cart_actions.php b/cart_actions.php index b8fc9082..567e5890 100644 --- a/cart_actions.php +++ b/cart_actions.php @@ -2,55 +2,51 @@ session_start(); require_once 'db/config.php'; +if (!isset($_GET['action'])) { + header('Location: index.php'); + exit; +} + +$action = $_GET['action']; $user_id = $_SESSION['user_id'] ?? null; $session_id = session_id(); -$action = $_POST['action'] ?? ''; +$pdoconnection = db(); -if ($_SERVER['REQUEST_METHOD'] === 'POST') { - if ($action === 'add') { - $menu_item_id = $_POST['menu_item_id'] ?? null; - $quantity = $_POST['quantity'] ?? 1; - - if ($menu_item_id) { - try { - $pdo = db(); - - // Check if the item is already in the cart - if ($user_id) { - $stmt = $pdo->prepare("SELECT * FROM cart WHERE user_id = ? AND menu_item_id = ?"); - $stmt->execute([$user_id, $menu_item_id]); - } else { - $stmt = $pdo->prepare("SELECT * FROM cart WHERE session_id = ? AND menu_item_id = ?"); - $stmt->execute([$session_id, $menu_item_id]); - } - $existing_item = $stmt->fetch(); - - if ($existing_item) { - // If item exists, update the quantity - $new_quantity = $existing_item['quantity'] + $quantity; - $update_stmt = $pdo->prepare("UPDATE cart SET quantity = ? WHERE id = ?"); - $update_stmt->execute([$new_quantity, $existing_item['id']]); - } else { - // If item does not exist, insert it - if ($user_id) { - $insert_stmt = $pdo->prepare("INSERT INTO cart (user_id, menu_item_id, quantity) VALUES (?, ?, ?)"); - $insert_stmt->execute([$user_id, $menu_item_id, $quantity]); - } else { - $insert_stmt = $pdo->prepare("INSERT INTO cart (session_id, menu_item_id, quantity) VALUES (?, ?, ?)"); - $insert_stmt->execute([$session_id, $menu_item_id, $quantity]); - } - } - - echo json_encode(['success' => true, 'message' => 'Item added to cart.']); - - } catch (PDOException $e) { - http_response_code(500); - echo json_encode(['success' => false, 'message' => 'Database error: ' . $e->getMessage()]); - } - } else { - http_response_code(400); - echo json_encode(['success' => false, 'message' => 'Menu item ID is required.']); - } +if ($action == 'add') { + if (!isset($_POST['menu_item_id']) || !isset($_POST['quantity'])) { + header('Location: cart.php'); + exit; } -} -?> \ No newline at end of file + + $menu_item_id = $_POST['menu_item_id']; + $quantity = $_POST['quantity']; + + // Check if item is already in cart + if ($user_id) { + $stmt = $pdoconnection->prepare("SELECT * FROM cart WHERE user_id = :user_id AND menu_item_id = :menu_item_id"); + $stmt->execute([':user_id' => $user_id, ':menu_item_id' => $menu_item_id]); + } else { + $stmt = $pdoconnection->prepare("SELECT * FROM cart WHERE session_id = :session_id AND menu_item_id = :menu_item_id"); + $stmt->execute([':session_id' => $session_id, ':menu_item_id' => $menu_item_id]); + } + $existing_item = $stmt->fetch(); + + if ($existing_item) { + // Update quantity + $new_quantity = $existing_item['quantity'] + $quantity; + $stmt = $pdoconnection->prepare("UPDATE cart SET quantity = :quantity WHERE id = :id"); + $stmt->execute([':quantity' => $new_quantity, ':id' => $existing_item['id']]); + } else { + // Insert new item + $stmt = $pdoconnection->prepare("INSERT INTO cart (user_id, session_id, menu_item_id, quantity) VALUES (:user_id, :session_id, :menu_item_id, :quantity)"); + $stmt->execute([ + ':user_id' => $user_id, + ':session_id' => $user_id ? null : $session_id, + ':menu_item_id' => $menu_item_id, + ':quantity' => $quantity + ]); + } + + header('Location: cart.php'); + exit; +} \ No newline at end of file diff --git a/checkout.php b/checkout.php index 25478a26..e202f126 100644 --- a/checkout.php +++ b/checkout.php @@ -1,19 +1,17 @@ prepare("SELECT c.id, mi.name, mi.price, c.quantity, r.name as restaurant_name, r.id as restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id JOIN restaurants r ON mi.restaurant_id = r.id WHERE c.user_id = :user_id"); +$stmt = $pdo->prepare("SELECT c.id, mi.name, mi.price, c.quantity, r.name as restaurant_name, r.id as restaurant_id FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id JOIN restaurants r ON mi.restaurant_id = r.id WHERE c.user_id = :user_id"); $stmt->bindParam(':user_id', $userId); $stmt->execute(); $cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -24,23 +22,25 @@ if (empty($cartItems)) { } $totalPrice = 0; -$restaurantId = $cartItems[0]['restaurant_id']; -$restaurantName = $cartItems[0]['restaurant_name']; foreach ($cartItems as $item) { $totalPrice += $item['price'] * $item['quantity']; } +$delivery_fee = 5.00; +$totalPriceWithDelivery = $totalPrice + $delivery_fee; + include 'header.php'; ?> +

Checkout

-
+

Delivery Information

-
+
@@ -53,29 +53,119 @@ include 'header.php';
- - - + +

Payment Method

+
+ + +
+
+ + +
+ +
+
-
+ +

Order Summary

-
    - +
  • (x) $
  • +
  • + Delivery Fee + $ +
  • Total - $ + $
+ + \ No newline at end of file diff --git a/create_stripe_session.php b/create_stripe_session.php index 78408df1..34e3111c 100644 --- a/create_stripe_session.php +++ b/create_stripe_session.php @@ -1,40 +1,36 @@ prepare("SELECT mi.name, mi.price, c.quantity FROM cart c JOIN menu_items mi ON c.menu_item_id = mi.id WHERE c.user_id = :user_id"); -$stmt->bindParam(':user_id', $userId); -$stmt->execute(); -$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC); +$stmt = $pdo->prepare("SELECT mi.name, mi.price, c.quantity 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($cartItems)) { +if (empty($cart_items)) { header("Location: cart.php"); exit(); } -// Set Stripe API key -\Stripe\Stripe::setApiKey(STRIPE_API_KEY); - $line_items = []; -foreach ($cartItems as $item) { +foreach ($cart_items as $item) { $line_items[] = [ 'price_data' => [ 'currency' => 'usd', @@ -47,38 +43,27 @@ foreach ($cartItems as $item) { ]; } -// Get delivery info from POST data -$customerName = $_POST['name'] ?? 'N/A'; -$address = $_POST['address'] ?? 'N/A'; -$phone = $_POST['phone'] ?? 'N/A'; -$restaurantId = $_POST['restaurant_id'] ?? 0; +// Add delivery fee +$delivery_fee = 5.00; +$line_items[] = [ + 'price_data' => [ + 'currency' => 'usd', + 'product_data' => [ + 'name' => 'Delivery Fee', + ], + 'unit_amount' => $delivery_fee * 100, + ], + 'quantity' => 1, +]; -// Get the protocol and host -$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http"; -$host = $_SERVER['HTTP_HOST']; -try { - $checkout_session = \Stripe\Checkout\Session::create([ - 'payment_method_types' => ['card'], - 'line_items' => $line_items, - 'mode' => 'payment', - 'success_url' => $protocol . '://' . $host . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}', - 'cancel_url' => $protocol . '://' . $host . '/payment-cancel.php', - 'metadata' => [ - 'user_id' => $userId, - 'restaurant_id' => $restaurantId, - 'customer_name' => $customerName, - 'address' => $address, - 'phone' => $phone, - ] - ]); +$checkout_session = \Stripe\Checkout\Session::create([ + 'payment_method_types' => ['card'], + 'line_items' => $line_items, + 'mode' => 'payment', + 'success_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}', + 'cancel_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-cancel.php', +]); - header("HTTP/1.1 303 See Other"); - header("Location: " . $checkout_session->url); -} catch (Exception $e) { - // Handle any errors from Stripe - http_response_code(500); - echo 'Error creating Stripe session: ' . $e->getMessage(); - // In a real app, you would log this error -} -?> \ No newline at end of file +header("HTTP/1.1 303 See Other"); +header("Location: " . $checkout_session->url); diff --git a/includes/api_keys.php b/includes/api_keys.php index c58b04fe..099c3308 100644 --- a/includes/api_keys.php +++ b/includes/api_keys.php @@ -3,10 +3,14 @@ // IMPORTANT: Replace these placeholder keys with your actual Stripe API keys. // You can find your keys in your Stripe dashboard: https://dashboard.stripe.com/apikeys +$stripeSecretKey = 'sk_test_YOUR_SECRET_KEY'; +$stripePublishableKey = 'pk_test_YOUR_PUBLISHABLE_KEY'; -// Secret key (keep this secure on the server) -define('STRIPE_API_KEY', 'sk_test_YOUR_SECRET_KEY'); -// Publishable key (safe to use in client-side code) -define('STRIPE_PUBLISHABLE_KEY', 'pk_test_YOUR_PUBLISHABLE_KEY'); +// IMPORTANT: Replace these placeholder keys with your actual PayPal API keys. +// You can find your keys in your PayPal Developer dashboard: https://developer.paypal.com/developer/applications +$paypalClientId = 'AVDnoNaRDnJkqCHwm7jOMl9Vbrt1ZLxdauuTo0sqprqOBhkCnwWI72pQeMs1aNYQCk0iZKoncQvQCDwS'; +$paypalSecret = 'EDE5TwL0lnTFvLwpr1QCIhK2LN5SYIWAlLc7OPrngfBP2XNX9L0InrQ7L4kXQlCa49RlGyflZVlAYBZF'; +$paypalApiBase = 'https://api-m.sandbox.paypal.com'; // Use https://api-m.paypal.com for production + ?> \ No newline at end of file diff --git a/menu.php b/menu.php index f88a2cba..b585b63f 100644 --- a/menu.php +++ b/menu.php @@ -1,128 +1,53 @@ Restaurant ID is missing.
"; + require_once 'footer.php'; + exit; } -$pdo = db(); +$restaurant_id = $_GET['id']; -// Fetch restaurant details along with average rating -$restaurant_stmt = $pdo->prepare(" - SELECT r.*, AVG(rt.rating) as rating, COUNT(rt.id) as rating_count - FROM restaurants r - LEFT JOIN ratings rt ON r.id = rt.restaurant_id - WHERE r.id = ? - GROUP BY r.id -"); -$restaurant_stmt->execute([$restaurant_id]); -$restaurant = $restaurant_stmt->fetch(PDO::FETCH_ASSOC); +// Fetch restaurant details +$stmt = db()->prepare("SELECT * FROM restaurants WHERE id = ?"); +$stmt->execute([$restaurant_id]); +$restaurant = $stmt->fetch(); -// If restaurant not found, redirect -if (!$restaurant) { - header('Location: index.php'); - exit(); -} +// Fetch menu items +$stmt = db()->prepare("SELECT * FROM menu_items WHERE restaurant_id = ?"); +$stmt->execute([$restaurant_id]); +$menu_items = $stmt->fetchAll(); -// Fetch menu items for the specific restaurant -$menu_items_stmt = $pdo->prepare("SELECT * FROM menu_items WHERE restaurant_id = ? ORDER BY name"); -$menu_items_stmt->execute([$restaurant_id]); -$menu_items = $menu_items_stmt->fetchAll(PDO::FETCH_ASSOC); - -include 'header.php'; ?> -
-
-
-
-

-

- 0): ?> -
- - - ( ratings) -
- -
No ratings yet
- -
-
- -
-

Menu

- -
+
+
+
+

+

+
-
- - - \ 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 @@
- - + \ 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(); +} -
- - Back to Home -
+$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.']); +}