Home / Help Center / pos-app / Sell / Billing / Home Delivery
🚚 Sell / Billing

Home Delivery

Home Delivery is a single board for every delivery order coming into the shop — whether it arrived through Swiggy, Zomato, a phone call, WhatsApp, your website, or was created directly at the counter — tracked from "New" through to "Delivered".

📍 Menu path: Sell / Billing → Home Delivery
👤 Who uses it: All roles with Billing menu access (featureKey: billing) — available on every plan tier, not gated to Advanced or above

Overview

Every delivery order, regardless of which channel it came from, is shown as a card with a platform badge (🧡 Swiggy, ❤️ Zomato, 📞 Phone, 💬 WhatsApp, 🌐 Website, 🏪 Direct) and a status badge that moves through a fixed pipeline: New → Accepted → Preparing → Ready → Out for Delivery → Delivered (or Cancelled at any point before Delivered).

The page auto-refreshes every 30 seconds in the background so orders placed on a food-delivery platform (or injected by a webhook) appear without anyone touching the Refresh button, and a manual Refresh icon is always available for an instant pull.

An elapsed-time badge sits on every active order card and turns amber once 70% of the estimated preparation/delivery time (ETA) has passed, then red with the word "LATE" once the ETA is fully used up — so a busy kitchen or counter can see at a glance which orders are falling behind.

Clicking an order card opens a detail drawer where you can assign a delivery agent by name, adjust the ETA, review the full item list and total, and push the order through the remaining statuses one at a time, or cancel it.

Before You Start

Step-by-Step Guide

1 Create a new delivery order

