A premium, modern, and real-time self-ordering Point of Sale (POS) system designed for restaurants. Customers can scan a table-specific QR code, input their basic information, browse the digital menu, place orders, and choose their preferred payment method. Kitchen staff receive orders in real-time, and cashiers manage active tables and payments dynamically.
The main goal of this system is to streamline the restaurant ordering process, minimize manual errors, and provide a seamless dining experience. By utilizing self-service ordering and real-time updates, we bridge the gap between customers, the kitchen, and the cashier.
sequenceDiagram
autonumber
actor Customer as Customer (Table)
actor Kitchen as Kitchen Staff
actor Cashier as Cashier
actor Admin as Admin
%% Setup phase
Admin->>Admin: Create Menu & Tables
Admin->>Admin: Generate & Print Table QR Codes
%% Customer Phase
Customer->>Customer: Scans Table QR Code
Customer->>Customer: Inputs Name & Phone Number
Customer->>Customer: Browse Menu & Add items to Cart
Customer->>Customer: Submits Order (Status: Pending)
%% Kitchen Phase
Note over Kitchen: Receives order in real-time (Laravel Reverb)
Kitchen->>Kitchen: Updates status to Cooking
Kitchen->>Kitchen: Updates status to Ready
%% Customer Requesting Bill
Customer->>Customer: Receives "Ready" notification
Customer->>Customer: Clicks "Request Bill"
Note over Cashier: Receives bill request in real-time
%% Payment Phase
alt Option A: Pay Cash to Cashier
Customer->>Cashier: Pays manually at the cashier counter
Cashier->>Cashier: Input amount & processes payment
Cashier->>Customer: Prints PDF receipt
else Option B: Pay Online (Xendit)
Customer->>Customer: Clicks "Pay Online"
Customer->>Customer: Redirected to Xendit Invoice page
Customer->>Customer: Completes payment (QRIS/VA/E-Wallet)
Xendit->>Cashier: Sends Webhook (Auto-approves payment)
end
%% Completion Phase
Note over Cashier, Customer: Order Status updated to Completed
Note over Cashier, Customer: Table Status reset to Available
- Scan QR Code: Scanning the table QR code redirects the customer to their table's specific ordering page.
- Identify & Access: Customers enter their name and phone number to create a session (order status:
draft). - Interactive Menu & Cart: Browse categories, customize items with notes, and add them to their interactive cart.
- Submit Order: Orders are sent to the kitchen in real-time. Customers can continuously append new items to their active order.
- Request Bill: Requesting the bill notifies the cashier instantly.
- Payment Choice:
- Cash: Notify cashier to pay manually at the counter.
- Online (Xendit): Instant checkout via QRIS, Virtual Accounts, or E-Wallets.
- Real-time Queue: View incoming orders automatically as they are submitted (broadcasted via Laravel Reverb).
- Order Status Transition: Transition orders from
pending➡️cooking➡️readywith intuitive action buttons. - Detailed Info: View item names, quantities, and customer-specific notes (e.g., "no onions").
- Table Grid: Visual layout displaying all tables, color-coded by occupancy status (
availablevsoccupied). - Real-time Notifications: Receive distinct visual alerts when a table clicks "Minta Bill" (Request Bill).
- Manual Checkout: Select a table, view the itemized summary, input the cash amount received, calculate change, and complete the order.
- Receipt Generation: Stream/download print-ready PDF receipts for customers.
- Menu Management: Full CRUD operations on categories and menu items (with image uploads hosted on Supabase Storage).
- Table Management: Manage tables, generate dynamic table-specific QR codes, and download them as PNGs.
- User Management: Create and manage user credentials for Cashier, Kitchen, and Admin roles.
- Financial Reports: View daily, weekly, or custom date-range sales reports. Export data directly to Excel or download PDF summaries.
Table Selection Page: Customers choose an empty table to start ordering. Occupied tables are marked with a dark color and "Sedang Terisi" (Occupied) status.
Customer Registration & Onboarding: Form to input full name and WhatsApp number to verify customer identity at the table before accessing the menu.
Self-Order Menu: Interactive menu listing with fast search, categories (Main Course, Drinks, etc.), kitchen queue estimation, and active order status.
Shopping Cart (Your Order): Modal showing details of customer's active order to review selected items and custom notes (e.g. spicy levels) before placing order.
Payment Method Options: Modal for selecting checkout method, offering online payment (QRIS/E-Wallet/Bank Transfer via Xendit) or cash payment directly to the cashier. Real-time Kitchen Queue: Dedicated kitchen dashboard updated in real-time via Laravel Reverb, showing incoming orders with custom notes and action buttons (e.g., "Selesai Masak").
Cashier Dashboard (Table Monitoring): Interactive visual table layout with color indicators for real-time operational status (Available, Waiting for Kitchen, Cooking, Ready to Serve, Requesting Bill).
Cashier Payment Detail & Checkout: Interface for cashier when processing payments, including order details, total bill, cash received input, auto change calculation, and payment confirmation.
Receipt / Invoice (PDF): Print-ready payment receipt (including thermal printing format) containing customer name, table details, itemized orders with custom notes, total paid, change, and completed/paid status.
Admin Dashboard & Sales Reports: Financial analytics page for restaurant owner. Provides transaction date filters, revenue metrics, and instant exports to Excel or PDF format.
Sales Report PDF: Sample of the exported sales report in PDF format.
- Backend Framework: Laravel 12 (Core API, Eloquent, Authentication)
- Frontend Library: Vue 3 (Composition API) with Inertia.js 2
- Styling Framework: Tailwind CSS
- UI Components: PrimeVue (using the modern Aura preset theme)
- Real-time Server: Laravel Reverb (WebSockets native broadcasting)
- Database & Storage: Supabase (PostgreSQL & Cloud Object Storage)
- Payment Gateway: Xendit PHP SDK (QRIS, VA, E-Wallet integration)
- QR Generator: Simple QR Code (
simplesoftwareio/simple-qrcode) - Reports & Exports: Laravel DomPDF & Maatwebsite Excel
- PHP >= 8.2
- Node.js & NPM
- PostgreSQL database (Supabase recommended)
-
Clone the repository:
git clone https://github.com/rahulken96/pos-self-order-system.git cd pos-self-order-system -
Install PHP & JavaScript dependencies:
composer install npm install
-
Configure Environment Variables: Copy the example environment file and fill in your Supabase connection parameters, Laravel Reverb keys, and Xendit API secret.
cp .env.example .env php artisan key:generate
-
Run Database Migrations & Seeders: Deploy the tables and seed default users (Admin, Kasir, Dapur) and 10 default tables.
php artisan migrate --seed
-
Start Dev Servers: Launch the Laravel backend server, the Reverb WebSocket server, and the Vite compilation server.
- Terminal 1 (Laravel Server):
php artisan serve
- Terminal 2 (Vite Asset compiler):
npm run dev
- Terminal 3 (Reverb WebSockets):
php artisan reverb:start --debug
- Terminal 4 (Queue Jobs):
php artisan queue:work
- Terminal 1 (Laravel Server):
-
Access the App:
- Go to
http://localhost:8000/loginto log in as Admin (admin@pos.com), Cashier (kasir@pos.com), or Kitchen (dapur@pos.com) with the passwordpassword. - Scan or browse
http://localhost:8000/order/1to test the customer flow on Table 1.
- Go to












