<?php
// checkout.php - M-Pesa STK Push payment processing with rate limiting and logo in confirmation email
ob_start();
session_start();
error_log("Entering checkout.php: Session ID = " . session_id());

// Check for required files
$required_files = ['config.php', 'auth.php', 'vendor/autoload.php'];
foreach ($required_files as $file) {
    if (!file_exists($file)) {
        error_log("Missing required file: $file");
        header('HTTP/1.1 500 Internal Server Error');
        echo "Server error: Missing $file. Please contact support.";
        ob_end_flush();
        exit();
    }
}
include_once 'config.php';
include_once 'auth.php';
require_once 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

// Enable error reporting for debugging
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// Log session data
error_log("Session data: " . json_encode($_SESSION));

// Fallback for display_flash_message
if (!function_exists('display_flash_message')) {
    error_log("display_flash_message() not defined, using fallback");
    function display_flash_message() {
        if (isset($_SESSION['flash_message'])) {
            $type = $_SESSION['flash_message']['type'] === 'success' ? 'success' : 'danger';
            $message = htmlspecialchars($_SESSION['flash_message']['message']);
            echo "<div class='alert alert-$type alert-dismissible fade show' role='alert'>
                    $message
                    <button type='button' class='btn-close' data-bs-dismiss='alert' aria-label='Close'></button>
                  </div>";
            unset($_SESSION['flash_message']);
        }
    }
}

if (!is_logged_in()) {
    error_log("User not logged in, redirecting to login.php");
    set_flash_message('error', 'Please log in to checkout.');
    header("Location: login.php?redirect=checkout");
    ob_end_flush();
    exit();
}

function set_flash_message($type, $message) {
    $_SESSION['flash_message'] = [
        'type' => $type,
        'message' => $message
    ];
}

// Rate limiting for STK Push (5 requests per 60 seconds)
function can_send_stk_push() {
    $rate_limit_file = 'stk_push_rate_limit.txt';
    $max_requests = 5;
    $time_window = 60; // seconds
    if (!file_exists($rate_limit_file)) {
        $data = ['requests' => [], 'last_cleanup' => time()];
        file_put_contents($rate_limit_file, json_encode($data));
    }
    $data = json_decode(file_get_contents($rate_limit_file), true);
    if (!$data) {
        error_log("Failed to read rate limit file, resetting");
        $data = ['requests' => [], 'last_cleanup' => time()];
    }
    $now = time();
    if ($now - $data['last_cleanup'] >= $time_window) {
        $data['requests'] = [];
        $data['last_cleanup'] = $now;
    } else {
        $data['requests'] = array_filter($data['requests'], function($timestamp) use ($now, $time_window) {
            return ($now - $timestamp) < $time_window;
        });
    }
    if (count($data['requests']) >= $max_requests) {
        error_log("Rate limit exceeded: " . count($data['requests']) . " requests in last $time_window seconds");
        return false;
    }
    $data['requests'][] = $now;
    file_put_contents($rate_limit_file, json_encode($data));
    error_log("Rate limit check passed: " . count($data['requests']) . " requests in window");
    return true;
}

