Интеграция взаимодействия со сторонними сервисами доставок, такими как Яндекс Go
Задача
В рамках проекта Xistore.by была поставлена задача реализовать интеграцию сервиса доставки Яндекс Go на сайте, интегрировать расчеты, обновление цен, связей с магазинами.
Реализация
Мы реализовали доставку при помощи сервиса Яндекс Go, который по статистике позволяет доставить заказ в течение 30 минут в пределах одного города. То есть можно быстро получить товар, например, в подарок, даже не посещая магазин. Для определения адреса доставки используется сторонний сервис DaData, который предоставляет координаты адреса, что сильно упрощает дальнейшее взаимодействие с сервисом Яндекс GO.
Работает это следующим образом:
Происходит сверка с базой — поиск нужного адреса в перечне доставки. Эта база адресов доступна из предоставленного списка сторонних сервисов доставки.
Пользователь вводит адрес доставки на сайте. Сервис DaData исключает ввод неверного адреса, так как предлагает к выбору из реально существующих.
После того, как пользователь выбрал адрес, нам известен город и координаты доставки, которые будут использованы в сервисе Яндекс GO.
Остается найти магазин/склад, который будет соответствовать следующим параметрам:
- оффлайн-магазин/склад находится в населенном пункте клиента;
- в магазине имеются все позиции из заказа в нужном количестве;
- у магазина ещё есть достаточно времени до закрытия.
После подбора магазина/склада, если существует подходящий по всем параметрам, производится предварительная бронь в яндексе и клиенту дается время на оплату заказа онлайн. Если клиент успел оплатить, то заказ в яндексе переходит из статуса брони в статус оформленного. На это время цена доставки для новых заказов этого клиента неизменна.
Особенности реализации
Как сделать так, чтобы система понимала, где ближайший магазин Xistore к адресу доставки, и именно из него везли заказ?
Сначала берем координаты точки заказчика и по ним определяем, доступна ли для них доставка и нужно ли ее отображать при оформлении заказа. Необходимо, чтобы адреса входили в зону, где осуществляется доставка. Если доставка по указанному адресу производится, соответствующий пункт отображается, а если доставка становится недоступна по данному адресу, возможность её оформления скрыта от пользователя.
Если подходящие магазины были обнаружены, происходит поиск магазинов, где заказываемый товар есть в наличии (если таких магазинов нет, возможность доставки также не отображается). И в конце по координатам магазинов вычисляем, какой из всех самый близкий к координатам клиента.
В процессе разработки рассматривали вопрос подключения дополнительного параметра для выбора магазина доставки: проверка стоимости доставки Яндекс GO и определение магазина с минимальной.
Однако от этого варианта решили отказаться по двум причинам :
1. Магазинов не так много. Стоимость доставки из ближайшего магазина в 90% случаев будет ниже, чем с более удаленного.
2. Возникла проблема с API Яндекса. Для получения конечной суммы доставки нужно было создавать предварительные заказы, которые просто засорили бы кабинет доставки.
Были ли проблемы с получением данных?
Несмотря на то, что у Яндекса неплохая документация, даже с ней многие моменты приходилось делать методом проб и ошибок, потому что не все нюансы были подробно расписаны, а некоторые сведения из документации не работали вовсе. Это вызвало появление проблемы с определением того, как и в каком виде передать все данные для создания заявки на доставку с сайта в API. После того, как весь необходимый набор данных и их формат был определен оставалось только передать их с нашей стороны.
При повторном заказе в течение пары минут стоимость доставки могла сильно измениться, что могло вызвать негатив и непонимание со стороны клиентов. Вот как решали эту проблему:
В ТЗ было определено, что стоимость доставки должна фиксироваться на определенное время. Но при создании новых заявок сумма доставки менялась чаще, чем нужно. Необходимо было придумать систему получения уже существующей заявки при повторном выборе доставки через Яндекс GO.
Мы использовали уникальный ID запроса к API. Для создания заявки нужно передавать набор данных, в числе которых фигурировал ее уникальный ID, который мы создавали на своей стороне. Если при повторном запросе отправлять хоть немного другие данные, то создавалась новая заявка, в которой была новая цена. Но если отдавать полностью идентичные данные, то API возвращало уже существующую заявку. Поэтому пришлось определяться, из каких данных и каким образом генерировать ID. Надо было учесть все данные, которые влияли бы на доставку и учитывать время, на которое должна отдаваться уже существующая заявка.
Перед нами стояла новая задача: нужно было просчитать все данные, из которых генерируется ID, и все варианты поведения пользователя, при которых должен отправляться новый или тот же ID.
Так как при клике по доставке всегда создавалась заявка, которая не обязательно была бы подтверждена (например, пользователь посмотрел, сколько это стоит и выбрал другой способ доставки), то нужно было придумать способ очистить все неактуальные заявки в кабинете. Для этого был реализован агент, который получал через API все заявки, которые были не подтверждены и были неактуальными, и удалял их. Это позволило держать кабинет в чистоте.
Из-за того, что на сайте установлена версия Bitrix 16.5, не получилось реализовать многие вещи быстро и красиво (например, запись новых свойств заказа в сам объект заказа \Bitrix\Sale\Order\). После осознания того, что ничего не выйдет, приходилось искать другие способы реализации, которые занимали много времени.