Проверка адреса доставки

POST /delivery/check

Отвечает на вопрос «возит ли заведение по этому адресу» — до того, как клиент увидит меню и соберёт корзину.

Так работают крупные сервисы доставки: сначала адрес, потом витрина. Иначе человек выберет блюда, дойдёт до оплаты и там узнает, что доставки в его район нет.

{ "latitude": 41.1568, "longitude": 70.2103 }

Адрес обслуживается

{
  "is_deliverable": true,
  "reason": null,
  "point_id": "acfc9a2c-244c-459e-9588-148885493a4e",
  "point_name": "Central Fast Food",
  "distance_km": null,
  "delivery": {
    "price": 10000,
    "zone_id": 3,
    "zone_name": "shohzone",
    "minutes": 60,
    "min_order_amount": 50000
  }
}

point_id — точка, которая обслуживает адрес. Именно её передавайте дальше в /menus/{id} и в заказ: меню, цены и стоп-лист у точек различаются.

Адрес не обслуживается

{
  "is_deliverable": false,
  "reason": "too_far",
  "message": "Адрес дальше максимальной дистанции доставки (809 км при лимите 10 км)",
  "point_id": "2de09dd4-709f-4259-b3b3-92573ef57181",
  "point_name": "Tortko'l | Shukrona",
  "distance_km": 808.99,
  "delivery": null
}

Ответ приходит с кодом 200 — это не ошибка запроса, а нормальный ответ «не возим». Смотрите на is_deliverable, а текст из message можно показать клиенту.

reasonЧто случилось
out_of_zoneЗаведение нарисовало зоны доставки, адрес не попал ни в одну
too_farЗон нет, но адрес дальше максимальной дистанции точки
no_pointsУ заведения нет точек с координатами — обратитесь к нему

Как заведение задаёт границы

Проверок две, и они не складываются — работает первая подходящая.

1. Зоны доставки. Заведение рисует на карте полигоны, у каждого свои цена, время и минимальная сумма заказа. Если зоны нарисованы, решают только они: адрес либо внутри полигона, либо доставки нет.

2. Максимальная дистанция точки. Когда зон нет, берётся ближайшая точка и её лимит («возим в радиусе 10 км»). Расстояние считается по прямой от точки до адреса.

Если у заведения нет ни зон, ни лимита — доставка доступна везде, а её стоимость 0.

Как встроить в приложение

Клиент выбрал адрес на карте
        ↓
POST /delivery/check
        ↓
is_deliverable = false → «Сюда мы не доставляем», меню не показываем
        ↓
is_deliverable = true  → берём point_id, грузим меню этой точки,
                         показываем стоимость доставки из delivery.price

Стоимость и время доставки известны уже здесь — их можно показать сразу под адресом, не дожидаясь сборки корзины.

Проверка не заменяет расчёт корзины

delivery.min_order_amount говорит, какой минимум нужен для этой зоны, но саму сумму корзины здесь никто не считает. Перед оформлением всё равно вызывайте POST /orders/calculate — он проверит и минимум, и стоп-лист.