query("CREATE TABLE IF NOT EXISTS `payment_gateways` ( `id` int(11) NOT NULL AUTO_INCREMENT, `gateway_type` varchar(50) NOT NULL, `enabled` tinyint(1) DEFAULT 0, `api_key` varchar(255) DEFAULT NULL, `api_secret` varchar(255) DEFAULT NULL, `merchant_id` varchar(255) DEFAULT NULL, `salt_key` varchar(255) DEFAULT NULL, `upi_id` varchar(100) DEFAULT NULL, `school_name` varchar(255) DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT current_timestamp(), `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`id`), UNIQUE KEY `unique_gateway` (`gateway_type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Insert default gateways $default_gateways = ['razorpay', 'upi', 'phonepe', 'easebuzz', 'payu']; foreach ($default_gateways as $gateway) { $check = $con->query("SELECT id FROM payment_gateways WHERE gateway_type = '$gateway'"); if ($check->num_rows == 0) { $con->query("INSERT INTO payment_gateways (gateway_type, enabled) VALUES ('$gateway', 0)"); } } // DROP and RECREATE payment_verifications table with correct structure $con->query("DROP TABLE IF EXISTS `payment_verifications`"); $con->query("CREATE TABLE `payment_verifications` ( `id` int(11) NOT NULL AUTO_INCREMENT, `student_id` int(11) NOT NULL, `enrollment_no` varchar(50) DEFAULT NULL, `amount` decimal(10,2) NOT NULL, `transaction_id` varchar(255) NOT NULL, `payment_mode` varchar(50) DEFAULT 'UPI', `status` enum('pending','approved','rejected') DEFAULT 'pending', `remarks` text DEFAULT NULL, `payment_date` date DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT current_timestamp(), PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); // Verify table structure $table_check = $con->query("SHOW COLUMNS FROM payment_verifications"); $table_columns = []; while($col = $table_check->fetch_assoc()) { $table_columns[] = $col['Field']; } // Fetch gateway settings $gateways = []; $gateway_query = $con->query("SELECT * FROM payment_gateways WHERE enabled = 1"); while ($gw = $gateway_query->fetch_assoc()) { $gateways[$gw['gateway_type']] = $gw; } $active_gateways = array_keys($gateways); // Fetch settings $settings = []; $settings_query = $con->query("SELECT * FROM settings"); while ($set = $settings_query->fetch_assoc()) { $settings[$set['setting_key']] = $set['setting_value']; } $school_name = $settings['school_name'] ?? 'Gujarat State Open School'; // Initialize variables $error_message = ''; $debug_info = ''; // Save Payment - Razorpay/PhonePe/PayU (Direct Gateway Payments) if (isset($_POST['action']) && $_POST['action'] == 'save_payment') { $student_id = mysqli_real_escape_string($con, $_POST['student_id']); $payment_id = mysqli_real_escape_string($con, $_POST['payment_id']); $order_id = mysqli_real_escape_string($con, $_POST['order_id']); $amount = mysqli_real_escape_string($con, $_POST['amount']); $payment_mode = mysqli_real_escape_string($con, $_POST['payment_mode']); $payment_date = date('Y-m-d'); $student = $con->query("SELECT s.*, c.course_name FROM students s LEFT JOIN courses c ON s.course_id = c.id WHERE s.id='$student_id'")->fetch_assoc(); $last_insert_id = null; if ($student) { $pending_fees = $con->query("SELECT fs.*, fc.category_name, COALESCE((SELECT SUM(fc2.paid_amount) FROM fee_collections fc2 WHERE fc2.student_id='$student_id' AND fc2.category_id=fs.category_id),0) as paid_so_far FROM fee_structure fs LEFT JOIN fee_categories fc ON fs.category_id = fc.id WHERE fs.class_name = '{$student['course_name']}' AND fs.status = 1 ORDER BY fc.id ASC"); $remaining_amount = $amount; if ($pending_fees && $pending_fees->num_rows > 0) { while ($pf = $pending_fees->fetch_assoc()) { if ($remaining_amount <= 0) break; $due = $pf['fee_amount'] - $pf['paid_so_far']; if ($due > 0) { $pay_now = min($remaining_amount, $due); $new_due = $due - $pay_now; $pay_status = ($new_due <= 0) ? 'Paid' : 'Partial'; $con->query("INSERT INTO fee_collections (student_id, category_id, fee_amount, paid_amount, due_amount, payment_mode, transaction_no, payment_date, remarks, status) VALUES ('$student_id', '{$pf['category_id']}', '{$pf['fee_amount']}', '$pay_now', '$new_due', '$payment_mode', '$payment_id', '$payment_date', 'Online - $order_id', '$pay_status')"); $last_insert_id = $con->insert_id; $remaining_amount -= $pay_now; } } } if ($remaining_amount > 0) { $con->query("INSERT INTO fee_collections (student_id, category_id, fee_amount, paid_amount, due_amount, payment_mode, transaction_no, payment_date, remarks, status) VALUES ('$student_id', '1', '$remaining_amount', '$remaining_amount', '0', '$payment_mode', '$payment_id', '$payment_date', 'Online - $order_id', 'Paid')"); $last_insert_id = $con->insert_id; } } echo ''; exit(); } // Save UPI Payment Verification if (isset($_POST['action']) && $_POST['action'] == 'submit_upi_verification') { // DEBUG: Check what's being received $debug_info = '
'; $debug_info .= '🔍 DEBUG INFO - Form Data Received:
'; $debug_info .= '$_POST array:
' . print_r($_POST, true) . '
'; $debug_info .= 'Table columns:
' . print_r($table_columns, true) . '
'; $debug_info .= '
'; // Check if all required fields are present if (!isset($_POST['student_id']) || empty($_POST['student_id'])) { $error_message = "❌ ERROR: Student ID is missing!"; } elseif (!isset($_POST['transaction_id']) || empty($_POST['transaction_id'])) { $error_message = "❌ ERROR: Transaction ID is missing!"; } elseif (!isset($_POST['amount']) || empty($_POST['amount']) || $_POST['amount'] <= 0) { $error_message = "❌ ERROR: Invalid amount!"; } elseif (!isset($_POST['payment_date']) || empty($_POST['payment_date'])) { $error_message = "❌ ERROR: Payment date is missing!"; } else { // All fields present, proceed with database insert $student_id = mysqli_real_escape_string($con, $_POST['student_id']); $enrollment_no = mysqli_real_escape_string($con, $_POST['enrollment_no'] ?? ''); $amount = mysqli_real_escape_string($con, $_POST['amount']); $transaction_id = mysqli_real_escape_string($con, $_POST['transaction_id']); $payment_date = mysqli_real_escape_string($con, $_POST['payment_date']); // Check for duplicate transaction ID $check_duplicate = $con->query("SELECT id FROM payment_verifications WHERE transaction_id = '$transaction_id'"); if ($check_duplicate && $check_duplicate->num_rows > 0) { $error_message = "❌ ERROR: This Transaction ID has already been submitted!"; } else { // Build insert query based on available columns $insert_query = "INSERT INTO payment_verifications (student_id, enrollment_no, amount, transaction_id, payment_mode, payment_date, status) VALUES ('$student_id', '$enrollment_no', '$amount', '$transaction_id', 'UPI', '$payment_date', 'pending')"; $debug_info .= '
'; $debug_info .= '📝 SQL Query:
' . htmlspecialchars($insert_query) . '
'; $result = $con->query($insert_query); if ($result) { $verification_id = $con->insert_id; $debug_info .= '✅ SUCCESS! Insert ID: ' . $verification_id . '
'; // 📧 SEND EMAIL TO ADMIN $student_query = $con->query("SELECT s.*, c.course_name, ce.institute_name FROM students s LEFT JOIN courses c ON s.course_id = c.id LEFT JOIN centers ce ON s.center_id = ce.id WHERE s.id = '$student_id'"); $student_info = $student_query->fetch_assoc(); if ($student_info) { $to_email = "gujaratstateopenschool@gmail.com"; $subject = "New UPI Payment Verification - " . $student_info['name'] . " (" . $student_info['enrollment_no'] . ")"; // Email HTML Body $email_body = '

🔔 New UPI Payment Verification

' . htmlspecialchars($school_name) . '

⚠️ Action Required: A student has submitted UPI payment details for verification. Please review and approve/reject this payment.
🏷️ Verification ID #' . str_pad($verification_id, 6, '0', STR_PAD_LEFT) . '
👤 Student Name ' . htmlspecialchars($student_info['name']) . '
📋 Enrollment No ' . htmlspecialchars($student_info['enrollment_no']) . '
📚 Course ' . htmlspecialchars($student_info['course_name'] ?? 'N/A') . '
🏫 Center ' . htmlspecialchars($student_info['institute_name'] ?? 'N/A') . '
👨‍👦 Father Name ' . htmlspecialchars($student_info['father'] ?? 'N/A') . '
📱 Mobile ' . htmlspecialchars($student_info['mobile'] ?? 'N/A') . '
💰 Amount Paid ₹ ' . number_format($amount, 2) . '
🔢 Transaction ID ' . htmlspecialchars($transaction_id) . '
📅 Payment Date ' . date('d M, Y', strtotime($payment_date)) . '
💳 Payment Mode UPI
🕐 Submitted On ' . date('d M, Y h:i A') . '

Please login to the admin panel to verify this payment.

Navigate to: Admin Panel → Payment Verifications

'; // Email headers $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n"; $headers .= "From: " . $school_name . " " . "\r\n"; $headers .= "Reply-To: noreply@gsos.in" . "\r\n"; $headers .= "X-Mailer: PHP/" . phpversion(); // Send email $mail_sent = mail($to_email, $subject, $email_body, $headers); if ($mail_sent) { $debug_info .= '📧 Email notification sent successfully to ' . $to_email . '
'; } else { $debug_info .= '⚠️ Email sending failed. Please check server mail configuration.
'; // Log error for debugging error_log("UPI Payment Email Failed - Verification ID: " . $verification_id . " - Student: " . $student_info['name']); } } else { $debug_info .= '⚠️ Student info not found for email notification.
'; } $debug_info .= '
'; // Redirect to pending page echo ''; exit(); } else { $debug_info .= '❌ DATABASE ERROR: ' . $con->error . '
'; $debug_info .= 'Error No: ' . $con->errno . '
'; $debug_info .= ''; $error_message = "❌ Database Error (#" . $con->errno . "): " . $con->error; } } } } // Show Receipt after payment $show_receipt = false; $receipt_data = null; if (isset($_GET['receipt']) && isset($_GET['sid'])) { $show_receipt = true; $receipt_id = intval($_GET['receipt']); $receipt_query = $con->query("SELECT fc.*, s.name, s.enrollment_no, s.father, s.mobile, c.course_name, ce.institute_name, fct.category_name FROM fee_collections fc LEFT JOIN students s ON fc.student_id = s.id LEFT JOIN courses c ON s.course_id = c.id LEFT JOIN centers ce ON s.center_id = ce.id LEFT JOIN fee_categories fct ON fc.category_id = fct.id WHERE fc.id = '$receipt_id'"); if ($receipt_query && $receipt_query->num_rows > 0) { $receipt_data = $receipt_query->fetch_assoc(); } } // UPI Pending Message $show_upi_pending = false; $upi_pending_data = null; if (isset($_GET['upi_pending']) && $_GET['upi_pending'] == 1) { $show_upi_pending = true; $upi_pending_data = [ 'vid' => $_GET['vid'] ?? '', 'amount' => $_GET['amt'] ?? 0, ]; } $student_data = null; $fee_breakdown = []; if (!$show_receipt && !$show_upi_pending && isset($_POST['search_student']) && !empty($_POST['enrollment_no'])) { $enrollment_no = mysqli_real_escape_string($con, $_POST['enrollment_no']); $stu_query = $con->query("SELECT s.*, c.course_name, ce.institute_name FROM students s LEFT JOIN courses c ON s.course_id = c.id LEFT JOIN centers ce ON s.center_id = ce.id WHERE s.enrollment_no = '$enrollment_no' AND s.status = 1"); if ($stu_query && $stu_query->num_rows > 0) { $student_data = $stu_query->fetch_assoc(); $course_name = $student_data['course_name']; $fee_structures = $con->query("SELECT fs.*, fc.category_name FROM fee_structure fs LEFT JOIN fee_categories fc ON fs.category_id = fc.id WHERE fs.class_name = '$course_name' AND fs.status = 1 ORDER BY fc.id ASC"); $total_fee = 0; $total_paid = 0; if ($fee_structures && $fee_structures->num_rows > 0) { while ($fs = $fee_structures->fetch_assoc()) { $paid_query = $con->query("SELECT COALESCE(SUM(paid_amount),0) as paid FROM fee_collections WHERE student_id = '" . $student_data['id'] . "' AND category_id = '" . $fs['category_id'] . "'"); $paid_for_category = $paid_query->fetch_assoc()['paid'] ?? 0; $due = $fs['fee_amount'] - $paid_for_category; $fee_breakdown[] = [ 'category_id' => $fs['category_id'], 'category_name' => $fs['category_name'], 'fee_amount' => $fs['fee_amount'], 'paid' => $paid_for_category, 'due' => max(0, $due), 'status' => ($due <= 0) ? 'Paid' : (($paid_for_category > 0) ? 'Partial' : 'Due') ]; $total_fee += $fs['fee_amount']; $total_paid += $paid_for_category; } } else { $tpq = $con->query("SELECT COALESCE(SUM(paid_amount),0) as total FROM fee_collections WHERE student_id = '" . $student_data['id'] . "'"); $total_paid = $tpq->fetch_assoc()['total'] ?? 0; } $student_data['total_fee'] = $total_fee; $student_data['total_paid'] = $total_paid; $student_data['balance'] = $total_fee - $total_paid; } else { $error_message = 'No student found with this enrollment number!'; } } // Generate UPI QR Code function generateUPIQR($upi_id, $name, $amount, $transaction_note = '') { $upi_url = "upi://pay?pa=" . urlencode($upi_id) . "&pn=" . urlencode($name) . "&am=" . urlencode($amount) . "&cu=INR"; if ($transaction_note) { $upi_url .= "&tn=" . urlencode($transaction_note); } $qr_api = "https://api.qrserver.com/v1/create-qr-code/?size=250x250&data=" . urlencode($upi_url); return $qr_api; } function numberToWords($num) { $ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']; $tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']; if ($num == 0) return 'Zero'; $result = ''; if ($num >= 100000) { $result .= numberToWords(floor($num / 100000)) . ' Lakh '; $num %= 100000; } if ($num >= 1000) { $result .= numberToWords(floor($num / 1000)) . ' Thousand '; $num %= 1000; } if ($num >= 100) { $result .= numberToWords(floor($num / 100)) . ' Hundred '; $num %= 100; } if ($num > 0) { if ($num < 20) $result .= $ones[$num]; else { $result .= $tens[floor($num / 10)]; if ($num % 10 > 0) $result .= ' ' . $ones[$num % 10]; } } return trim($result); } ?>

Payment Successful!

Receipt No. GSOS/FEE/
Student Name
Enrollment No.
Course
Payment Date
Payment Mode
Transaction ID
Amount Paid
Amount in Words: Rupees Only
Status
Search Another

Payment Verification Pending

Your payment details have been submitted successfully. The admin will verify your payment within 24 hours.
Verification ID #
Amount
Payment Mode UPI
Status ⏳ Pending Verification
Note: Please save your Verification ID for future reference.
Search Another

Find Your Fee Details

Online payment is currently disabled.
Photo

Total Fee
Paid
Balance
0): ?>
CategoryTotalPaidDueStatus
0 && !empty($active_gateways)): ?>

Select Payment Method

📱 UPI
💳 Card/NetBanking
📲 PhonePe
🏦 PayU

📱 Pay via UPI

Please enter a valid amount (1 to )
Scan QR Code

📷 Scan this QR code with any UPI app

  1. Open any UPI app
  2. Scan the QR code
  3. Complete payment
  4. Copy Transaction ID
  5. Submit below
Secure Payment: UPI ID is embedded in QR code only.
Minimum 6 characters required
Select a valid date

💳 Pay via Card / NetBanking

📲 Pay via PhonePe

🏦 Pay via PayU

All fees paid!