A comprehensive web-based student registration and payment management system built with Laravel 12. This application facilitates online diploma program registrations with integrated payment processing through bank transfers and PayHere gateway, along with a full-featured admin panel for student data management.
- Features
- Tech Stack
- System Requirements
- Installation
- Configuration
- Database Schema
- Application Architecture
- Best Practices Implemented
- Usage Guide
- Routes Documentation
- Troubleshooting
- License
- Multi-step Registration Process: Intuitive 3-step workflow (Diploma Selection β Personal Information β Payment)
- Progress Indicators: Visual progress bars and countdown timers on each step
- Dynamic Diploma Selection: Choose from 5 UGC-recognized diploma programs
- Comprehensive Data Collection: Personal details, contact information, address, NIC validation
- Per-Diploma Uniqueness: Same student can register for multiple diplomas using same contact details
- Dual Payment Methods:
- Bank Transfer: Upload payment slips to 4 major Sri Lankan banks (Bank of Ceylon, Sampath Bank, Commercial Bank, People's Bank)
- Online Payment: Integrated PayHere payment gateway for instant processing
- Payment Slip Upload: Supports multiple file formats (JPG, PNG, PDF, DOCX, DOC) up to 10MB
- Automated SMS Notifications: Confirmation messages sent to WhatsApp number upon successful payment
- Print-Optimized Success Pages: A4-ready receipts for both payment methods
- Secure Authentication: Session-based admin login with environment-configured credentials
- Student Management Dashboard:
- Advanced search across 5 fields (Registration ID, Full Name, WhatsApp, NIC, Email)
- Filter by diploma program
- Pagination (15 records per page)
- View complete student details
- Edit student information with dynamic dropdowns
- Delete students with double confirmation (type "DELETE" to confirm)
- Excel Export: Generate comprehensive reports with 17 data columns
- Payment Slip Management: View uploaded payment slips, automatic deletion on student removal
- Responsive UI: Modern glass-morphism design with TailwindCSS
- Custom Validation Rules: Per-diploma uniqueness for NIC, Email, and WhatsApp number
- Composite Unique Constraints: Database-level enforcement of data integrity
- CSRF Protection: Laravel's built-in protection on all forms
- File Validation: Secure file upload with type and size restrictions
- Session Management: Secure data flow between registration steps
- Laravel: 12.38.1
- PHP: 8.4.6
- Database: SQLite (production-ready, easily switchable to MySQL/PostgreSQL)
- Excel Processing: PhpOffice/PhpSpreadsheet 5.2
- CSS Framework: TailwindCSS 4.0
- JavaScript: Alpine.js 3.15.1
- Build Tool: Vite 7.0.7
- HTTP Client: Axios 1.11.0
- Font: Inter (Google Fonts)
- PayHere: Sri Lankan payment gateway with MD5 hash verification
- SMS Service: Custom implementation for payment notifications
- PHP: >= 8.2
- Composer: Latest version
- Node.js: >= 18.x
- npm: >= 9.x
- SQLite3: Enabled in PHP (or MySQL/PostgreSQL if preferred)
- Required PHP Extensions:
- PDO
- SQLite/MySQL/PostgreSQL
- Mbstring
- OpenSSL
- Fileinfo
- GD (for image processing)
git clone <repository-url>
cd std-procomposer installnpm installcp .env.example .env
php artisan key:generateEdit .env file and set the following:
# Application
APP_NAME="SITC Student Registration"
APP_URL=http://localhost:8000
# Database (SQLite default)
DB_CONNECTION=sqlite
# DB_DATABASE=/absolute/path/to/database/database.sqlite
# Admin Credentials
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your_secure_password
# PayHere Configuration
PAYHERE_MERCHANT_ID=your_merchant_id
PAYHERE_MERCHANT_SECRET=your_merchant_secret
# SMS Service (Configure based on your provider)
SMS_API_KEY=your_sms_api_key
SMS_API_URL=https://your-sms-provider.com/apitouch database/database.sqlitephp artisan migratephp artisan storage:linknpm run build# Option 1: Simple server
php artisan serve
# Option 2: With Vite hot reload
npm run dev
# In separate terminal:
php artisan serveVisit: http://localhost:8000
Configure available diploma programs with registration prefixes:
return [
[
'name' => 'Diploma in English',
'full_name' => 'Diploma in English β 2025 β UGC Recognized University Diploma',
'reg_prefix' => 'SITC/SC/2025/3B/EN',
],
// Add more diplomas...
];Fields:
name: Short display namefull_name: Complete program titlereg_prefix: Prefix for registration ID generation (e.g.,SITC/SC/2025/3B/EN/12345678)
List of Sri Lankan districts for address dropdown:
return [
'Colombo',
'Gampaha',
'Kalutara',
// ... all 25 districts
];Update bank account details in the accordion section:
// Bank of Ceylon
Account Name: XXXXX
Account Number: XXXXXXXXXX
Branch: XXXXX
// Sampath Bank
Account Name: XXXXX
Account Number: XXXXXXXXXX
Branch: XXXXX
// Commercial Bank
Account Name: XXXXX
Account Number: XXXXXXXXXX
Branch: XXXXX
// People's Bank
Account Name: XXXXX
Account Number: XXXXXXXXXX
Branch: XXXXXSet in .env:
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your_secure_passwordAccess admin panel at: /sitc-admin-area/login
| Column | Type | Constraints | Description |
|---|---|---|---|
id |
INTEGER | PRIMARY KEY | Auto-increment ID |
registration_id |
VARCHAR(255) | UNIQUE, NOT NULL | Format: PREFIX/RANDOM8DIGITS |
student_id |
VARCHAR(255) | NULLABLE | Auto-generated after payment confirmation |
full_name |
VARCHAR(255) | NOT NULL | Student's full name |
name_with_initials |
VARCHAR(255) | NOT NULL | Name with initials format |
gender |
VARCHAR(50) | NOT NULL | Male/Female |
nic |
VARCHAR(20) | NOT NULL | National Identity Card number |
date_of_birth |
DATE | NOT NULL | Student's date of birth |
whatsapp_number |
VARCHAR(20) | NOT NULL | WhatsApp contact (for SMS) |
home_contact_number |
VARCHAR(20) | NULLABLE | Alternative contact number |
email |
VARCHAR(255) | NOT NULL | Email address |
permanent_address |
TEXT | NOT NULL | Full address |
postal_code |
VARCHAR(10) | NOT NULL | Postal/ZIP code |
district |
VARCHAR(100) | NOT NULL | Sri Lankan district |
selected_diploma |
VARCHAR(255) | NOT NULL | Selected diploma program name |
terms_accepted |
BOOLEAN | DEFAULT 0 | Terms & conditions acceptance |
payment_method |
VARCHAR(50) | NULLABLE | bank_slip or payhere |
payment_status |
VARCHAR(50) | NULLABLE | Payment confirmation status |
amount_paid |
DECIMAL(10,2) | NULLABLE | Payment amount in LKR |
payment_date |
DATETIME | NULLABLE | Payment completion timestamp |
payment_slip |
VARCHAR(255) | NULLABLE | File path to uploaded slip |
created_at |
TIMESTAMP | AUTO | Record creation time |
updated_at |
TIMESTAMP | AUTO | Last update time |
Per-diploma uniqueness implemented with composite keys:
UNIQUE (nic, selected_diploma)
UNIQUE (email, selected_diploma)
UNIQUE (whatsapp_number, selected_diploma)Purpose: Allows the same student to register for different diplomas using the same contact information.
2025_11_14_000000_create_students_table.php- Initial schema2025_11_27_000001_drop_contact_number_from_students.php- Removed legacy field2025_11_27_000002_update_selected_diploma_enum.php- Changed to string type2025_11_27_000003_update_unique_constraints_per_diploma.php- Composite constraints
app/
βββ Http/
β βββ Controllers/
β β βββ RegistrationController.php # Student registration flow
β β βββ PaymentController.php # Payment processing
β β βββ AdminController.php # Admin panel CRUD
β βββ Requests/
β βββ StoreStudentRequest.php # Custom validation
βββ Models/
β βββ Student.php # Eloquent model
βββ Services/
βββ SmsService.php # SMS notifications
Handles the multi-step registration workflow:
landing(): Welcome pageselectDiploma(POST): Stores selected diploma in sessionshowRegistrationForm(): Displays registration formstore(POST): Validates and stores student data, generates registration IDgenerateRegistrationId(): Creates unique 8-digit random registration ID
Session Management:
session(['selected_diploma' => $request->diploma]);
session(['student_data' => $validated]);Manages dual payment methods:
paymentOptions(): Shows bank slip vs PayHere choiceshowUploadSlip(): Bank transfer form with 4 bank accountsstoreSlip(POST): Processes file upload, generates student ID, sends SMSpayhere(): Initiates PayHere transaction with MD5 hashpayhereNotify(POST): Webhook for payment status updatespayhereSuccess(GET): Success redirect handler
File Storage:
$path = $request->file('payment_slip')->store('payment_slips', 'public');SMS Notification:
$smsService = new \App\Services\SmsService();
$smsService->sendPaymentConfirmation($student->whatsapp_number, $student->registration_id);Full CRUD operations for admin panel:
showLogin()/login(POST): Session-based authenticationdashboard(GET): Search, filter, pagination (15 per page)export(GET): Excel file with 17 columnsview($id): JSON response with full student dataedit($id): Edit form with dynamic dropdownsupdate(PUT, $id): Validation and update logicdestroy(DELETE, $id): Deletes student and payment slip filelogout(POST): Clears admin session
Search Implementation:
$students = Student::query()
->when($search, fn($q) => $q->where('registration_id', 'like', "%{$search}%")
->orWhere('whatsapp_number', 'like', "%{$search}%")
->orWhere('nic', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('full_name', 'like', "%{$search}%"))
->when($diploma, fn($q) => $q->where('selected_diploma', $diploma))
->orderBy('created_at', 'desc')
->paginate(15);Excel Export Columns:
- Registration ID
- Full Name
- Name with Initials
- Gender
- NIC
- Date of Birth
- WhatsApp Number
- Home Contact Number
- Permanent Address
- Postal Code
- District
- Selected Diploma
- Payment Method
- Amount Paid
- Payment Date
- Payment Slip URL
Per-diploma uniqueness validation using closure:
'nic' => [
'required',
'string',
'max:20',
function ($attribute, $value, $fail) {
$diploma = session('selected_diploma');
$exists = Student::where('nic', $value)
->where('selected_diploma', $diploma)
->exists();
if ($exists) {
$fail('This NIC has already been registered for this diploma.');
}
}
],Similar logic for email and whatsapp_number.
Fillable Fields:
protected $fillable = [
'registration_id', 'student_id', 'full_name', 'name_with_initials',
'gender', 'nic', 'date_of_birth', 'home_contact_number',
'whatsapp_number', 'email', 'permanent_address', 'postal_code',
'district', 'selected_diploma', 'terms_accepted', 'payment_method',
'payment_status', 'amount_paid', 'payment_date', 'payment_slip'
];Timestamps: Enabled (created_at, updated_at)
Custom SMS integration for payment notifications:
public function sendPaymentConfirmation($phoneNumber, $registrationId)
{
// Implementation depends on SMS provider API
// Sends confirmation message with registration details
}- Controllers handle HTTP logic only
- Models manage data relationships
- Services encapsulate business logic (SMS)
- Custom Request classes for validation
- CSRF Protection: All forms include
@csrftokens - Input Validation: Comprehensive validation rules in StoreStudentRequest
- SQL Injection Prevention: Eloquent ORM with parameterized queries
- File Upload Security: Type and size validation, secure storage paths
- Session Security: Environment-configured credentials, session encryption
- POST-only Destructive Routes: Logout and delete use POST method
- Composite Unique Constraints: Per-diploma data integrity
- Proper Indexing: Unique keys on frequently queried fields
- Nullable Fields: Optional data (home_contact_number, student_id)
- Appropriate Data Types: VARCHAR for text, DECIMAL for currency, DATE for dates
- Migration History: Tracked changes with separate migration files
- Config Files: Centralized diploma and district data
- Blade Components: Reusable UI elements (button.blade.php, input.blade.php, card.blade.php, layout.blade.php)
- Route Grouping: Admin routes under
/sitc-admin-areaprefix with middleware - Descriptive Naming: Clear function and variable names
- Comments: Inline documentation for complex logic
- Progress Indicators: Visual feedback on registration steps
- Countdown Timers: JavaScript-based time limits per step
- Responsive Design: Mobile-friendly TailwindCSS layouts
- Glass Morphism UI: Modern backdrop-filter effects
- Loading States: Disabled buttons during form submission
- Error Messages: User-friendly validation feedback
- Print Optimization: A4-ready success pages with
@media printCSS
- Pagination: Efficient data loading (15 records per page)
- Eager Loading: Optimized queries (where applicable)
- Asset Bundling: Vite for optimized CSS/JS
- Database Connection Pooling: SQLite for lightweight operations
- File Storage: Public disk with symlink for efficient serving
- Version Control: Git-based workflow
- Environment Configuration:
.envfor sensitive data - Composer Scripts: Automated setup commands
- Consistent Code Style: Laravel conventions
- Migration-based Schema: Reversible database changes
- Database-level Constraints: Enforced uniqueness
- Application-level Validation: Double-checked in StoreStudentRequest
- Double Confirmation: Type "DELETE" to confirm destructive actions
- File Cleanup: Deletes payment slips when student is removed
- Visit the landing page
- Click "Start Registration"
- Choose from 5 diploma programs
- Click "Next"
- Personal Information:
- Full Name
- Name with Initials
- Gender (dropdown)
- NIC Number
- Date of Birth
- Contact Information:
- WhatsApp Number (will receive SMS confirmation)
- Home Contact Number (optional)
- Email Address
- Address Information:
- Permanent Address
- Postal Code
- District (dropdown)
- Accept Terms & Conditions
- Click "Submit"
Option A: Bank Transfer
- Select "Upload Bank Slip"
- Click on preferred bank to view account details
- Transfer Rs. 50,000.00 to the account
- Upload payment slip (JPG/PNG/PDF/DOCX/DOC, max 10MB)
- Receive SMS confirmation with Registration ID
Option B: Online Payment
- Select "Pay Online with PayHere"
- Click "Proceed to Payment"
- Complete payment on PayHere gateway
- Automatic redirect to success page
- Receive SMS confirmation with Registration ID
- Print success page (A4 format)
- Note your Registration ID (e.g.,
SITC/SC/2025/3B/EN/12345678) - Student ID will be generated after payment verification
- Navigate to
/sitc-admin-area/login - Enter credentials from
.envfile - Access dashboard
Search Students:
- Type in search box to filter by:
- Registration ID
- Full Name
- WhatsApp Number
- NIC
- Results update in real-time
Filter by Diploma:
- Use dropdown to show only students from specific diploma program
View Student Details:
- Click "View" button in Actions column
- Modal displays all 18+ fields including:
- Personal information
- Contact details
- Address
- Payment information
- Payment slip (clickable link)
Edit Student:
- Click "Edit" button
- Modify any field except:
- Registration ID (read-only)
- Payment fields (read-only)
- Districts and Diplomas populated from config files
- Click "Update Student"
Delete Student:
- Click "Delete" button
- Modal appears
- Type exactly "DELETE" in confirmation field
- Click "Confirm Delete"
- Student record AND payment slip file are removed
Export to Excel:
- Click "Export to Excel" button (top right)
- Downloads
.xlsxfile with 17 columns - All visible students (respects current filters)
Logout:
- Click "Logout" in header
- Session cleared, redirected to login
// Welcome & Landing
GET / β welcome.blade.php
// Registration Flow
GET /register β RegistrationController@landing
POST /register/select-diploma β RegistrationController@selectDiploma
GET /register/form β RegistrationController@showRegistrationForm
POST /register/store β RegistrationController@store
// Payment Flow
GET /payment/options β PaymentController@paymentOptions
GET /payment/upload-slip β PaymentController@showUploadSlip
POST /payment/upload-slip β PaymentController@storeSlip
GET /payment/slip-success β slip-success.blade.php
GET /payment/payhere β PaymentController@payhere
POST /payment/payhere/notify β PaymentController@payhereNotify (webhook)
GET /payment/payhere/success β PaymentController@payhereSuccess
GET /payment/success β payment-success.blade.php// Authentication
GET /sitc-admin-area/login β AdminController@showLogin
POST /sitc-admin-area/login β AdminController@login
POST /sitc-admin-area/logout β AdminController@logout
// Dashboard
GET /sitc-admin-area/dashboard β AdminController@dashboard
// CRUD Operations
GET /sitc-admin-area/export β AdminController@export (Excel download)
GET /sitc-admin-area/student/{id} β AdminController@view (JSON)
GET /sitc-admin-area/student/{id}/edit β AdminController@edit
PUT /sitc-admin-area/student/{id} β AdminController@update
DELETE /sitc-admin-area/student/{id} β AdminController@destroyphp artisan key:generatetouch database/database.sqlite
php artisan migratephp artisan storage:link
# Verify symlink: public/storage -> storage/app/publicnpm install
npm run build- Error: "Duplicate entry for NIC/Email/WhatsApp"
- Solution: Student already registered for this diploma. Use different details or select different diploma.
- Check
.envfile for correctADMIN_USERNAMEandADMIN_PASSWORD - Ensure no extra spaces in credentials
- Verify
PhpOffice/PhpSpreadsheetis installed:composer require phpoffice/phpspreadsheet
- Check
SmsService.phpconfiguration - Verify API credentials in
.env - Check SMS provider logs
- Verify
PAYHERE_MERCHANT_IDandPAYHERE_MERCHANT_SECRETin.env - Check MD5 hash generation logic
- Enable PayHere sandbox mode for testing
- Ensure using
$students->appends(request()->query())in blade template - Check if search/diploma parameters are in URL
This project is proprietary software developed for SITC Campus. All rights reserved.
Developed by: Codezela Technologies
Framework: Laravel 12.38.1
Payment Gateway: PayHere (Sri Lanka)
UI Design: TailwindCSS with glass-morphism effects
For technical support or inquiries:
- Email: info@sitc.lk
Last Updated: 27 November 2025
Version: 1.0.0