// Handle payment confirmation check
if (isset($_GET['order_id']) && isset($_GET['check_payment'])) {
    try {
        $order_id = intval($_GET['order_id']);
        $stmt = $conn->prepare("SELECT o.status, o.total, o.delivery_date, o.delivery_location, o.email
                                FROM orders o
                                WHERE o.id = ? AND o.user_id = ?");
        $stmt->bind_param("ii", $order_id, $_SESSION['user_id']);
        $stmt->execute();
        $result = $stmt->get_result();
        $order = $result->fetch_assoc();
        if (!$order) {
            throw new Exception("Order not found or access denied for order ID: $order_id");
        }
        if ($order['status'] === 'completed') {
            // Fetch order items
            $stmt = $conn->prepare("SELECT p.name, oi.quantity, oi.price
                                    FROM order_items oi
                                    JOIN products p ON oi.product_id = p.id
                                    WHERE oi.order_id = ?");
            $stmt->bind_param("i", $order_id);
            $stmt->execute();
            $result = $stmt->get_result();
            $order_items = [];
            while ($row = $result->fetch_assoc()) {
                $order_items[] = [
                    'name' => $row['name'],
                    'quantity' => $row['quantity'],
                    'price' => $row['price']
                ];
            }
            // Send order confirmation email with logo
            $mail = new PHPMailer(true);
            try {
                $mail->isSMTP();
                $mail->Host = 'smtp.gmail.com';
                $mail->SMTPAuth = true;
                $mail->Username = getenv('EMAIL_USERNAME') ?: 'mautimasea14@gmail.com';
                $mail->Password = getenv('EMAIL_PASSWORD') ?: 'ykqf cpzz bizx wcix';
                $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                $mail->Port = 587;
                $mail->setFrom('mautimasea14@gmail.com', 'Doyle Enterprise');
                $mail->addAddress($order['email']);
                $mail->isHTML(true);
                $mail->Subject = 'Order Confirmation - Doyle Enterprise';
                $items_list = '';
                foreach ($order_items as $item) {
                    $items_list .= "<li style='margin-bottom: 10px;'>" . htmlspecialchars($item['name']) . " (x" . $item['quantity'] . ") - KES " . number_format($item['price'] * $item['quantity'], 2) . "</li>";
                }
                $logo_url = 'http://idealtracking.co.ke/doyle_enterprise/images/logo.png';
                $mail->Body = "
                    <div style='font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;'>
                        <img src='$logo_url' alt='Doyle Enterprise Logo' style='max-width: 150px; height: auto; display: block; margin: 0 auto 20px;'>
                        <h2 style='color: #333; text-align: center;'>Order Confirmation</h2>
                        <p>Dear Customer,</p>
                        <p>Your payment for Order #{$order_id} has been confirmed.</p>
                        <h3 style='color: #333;'>Order Details:</h3>
                        <ul style='list-style: none; padding: 0;'>$items_list</ul>
                        <p><strong>Total:</strong> KES " . number_format($order['total'], 2) . "</p>
                        <p><strong>Estimated Delivery Date:</strong> " . htmlspecialchars($order['delivery_date']) . "</p>
                        <p><strong>Delivery Location:</strong> " . htmlspecialchars($order['delivery_location']) . "</p>
                        <p style='text-align: center;'>Thank you for shopping with Doyle Enterprise!</p>
                        <p style='text-align: center; font-size: 12px; color: #777;'>Doyle Enterprise &copy; " . date('Y') . "</p>
                    </div>
                ";
                $mail->AltBody = "Order Confirmation\n\nOrder ID: #$order_id\n\nItems:\n" .
                    implode("\n", array_map(function($item) {
                        return "{$item['name']} (x{$item['quantity']}) - KES " . number_format($item['price'] * $item['quantity'], 2);
                    }, $order_items)) .
                    "\n\nTotal: KES " . number_format($order['total'], 2) .
                    "\nEstimated Delivery Date: {$order['delivery_date']}\nDelivery Location: {$order['delivery_location']}\n\nThank you for shopping with Doyle Enterprise!";
                $mail->send();
                error_log("Email sent to {$order['email']} for order #$order_id with logo");
            } catch (Exception $e) {
                error_log("Email sending failed for order #$order_id: " . $mail->ErrorInfo);
                set_flash_message('warning', "Payment successful! Order #$order_id confirmed, but email sending failed.");
            }
            // Clear cart and set success message
            unset($_SESSION['cart']);
            error_log("Cart cleared after payment confirmation for order #$order_id");
            set_flash_message('success', "Payment successful! Order #$order_id confirmed.");
            header("Location: orders.php");
            ob_end_flush();
            exit();
        } elseif ($order['status'] === 'failed') {
            set_flash_message('error', "Payment failed for Order #$order_id. Please try again.");
            header("Location: cart.php");
            ob_end_flush();
            exit();
        } else {
            header("Location: confirmation.php?order_id=$order_id");
            ob_end_flush();
            exit();
        }
    } catch (Exception $e) {
        error_log("Payment check error: " . $e->getMessage());
        set_flash_message('error', 'Error checking payment status: ' . htmlspecialchars($e->getMessage()));
        header("Location: cart.php");
        ob_end_flush();
        exit();
    }
}

$cart = $_SESSION['cart'] ?? [];
error_log("Cart: " . json_encode($cart));
if (empty($cart)) {
    error_log("Cart is empty, redirecting to cart.php");
    set_flash_message('error', 'Your cart is empty.');
    header("Location: cart.php");
    ob_end_flush();
    exit();
}

// === FIXED: USE EXACT SAME TOTAL AS CART (LIVE) ===
$total = 0;
$order_items = [];

if (!empty($cart)) {
    $ids = implode(',', array_map('intval', array_keys($cart)));
    if (!empty($ids)) {
        $stmt = $conn->prepare("SELECT id, name, price FROM products WHERE id IN ($ids)");
        if (!$stmt) {
            error_log("Prepare failed: " . $conn->error);
            set_flash_message('error', 'Database error. Please try again.');
            header("Location: cart.php");
            ob_end_flush();
            exit();
        }
        $stmt->execute();
        $result = $stmt->get_result();

        while ($row = $result->fetch_assoc()) {
            $quantity = $cart[$row['id']] ?? 0;
            $subtotal = $row['price'] * $quantity;
            $total += $subtotal;

            $order_items[] = [
                'id'       => $row['id'],
                'name'     => $row['name'],
                'price'    => $row['price'],
                'quantity' => $quantity
            ];
        }
    }
}

if ($total < 1) {
    error_log("Total amount too low: $total");
    set_flash_message('error', 'Order total must be at least KES 1.');
    header("Location: cart.php");
    ob_end_flush();
    exit();
}
// === END OF FIX ===

// Fetch user details
try {
    $stmt = $conn->prepare("SELECT username, email, address FROM users WHERE id = ?");
    $stmt->bind_param("i", $_SESSION['user_id']);
    $stmt->execute();
    $user = $stmt->get_result()->fetch_assoc();
    if (!$user) {
        throw new Exception("User not found for ID: " . $_SESSION['user_id']);
    }
    $user_name = $user['username'] ?: 'Customer';
    $user_email = $user['email'];
    $user_address = $user['address'] ?: 'Nairobi, Kenya';
} catch (Exception $e) {
    error_log("User fetch error: " . $e->getMessage());
    set_flash_message('error', 'Error fetching user details.');
    header("Location: cart.php");
    ob_end_flush();
    exit();
}

// Check and add missing columns to orders table
try {
    $columns = [
        'name' => 'VARCHAR(255) NOT NULL',
        'email' => 'VARCHAR(255) NOT NULL',
        'address' => 'VARCHAR(255) NOT NULL',
        'items' => 'TEXT NOT NULL',
        'transaction_id' => 'VARCHAR(50) DEFAULT "Pending"',
        'created_at' => 'DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP',
        'mpesa_checkout_request_id' => 'VARCHAR(50)',
        'mpesa_result_desc' => 'TEXT DEFAULT "Awaiting callback"'
    ];
    foreach ($columns as $column => $type) {
        $result = $conn->query("SHOW COLUMNS FROM orders LIKE '$column'");
        if ($result->num_rows == 0) {
            $conn->query("ALTER TABLE orders ADD COLUMN $column $type");
            error_log("Added $column column to orders table");
        }
    }
} catch (Exception $e) {
    error_log("Database schema update error: " . $e->getMessage());
    set_flash_message('error', 'Error updating database schema: ' . htmlspecialchars($e->getMessage()));
    header("Location: cart.php");
    ob_end_flush();
    exit();
}

// Handle payment initiation
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['phone']) && isset($_POST['csrf_token']) && $_POST['csrf_token'] === $_SESSION['csrf_token']) {
    $phone = preg_replace('/[^0-9]/', '', $_POST['phone']);
    error_log("Payment initiated: Phone = $phone, Total = $total, Order ID to be created");
    if (!preg_match('/^2547[0-9]{8}$/', $phone)) {
        set_flash_message('error', 'Invalid phone number. Use format +2547XXXXXXXX.');
        header("Location: cart.php");
        ob_end_flush();
        exit();
    }
    // Check rate limit
    if (!can_send_stk_push()) {
        set_flash_message('error', 'Too many payment requests. Please wait a minute and try again.');
        error_log("STK Push blocked due to rate limit");
        header("Location: cart.php");
        ob_end_flush();
        exit();
    }
    try {
        $delivery_date = date('Y-m-d', strtotime('+3 days'));
        $delivery_location = $user_address;
        $items_json = json_encode(array_map(function($item) {
            return [
                'product_id' => $item['id'],
                'name' => $item['name'],
                'quantity' => $item['quantity'],
                'price' => $item['price']
            ];
        }, $order_items));
        $status = 'pending';
        $transaction_id = 'Pending';
        $mpesa_result_desc = 'Awaiting callback';
        // Insert order with all columns
        $stmt = $conn->prepare("
            INSERT INTO orders (
                user_id, name, email, address, total, status, items,
                transaction_id, delivery_date, delivery_location,
                mpesa_checkout_request_id, mpesa_result_desc
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        $stmt->bind_param(
            "isssdssissss",
            $_SESSION['user_id'],
            $user_name,
            $user_email,
            $user_address,
            $total,
            $status,
            $items_json,
            $transaction_id,
            $delivery_date,
            $delivery_location,
            $mpesa_checkout_request_id,
            $mpesa_result_desc
        );
        if (!$stmt->execute()) {
            throw new Exception("Order creation failed: " . $conn->error);
        }
        $order_id = $conn->insert_id;
        error_log("Order created: ID = $order_id, Items = $items_json");
        $stmt = $conn->prepare("INSERT INTO order_items (order_id, product_id, quantity, price) VALUES (?, ?, ?, ?)");
        foreach ($order_items as $item) {
            $stmt->bind_param("iiid", $order_id, $item['id'], $item['quantity'], $item['price']);
            if (!$stmt->execute()) {
                throw new Exception("Order item insertion failed: " . $conn->error);
            }
        }
        // M-Pesa STK Push (Sandbox)
        $consumer_key = getenv('MPESA_CONSUMER_KEY') ?: 'DSovbTsvYuqTcpnvr2KUWpTI1foiPIKVx8p39Onetg4qfLCI';
        $consumer_secret = getenv('MPESA_CONSUMER_SECRET') ?: 'qhJGuyv3ZWHAu5JhVMaygsuNr2mgG1GvAmD2js4kIshc4JAM3qcpKa4NNfynEAek';
        $shortcode = '174379';
        $passkey = 'bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919';
        $timestamp = date('YmdHis');
        $password = base64_encode($shortcode . $passkey . $timestamp);
        $access_token = get_mpesa_access_token($consumer_key, $consumer_secret);
        if (empty($access_token)) {
            throw new Exception("Failed to obtain M-Pesa access token.");
        }
        error_log("M-Pesa access token obtained: $access_token");
        $stk_push_data = [
            'BusinessShortCode' => $shortcode,
            'Password' => $password,
            'Timestamp' => $timestamp,
            'TransactionType' => 'CustomerPayBillOnline',
            'Amount' => round($total),
            'PartyA' => $phone,
            'PartyB' => $shortcode,
            'PhoneNumber' => $phone,
            'CallBackURL' => 'http://idealtracking.co.ke/doyle_enterprise/callback.php',
            'AccountReference' => 'Order' . $order_id,
            'TransactionDesc' => 'Payment for Order #' . $order_id
        ];
        $stk_push_json = json_encode($stk_push_data);
        if ($stk_push_json === false) {
            throw new Exception("Failed to encode STK Push JSON: " . json_last_error_msg());
        }
        error_log("STK Push Data: Phone = $phone, Order ID = $order_id, Data = $stk_push_json");
        // M-Pesa API call (Sandbox)
        $ch = curl_init('https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest');
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $access_token,
            'Content-Type: application/json'
        ]);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $stk_push_json);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        $stderr = fopen('php://temp', 'w+');
        curl_setopt($ch, CURLOPT_STDERR, $stderr);
        $response = curl_exec($ch);
        $curl_error = curl_error($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        rewind($stderr);
        $curl_debug = stream_get_contents($stderr);
        fclose($stderr);
        error_log("cURL Debug Info for STK Push: " . $curl_debug);
        curl_close($ch);
        if ($curl_error) {
            set_flash_message('error', 'Payment initiation failed: cURL error - ' . htmlspecialchars($curl_error));
            error_log("Payment failed: cURL error: " . $curl_error);
            header("Location: cart.php");
            ob_end_flush();
            exit();
        }
        if ($http_code !== 200) {
            $decoded_response = json_decode($response, true);
            $error_message = 'Payment initiation failed: HTTP error ' . $http_code . ' - ' . ($decoded_response ? json_encode($decoded_response) : $response);
            set_flash_message('error', $error_message);
            error_log("Payment failed: " . $error_message);
            header("Location: cart.php");
            ob_end_flush();
            exit();
        }
        $decoded_response = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            set_flash_message('error', 'Payment initiation failed: Invalid JSON response from M-Pesa');
            error_log("Payment failed: Invalid JSON response: " . json_last_error_msg());
            header("Location: cart.php");
            ob_end_flush();
            exit();
        }
        error_log("M-Pesa STK Push Response: " . json_encode($decoded_response));
        if (isset($decoded_response['ResponseCode']) && $decoded_response['ResponseCode'] === '0') {
            $stmt = $conn->prepare("UPDATE orders SET mpesa_checkout_request_id = ? WHERE id = ?");
            $stmt->bind_param("si", $decoded_response['CheckoutRequestID'], $order_id);
            if (!$stmt->execute()) {
                set_flash_message('error', 'Payment request sent, but failed to store transaction ID: ' . htmlspecialchars($conn->error));
                error_log("Failed to store CheckoutRequestID: " . $conn->error);
                header("Location: cart.php");
                ob_end_flush();
                exit();
            }
            set_flash_message('info', "Processing payment for Order #$order_id. Please wait.");
            header("Location: confirmation.php?order_id=$order_id");
            ob_end_flush();
            exit();
        } else {
            $error_message = 'Payment initiation failed: ';
            if (isset($decoded_response['errorCode'])) {
                switch ($decoded_response['errorCode']) {
                    case '404.001.03':
                        $error_message .= 'Invalid access token. Please verify your M-Pesa credentials in the Safaricom Developer Portal.';
                        break;
                    case '400.02':
                        $error_message .= 'Invalid phone number or transaction details.';
                        break;
                    case '400.03':
                        $error_message .= 'Insufficient balance or M-Pesa service issue.';
                        break;
                    default:
                        $error_message .= ($decoded_response['errorMessage'] ?? 'Unknown error.');
                }
            } else {
                $error_message .= 'Unexpected response: ' . json_encode($decoded_response);
            }
            set_flash_message('error', $error_message);
            error_log("Payment failed: " . $error_message);
            header("Location: cart.php");
            ob_end_flush();
            exit();
        }
    } catch (Exception $e) {
        set_flash_message('error', 'Error processing payment: ' . htmlspecialchars($e->getMessage()));
        error_log("Payment processing error: " . $e->getMessage());
        header("Location: cart.php");
        ob_end_flush();
        exit();
    }
}

