How to develop Projects(AMS)
Using PHP and Mysql
Part 12
💡 Module 4:
Astrologer Appointment Booking (User Module)
Purpose:
Allow users to book confirmed appointments with astrologers — going beyond just
contact. This handles scheduling, availability, and confirmations.
Functionalities:
✅
View available astrologers with their time slots
✅
Book an appointment (date, time, topic)
✅
View booking status (Pending, Confirmed, Canceled)
✅
Astrologer/Admin can Approve/Reject bookings
✅
Users get notified on status change (optional email or notification)
✅
Admin can manage all bookings
Project Structure:
/appointment_booking/
├── book_appointment.php #
User-facing form
to book appointments
├── appointment_list.php #
Admin/astrologer
view
of
all appointments
├── update_appointment_status.php #
Update status (Pending, Confirmed, Canceled)
├── delete_appointment.php #
Delete/cancel an appointment
Database Table:
CREATE
TABLE appointments (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
astrologer_id
INT
NOT
NULL,
appointment_date
DATE
NOT
NULL,
appointment_time
TIME
NOT
NULL,
concern TEXT,
status ENUM(
'Pending',
'Confirmed',
'Canceled')
DEFAULT
'Pending',
reply TEXT,
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
💫 Module 5: Payment Module (User Module)
🧾 Purpose:
Allows
users to pay for services like consultation, appointments, reports, or
horoscope readings. Securely handles transactions and tracks payment status.
🔥 Functionalities:
✅
View service pricing (Consultation fees, Reports, Appointment fees)
✅
Make payments (using Razorpay, PayPal, Stripe, or manual bank transfer)
✅
Generate Payment Invoice
✅
View payment history (user side & admin side)
✅
Admin can verify payments and update status (Pending, Paid, Failed, Refunded)
✅
Integration with Appointment & Contact modules for “Paid Consultations”
🗂️ Folder Structure:
/payments/
├── pricing_list.php
# Show available services and fees
├── checkout.php
# Payment gateway or manual payment form
├── payment_process.php
# Handle payment logic
├── payment_history.php
# User's view of their past payments
├── payment_status_update.php
# Admin updates payment status
💾 Database
Table:
CREATE
TABLE payments (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
service_type ENUM(
'Consultation',
'Appointment',
'Horoscope Report')
NOT
NULL,
astrologer_id
INT,
amount
DECIMAL(
10,
2)
NOT
NULL,
payment_method ENUM(
'Razorpay',
'PayPal',
'Stripe',
'Bank Transfer')
NOT
NULL,
payment_status ENUM(
'Pending',
'Paid',
'Failed',
'Refunded')
DEFAULT
'Pending',
transaction_id
VARCHAR(
100),
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
✨ Module 6: Horoscope Reports Generation (User Module)
🧾 Purpose:
Allow
users to receive personalized horoscope reports based on their birth details
(date, time, and place of birth). These reports can either be free or paid,
depending on the type of service.
🔥 Functionalities:
✅
Users can input their birth details (date, time, and location)
✅
Generate a personalized horoscope report based on user data
✅
View report status (Pending, Generated)
✅
Admin/Astrologer can manually generate or review the report
✅
Users can download or view the report in PDF/HTML format
✅
Admin can manage report types (free or paid)
✅
Admin can assign astrologers to generate reports
✅
Send email notifications once the report is generated or ready
🗂️ Project
Structure:
/horoscope_reports/
├── generate_report.php # Form
for users
to
input their birth details
├── report_list.php # List
of reports
generated
by astrologer
or
admin
├── view_report.php #
User
view
of their
generated horoscope report
├── download_report.php #
Option
for users
to download the report
├── admin_report_management.php #
Admin side
to manage
and assign reports
💾 Database
Table:
CREATE
TABLE horoscope_reports (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
astrologer_id
INT,
birth_date
DATE
NOT
NULL,
birth_time
TIME
NOT
NULL,
birth_location
VARCHAR(
255)
NOT
NULL,
report_type ENUM(
'Free',
'Paid')
DEFAULT
'Paid',
status ENUM(
'Pending',
'Generated')
DEFAULT
'Pending',
report_link
VARCHAR(
255), # Link
to the generated report (PDF
/HTML)
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
Code in Detail:
💾 Database Table
(as you’ve written):
CREATE
TABLE appointments (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
astrologer_id
INT
NOT
NULL,
appointment_date
DATE
NOT
NULL,
appointment_time
TIME
NOT
NULL,
concern TEXT,
status ENUM(
'Pending',
'Confirmed',
'Canceled')
DEFAULT
'Pending',
reply TEXT,
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
📂 /appointment_booking/book_appointment.php
<?php
include
'../config.php';
// Your DB connection
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$user_id =
$_POST[
'user_id'];
$astrologer_id =
$_POST[
'astrologer_id'];
$appointment_date =
$_POST[
'appointment_date'];
$appointment_time =
$_POST[
'appointment_time'];
$concern =
$_POST[
'concern'];
$sql =
"INSERT INTO appointments (user_id, astrologer_id, appointment_date, appointment_time, concern)
VALUES ('$user_id', '
$astrologer_id', '
$appointment_date', '
$appointment_time', '
$concern')";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Appointment booked successfully!";
}
else {
echo
"Error: " .
mysqli_error(
$conn);
}
}
?>
<form method=
"POST">
<input type=
"hidden" name=
"user_id" value=
"1"> <!-- Replace with logged-in user id -->
Astrologer ID: <input type=
"number" name=
"astrologer_id" required><br>
Date: <input type=
"date" name=
"appointment_date" required><br>
Time: <input type=
"time" name=
"appointment_time" required><br>
Concern: <textarea name=
"concern" required></textarea><br>
<button type=
"submit">Book Appointment</button>
</form>
📂 /appointment_booking/appointment_list.php
<?php
include
'../config.php';
$result =
mysqli_query(
$conn,
"SELECT * FROM appointments");
echo
"<table border='1'>
<tr>
<th>ID</th><th>User ID</th><th>Astrologer ID</th><th>Date</th><th>Time</th><th>Concern</th><th>Status</th><th>Reply</th><th>Action</th>
</tr>";
while (
$row =
mysqli_fetch_assoc(
$result)) {
echo
"<tr>
<td>{$row['id']}</td>
<td>
{$row['user_id']}</td>
<td>
{$row['astrologer_id']}</td>
<td>
{$row['appointment_date']}</td>
<td>
{$row['appointment_time']}</td>
<td>
{$row['concern']}</td>
<td>
{$row['status']}</td>
<td>
{$row['reply']}</td>
<td><a href='update_appointment_status.php?id=
{$row['id']}'>Update</a> |
<a href='delete_appointment.php?id=
{$row['id']}'>Delete</a></td>
</tr>";
}
echo
"</table>";
?>
📂 /appointment_booking/update_appointment_status.php
<?php
include
'../config.php';
$id =
$_GET[
'id'];
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$status =
$_POST[
'status'];
$reply =
$_POST[
'reply'];
$sql =
"UPDATE appointments SET status='$status', reply='
$reply' WHERE id='
$id'";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Appointment updated successfully!";
}
else {
echo
"Error updating: " .
mysqli_error(
$conn);
}
}
$result =
mysqli_query(
$conn,
"SELECT * FROM appointments WHERE id='$id'");
$row =
mysqli_fetch_assoc(
$result);
?>
<form method=
"POST">
Status:
<select name=
"status" required>
<option value=
"Pending"
<?=
$row[
'status'] ==
'Pending' ?
'selected' :
''
?>>Pending</option>
<option value=
"Confirmed"
<?=
$row[
'status'] ==
'Confirmed' ?
'selected' :
''
?>>Confirmed</option>
<option value=
"Canceled"
<?=
$row[
'status'] ==
'Canceled' ?
'selected' :
''
?>>Canceled</option>
</select><br>
Reply: <textarea name=
"reply">
<?=
$row[
'reply'];
?></textarea><br>
<button type=
"submit">Update</button>
</form>
📂 /appointment_booking/delete_appointment.php
<?php
include
'../config.php';
$id =
$_GET[
'id'];
$sql =
"DELETE FROM appointments WHERE id='$id'";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Appointment deleted successfully!";
}
else {
echo
"Error deleting: " .
mysqli_error(
$conn);
}
?>
<a href=
"appointment_list.php">Back to Appointment List</a>
✅
Notes:
- Replace
../config.php
with your actual database connection file. - Add proper login and role checks in production.
- You can extend this with email notifications or
user-friendly front-end.
CREATE
TABLE payments (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
service_type ENUM(
'Consultation',
'Appointment',
'Horoscope Report')
NOT
NULL,
astrologer_id
INT,
amount
DECIMAL(
10,
2)
NOT
NULL,
payment_method ENUM(
'Razorpay',
'PayPal',
'Stripe',
'Bank Transfer')
NOT
NULL,
payment_status ENUM(
'Pending',
'Paid',
'Failed',
'Refunded')
DEFAULT
'Pending',
transaction_id
VARCHAR(
100),
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
📂 /payments/pricing_list.php
<?php
// Simple static list or you can pull from DB
$services = [
[
'type' =>
'Consultation',
'price' =>
500],
[
'type' =>
'Appointment',
'price' =>
1000],
[
'type' =>
'Horoscope Report',
'price' =>
1500]
];
?>
<h2>Available Services</h2>
<ul>
<?php
foreach (
$services
as
$service):
?>
<li>
<?=
$service[
'type'];
?> — ₹
<?=
$service[
'price'];
?>
<a href=
"checkout.php?service=<?= urlencode($service['type']); ?>&amount=<?=
$service['price']; ?>">Book Now</a>
</li>
<?php
endforeach;
?>
</ul>
📂 /payments/checkout.php
<?php
include
'../config.php';
if (!
isset(
$_GET[
'service']) || !
isset(
$_GET[
'amount'])) {
echo
"Invalid Request!";
exit;
}
$service =
$_GET[
'service'];
$amount =
$_GET[
'amount'];
?>
<h2>Checkout —
<?=
htmlspecialchars(
$service);
?></h2>
<form method=
"POST" action=
"payment_process.php">
<input type=
"hidden" name=
"user_id" value=
"1"> <!-- Replace with session ID -->
<input type=
"hidden" name=
"astrologer_id" value=
"2"> <!-- Example astrologer -->
<input type=
"hidden" name=
"amount" value=
"<?= $amount; ?>">
<input type=
"hidden" name=
"service_type" value=
"<?= htmlspecialchars($service); ?>">
<label>Select Payment Method:</label>
<select name=
"payment_method" required>
<option value=
"Razorpay">Razorpay</option>
<option value=
"PayPal">PayPal</option>
<option value=
"Stripe">Stripe</option>
<option value=
"Bank Transfer">Bank Transfer</option>
</select><br><br>
<button type=
"submit">Pay ₹
<?=
$amount;
?></button>
</form>
📂 /payments/payment_process.php
<?php
include
'../config.php';
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$user_id =
$_POST[
'user_id'];
$astrologer_id =
$_POST[
'astrologer_id'];
$service_type =
$_POST[
'service_type'];
$amount =
$_POST[
'amount'];
$payment_method =
$_POST[
'payment_method'];
$transaction_id =
strtoupper(
uniqid(
'TXN'));
// Dummy transaction ID
$sql =
"INSERT INTO payments (user_id, astrologer_id, service_type, amount, payment_method, payment_status, transaction_id)
VALUES ('$user_id', '
$astrologer_id', '
$service_type', '
$amount', '
$payment_method', 'Paid', '
$transaction_id')";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Payment Successful! Transaction ID: $transaction_id";
}
else {
echo
"Error: " .
mysqli_error(
$conn);
}
}
?>
📂 /payments/payment_history.php
<?php
include
'../config.php';
$user_id =
1;
// Replace with logged-in user ID
$result =
mysqli_query(
$conn,
"SELECT * FROM payments WHERE user_id='$user_id'");
echo
"<h2>Your Payment History</h2>";
echo
"<table border='1'>
<tr><th>ID</th><th>Service</th><th>Amount</th><th>Method</th><th>Status</th><th>Transaction ID</th><th>Date</th></tr>";
while (
$row =
mysqli_fetch_assoc(
$result)) {
echo
"<tr>
<td>{$row['id']}</td>
<td>
{$row['service_type']}</td>
<td>₹
{$row['amount']}</td>
<td>
{$row['payment_method']}</td>
<td>
{$row['payment_status']}</td>
<td>
{$row['transaction_id']}</td>
<td>
{$row['created_at']}</td>
</tr>";
}
echo
"</table>";
?>
📂 /payments/payment_status_update.php
<?php
include
'../config.php';
$id =
$_GET[
'id'];
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$payment_status =
$_POST[
'payment_status'];
$sql =
"UPDATE payments SET payment_status='$payment_status' WHERE id='
$id'";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Payment status updated!";
}
else {
echo
"Error: " .
mysqli_error(
$conn);
}
}
$result =
mysqli_query(
$conn,
"SELECT * FROM payments WHERE id='$id'");
$row =
mysqli_fetch_assoc(
$result);
?>
<h2>Update Payment Status</h2>
<form method=
"POST">
<label>Status:</label>
<select name=
"payment_status" required>
<option value=
"Pending"
<?=
$row[
'payment_status'] ==
'Pending' ?
'selected' :
''
?>>Pending</option>
<option value=
"Paid"
<?=
$row[
'payment_status'] ==
'Paid' ?
'selected' :
''
?>>Paid</option>
<option value=
"Failed"
<?=
$row[
'payment_status'] ==
'Failed' ?
'selected' :
''
?>>Failed</option>
<option value=
"Refunded"
<?=
$row[
'payment_status'] ==
'Refunded' ?
'selected' :
''
?>>Refunded</option>
</select><br><br>
<button type=
"submit">Update</button>
</form>
✅
Summary:
pricing_list.php
— lists services.checkout.php
— form to choose payment method.payment_process.php
— handles form submission and payment record.payment_history.php
— shows the logged-in user's past payments.payment_status_update.php
— lets the admin change payment status.
💾 Database Table
CREATE
TABLE horoscope_reports (
id
INT AUTO_INCREMENT
PRIMARY KEY,
user_id
INT
NOT
NULL,
astrologer_id
INT,
birth_date
DATE
NOT
NULL,
birth_time
TIME
NOT
NULL,
birth_location
VARCHAR(
255)
NOT
NULL,
report_type ENUM(
'Free',
'Paid')
DEFAULT
'Paid',
status ENUM(
'Pending',
'Generated')
DEFAULT
'Pending',
report_link
VARCHAR(
255),
created_at
TIMESTAMP
DEFAULT
CURRENT_TIMESTAMP,
FOREIGN KEY (user_id)
REFERENCES users(id),
FOREIGN KEY (astrologer_id)
REFERENCES astrologers(id)
);
📂 /horoscope_reports/generate_report.php
<?php
include
'../config.php';
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$user_id =
$_POST[
'user_id'];
$astrologer_id =
$_POST[
'astrologer_id'];
$birth_date =
$_POST[
'birth_date'];
$birth_time =
$_POST[
'birth_time'];
$birth_location =
$_POST[
'birth_location'];
$report_type =
$_POST[
'report_type'];
$sql =
"INSERT INTO horoscope_reports (user_id, astrologer_id, birth_date, birth_time, birth_location, report_type)
VALUES ('$user_id', '
$astrologer_id', '
$birth_date', '
$birth_time', '
$birth_location', '
$report_type')";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Horoscope Report Request Submitted!";
}
else {
echo
"Error: " .
mysqli_error(
$conn);
}
}
?>
<h2>Request Horoscope Report</h2>
<form method=
"POST">
<input type=
"hidden" name=
"user_id" value=
"1"> <!-- Replace with session -->
<input type=
"hidden" name=
"astrologer_id" value=
"2"> <!-- Example astrologer -->
Birth Date: <input type=
"date" name=
"birth_date" required><br><br>
Birth Time: <input type=
"time" name=
"birth_time" required><br><br>
Birth Location: <input type=
"text" name=
"birth_location" required><br><br>
Report Type:
<select name=
"report_type" required>
<option value=
"Free">Free</option>
<option value=
"Paid">Paid</option>
</select><br><br>
<button type=
"submit">Submit Request</button>
</form>
📂 /horoscope_reports/report_list.php
<?php
include
'../config.php';
$result =
mysqli_query(
$conn,
"SELECT * FROM horoscope_reports ORDER BY created_at DESC");
echo
"<h2>All Horoscope Reports</h2>";
echo
"<table border='1'>
<tr><th>ID</th><th>User</th><th>Astrologer</th><th>Status</th><th>Link</th><th>Date</th></tr>";
while (
$row =
mysqli_fetch_assoc(
$result)) {
echo
"<tr>
<td>{$row['id']}</td>
<td>
{$row['user_id']}</td>
<td>
{$row['astrologer_id']}</td>
<td>
{$row['status']}</td>
<td>" . (
$row[
'report_link'] ?
"<a href='{$row['report_link']}'>View</a>" :
"Not Available") .
"</td>
<td>{$row['created_at']}</td>
</tr>";
}
echo
"</table>";
?>
📂 /horoscope_reports/view_report.php
<?php
include
'../config.php';
$id =
$_GET[
'id'];
$result =
mysqli_query(
$conn,
"SELECT * FROM horoscope_reports WHERE id = '$id'");
$row =
mysqli_fetch_assoc(
$result);
if (!
$row) {
echo
"Report not found!";
}
else {
echo
"<h2>Horoscope Report for User #{$row['user_id']}</h2>";
echo
"<p><strong>Birth Date:</strong> {$row['birth_date']}</p>";
echo
"<p><strong>Birth Time:</strong> {$row['birth_time']}</p>";
echo
"<p><strong>Location:</strong> {$row['birth_location']}</p>";
echo
"<p><strong>Status:</strong> {$row['status']}</p>";
if (
$row[
'report_link']) {
echo
"<a href='{$row['report_link']}' target='_blank'>Download Report</a>";
}
else {
echo
"<p>Report not generated yet.</p>";
}
}
?>
📂 /horoscope_reports/download_report.php
<?php
include
'../config.php';
$id =
$_GET[
'id'];
$result =
mysqli_query(
$conn,
"SELECT report_link FROM horoscope_reports WHERE id = '$id'");
$row =
mysqli_fetch_assoc(
$result);
if (
$row &&
$row[
'report_link']) {
header(
'Location: ' .
$row[
'report_link']);
exit;
}
else {
echo
"Report not available for download.";
}
?>
📂 /horoscope_reports/admin_report_management.php
<?php
include
'../config.php';
if (
$_SERVER[
'REQUEST_METHOD'] ==
'POST') {
$id =
$_POST[
'id'];
$report_link =
$_POST[
'report_link'];
$status =
'Generated';
$sql =
"UPDATE horoscope_reports SET status='$status', report_link='
$report_link' WHERE id='
$id'";
if (
mysqli_query(
$conn,
$sql)) {
echo
"Report updated successfully!";
}
else {
echo
"Error: " .
mysqli_error(
$conn);
}
}
$result =
mysqli_query(
$conn,
"SELECT * FROM horoscope_reports WHERE status='Pending'");
echo
"<h2>Pending Reports</h2>";
while (
$row =
mysqli_fetch_assoc(
$result)) {
echo
"<form method='POST'>
<p><b>User:</b> {$row['user_id']} | <b>Date:</b>
{$row['birth_date']} | <b>Location:</b>
{$row['birth_location']}</p>
<input type='hidden' name='id' value='
{$row['id']}'>
Report Link: <input type='text' name='report_link' required>
<button type='submit'>Mark as Generated</button>
</form><hr>";
}
?>
✅
Summary:
generate_report.php
— Users request a horoscope.report_list.php
— Shows all generated and pending reports.view_report.php
— View single report details.download_report.php
— Download the PDF or file.admin_report_management.php
— Admin assigns or uploads reports and marks themGenerated
.