Door-to-door delivery
Registered customers order from a store for home delivery. Managers accept and assign (or riders self-claim from the open pool). Riders use the installable /delivery PWA, the Flutter mobile app, or the Sanctum JSON API. After COD deliveries, cash is returned to the store cashier and settled against the rider’s balance.
Store setup
- Edit the store → enable Door-to-door delivery, optionally open job pool, and set the service charge.
- Create a staff user with the Delivery role for that store.
- Enable customer portal login and password.
- Give cashiers the Receive COD permission (
delivery.cod.receive) so they can take cash handovers — built-in Cashier and Manager roles include this by default. - Configure payment gateways (Settings → Payment gateways) for real online pay; without gateways, online is mocked.
- Configure SMS/FCM under Settings → SMS & Push (Twilio, Bangladesh HTTP SMS, or log driver).
Customer ordering
Sign in at /customer/login. Checkout supports COD or online. When gateways are enabled, checkout opens a payment link and polls until paid. Optional browser GPS is stored on the order for the live map.
Store operations
Sales → Delivery orders: accept, assign, print, cancel. The order live map shows the customer destination (home pin) and all store delivery staff currently sharing GPS (scooter pins). Hover a pin for customer or rider details; the assigned rider is highlighted in blue with route/ETA.
Sales → COD cash (/admin/delivery-cod): store-wide COD summary by delivery staff — amounts still to collect, cash outstanding with riders (item total, service charge, COD total), and settlements in a date range. Recent handovers list who returned cash and which cashier received it.
COD cash flow
- Customer pays COD at the door. The rider confirms collection on the order (status becomes COD collected). The rider may still be holding that cash.
- Rider returns cash to the store. On the delivery portal, open COD to see totals: still to collect from customers, cash to hand over, and settlements today — each broken into item total, delivery service charge, and COD total.
- Cashier receives COD at Operations → Receive COD (
/cashier/cod-receive), or from the POS overflow menu. Pick the rider, select orders, confirm. Orders become COD settled. If the cashier has an open shift, the amount is recorded as a cash pay-in on that shift.
Permissions: riders use delivery.orders.collect_cod and can view their own summary; cashiers use delivery.cod.receive; managers/admins see the full COD cash report via delivery.orders.view / delivery.cod.view_summary.
Rider portal (PWA)
- My jobs and Open pool (self-claim).
- Overview KPIs with a period selector: Today, Last 3 days, Last week, Last 15 days, This month, Last month, Last 90 days. Charts and “delivered in period” / delivered value follow the selection; live COD and active-job figures stay current.
- COD tab — personal COD summary (to collect / to return / settled today).
- Status: picked up → out for delivery → delivered; COD confirm.
- GPS sharing while the portal is open; Leaflet live map; Install app prompt.
Period is passed as ?range= on /delivery and /delivery/pool (keys: today, 3d, 7d, 15d, this_month, last_month, 90d). Default is last week (7d).
Rider mobile API
Base path /api/delivery. Auth: POST /login → Bearer token (Sanctum).
GET /me,GET /dashboard?range=7d(KPIs / earnings; same range keys as the PWA; response includesrange,range_label, andranges)GET /cod-summary(rider’s COD to collect / to return / settled today)GET /orders,GET /orders/pool,POST /orders/{id}/claimPOST /orders/{id}/status,POST /orders/{id}/collect-codPOST /location,GET /orders/{id}/tracking(includesdistance_km,eta_minutes)POST /device-tokens(FCM)
Demo rider: delivery@demo.test / delivery1234.
Customer mobile API
Base path /api/customer. Auth: POST /login with store_code, login (email/phone), password → Bearer token (Sanctum on customers).
GET /me,PUT /password,GET /catalogGET/POST /addresses,PUT/DELETE /addresses/{id}POST /checkout,GET /orders,GET /orders/{id}GET /orders/{id}/tracking(rider pin + ETA/distance)POST /orders/{id}/pay,GET /orders/{id}/payment-statusPOST /orders/{id}/cancel,POST /orders/{id}/reorderPOST /device-tokens(FCM)
Flutter app
Dual-role Customer & Rider app lives in /mobile. See mobile/README.md. Maps use OpenStreetMap via flutter_map; tracking polls every 5 seconds while the map screen is open.
- Home and Earnings share a period menu (same ranges as the web portal) and call
GET /api/delivery/dashboard?range=…. - Riders still confirm COD on the job; store settlement is done by the cashier on the web POS / Receive COD screen.