redirectToLogin('Session expired. Please log in again.'); } // Initialize database try { $db = new Database(); $pdo = $db->getConnection(); } catch (Exception $e) { logError('Database connection failed in mobile-verification.php: ' . $e->getMessage()); die('System error. Please try again later.'); } $errors = []; $success_message = ''; $step = 'enter_mobile'; // enter_mobile, verify_otp, completed // Check if mobile is already verified $mobileData = null; try { $stmt = $pdo->prepare("SELECT mobile_number, is_verified, otp_code, otp_expires_at, verification_attempts FROM mobile_verifications WHERE user_id = ?"); $stmt->execute([$user['id']]); $mobileData = $stmt->fetch(); if ($mobileData && $mobileData['is_verified']) { $step = 'completed'; } elseif ($mobileData && $mobileData['otp_code'] && $mobileData['otp_expires_at'] > date('Y-m-d H:i:s')) { $step = 'verify_otp'; } } catch (Exception $e) { logError('Error fetching mobile verification data', ['user_id' => $user['id'], 'error' => $e->getMessage()]); } // Handle form submissions if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['action'])) { if ($_POST['action'] === 'send_otp') { $mobileNumber = isset($_POST['mobile_number']) ? sanitize($_POST['mobile_number']) : ''; // Validate mobile number if (empty($mobileNumber)) { $errors[] = 'Please enter your mobile number.'; } elseif (!preg_match('/^[6-9]\d{9}$/', $mobileNumber)) { $errors[] = 'Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9.'; } else { // Check if mobile number is already verified by another user try { $stmt = $pdo->prepare("SELECT user_id FROM mobile_verifications WHERE mobile_number = ? AND is_verified = 1 AND user_id != ?"); $stmt->execute([$mobileNumber, $user['id']]); $existingUser = $stmt->fetch(); if ($existingUser) { $errors[] = 'This mobile number is already verified by another account.'; } else { // Generate OTP $otpCode = sprintf('%06d', mt_rand(100000, 999999)); $otpExpiry = date('Y-m-d H:i:s', strtotime('+10 minutes')); // Store OTP in database $stmt = $pdo->prepare("INSERT INTO mobile_verifications (user_id, mobile_number, otp_code, otp_expires_at, verification_attempts) VALUES (?, ?, ?, ?, 0) ON DUPLICATE KEY UPDATE mobile_number = ?, otp_code = ?, otp_expires_at = ?, verification_attempts = 0, updated_at = NOW()"); $stmt->execute([$user['id'], $mobileNumber, $otpCode, $otpExpiry, $mobileNumber, $otpCode, $otpExpiry]); // Here you would integrate with SMS gateway to send OTP // For now, we'll just log it for testing logError('OTP generated for mobile verification', [ 'user_id' => $user['id'], 'mobile_number' => $mobileNumber, 'otp_code' => $otpCode // Remove this in production ]); $success_message = 'OTP sent to your mobile number. Please enter the 6-digit code below.'; $step = 'verify_otp'; $mobileData = ['mobile_number' => $mobileNumber, 'verification_attempts' => 0]; } } catch (Exception $e) { logError('Error sending OTP', ['user_id' => $user['id'], 'mobile' => $mobileNumber, 'error' => $e->getMessage()]); $errors[] = 'Error sending OTP. Please try again.'; } } } elseif ($_POST['action'] === 'verify_otp') { $otpCode = isset($_POST['otp_code']) ? sanitize($_POST['otp_code']) : ''; if (empty($otpCode)) { $errors[] = 'Please enter the OTP code.'; } elseif (!preg_match('/^\d{6}$/', $otpCode)) { $errors[] = 'Please enter a valid 6-digit OTP code.'; } else { try { // Get stored OTP $stmt = $pdo->prepare("SELECT mobile_number, otp_code, otp_expires_at, verification_attempts FROM mobile_verifications WHERE user_id = ?"); $stmt->execute([$user['id']]); $storedData = $stmt->fetch(); if (!$storedData) { $errors[] = 'No OTP found. Please request a new OTP.'; $step = 'enter_mobile'; } elseif ($storedData['otp_expires_at'] < date('Y-m-d H:i:s')) { $errors[] = 'OTP has expired. Please request a new OTP.'; $step = 'enter_mobile'; } elseif ($storedData['verification_attempts'] >= 3) { $errors[] = 'Maximum verification attempts exceeded. Please request a new OTP.'; $step = 'enter_mobile'; } elseif ($storedData['otp_code'] !== $otpCode) { // Increment verification attempts $stmt = $pdo->prepare("UPDATE mobile_verifications SET verification_attempts = verification_attempts + 1 WHERE user_id = ?"); $stmt->execute([$user['id']]); $remainingAttempts = 3 - ($storedData['verification_attempts'] + 1); $errors[] = "Invalid OTP code. You have $remainingAttempts attempts remaining."; $step = 'verify_otp'; $mobileData = $storedData; } else { // OTP is correct - verify mobile $pdo->beginTransaction(); // Mark mobile as verified $stmt = $pdo->prepare("UPDATE mobile_verifications SET is_verified = 1, verified_at = NOW() WHERE user_id = ?"); $stmt->execute([$user['id']]); // Award points for mobile verification $stmt = $pdo->prepare("INSERT INTO user_points (user_id, points, total_earned) VALUES (?, 10.00, 10.00) ON DUPLICATE KEY UPDATE points = points + 10.00, total_earned = total_earned + 10.00"); $stmt->execute([$user['id']]); // Add transaction record $stmt = $pdo->prepare("INSERT INTO point_transactions (user_id, transaction_type, points, source, description) VALUES (?, 'earned', 10.00, 'mobile_verification', 'Mobile number verification completed')"); $stmt->execute([$user['id']]); $pdo->commit(); logError('Mobile verification completed', [ 'user_id' => $user['id'], 'mobile_number' => $storedData['mobile_number'], 'points_awarded' => 10 ]); $success_message = 'Mobile number verified successfully! You have earned 10 points.'; $step = 'completed'; $mobileData = array_merge($storedData, ['is_verified' => 1]); } } catch (Exception $e) { $pdo->rollback(); logError('Error verifying OTP', ['user_id' => $user['id'], 'error' => $e->getMessage()]); $errors[] = 'Error verifying OTP. Please try again.'; } } } elseif ($_POST['action'] === 'resend_otp') { try { $stmt = $pdo->prepare("SELECT mobile_number FROM mobile_verifications WHERE user_id = ?"); $stmt->execute([$user['id']]); $existing = $stmt->fetch(); if ($existing) { // Generate new OTP $otpCode = sprintf('%06d', mt_rand(100000, 999999)); $otpExpiry = date('Y-m-d H:i:s', strtotime('+10 minutes')); $stmt = $pdo->prepare("UPDATE mobile_verifications SET otp_code = ?, otp_expires_at = ?, verification_attempts = 0, updated_at = NOW() WHERE user_id = ?"); $stmt->execute([$otpCode, $otpExpiry, $user['id']]); // Send SMS using 2Factor require_once 'sms-config.php'; $smsResult = sendOTPSMS($existing['mobile_number'], $otpCode); if ($smsResult['success']) { logError('OTP resent successfully via 2Factor', [ 'user_id' => $user['id'], 'mobile_number' => $existing['mobile_number'], 'sms_response' => $smsResult['response'] ]); $success_message = 'New OTP sent to your mobile number +91-' . $existing['mobile_number']; } else { logError('Failed to resend OTP via 2Factor', [ 'user_id' => $user['id'], 'mobile_number' => $existing['mobile_number'], 'error' => $smsResult['message'] ]); $errors[] = 'Failed to resend OTP. Please try again or contact support.'; } $step = 'verify_otp'; $mobileData = $existing; } } catch (Exception $e) { logError('Error resending OTP', ['user_id' => $user['id'], 'error' => $e->getMessage()]); $errors[] = 'Error resending OTP. Please try again.'; } } } } ?>
Your mobile number has been verified successfully! Verify your mobile number to earn 10 points and receive survey notifications
We'll send you a 6-digit OTP to verify your mobile number
We've sent a 6-digit OTP to
+91
You have earned 10 points!
Your mobile number +91 has been verified.
You'll now receive survey notifications and updates on this number.