Self-Order Kiosk
Self-Order Kiosk turns any screen (a tablet at the counter, a stand near the door) into a full-screen, touch-first ordering terminal customers can use themselves — browse the menu, build a cart, pay, and walk away with a token number.
Overview
The kiosk takes over the entire screen (it renders as a full-screen overlay on top of the app, not a normal page) and walks the customer through seven screens in order: Welcome → Order Type (Dine In / Take Away) → Table Number (dine-in only) → Menu → Cart → Payment → Thank You.
It reuses the same product catalogue, categories, tax rates and scope (branch/company) as the rest of BazaarPOS, so anything you manage on Products and Inventory shows up here automatically — including images, discounts, allergens, calories and out-of-stock overlays.
The kiosk is generic across variants (restaurant, bakery, café) — nothing in the component is bakery-specific, it simply reads whatever products and categories exist for your store.
After 180 seconds of no interaction (no tap, click, key press or mouse movement) the kiosk automatically resets itself back to the Welcome screen, so it is always ready for the next customer.
Before You Start
- Products should have images, and optionally the badge flags (isFeatured/isPopular/isBestseller/isChefPick/isNew), allergens, and calories filled in — the kiosk reads these directly from the product record to show badges, allergen tags and calorie counts.
- To accept UPI or card payments with a QR code on the kiosk, at least one payment gateway must be enabled under your payment gateway settings; otherwise the kiosk falls back to "Debit / Credit Card" (pay at counter) and "Cash at Counter" only.
- Promo codes used in the cart step must already exist and be active (created under Offers & Coupons) — the kiosk validates whatever code the customer types against that list.
Step-by-Step Guide
1 Start an order and choose Dine In or Take Away
- The kiosk opens on the Welcome screen showing your store name and a large "Touch to Start" button.
- Tapping it moves to the Order Type screen — the customer picks Dine In (eat at a table) or Take Away (collect from counter).
- Dine In goes to a Table Number screen with a number pad (up to 4 digits) — the customer can enter their table number or tap Skip table number to continue without one.
- Take Away skips straight to the Menu.
2 Browse the menu and build a cart
- The category sidebar on the left lists "All Items" plus every product category, each tappable to filter the grid; the search box at the top filters by name as the customer types (debounced ~320ms).
- A Featured horizontal banner appears at the top of "All Items" showing up to 8 products flagged as featured, bestseller or popular — it disappears once a category or search is active.
- Tapping a product card opens its detail modal (image, price, discount strikethrough, GST %, calories, allergen tags, a low-stock warning when 5 or fewer units remain, an optional special-instructions note, and a quantity stepper) — tap Add · ₹total to add it to the cart.
- Tapping the green ⊕ quick-add button on a card instead adds 1 unit directly without opening the modal.
- Out-of-stock products (inventory quantity ≤ 0) show a dimmed "Out of Stock" overlay and cannot be tapped or added.
- After the very first item is added, an "Complete Your Meal" upsell panel may pop up from the bottom suggesting 3 random in-stock products from a different category — tap one to add it, or "No thanks, continue to cart" to dismiss.
3 Review the cart and apply a promo code
- Tap the floating "View Order · ₹total" pill (or the cart icon in the menu header) to open the Cart screen.
- Adjust quantity with the − / + steppers on each line, or tap the trash icon to remove a line entirely.
- Type an overall Order Note (e.g. an allergy request that applies to the whole order) in the notes box.
- Enter a promo code and tap Apply — a valid code shows a green confirmation with the % off; an invalid or expired code shows an error toast and applies no discount.
- Review the Subtotal / CGST / SGST / Promo Discount / Total breakdown, then tap Proceed to Payment · ₹total.
4 Choose a payment method and pay
- The Payment screen lists whatever methods are available: one entry per enabled payment gateway (UPI/QR or Card, generated dynamically from Settings → Payment Gateways), plus "Debit / Credit Card" (pay at counter, only shown if no card gateway is configured) and "Cash at Counter" always last.
- Selecting a gateway-backed method automatically requests a payment QR from that gateway and displays it; BazaarPOS then polls the gateway every 3 seconds and automatically completes the order the moment payment is detected — no button press needed once payment is done.
- Selecting Cash or the plain Card option instead requires the customer to tap the big Confirm Order / Pay by Card button at the bottom to place the order.
- Placing the order posts it to the kiosk order queue and moves to the Thank You screen with a token number.
5 Show the token, print a receipt, and reset for the next customer
- The Thank You screen displays a large token number and a message telling the customer whether to pay/collect at the counter (cash/card) or that UPI payment was received.
- Tap Show Receipt to expand the itemised bill on-screen, then 🖨 Print Receipt to open a print-formatted popup window with the same token number.
- A 30-second countdown ("New order in Ns") automatically returns the kiosk to Welcome; tap Start New Order to reset immediately instead.
6 Use the accessibility large-text toggle
- On every screen except Welcome, a small circular button in the bottom-right corner toggles "large text" mode.
- Turning it on scales up all text and controls by 1.25× for easier reading/tapping — useful for older customers or a kiosk mounted further from eye level.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Touch to Start | Welcome-screen button that begins a new order and moves to the Order Type screen. |
Dine In / Take Away | Order type selection; Dine In routes to the table-number screen first, Take Away skips straight to the Menu. |
Table number pad | On-screen numeric keypad (up to 4 digits) for entering a table number; "Skip table number" continues without one. |
Category sidebar | All Items plus every product category; tapping one filters the product grid instantly. |
Search menu… | Debounced text search across product names, replacing the category grid with matching results. |
Featured banner | Horizontal scroll strip of up to 8 products flagged Featured/Bestseller/Popular; only shown on "All Items" with no active search. |
Product badges | BESTSELLER, CHEF'S PICK, POPULAR, NEW or FEATURED — shown in that priority order based on flags on the product record. |
Quick-add (⊕) | Adds 1 unit of a product straight to the cart without opening its detail modal. |
Item detail modal | Full product view with image, discount price, GST, calories, allergen tags, a low-stock note, a special-instructions field and an Add-to-cart button with live quantity/price. |
Upsell panel | "Complete Your Meal" suggestion of 3 random in-stock products from a different category, shown once after the first item is added to an empty cart. |
Cart quantity steppers / trash icon | Adjusts or removes a line item in the Cart screen. |
Order notes | A free-text note for the whole order (e.g. allergy or special request), separate from any per-item note. |
Promo code + Apply | Validates the typed code against active promotions and applies a flat percentage discount to the order if valid. |
Proceed to Payment | Moves from Cart to the Payment screen with the current totals locked in. |
Payment method cards | One card per enabled payment gateway (UPI/Card with QR), "Debit / Credit Card" (counter, shown only without a configured card gateway), and "Cash at Counter". |
Payment QR | Shown automatically once a gateway-backed method is selected; the kiosk polls for payment status every 3 seconds and auto-completes on success. |
Confirm Order / Pay by Card / Confirm Payment | Places the order — label and behaviour change based on the selected payment method. |
Token number | The large number shown on the Thank You screen; the customer shows this at the counter to collect their order. |
Show/Hide Receipt | Expands an on-screen itemised receipt on the Thank You screen. |
🖨 Print Receipt | Opens a separate print-formatted window with the itemised bill and token number, and triggers the browser print dialog. |
Start New Order | Immediately resets the kiosk back to the Welcome screen, ahead of the automatic 30-second countdown. |
Accessibility toggle (bottom-right circle) | Switches between normal and 1.25× "large text" mode on every screen except Welcome. |
Tips & Best Practices
- Fill in product images, allergens and calories on the Products page before going live — kiosk customers rely much more heavily on visuals than staff do at POS.
- Configure at least one UPI payment gateway so the kiosk can show a real QR and auto-complete payment without a staff member touching the screen.
- Mount the kiosk where a staff member can glance at the Kiosk Orders screen — new orders need to be confirmed there before they turn into a bill.
- Use the large-text accessibility toggle for kiosks placed at a height or angle that is harder to read, e.g. a wall-mounted unit.
Troubleshooting & FAQ
The kiosk went back to the Welcome screen while a customer was mid-order.
No QR code shows up for UPI or Card payment.
A promo code the customer typed says invalid even though it exists.
An order placed on the kiosk isn't showing up as a sale yet.
The theme/accent colour on the kiosk doesn't match my store theme.
🧑💻 Developer Notes
Source component(s):
frontend-app/packages/pos-react-lib/src/pages/KioskPage.jsx
Backend endpoints used:
GET /categoriesGET /productsGET /tax-master/products/:id/taxesPOST /tax-master/products/:id/calculate-taxGET /settingsGET /promotions/validate (POST)GET /payment-gatewaysPOST /payment-gateways/create-orderGET /payment-gateways/status/:provider/:orderIdPOST /kiosk/orders
Related tables (db-core repositories):
ProductCategoryPromotionPaymentGatewayKioskOrderTaxGroup
Redux slices:
theme (accent colour)scope (selectCurrentScope / getScopeQueryParams)
Feature flag key: billing
Mounted at /bakery/kiosk with no minTier restriction (available on the Basic plan). The component is rendered via ReactDOM.createPortal straight onto document.body so it truly covers the whole screen regardless of where it is routed from. Payment-gateway polling and the 180-second idle-reset are both plain setInterval/setTimeout hooks local to the component — there is no server push/websocket involved.