PWEB EAS
muhammad rafi budi purnama
5025221307
pweb
📚 DOKUMENTASI LENGKAP E-COMMERCE SYSTEM
With Payment System, Order Tracking & Live Search API
CODE : https://github.com/mbahbud/ecomerce-with-api.git
📖 TABLE OF CONTENTS
- Overview
- Arsitektur Sistem
- Frontend Explanation
- Backend Explanation
- Database Implementation
- API Integration
- Testing Guide
- Diagram Sistem
- User Guide
1️⃣ OVERVIEW
Teknologi Stack
Frontend: HTML5, CSS3, JavaScript (Vanilla), Bootstrap 5
Backend: PHP Native (No Framework)
Database: MySQL
API: REST API (JSON Response)
Fitur Utama
✅ User Management (Register, Login, Profile)
✅ Product Management (CRUD)
✅ Shopping Cart (AJAX)
✅ Payment System (Upload Proof & Verification)
✅ Order Tracking (Real-time Timeline)
✅ Live Search (Search as you type) (API)
✅ Admin Dashboard
2️⃣ ARSITEKTUR SISTEM
System Architecture
┌─────────────┐
│ Browser │
│ (Client) │
└──────┬──────┘
│
│ HTTP Request
▼
┌─────────────────────────┐
│ Web Server (Apache) │
│ ┌─────────────────┐ │
│ │ PHP Engine │ │
│ └─────────────────┘ │
└──────────┬──────────────┘
│
│ Query
▼
┌─────────────┐
│ MySQL │
│ Database │
└─────────────┘
Folder Structure
ecommerce/
├── 📁 admin/ → Admin Panel
├── 📁 ajax/ → AJAX Endpoints
├── 📁 api/ → REST API Endpoints ⭐
├── 📁 assets/ → CSS, JS, Images
├── 📁 config/ → Database Config
├── 📁 includes/ → Reusable Components
├── 📄 index.php → Homepage
├── 📄 products.php → Product Listing
├── 📄 cart.php → Shopping Cart
├── 📄 checkout.php → Checkout Page
├── 📄 payment.php → Payment Page ⭐
├── 📄 order_tracking.php → Order Tracking ⭐
└── 📄 database.sql → Database Schema
3️⃣ FRONTEND EXPLANATION
A. HTML Structure
1. products.php (Product Listing with Live Search)
<!-- Search Input -->
<input type="text"
id="liveSearchInput"
placeholder="Type to search..."
autocomplete="off">
<!-- Loading Indicator -->
<div id="loadingIndicator" style="display: none;">
Searching...
</div>
<!-- Products Container -->
<div id="productsContainer">
<!-- Dynamic content dari JS -->
</div>
Penjelasan:
- Search Input: User ketik keyword → trigger search
- Loading: Muncul saat fetching data
- Container: Tempat render hasil search
2. payment.php (Payment Upload)
<form method="POST" action="payment_confirm.php" enctype="multipart/form-data">
<input type="text" name="account_name" placeholder="Nama Pengirim">
<input type="text" name="bank_account" placeholder="No. Rekening">
<input type="file" name="payment_proof" accept="image/*,.pdf">
<button type="submit">Upload Payment Proof</button>
</form>
Penjelasan:
- Form: Upload bukti transfer
- enctype: Wajib untuk file upload
- accept: Limit file type (image/pdf only)
3. order_tracking.php (Tracking Timeline)
<div class="tracking-timeline">
<div class="tracking-item active">
<h6>Order Shipped</h6>
<p>Jakarta Hub</p>
<small>15 Dec 2024, 10:30</small>
</div>
<div class="tracking-item">
<h6>Order Processed</h6>
<p>Warehouse</p>
<small>14 Dec 2024, 14:00</small>
</div>
</div>
Penjelasan:
- Timeline: Vertical timeline dengan CSS
- Active: Item terbaru highlighted
- Dynamic: Data dari database
B. CSS Styling
1. Live Search Styling
#liveSearchInput {
border: 2px solid #dee2e6;
transition: border-color 0.3s ease;
}
#liveSearchInput:focus {
border-color: #0d6efd;
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}
Penjelasan:
- Focus effect saat user click search box
- Smooth transition 0.3s
2. Tracking Timeline CSS
.tracking-timeline {
position: relative;
padding-left: 40px;
}
.tracking-timeline::before {
content: '';
position: absolute;
left: 12px;
width: 3px;
height: 100%;
background: linear-gradient(to bottom, #0d6efd, #dee2e6);
}
.tracking-item::before {
content: '';
position: absolute;
left: -32px;
width: 20px;
height: 20px;
border-radius: 50%;
background: #fff;
border: 4px solid #dee2e6;
}
.tracking-item.active::before {
border-color: #0d6efd;
background: #0d6efd;
box-shadow: 0 0 0 4px rgba(13, 110, 253, 0.2);
}
Penjelasan:
- ::before: Pseudo-element untuk garis vertical
- Circle: Bullet point untuk setiap status
- Active: Highlight status terbaru
3. Payment Status Badge
.payment-status {
padding: 8px 16px;
border-radius: 20px;
font-weight: 600;
}
.payment-unpaid { background: #dc3545; color: white; }
.payment-pending { background: #ffc107; color: #000; }
.payment-verified { background: #198754; color: white; }
Penjelasan:
- Badge dengan warna berbeda per status
- Border-radius untuk rounded corners
C. JavaScript Logic
1. Live Search Function
let searchTimeout;
liveSearchInput.addEventListener('input', function() {
clearTimeout(searchTimeout);
const keyword = this.value.trim();
// Minimal 2 karakter
if (keyword.length < 2) return;
// Debounce: Tunggu 500ms
searchTimeout = setTimeout(() => {
performLiveSearch(keyword);
}, 500);
});
async function performLiveSearch(keyword) {
loadingIndicator.style.display = 'block';
const response = await fetch(`api/search_products.php?q=${keyword}`);
const data = await response.json();
loadingIndicator.style.display = 'none';
displayProducts(data.products);
}
Penjelasan:
- Debounce: Delay 500ms agar tidak spam request
- Async/Await: Modern JavaScript untuk async operation
- Fetch API: HTTP request ke backend
- JSON: Parse response dari server
2. Display Products Function
function displayProducts(products) {
let html = '<div class="row g-4">';
products.forEach(product => {
html += `
<div class="col-md-4">
<div class="card">
<img src="${product.image_url}">
<h5>${product.name}</h5>
<p>${product.price_formatted}</p>
<button onclick="addToCart(${product.id})">
Add to Cart
</button>
</div>
</div>
`;
});
html += '</div>';
productsContainer.innerHTML = html;
}
Penjelasan:
- Template Literals: ES6 syntax untuk string interpolation
- forEach: Loop through products array
- innerHTML: Update DOM dengan HTML baru
3. Add to Cart (AJAX)
async function addToCart(productId) {
const response = await fetch('ajax/add_to_cart.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `product_id=${productId}`
});
const data = await response.json();
if (data.success) {
alert('Product added to cart!');
updateCartCount();
}
}
Penjelasan:
- POST request: Kirim product_id ke server
- Headers: Set content type
- Response handling: Check success status
4️⃣ BACKEND EXPLANATION
A. Database Connection
config/database.php
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'ecommerce_db');
function getDBConnection() {
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$conn->set_charset("utf8mb4");
return $conn;
}
function sanitize($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
Penjelasan:
- MySQLi: PHP extension untuk MySQL
- utf8mb4: Support emoji & special characters
- sanitize(): Clean user input (XSS protection)
B. API Endpoint
api/search_products.php
<?php
header('Content-Type: application/json');
$keyword = sanitize($_GET['q']);
$conn = getDBConnection();
$query = "SELECT p.*, c.name as category_name
FROM products p
LEFT JOIN categories c ON p.category_id = c.id
WHERE p.name LIKE ? OR p.description LIKE ?
LIMIT 20";
$stmt = $conn->prepare($query);
$search = "%$keyword%";
$stmt->bind_param("ss", $search, $search);
$stmt->execute();
$products = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
echo json_encode([
'success' => true,
'count' => count($products),
'products' => $products
]);
?>
Penjelasan:
- JSON Header: Tell browser response is JSON
- Prepared Statement: Prevent SQL injection
- LIKE: Search pattern matching
- LEFT JOIN: Get category name
- json_encode: Convert array to JSON
C. Payment Processing
payment_confirm.php
<?php
// Handle file upload
if (isset($_FILES['payment_proof'])) {
$allowed = ['image/jpeg', 'image/png', 'application/pdf'];
$file_type = $_FILES['payment_proof']['type'];
if (!in_array($file_type, $allowed)) {
die('Invalid file type');
}
$filename = 'payment_' . $order_id . '_' . time() . '.jpg';
$upload_path = 'assets/uploads/payments/' . $filename;
move_uploaded_file($_FILES['payment_proof']['tmp_name'], $upload_path);
// Save to database
$query = "INSERT INTO payments (order_id, payment_proof, payment_status)
VALUES (?, ?, 'pending')";
$stmt->bind_param("is", $order_id, $filename);
$stmt->execute();
}
?>
Penjelasan:
- File validation: Check type & size
- Unique filename: Timestamp untuk avoid conflict
- move_uploaded_file: PHP function untuk upload
- Database insert: Save filename reference
D. Order Tracking
order_tracking.php (Backend Query)
<?php
// Get shipping info
$query = "SELECT o.*, s.tracking_number, s.courier, s.shipping_status
FROM orders o
LEFT JOIN shipping s ON o.id = s.order_id
WHERE o.id = ? AND o.user_id = ?";
$stmt->bind_param("ii", $order_id, $user_id);
$stmt->execute();
$order = $stmt->get_result()->fetch_assoc();
// Get tracking history
$history_query = "SELECT * FROM tracking_history
WHERE shipping_id = ?
ORDER BY created_at DESC";
$history = $conn->query($history_query)->fetch_all(MYSQLI_ASSOC);
?>
Penjelasan:
- LEFT JOIN: Ambil data shipping
- ORDER BY DESC: Latest first
- Two queries: Order info + history
5️⃣ DATABASE IMPLEMENTATION
Database Schema
-- Products Table
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
category_id INT,
name VARCHAR(200) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock INT DEFAULT 0,
image VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
-- Orders Table
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled'),
payment_status ENUM('unpaid', 'pending', 'verified', 'rejected'),
shipping_address TEXT NOT NULL,
payment_method VARCHAR(50),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Payments Table ⭐ NEW
CREATE TABLE payments (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
amount DECIMAL(10,2) NOT NULL,
payment_method VARCHAR(50),
payment_status ENUM('unpaid', 'pending', 'verified', 'rejected'),
payment_proof VARCHAR(255),
bank_account VARCHAR(100),
account_name VARCHAR(100),
payment_date DATETIME,
verified_by INT,
verified_at DATETIME,
rejection_reason TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
-- Shipping Table ⭐ NEW
CREATE TABLE shipping (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
tracking_number VARCHAR(100),
courier VARCHAR(50),
shipping_status ENUM('processing', 'picked_up', 'in_transit', 'out_for_delivery', 'delivered'),
estimated_delivery DATE,
actual_delivery DATETIME,
notes TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
-- Tracking History Table ⭐ NEW
CREATE TABLE tracking_history (
id INT AUTO_INCREMENT PRIMARY KEY,
shipping_id INT NOT NULL,
status VARCHAR(50) NOT NULL,
location VARCHAR(200),
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (shipping_id) REFERENCES shipping(id)
);
Key Relationships
users (1) ──→ (N) orders
orders (1) ──→ (N) order_items
orders (1) ──→ (1) payments
orders (1) ──→ (1) shipping
shipping (1) ──→ (N) tracking_history
products (1) ──→ (N) order_items
categories (1) ──→ (N) products
6️⃣ API INTEGRATION
REST API Endpoints
1. Search Products
GET /api/search_products.php?q=keyword
Response:
{
"success": true,
"count": 3,
"products": [
{
"id": 1,
"name": "Laptop Gaming",
"price": 15000000,
"price_formatted": "Rp 15.000.000",
"stock": 10,
"in_stock": true,
"category_name": "Electronics"
}
]
}
2. Add to Cart
POST /ajax/add_to_cart.php
Body: product_id=1
Response:
{
"success": true,
"message": "Product added to cart"
}
3. Get Cart Count
GET /ajax/get_cart_count.php
Response:
{
"count": 3
}
API Flow Diagram
┌────────┐ HTTP GET ┌──────────────┐
│Browser │ ───────────────→│ API Endpoint │
└────────┘ └──────┬───────┘
│
│ SQL Query
▼
┌──────────────┐
│ Database │
└──────┬───────┘
│
│ Result Set
┌────────┐ JSON Response │
│Browser │ ←──────────────────────┘
└────────┘
7️⃣ TESTING GUIDE
A. Manual Testing Checklist
User Flow Testing
✅ 1. Register Account
- Buka register.php
- Isi form lengkap
- Klik Register
- Expected: Redirect ke login
✅ 2. Login
- Username: admin / Password: admin123
- Expected: Redirect ke dashboard (admin) atau home (user)
✅ 3. Browse Products
- Buka products.php
- Expected: Muncul list products
✅ 4. Live Search ⭐
- Ketik "laptop" di search box
- Expected: Hasil muncul tanpa reload
- Ketik "phone"
- Expected: Update hasil real-time
✅ 5. Add to Cart
- Klik "Add to Cart" pada product
- Expected: Alert "Product added"
- Badge cart bertambah
✅ 6. Checkout
- Buka cart.php
- Klik "Proceed to Checkout"
- Isi shipping address
- Pilih payment method
- Expected: Redirect ke payment.php
✅ 7. Payment Upload
- Upload bukti transfer
- Isi nama & no rekening
- Expected: Status "Pending Verification"
✅ 8. Admin Verify Payment
- Login sebagai admin
- Buka admin/payments.php
- Klik "View" payment
- Klik "Verify"
- Expected: Payment status → "Verified"
✅ 9. Admin Add Tracking
- Buka admin/shipping.php
- Input tracking number & courier
- Update shipping status
- Expected: Tracking visible di user
✅ 10. User Track Order
- Login sebagai user
- Buka order_tracking.php?order_id=X
- Expected: Muncul timeline tracking
B. API Testing
Test Live Search API
# Test 1: Valid search
curl "http://localhost/ecommerce/api/search_products.php?q=laptop"
# Expected Response:
{
"success": true,
"count": 1,
"products": [...]
}
# Test 2: Empty search
curl "http://localhost/ecommerce/api/search_products.php?q="
# Expected Response:
{
"success": false,
"message": "Search keyword required"
}
# Test 3: No results
curl "http://localhost/ecommerce/api/search_products.php?q=xyz123"
# Expected Response:
{
"success": true,
"count": 0,
"products": []
}
C. Database Testing
-- Test 1: Check products exist
SELECT * FROM products;
-- Test 2: Check search query
SELECT * FROM products WHERE name LIKE '%laptop%';
-- Test 3: Check orders with payment
SELECT o.*, p.payment_status
FROM orders o
LEFT JOIN payments p ON o.id = p.order_id;
-- Test 4: Check tracking history
SELECT * FROM tracking_history WHERE shipping_id = 1;
8️⃣ DIAGRAM SISTEM
A. System Flow Diagram
┌──────────────────────────────────────────────────┐
│ USER ACTIONS │
└───────────┬──────────────────────────────────────┘
│
▼
┌──────────────┐
│ Browse │
│ Products │
└──────┬───────┘
│
▼
┌──────────────┐ ┌──────────────┐
│ Live Search │────→│ Search API │
│ (AJAX) │ │ Endpoint │
└──────┬───────┘ └──────────────┘
│
▼
┌──────────────┐
│ Add to Cart │
│ (AJAX) │
└──────┬───────┘
│
▼
┌──────────────┐
│ Checkout │
└──────┬───────┘
│
▼
┌──────────────┐
│Payment Upload│
└──────┬───────┘
│
▼
┌──────────────────────┐
│ ADMIN VERIFICATION │
└──────────┬───────────┘
│
▼
┌──────────────┐
│Admin Verify │
│ Payment │
└──────┬───────┘
│
▼
┌──────────────┐
│ Admin Add │
│ Tracking │
└──────┬───────┘
│
▼
┌──────────────┐
│ User Track │
│ Order │
└──────────────┘
B. Database ER Diagram
┌─────────┐ ┌──────────┐ ┌─────────────┐
│ users │───1:N─│ orders │───1:1─│ payments │
└─────────┘ └────┬─────┘ └─────────────┘
│
│1:1
▼
┌───────────┐
│ shipping │
└─────┬─────┘
│
│1:N
▼
┌─────────────────┐
│tracking_history │
└─────────────────┘
┌────────────┐ ┌──────────┐
│ categories │───1:N─│ products │
└────────────┘ └────┬─────┘
│
│N:M (via order_items)
▼
┌──────────┐
│ orders │
└──────────┘
C. Payment Flow Diagram
USER SIDE SYSTEM ADMIN SIDE
│ │ │
│ 1. Checkout │ │
├──────────────────────────→│ │
│ │ │
│ 2. Upload Payment Proof │ │
├──────────────────────────→│ │
│ │ Save to DB │
│ │ Status: PENDING │
│ ├─────────────────────────→│
│ │ │
│ │ 3. Admin View │
│ │←─────────────────────────│
│ │ │
│ │ 4. Admin Verify │
│ │←─────────────────────────│
│ │ Status: VERIFIED │
│ │ │
│ 5. Notification │ │
│←──────────────────────────│ │
│ "Payment Verified!" │ │
│ │ │
9️⃣ USER GUIDE
A. User Registration & Login
Step 1: Register
1. Buka http://localhost/ecommerce/register.php
2. Isi form:
- Username: johndoe
- Email: john@example.com
- Password: 123456
- Full Name: John Doe
- Phone: 081234567890
3. Klik "Register"
4. Redirect ke login page
Step 2: Login
1. Buka http://localhost/ecommerce/login.php
2. Isi credentials:
- Username: johndoe
- Password: 123456
3. Klik "Login"
4. Redirect ke homepage
B. Shopping Flow
Step 1: Browse & Search Products
1. Buka products.php
2. Cara 1: Filter by category (klik sidebar)
3. Cara 2: Live Search
- Ketik "laptop" di search box
- Hasil muncul otomatis
- Tidak perlu klik search button
Step 2: View Product Detail
1. Klik "View Details" pada product card
2. Lihat informasi lengkap
3. Klik "Add to Cart"
4. Alert muncul: "Product added to cart!"
Step 3: Manage Cart
1. Klik icon cart di navbar
2. Lihat items di cart
3. Ubah quantity:
- Klik (+) untuk tambah
- Klik (-) untuk kurang
4. Klik (🗑️) untuk hapus item
5. Klik "Proceed to Checkout"
Step 4: Checkout
1. Review order summary
2. Isi/edit shipping address
3. Pilih payment method:
- Bank Transfer
- Credit Card
- E-Wallet
- COD
4. Klik "Place Order"
5. Redirect ke payment page
C. Payment Process
Step 1: Upload Payment Proof
1. Transfer ke rekening toko
2. Screenshot/foto bukti transfer
3. Isi form payment:
- Nama Pengirim: John Doe
- No. Rekening: 1234567890
- Tanggal Transfer: 15-12-2024 10:30
- Upload File: bukti_transfer.jpg
4. Klik "Submit Payment Proof"
5. Status: "Pending Verification"
Step 2: Wait for Verification
1. Buka "My Orders"
2. Klik order yang sudah upload payment
3. Status Payment: "PENDING"
4. Keterangan: "Payment verification in progress"
5. Tunggu admin verify (biasanya < 1 jam)
Step 3: Payment Verified
1. Refresh page / cek orders
2. Status Payment: "VERIFIED"
3. Button "Track Order" muncul
4. Order masuk processing
D. Order Tracking
View Tracking Information
1. Buka "My Orders"
2. Klik "Track Order" pada order verified
3. Lihat informasi:
- Tracking Number: JNE123456789
- Courier: JNE
- Status: In Transit
- Estimated Delivery: 20-12-2024
4. Lihat Timeline:
- [Active] In Transit - Jakarta Hub
- [Done] Order Picked Up - Warehouse
- [Done] Order Processing
5. Auto-refresh setiap update admin
E. Admin Guide
Admin Login
Username: admin
Password: admin123
URL: http://localhost/ecommerce/admin/
Manage Payments
1. Menu "Payments"
2. Lihat list pending payments
3. Klik "View" untuk lihat bukti transfer
4. Verify:
- Jika valid: Klik "Verify"
- Jika invalid: Klik "Reject" + isi reason
Manage Shipping
1. Menu "Shipping"
2. Pilih order yang sudah verified payment
3. Klik "Update"
4. Isi form:
- Tracking Number: JNE123456789
- Courier: JNE
- Shipping Status: In Transit
- Estimated Delivery: 20-12-2024
- Description: Package on the way
5. Klik "Update Shipping"
6. User bisa langsung track!
🎯 KESIMPULAN
What We Built
✅ E-Commerce System lengkap
✅ Payment Upload & Verification
✅ Order Tracking System
✅ Live Search API
✅ Admin Management Panel
✅ Responsive Design
Technologies Used
Frontend: HTML5, CSS3, Vanilla JS, Bootstrap 5
Backend: PHP Native, MySQLi
Database: MySQL
API: REST API, JSON
Key Features
🔍 Live Search - Instant search tanpa reload
💳 Payment System - Upload & verify payment
📦 Order Tracking - Real-time timeline
🛒 Shopping Cart - AJAX operations
👥 User Management - Register, Login, Profile
🎨 Admin Panel - Complete management
📚 ADDITIONAL RESOURCES
File Structure Summary
Komentar
Posting Komentar