Skip to content

Delivery areas, geofencing and delivery quotes

logistics-api is the only service that knows where a tenant delivers and what a delivery costs. Every other service asks it. This page is the integration contract; the full rule and field list live in logistics-api docs/delivery-zones.md.

Who owns what

Data Owner Others keep
Delivery areas (circles and polygons, fee or free, minimum order, ETA, priority, outlet scope, no-delivery areas) logistics-api geo_fences nothing
Distance pricing and geofence policy (per-km rate, minimum, rounding, coverage rule, buffer, maximum distance, customer confirmation) logistics-api logistics.delivery_quote_policy nothing
Outlet map pin auth-api outlet metadata (latitude, longitude), published on auth.outlet.* mirrors in logistics and ordering
The fee charged on an order ordering-backend orders.delivery_fee plus metadata.delivery_quote snapshot logistics task metadata (zone_id, zone_name, distance_km, delivery_fee)
Ordering's own fees (service, packaging, small order, delivery discount, free delivery minimum) ordering-backend service_configs.fee_config nothing

No service other than logistics-api computes distances, point-in-area checks or delivery fees.

How to price a delivery

Server side, at checkout:

POST {LOGISTICS_SERVICE_URL}/api/v1/s2s/zones/{tenant-uuid-or-slug}/quote
X-API-Key: <INTERNAL_SERVICE_KEY>
{"lat": 0.47, "lng": 34.16, "outlet_id": "<optional>", "order_total": 800}

The response says whether the pin is deliverable, the fee, the matched area or the nearest one, the distance and the ETA. A pin outside every named area is still delivered (priced by distance, method = per_km) when it lies on the way to a delivery area: within the policy's corridor_km (default 5) of the straight route from the outlet to that area's far edge, or just past it. Direction counts, so a place in the opposite direction is refused however near it is; the tenant can switch to "near an area only" in the policy. A refusal carries direction, outlet_km, route_area and route_off_km so the customer sees which way the pin lies and how far off the delivery routes it is. The distance price is held to the published area fees on the same route: never above the furthest area's fee on that route and never below the fee of a nearer area already passed (breakdown.adjusted). A distance-priced quote also carries needs_confirmation when the tenant wants the customer to check it: ordering passes it on and the order confirmation email states the area, distance and fee. Charge the returned fee (after any of your own adjustments) and store the quote with the order. Never fall back to a guessed fee: if logistics cannot be reached, refuse delivery and keep pickup working. Quotes may be cached for cache_seconds per tenant, outlet and pin.

Browser side (public, throttled per IP):

Endpoint Use
GET /api/v1/{tenant}/zones/coverage Draw the delivery areas and centre a map
GET /api/v1/{tenant}/zones/quote?lat&lng&outlet_id&order_total Live fee while a customer moves the pin
GET /api/v1/{tenant}/routing/geocode/search?q Place search (tenant areas first)
GET /api/v1/{tenant}/routing/geocode/reverse?lat&lng Name the place at a pin

Use @bengo-hub/maps v0.3.0 or later for the UI: LocationPicker for a single pin, ZoneLayer to draw areas, ZoneEditor for admin editing.

Where admins configure it

logistics-ui, Delivery areas (/{tenant}/zones): add or edit areas on the map or by typed coordinates, set the distance rate, coverage rule and geofence, test any location, and see deliveries by area. Everything follows the branch chosen in the header switcher (the main outlet is preselected), and a new area's fee is suggested from the distance between that outlet and the area using the tenant's own distance rates. The Outlets tab sets each outlet's map pin (stored in auth-api, which owns outlets), so every outlet that delivers has its own origin and its own areas. Shifts can list the areas a rider covers, which auto-dispatch prefers. Other UIs link there instead of copying the screens.

Current consumers

  • ordering-backend and ordering-frontend (checkout, header location, saved addresses, outlet listing).
  • logistics task intake and dispatch (zone tagging, zone-aware rider choice, rider earnings by real distance).
  • rider-app (area, distance and fee on jobs).

POS till deliveries, courier tenants and distribution tenants (KEMSA-style regional delivery) use the same quote and areas: configure areas in logistics-ui and call the S2S quote.