Use this for phone, WhatsApp or walk-in delivery requests — orders coming from Swiggy/Zomato webhooks appear automatically without this step.

  1. Click New Order in the top-right of the page.
  2. Pick the source Platform tile (Swiggy, Zomato, Phone, WhatsApp, Website or Direct) — this only affects the badge shown on the order, not how it is fulfilled.
  3. Type into Customer Name * to search existing customers; picking one auto-fills phone, delivery address (built from the customer's address, city and pincode) and delivery route, and silently fetches that customer's most recent delivery order so its item lines can be reused as a starting point (you'll see "Items from last order on …" while this loads).
  4. Fill in Delivery Address * if it was not auto-filled, and adjust Phone if needed.
  5. Add one or more Order Items (name, quantity, price) with the + Add Item button; remove a line with its ✕ button. The running total is shown once any line has a price.
  6. Optionally set a Delivery Route label (e.g. "North Route") to group orders for a delivery agent, an ETA (minutes), and any Notes / Special Instructions (e.g. "No onion").
  7. Click Create Order. Both Customer Name and Delivery Address are required — the page blocks saving and shows a toast if either is blank.

2 Move an order through its delivery stages

  1. On the order card, click the colored status button in the bottom-right (e.g. Accepted, Preparing, Ready, Out for Delivery, Delivered) to advance it to the next stage in the pipeline — each click moves it exactly one step forward.
  2. The card's left accent color and status pill always reflect the current stage, and the elapsed-time badge keeps counting from the moment the order was created.
  3. To cancel an order instead of progressing it, open its detail drawer and use ✕ Cancel Order — available on any order that is not already Delivered or Cancelled.

3 Assign a delivery agent and adjust the ETA

  1. Click anywhere on an order card (not the status button) to open its detail drawer.
  2. Enter the rider/agent's name in the Delivery agent name field and adjust the min ETA number (5–180 minutes), then click Save — this updates the order without changing its status.
  3. The drawer also lists customer name, phone, address and any notes, plus the full item list with quantities and line totals, and lets you jump straight to any later status with a single click.

4 Filter, search and monitor the day's deliveries

  1. Use the date picker to review a different day's orders.
  2. Type in the search box to filter by order number, customer name or phone.
  3. Use the All statuses and All platforms dropdowns to narrow the list to, say, only Zomato orders that are Out for Delivery.
  4. Watch the four KPI tiles above the list — Active, Out for Delivery, Delivered Today and Delivered Revenue — for a running summary of the day.

Every Field & Button, Explained

Field / ButtonWhat it does
Active / Out for Delivery / Delivered Today / Delivered RevenueKPI tiles counting orders currently in any non-final status, orders specifically Out for Delivery, orders Delivered so far today, and the ₹ total of Delivered orders today.
Platform tilesSwiggy, Zomato, Phone, WhatsApp, Website, Direct — sets the source badge shown on the order card and in filters; purely informational, does not change fulfilment.
Customer Name *Type-ahead customer search; selecting a match auto-fills phone, delivery address and route, and pulls that customer's last delivery order's items as a starting point. Required to save.
Delivery Address *Free-text multi-line address; required to save an order.
Order ItemsRepeatable name / quantity / price rows; use + Add Item to add a row and the ✕ button to remove one. Total is computed live from quantity × price across all rows.
Delivery RouteFree-text label (e.g. "North Route", "Route A") to help group orders by area for a delivery agent's round.
ETA (minutes)Expected time to prepare and deliver the order; drives the elapsed-time badge's amber/red thresholds on the order card.
Elapsed badgeLive "Xm" counter on active orders; turns amber past 70% of ETA and red with "LATE" once elapsed time exceeds the ETA.
Next-status buttonThe colored pill button on each card (e.g. "→ Preparing") advances the order exactly one step along New → Accepted → Preparing → Ready → Out for Delivery → Delivered.
Detail drawer — Delivery agent name / min ETA / SaveUpdates the assigned rider and the ETA on an existing order without changing its status.
Detail drawer — Update Status listJump directly to any later status in one click, or use ✕ Cancel Order to cancel (hidden once Delivered or Cancelled).
Refresh buttonManually re-fetches the order list for the selected date immediately; the page also silently re-fetches every 30 seconds on its own.
Date / Search / status & platform filtersNarrow the list to a specific day, a text match on order number/customer/phone, a specific pipeline stage, or a specific source platform.

Tips & Best Practices

Troubleshooting & FAQ

An order from Swiggy/Zomato has not shown up yet.
The list refreshes automatically every 30 seconds, and you can force it immediately with the Refresh button. If it still does not appear, check that the correct Date filter is selected — orders are filtered by the date shown in the date picker.
I can't click Create Order.
Customer Name and Delivery Address are both required. A toast will tell you which one is missing — fill it in and try again.
The elapsed badge on an order suddenly turned red.
That order's elapsed time has passed its ETA. Either the order is genuinely running late, or the ETA entered when it was created was set too low — open the order and adjust the ETA if needed.
Can I un-cancel an order?
No — Cancelling is a one-way action reached from the detail drawer's Update Status list. Create a new order if it needs to be redone.

🧑‍💻 Developer Notes

Source component(s):

  • frontend-app/packages/pos-react-lib/src/pages/shared/FnbDeliveryOrdersPage.jsx

Backend endpoints used:

  • GET /delivery-orders?date=&status=&platform= (list for the selected day, optionally filtered)
  • GET /delivery-orders?customerPhone=&limit=1 (fetch a customer's most recent order to pre-fill items)
  • POST /delivery-orders (create)
  • PUT /delivery-orders/:id (update status, agent name, ETA)

Related tables (db-core repositories):

  • FnbDeliveryOrder

Feature flag key: billing

Mounted generically as <FnbDeliveryOrdersPage apiPrefix="" /> at pos-app's /deliveries route (App.js), reusing the same component that powers the bakery/restaurant delivery channel behind their own apiPrefix (e.g. /bakery, /restaurant) — the generic mount hits the routes in backend/src/routes/delivery.routes.js, which is registered at the API root (not variant-gated) and dispatches to the same bakery.controller handlers as the variant-specific mounts. Polling for new orders uses a 30-second setInterval with a silent (non-blocking) reload so the spinner never flickers.