A Full-Stack Web Application for Clinic Appointment System with Integrated Payment Gateway
Clinic Appointment Booking System is a comprehensive solution that enables patients to book appointments with doctors seamlessly. The system features role-based access control (Admin/Patient), dynamic time slot management, secure online payment processing via Stripe, and a complete authentication system
- RESTful API
- Separation of concerns (Admin / Patient)
- Token-based authentication
- Secure payment processing
- User Registration with email verification
- Secure Login with Laravel Sanctum tokens
- Password Recovery via email link
- Email Verification system
- Role-based Access Control (Admin/Patient)
- PCI-compliant payment processing via Stripe
- Stripe Payment Gateway - Secure online payment processing
- Consultation Fee Payment - Patients pay when booking appointments
- Payment Confirmation - Instant booking confirmation after successful payment
- Webhook Integration - Real-time payment status updates
- Availability Management - Set working hours and dates
- Dynamic Time Slot Generation - Auto-generate slots based on duration
- Appointment Overview - View and manage all bookings
- CRUD Operations for all resources
- Browse Available Slots - View all open time slots
- Book Appointments - Reserve time slots after payment confirmation
- Cancel Bookings - Cancel appointments
- Secure Payment - Pay consultation fees via Stripe
- Payment Receipts - Download payment invoices
| Technology | Purpose |
|---|---|
| Laravel 12+ | PHP Framework |
| PHP 8.2+ | Programming Language |
| MySQL | Database |
| Laravel Sanctum | API Authentication |
| Stripe API | Payment Gateway |
| Vue.js 3 | Frontend Framework |
| Postman | API Testing & Documentation |
| Manage Availability | Manage Time Slots | Appointment Details & Patient Info |
|---|---|---|
Manage Availability |
Manage Time Slots |
Appointments List |
| Home Screen | Book New Appointment | Payment Processing | My Appointments |
|---|---|---|---|
Home |
Book Appointment |
Stripe Payment |
My Appointments |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register new user |
| POST | /api/auth/login |
User login |
| POST | /api/auth/logout |
User logout |
| POST | /api/auth/forgot-password |
Send reset link |
| POST | /api/auth/reset-password |
Reset password |
| POST | /api/auth/verify-email |
Verify email address |
Note: All admin endpoints require authentication with admin role.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/availabilities |
List all availabilities |
| POST | /api/admin/availabilities |
Create new availability |
| PUT | /api/admin/availabilities/{id} |
Update availability |
| DELETE | /api/admin/availabilities/{id} |
Delete availability |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/time-slots |
List all time slots |
| POST | /api/admin/time-slots |
Create single time slot |
| PUT | /api/admin/time-slots/{id} |
Update time slot |
| DELETE | /api/admin/time-slots/{id} |
Delete time slot |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/appointments |
List all appointments |
| DELETE | /api/admin/appointments/{id} |
Delete appointment |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/admin/payments |
List all payments |
| GET | /api/admin/payments/{id} |
View payment details |
GET /api/time-slotsGET /api/user/time-slots
Authorization: Bearer {token}POST /api/payments/create-intent
Authorization: Bearer {token}
{
"slot_id": 61,
"amount": 50.00
}POST /api/appointments
Authorization: Bearer {token}
{
"slot_id": 61,
"payment_intent_id": "pi_xxxxx"
}DELETE /api/appointments/{id}
Authorization: Bearer {token}POST /api/webhooks/stripeThis endpoint handles real-time payment status updates from Stripe, including:
- Payment confirmations
- Failed payment alerts
- Import the Postman collection from
docs/apis/postman_collection.json - Set up environment variables:
baseURL:http://localhost:8000adminToken: Token received after admin loginuserToken: Token received after user login
- Success:
4242 4242 4242 4242 - Decline:
4000 0000 0000 0002 - Authentication Required:
4000 0025 0000 3155
All API responses follow a consistent format:
{
"status": "success",
"message": "Operation successful",
"data": {}
}{
"status": "error",
"message": "Error description",
"errors": {}
}backend/
├── app/
│ ├── Exceptions/ # Exception Handler
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── Admin/ # Admin controllers
│ │ │ ├── Auth/ # Authentication logic
│ │ │ └── User/ # Patient controllers
│ │ ├── Middleware/
│ │ │ └── Admin/
│ │ ├── Requests/
│ │ │ ├── Admin/
│ │ │ ├── Auth/
│ │ │ └── User/
│ │ └── Resources/ # API response formatting
│ ├── Mail/ # Email notifications
│ ├── Models/ # Eloquent models
│ ├── Policies/ # Authorization policies
│ ├── Services/ # Business logic layer
│ └── Traits/
├── routes/
│ ├── api.php # API routes
│ ├── auth.php # Auth routes
│ └── web.php
├── database/
│ ├── migrations/
│ ├── factories/
│ └── seeders/
frontend/
├── src/
│ ├── assets/
│ ├── components/
│ │ ├── Admin/
│ ├── layouts/
│ │ ├── Admin/ # Admin dashboard layouts
│ │ ├── User/ # Patient layouts
│ │ └── AuthLayout.vue
│ ├── router/
│ │ └── index.js # Vue Router configuration
│ ├── views/
│ │ ├── Admin/ # Admin pages
│ │ ├── Auth/
│ │ └── User/ # Patient pages
│ ├── App.vue
│ └── main.js
The following diagram represents the Entity Relationship Diagram (ERD) for the Clinic Appointment Booking System.
- users - User accounts (patients and admins)
- availabilities - Doctor availability schedules
- time_slots - Available appointment slots
- appointments - Booked appointments
- payments - Payment transactions
- PHP 8.2 or higher
- Composer
- Node.js 18+ and npm
- MySQL 8.0+
- Stripe Account (for payment processing)
git clone https://github.com/fathallah7/clinic-appointment-system
cd clinic-appointment-system/backendcomposer installcp .env.example .env
php artisan key:generateEdit .env:
APP_NAME="Clinic Appointment System"
APP_URL=http://localhost:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=clinic_appointment_system
DB_USERNAME=root
DB_PASSWORD=your_password
# Stripe Configuration
STRIPE_SECRET=sk_test_xxxxxxxxxxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxx
# Mail Configuration
MAIL_MAILER=smtp
MAIL_ENCRYPTION=tls
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=587
MAIL_USERNAME=your_username
MAIL_PASSWORD=your_password
MAIL_FROM_ADDRESS=noreply@clinic.com
MAIL_FROM_NAME="${APP_NAME}"- Create a Stripe account at https://stripe.com
- Go to Developers → API keys
- Copy your Secret key
- For webhooks:
- Go to Developers → Webhooks
- Add endpoint:
http://your-domain.com/api/webhooks/stripe - Select events:
payment_intent.succeeded,payment_intent.payment_failed - Copy the Signing secret
# Run migrations
php artisan migrate
# Seed database with sample data
php artisan db:seedphp artisan serve
# API available at: http://localhost:8000Default Admin Credentials:
Email: admin@doctor.com
Password: admin123
cd ../frontend
# or
cd clinic-appointment-system/frontendnpm installCreate .env file:
VITE_API_URL=http://localhost:8000
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxxxxxxxxxxnpm run dev
# available at: http://localhost:3000npm run build
# Output in: dist/User selects time slot → Creates payment intent → Stripe checkout opens
User enters card details → Stripe processes payment → Webhook confirms payment
Payment confirmed → Appointment created → Confirmation email sent
User cancels appointment → Confirmation email
- PCI DSS Compliance - Stripe handles all sensitive card data
- HTTPS Required - Secure data transmission
- CSRF Protection - Laravel built-in protection
- API Token Authentication - Sanctum tokens
- Input Validation - Server-side validation for all requests
- SQL Injection Prevention - Eloquent ORM protection
- XSS Protection - Vue.js automatic escaping
- Webhook Signature Verification - Validate Stripe webhooks
cd backend
php artisan test# Test with Stripe CLI
stripe listen --forward-to localhost:8000/api/webhooks/stripe
# Trigger test webhook
stripe trigger payment_intent.succeededProblem: Payment not processing
- Verify Stripe API keys are correct
- Check webhook endpoint is accessible
- Ensure HTTPS is enabled in production
Problem: Webhook not working
- Verify webhook secret is correct
- Check webhook endpoint returns 200 status
- Review Stripe webhook logs in dashboard
Error: "Invalid API Key"
- Check
.envfile has correct Stripe keys - Run
php artisan config:cacheafter updating
Error: "Webhook signature verification failed"
- Ensure webhook secret matches Stripe dashboard
- Verify endpoint URL is correct
Abdullah Fathallah







