V7
This commit is contained in:
parent
369f552c9f
commit
2c8c9bfe04
@ -2,55 +2,51 @@
|
|||||||
session_start();
|
session_start();
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
if (!isset($_GET['action'])) {
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = $_GET['action'];
|
||||||
$user_id = $_SESSION['user_id'] ?? null;
|
$user_id = $_SESSION['user_id'] ?? null;
|
||||||
$session_id = session_id();
|
$session_id = session_id();
|
||||||
$action = $_POST['action'] ?? '';
|
$pdoconnection = db();
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($action == 'add') {
|
||||||
if ($action === 'add') {
|
if (!isset($_POST['menu_item_id']) || !isset($_POST['quantity'])) {
|
||||||
$menu_item_id = $_POST['menu_item_id'] ?? null;
|
header('Location: cart.php');
|
||||||
$quantity = $_POST['quantity'] ?? 1;
|
exit;
|
||||||
|
|
||||||
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.']);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$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;
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
124
checkout.php
124
checkout.php
@ -1,19 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
require_once 'includes/api_keys.php'; // Include Stripe API keys
|
require_once 'includes/api_keys.php';
|
||||||
|
|
||||||
// Redirect to login if user is not logged in
|
|
||||||
if (!isset($_SESSION['user_id'])) {
|
if (!isset($_SESSION['user_id'])) {
|
||||||
header("Location: login.php");
|
header("Location: login.php");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$userId = $_SESSION['user_id'];
|
$userId = $_SESSION['user_id'];
|
||||||
$pdoconnection = db();
|
$pdo = db();
|
||||||
|
|
||||||
// Fetch cart items
|
$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 = $pdoconnection->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->bindParam(':user_id', $userId);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
@ -24,23 +22,25 @@ if (empty($cartItems)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$totalPrice = 0;
|
$totalPrice = 0;
|
||||||
$restaurantId = $cartItems[0]['restaurant_id'];
|
|
||||||
$restaurantName = $cartItems[0]['restaurant_name'];
|
|
||||||
foreach ($cartItems as $item) {
|
foreach ($cartItems as $item) {
|
||||||
$totalPrice += $item['price'] * $item['quantity'];
|
$totalPrice += $item['price'] * $item['quantity'];
|
||||||
}
|
}
|
||||||
|
$delivery_fee = 5.00;
|
||||||
|
$totalPriceWithDelivery = $totalPrice + $delivery_fee;
|
||||||
|
|
||||||
|
|
||||||
include 'header.php';
|
include 'header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<script src="https://www.paypal.com/sdk/js?client-id=<?php echo $paypalClientId; ?>¤cy=USD"></script>
|
||||||
<script src="https://js.stripe.com/v3/"></script>
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
|
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<h2 class="text-center mb-4">Checkout</h2>
|
<h2 class="text-center mb-4">Checkout</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8">
|
<div class="col-md-7">
|
||||||
<h4>Delivery Information</h4>
|
<h4>Delivery Information</h4>
|
||||||
<form action="create_stripe_session.php" method="POST">
|
<form id="payment-form" action="create_stripe_session.php" method="POST">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="name" class="form-label">Full Name</label>
|
<label for="name" class="form-label">Full Name</label>
|
||||||
<input type="text" class="form-control" id="name" name="name" required>
|
<input type="text" class="form-control" id="name" name="name" required>
|
||||||
@ -53,29 +53,119 @@ include 'header.php';
|
|||||||
<label for="phone" class="form-label">Phone Number</label>
|
<label for="phone" class="form-label">Phone Number</label>
|
||||||
<input type="text" class="form-control" id="phone" name="phone" required>
|
<input type="text" class="form-control" id="phone" name="phone" required>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="restaurant_id" value="<?php echo $restaurantId; ?>">
|
|
||||||
<input type="hidden" name="total_price" value="<?php echo $totalPrice; ?>">
|
<h4 class="mt-4">Payment Method</h4>
|
||||||
<button type="submit" class="btn btn-primary">Proceed to Payment</button>
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="payment_method" id="stripe-radio" value="stripe" checked>
|
||||||
|
<label class="form-check-label" for="stripe-radio">
|
||||||
|
Pay with Credit Card (Stripe)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="payment_method" id="paypal-radio" value="paypal">
|
||||||
|
<label class="form-check-label" for="paypal-radio">
|
||||||
|
Pay with PayPal
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="stripe-button" type="submit" class="btn btn-primary mt-3">Proceed to Payment</button>
|
||||||
</form>
|
</form>
|
||||||
|
<div id="paypal-button-container" class="mt-3" style="display: none;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
|
||||||
|
<div class="col-md-5">
|
||||||
<h4>Order Summary</h4>
|
<h4>Order Summary</h4>
|
||||||
<h5><?php echo htmlspecialchars($restaurantName); ?></h5>
|
|
||||||
<ul class="list-group mb-3">
|
<ul class="list-group mb-3">
|
||||||
<?php foreach ($cartItems as $item):
|
<?php foreach ($cartItems as $item): ?>
|
||||||
?>
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
<?php echo htmlspecialchars($item['name']); ?> (x<?php echo $item['quantity']; ?>)
|
<?php echo htmlspecialchars($item['name']); ?> (x<?php echo $item['quantity']; ?>)
|
||||||
<span>$<?php echo number_format($item['price'] * $item['quantity'], 2); ?></span>
|
<span>$<?php echo number_format($item['price'] * $item['quantity'], 2); ?></span>
|
||||||
</li>
|
</li>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
Delivery Fee
|
||||||
|
<span>$<?php echo number_format($delivery_fee, 2); ?></span>
|
||||||
|
</li>
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center fw-bold">
|
<li class="list-group-item d-flex justify-content-between align-items-center fw-bold">
|
||||||
Total
|
Total
|
||||||
<span>$<?php echo number_format($totalPrice, 2); ?></span>
|
<span>$<?php echo number_format($totalPriceWithDelivery, 2); ?></span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const form = document.getElementById('payment-form');
|
||||||
|
const stripeButton = document.getElementById('stripe-button');
|
||||||
|
const paypalButtonContainer = document.getElementById('paypal-button-container');
|
||||||
|
const stripeRadio = document.getElementById('stripe-radio');
|
||||||
|
const paypalRadio = document.getElementById('paypal-radio');
|
||||||
|
|
||||||
|
function togglePaymentMethod() {
|
||||||
|
if (paypalRadio.checked) {
|
||||||
|
stripeButton.style.display = 'none';
|
||||||
|
paypalButtonContainer.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
stripeButton.style.display = 'block';
|
||||||
|
paypalButtonContainer.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stripeRadio.addEventListener('change', togglePaymentMethod);
|
||||||
|
paypalRadio.addEventListener('change', togglePaymentMethod);
|
||||||
|
|
||||||
|
// Initial check
|
||||||
|
togglePaymentMethod();
|
||||||
|
|
||||||
|
// PayPal integration
|
||||||
|
paypal.Buttons({
|
||||||
|
createOrder: function(data, actions) {
|
||||||
|
// Basic validation
|
||||||
|
if (!document.getElementById('name').value || !document.getElementById('address').value || !document.getElementById('phone').value) {
|
||||||
|
alert('Please fill out the delivery information before proceeding.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return actions.order.create({
|
||||||
|
purchase_units: [{
|
||||||
|
amount: {
|
||||||
|
value: '<?php echo number_format($totalPriceWithDelivery, 2, '.', ''); ?>'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onApprove: function(data, actions) {
|
||||||
|
// Capture delivery info and submit
|
||||||
|
const name = document.getElementById('name').value;
|
||||||
|
const address = document.getElementById('address').value;
|
||||||
|
const phone = document.getElementById('phone').value;
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('orderID', data.orderID);
|
||||||
|
formData.append('name', name);
|
||||||
|
formData.append('address', address);
|
||||||
|
formData.append('phone', phone);
|
||||||
|
|
||||||
|
fetch('paypal-capture.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
}).then(res => res.json())
|
||||||
|
.then(details => {
|
||||||
|
if (details.error) {
|
||||||
|
alert(details.error);
|
||||||
|
window.location.href = 'payment-cancel.php';
|
||||||
|
} else {
|
||||||
|
window.location.href = 'order_confirmation.php';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: function(err) {
|
||||||
|
console.error('PayPal Error:', err);
|
||||||
|
alert('An error occurred with your PayPal payment.');
|
||||||
|
}
|
||||||
|
}).render('#paypal-button-container');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<?php include 'footer.php'; ?>
|
<?php include 'footer.php'; ?>
|
||||||
@ -1,40 +1,36 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
require_once 'includes/api_keys.php';
|
|
||||||
require_once 'vendor/autoload.php';
|
require_once 'vendor/autoload.php';
|
||||||
|
require_once 'includes/api_keys.php';
|
||||||
|
|
||||||
// Redirect to login if user is not logged in
|
|
||||||
if (!isset($_SESSION['user_id'])) {
|
if (!isset($_SESSION['user_id'])) {
|
||||||
header("Location: login.php");
|
header("Location: login.php");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
http_response_code(405);
|
header("Location: checkout.php");
|
||||||
echo 'Method Not Allowed';
|
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$userId = $_SESSION['user_id'];
|
\Stripe\Stripe::setApiKey($stripeSecretKey);
|
||||||
$pdoconnection = db();
|
|
||||||
|
$user_id = $_SESSION['user_id'];
|
||||||
|
$pdo = db();
|
||||||
|
|
||||||
// Fetch cart items
|
// Fetch cart items
|
||||||
$stmt = $pdoconnection->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 = $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->bindParam(':user_id', $userId);
|
$stmt->execute([$user_id]);
|
||||||
$stmt->execute();
|
$cart_items = $stmt->fetchAll();
|
||||||
$cartItems = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (empty($cartItems)) {
|
if (empty($cart_items)) {
|
||||||
header("Location: cart.php");
|
header("Location: cart.php");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Stripe API key
|
|
||||||
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
|
|
||||||
|
|
||||||
$line_items = [];
|
$line_items = [];
|
||||||
foreach ($cartItems as $item) {
|
foreach ($cart_items as $item) {
|
||||||
$line_items[] = [
|
$line_items[] = [
|
||||||
'price_data' => [
|
'price_data' => [
|
||||||
'currency' => 'usd',
|
'currency' => 'usd',
|
||||||
@ -47,38 +43,27 @@ foreach ($cartItems as $item) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get delivery info from POST data
|
// Add delivery fee
|
||||||
$customerName = $_POST['name'] ?? 'N/A';
|
$delivery_fee = 5.00;
|
||||||
$address = $_POST['address'] ?? 'N/A';
|
$line_items[] = [
|
||||||
$phone = $_POST['phone'] ?? 'N/A';
|
'price_data' => [
|
||||||
$restaurantId = $_POST['restaurant_id'] ?? 0;
|
'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([
|
||||||
$checkout_session = \Stripe\Checkout\Session::create([
|
'payment_method_types' => ['card'],
|
||||||
'payment_method_types' => ['card'],
|
'line_items' => $line_items,
|
||||||
'line_items' => $line_items,
|
'mode' => 'payment',
|
||||||
'mode' => 'payment',
|
'success_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}',
|
||||||
'success_url' => $protocol . '://' . $host . '/payment-success.php?session_id={CHECKOUT_SESSION_ID}',
|
'cancel_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/payment-cancel.php',
|
||||||
'cancel_url' => $protocol . '://' . $host . '/payment-cancel.php',
|
]);
|
||||||
'metadata' => [
|
|
||||||
'user_id' => $userId,
|
|
||||||
'restaurant_id' => $restaurantId,
|
|
||||||
'customer_name' => $customerName,
|
|
||||||
'address' => $address,
|
|
||||||
'phone' => $phone,
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
header("HTTP/1.1 303 See Other");
|
header("HTTP/1.1 303 See Other");
|
||||||
header("Location: " . $checkout_session->url);
|
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
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|||||||
@ -3,10 +3,14 @@
|
|||||||
|
|
||||||
// IMPORTANT: Replace these placeholder keys with your actual Stripe API keys.
|
// 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
|
// 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)
|
// IMPORTANT: Replace these placeholder keys with your actual PayPal API keys.
|
||||||
define('STRIPE_PUBLISHABLE_KEY', 'pk_test_YOUR_PUBLISHABLE_KEY');
|
// 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
|
||||||
|
|
||||||
?>
|
?>
|
||||||
155
menu.php
155
menu.php
@ -1,128 +1,53 @@
|
|||||||
<?php
|
<?php
|
||||||
|
require_once 'header.php';
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
|
|
||||||
// Get restaurant ID from the URL
|
if (!isset($_GET['id'])) {
|
||||||
$restaurant_id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
echo "<div class='alert alert-danger'>Restaurant ID is missing.</div>";
|
||||||
|
require_once 'footer.php';
|
||||||
if (!$restaurant_id) {
|
exit;
|
||||||
header('Location: index.php');
|
|
||||||
exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdo = db();
|
$restaurant_id = $_GET['id'];
|
||||||
|
|
||||||
// Fetch restaurant details along with average rating
|
// Fetch restaurant details
|
||||||
$restaurant_stmt = $pdo->prepare("
|
$stmt = db()->prepare("SELECT * FROM restaurants WHERE id = ?");
|
||||||
SELECT r.*, AVG(rt.rating) as rating, COUNT(rt.id) as rating_count
|
$stmt->execute([$restaurant_id]);
|
||||||
FROM restaurants r
|
$restaurant = $stmt->fetch();
|
||||||
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);
|
|
||||||
|
|
||||||
// If restaurant not found, redirect
|
// Fetch menu items
|
||||||
if (!$restaurant) {
|
$stmt = db()->prepare("SELECT * FROM menu_items WHERE restaurant_id = ?");
|
||||||
header('Location: index.php');
|
$stmt->execute([$restaurant_id]);
|
||||||
exit();
|
$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';
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<main>
|
<div class="container">
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<section class="restaurant-hero" style="background-image: url('<?= htmlspecialchars($restaurant['image_url']) ?>');">
|
<div class="col-md-12">
|
||||||
<div class="restaurant-hero-content">
|
<h1 class="mt-5"><?php echo htmlspecialchars($restaurant['name']); ?></h1>
|
||||||
<h1><?= htmlspecialchars($restaurant['name']) ?></h1>
|
<p class="lead"><?php echo htmlspecialchars($restaurant['description']); ?></p>
|
||||||
<p><?= htmlspecialchars($restaurant['cuisine']) ?></p>
|
</div>
|
||||||
<?php if (isset($restaurant['rating']) && $restaurant['rating'] > 0): ?>
|
|
||||||
<div class="rating-display">
|
|
||||||
<span class="star">★</span>
|
|
||||||
<span><?= htmlspecialchars(number_format($restaurant['rating'], 1)) ?></span>
|
|
||||||
<span class="rating-count">(<?= htmlspecialchars($restaurant['rating_count']) ?> ratings)</span>
|
|
||||||
</div>
|
|
||||||
<?php else: ?>
|
|
||||||
<div class="rating-display"><span class="rating-count">No ratings yet</span></div>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="restaurant-menu">
|
|
||||||
<h2>Menu</h2>
|
|
||||||
<div class="menu-grid">
|
|
||||||
<?php if (empty($menu_items)): ?>
|
|
||||||
<p>No menu items available for this restaurant.</p>
|
|
||||||
<?php else: ?>
|
|
||||||
<?php foreach ($menu_items as $item): ?>
|
|
||||||
<div class="menu-item-card">
|
|
||||||
<img src="<?= htmlspecialchars($item['image_url']) ?>" alt="<?= htmlspecialchars($item['name']) ?>">
|
|
||||||
<div class="menu-item-card-content">
|
|
||||||
<h3><?= htmlspecialchars($item['name']) ?></h3>
|
|
||||||
<p class="description"><?= htmlspecialchars($item['description']) ?></p>
|
|
||||||
<p class="price">$<?= htmlspecialchars(number_format($item['price'], 2)) ?></p>
|
|
||||||
<form class="add-to-cart-form">
|
|
||||||
<input type="hidden" name="action" value="add">
|
|
||||||
<input type="hidden" name="menu_item_id" value="<?= $item['id'] ?>">
|
|
||||||
<div class="form-row">
|
|
||||||
<input type="number" name="quantity" value="1" min="1" class="quantity-input">
|
|
||||||
<button type="submit" class="add-to-cart-btn">Add to Cart</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
|
||||||
|
|
||||||
<script>
|
<div class="row">
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
<?php foreach ($menu_items as $item): ?>
|
||||||
const forms = document.querySelectorAll('.add-to-cart-form');
|
<div class="col-md-4">
|
||||||
forms.forEach(form => {
|
<div class="card mb-4">
|
||||||
form.addEventListener('submit', function (e) {
|
<div class="card-body">
|
||||||
e.preventDefault();
|
<h5 class="card-title"><?php echo htmlspecialchars($item['name']); ?></h5>
|
||||||
|
<p class="card-text"><?php echo htmlspecialchars($item['description']); ?></p>
|
||||||
|
<p class="card-text font-weight-bold">$<?php echo htmlspecialchars($item['price']); ?></p>
|
||||||
|
<form action="cart_actions.php?action=add" method="post">
|
||||||
|
<input type="hidden" name="menu_item_id" value="<?php echo $item['id']; ?>">
|
||||||
|
<input type="number" name="quantity" value="1" min="1" class="form-control mb-2">
|
||||||
|
<button type="submit" class="btn btn-primary">Add to Cart</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
const formData = new FormData(this);
|
<?php require_once 'footer.php'; ?>
|
||||||
const menuItemId = formData.get('menu_item_id');
|
|
||||||
const quantity = formData.get('quantity');
|
|
||||||
|
|
||||||
// Since we don't have user authentication, we'll use a hardcoded user_id.
|
|
||||||
const userId = 1;
|
|
||||||
|
|
||||||
const data = new FormData();
|
|
||||||
data.append('action', 'add');
|
|
||||||
data.append('menu_item_id', menuItemId);
|
|
||||||
data.append('quantity', quantity);
|
|
||||||
data.append('user_id', userId);
|
|
||||||
|
|
||||||
fetch('cart_actions.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: data
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(result => {
|
|
||||||
if (result.success) {
|
|
||||||
alert('Item added to cart!');
|
|
||||||
} else {
|
|
||||||
alert('Error: ' + (result.error || 'Could not add item to cart.'));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
alert('An unexpected error occurred.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<?php include 'footer.php'; ?>
|
|
||||||
|
|||||||
4
migrations/20251015_add_menu_item_id_to_cart.sql
Normal file
4
migrations/20251015_add_menu_item_id_to_cart.sql
Normal file
@ -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);
|
||||||
@ -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);
|
||||||
@ -1,16 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
include 'header.php';
|
require_once 'header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="row">
|
||||||
<h4 class="alert-heading">Payment Canceled</h4>
|
<div class="col-md-8 offset-md-2 text-center">
|
||||||
<p>Your payment process was canceled. You have not been charged.</p>
|
<div class="alert alert-warning" role="alert">
|
||||||
<hr>
|
<h4 class="alert-heading">Payment Canceled</h4>
|
||||||
<p class="mb-0">You can return to your cart to review your items or go back to the homepage.</p>
|
<p>Your payment was canceled. You have not been charged.</p>
|
||||||
|
<hr>
|
||||||
|
<p class="mb-0">You can continue shopping or go back to your cart.</p>
|
||||||
|
</div>
|
||||||
|
<a href="index.php" class="btn btn-primary">Back to Home</a>
|
||||||
|
<a href="cart.php" class="btn btn-secondary">View Cart</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a href="cart.php" class="btn btn-secondary">Back to Cart</a>
|
|
||||||
<a href="index.php" class="btn btn-primary">Back to Home</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php include 'footer.php'; ?>
|
<?php
|
||||||
|
require_once 'footer.php';
|
||||||
|
?>
|
||||||
@ -1,94 +1,79 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
require_once 'includes/api_keys.php';
|
|
||||||
require_once 'vendor/autoload.php';
|
require_once 'vendor/autoload.php';
|
||||||
|
require_once 'includes/api_keys.php';
|
||||||
|
|
||||||
$pdoconnection = db();
|
if (!isset($_SESSION['user_id'])) {
|
||||||
|
header("Location: login.php");
|
||||||
if (isset($_GET['session_id'])) {
|
exit();
|
||||||
\Stripe\Stripe::setApiKey(STRIPE_API_KEY);
|
|
||||||
$sessionId = $_GET['session_id'];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$session = \Stripe\Checkout\Session::retrieve($sessionId);
|
|
||||||
|
|
||||||
if ($session->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.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
include 'header.php';
|
if (!isset($_GET['session_id'])) {
|
||||||
?>
|
header("Location: index.php");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
<div class="container mt-5">
|
$stripe_session_id = $_GET['session_id'];
|
||||||
<div class="alert alert-info" role="alert">
|
$user_id = $_SESSION['user_id'];
|
||||||
<?php echo htmlspecialchars($message); ?>
|
$pdo = db();
|
||||||
</div>
|
|
||||||
<a href="index.php" class="btn btn-primary">Back to Home</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php include 'footer.php'; ?>
|
\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();
|
||||||
|
}
|
||||||
103
paypal-capture.php
Normal file
103
paypal-capture.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
require_once 'db/config.php';
|
||||||
|
require_once 'includes/api_keys.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
if (!isset($_SESSION['user_id']) || !isset($_POST['orderID'])) {
|
||||||
|
echo json_encode(['error' => '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.']);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user