// Generate CSRF token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
error_log("CSRF token generated: " . $_SESSION['csrf_token']);

// M-Pesa Access Token Function
function get_mpesa_access_token($consumer_key, $consumer_secret, $retry = 0) {
    $max_retries = 2;
    $ch = curl_init('https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials');
    $auth = base64_encode($consumer_key . ':' . $consumer_secret);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Basic ' . $auth,
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_VERBOSE, true);
    $stderr = fopen('php://temp', 'w+');
    curl_setopt($ch, CURLOPT_STDERR, $stderr);
    $response = curl_exec($ch);
    $curl_error = curl_error($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    rewind($stderr);
    $curl_debug = stream_get_contents($stderr);
    fclose($stderr);
    error_log("M-Pesa access token cURL Debug Info: " . $curl_debug);
    curl_close($ch);
    if ($curl_error) {
        error_log("M-Pesa access token cURL error: " . $curl_error);
        throw new Exception("Failed to get M-Pesa access token: " . $curl_error);
    }
    if ($http_code !== 200) {
        error_log("M-Pesa access token HTTP error: $http_code, Response: " . $response);
        if ($retry < $max_retries && $http_code == 401) {
            error_log("Retrying access token request ($retry/$max_retries)");
            sleep(1);
            return get_mpesa_access_token($consumer_key, $consumer_secret, $retry + 1);
        }
        throw new Exception("Failed to get M-Pesa access token: HTTP $http_code");
    }
    $decoded_response = json_decode($response, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log("M-Pesa access token invalid JSON: " . json_last_error_msg() . ", Response: " . $response);
        throw new Exception("Failed to parse M-Pesa access token response: " . json_last_error_msg());
    }
    if (!isset($decoded_response['access_token'])) {
        error_log("M-Pesa access token missing: " . json_encode($decoded_response));
        throw new Exception("Failed to get M-Pesa access token: No access token in response");
    }
    error_log("M-Pesa access token: " . $decoded_response['access_token']);
    return $decoded_response['access_token'];
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Checkout - Doyle Enterprise</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
</head>
<body>
    <?php include_once 'header.php'; ?>
    <div class="container mt-4">
        <h2 class="text-center mb-4">Checkout</h2>
        <?php display_flash_message(); ?>
        <div class="row justify-content-center">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5 class="card-title">Order Summary</h5>
                        <ul class="list-group list-group-flush">
                            <?php foreach ($order_items as $item): ?>
                                <li class="list-group-item d-flex justify-content-between">
                                    <span><?php echo htmlspecialchars($item['name']); ?> (x<?php echo $item['quantity']; ?>)</span>
                                    <span>KES <?php echo number_format($item['price'] * $item['quantity'], 2); ?></span>
                                </li>
                            <?php endforeach; ?>
                            <li class="list-group-item d-flex justify-content-between fw-bold">
                                <span>Total</span>
                                <span>KES <?php echo number_format($total, 2); ?></span>
                            </li>
                        </ul>
                        <button type="button" class="btn btn-primary mt-3 w-100" data-bs-toggle="modal" data-bs-target="#paymentModal">Proceed to Payment</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="modal fade" id="paymentModal" tabindex="-1" aria-labelledby="paymentModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="paymentModalLabel">M-Pesa Payment</h5>
                    <button type="button" class="btn-close" data-bs-dismiss='modal' aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form method="post">
                        <div class="mb-3">
                            <label for="phone" class="form-label">Phone Number (e.g., +2547XXXXXXXX)</label>
                            <input type="text" class="form-control" id="phone" name="phone" placeholder="+2547XXXXXXXX" required>
                            <small class="form-text text-muted">Use a sandbox-registered number like +254708374149 for testing.</small>
                        </div>
                        <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
                        <button type="submit" class="btn btn-primary w-100">Pay Now</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <?php include_once 'footer.php'; ?>
</body>
</html>
<?php ob_end_flush(); ?>