REST API заказов
Описание
Этот раздел описывает процесс интеграции Ютеки и Партнера через реализацию на стороне Партнера HTTP REST интерфейса для обработки заказов.
Хоть и реализация интерфейса кладется на плечи Партнера, взаимодействие является двусторонним: Ютека отправляет новые заказы и отмены заказов Партнеру, а Партнер отправляет Ютеке информацию об изменении статуса.
Список используемых методов
Интерфейс Партнёра:
Интерфейс Ютеки:
АПИ и механики работы
В этом разделе описаны технические моменты реализации АПИ и механики работы.
Формат работы АПИ - JSON
. HTTP методы, используемые в запросах: POST
.
Авторизация
Во время начала интегрирования, Ютека и Партнёр договариваются о способе авторизации и аутентификации друг друга. Это нужно, что бы исключить возможность третьих лиц делать ложные заказы или присылать неправильные статусы. Поэтому Партнёр, при реализации АПИ должен добавить проверку запросов на ключ авторизации.
Пусть, далее в документации, ключ доступа будет hee7vaisahchu4O
(случайная строка, не пытайтесь делать с ней запросы).
Ютека может авторизировать запросы способами:
- Basic Auth авторизация.
Партнёр закрывает HTTP endpoint при помощи Basic Auth, а Ютека добавляет к запросам логин и пароль доступа. Authorization
заголовок.
Ютека и Партнёр добавляют к своим запросам заголовок с секретным токеном. В HTTP запросе будет заголовок видаAuthorization: hee7vaisahchu4O
- Один из параметров запроса (поле JSON объекта).
Ютека и Партнёр добавляют к телу запроса полеtoken
. Тогда, минимальное тело запроса будет{"token": "hee7vaisahchu4O"}
Работа с ошибками
За успешность выполнения запроса отвечает HTTP Status Code ответа. При успешном выполнении запроса, АПИ должно возвращать код 200 OK.
Если по какой-либо причине запрос выполнился неудачно, АПИ не должно возвращать 200 ОК.
В теле отведа должно быть описание ошибки в поле error
:
{
"error": "Ошибка установки соединения с базой данных"
}
А код ответа должен быть одиним из:
- 403 - Ошибка авторизации, токен или пара логин/пароль не совпали.
- 400 - В запросе неверные данные. Например, неправильный JSON формат тела запроса.
- 500 - Остальные ошибки. Недоступность сервера, отказ базы данных и др.
Номера заказов
При начале интеграции Партнёр и Ютека договариваются, чей номер заказа показывать клиенту на сайте Ютеки и по этому же номеру клиент будет забирать заказ в аптеке.
В случае, если Партнёр хочет использовать свои номера заказов,
то в ответе метода Создания заказа,
в поле partnerOrderId
нужно присылать номер заказа в системе Партнёра.
Создание заказа
При появлении нового заказа от клиента на сайте Ютеки, делается запрос на подготовленный URL Партнёра в котором будет данные по заказу и контакты клиента.
{
"utekaOrderId": "123",
"pharmacyId": "1234",
"items":[
{
"productId": "60001090",
"quantity": 2,
"price": 880
},
{
"productId": "60001040",
"quantity": 1,
"price": 73000
}
],
"amount": 74760,
"name": "Кирилл",
"phone": "9997651151"
}
Параметр | JSON Тип | Описание |
---|---|---|
utekaOrderId |
String | Номер заказа в сервисе Ютеки. (*) |
pharmacyId |
String | ID аптеки Партнера |
items |
Array | Список позиций заказа. Каждый элемент имеет уникальный productId (т.е. позиции не повторяются) |
items .productId |
String | Идентификатор товара Партнёра |
items .quantity |
Number (целочисленный) | Количество позиции товара в заказе. Дробные числа не поддерживаются. |
items .price |
Number | Цена товара в рублях. Может содержать дробную часть - копейки. |
amount |
Number | Общая сумма заказа. Может содержать дробную часть - копейки. |
name |
String | Имя/Фамилия/Псевдоним пользователя под которым он будет забирать заказ. |
phone |
String | Номер телефона клиента в формате 9001112233 (без +7 или 8) |
(*) Используется как ключ идемпотентности. В случае, если на стороне партнера уже есть заказ с этим номером Ютеки, то не нужно создавать новый, а вернуть данные уже созданного заказа. Повторный запрос может быть, например отправлен в случае переотправки заказа из-за технических проблем и для избавления от дублирования.
При успешном получении нового заказа, Партнёр ответить на HTTP запрос статусом 200.
Если клиенту нужно показывать номер заказа в системе Партнёра, то ответ должен содержать тело и быть вида:
{
"partnerOrderId": "textAndNumbers12345",
"utekaOrderId": "99"
}
Проверка статуса
Периодически Ютека опрашивает АПИ партнера о текущем статусе заказа. Ютека делает запрос вида:
{
"orderIds": [
{"partnerOrderId": "4567", "utekaOrderId": "123"},
{"partnerOrderId": "xxxx", "utekaOrderId": "4568"},
{"partnerOrderId": "4569", "utekaOrderId": "2"}
]
}
и ожидает в ответ JSON массив из текущих статусов заказов.
[
{
"utekaOrderId": "4567",
"partnerOrderId": "xxx",
"status": "cancelled"
},
{
"utekaOrderId": "4568",
"partnerOrderId": "xxxx",
"status": "approved"
},
{
"utekaOrderId": "4569",
"partnerOrderId": "xxxxx",
"status": "ready"
}
]
Возможные статусы заказа
approved
- подтвержден. Новый заказ был обработан системой и/или заказ собирается.ready
- готов к выдаче. Заказ укомплектован и клиент может идти забирать его из аптеки.cancelled_by_pharmacy
- отменен аптекой. В случае, когда аптека не может выполнить этот заказ. Например, неактуальные остатки или разница в цене в аптеке и в заказе.completed
- выполнен. Клиент успешно забрал/выкупил заказ.cancelled
- отменен клиентом. Ютека присылает этот статус в методе отмены заказа.
Все другие возможные внутренние статусы (например, Отгружено, Аннулирован, Требуется подтверждение аптекой или любые другие) Партнер должен максимально точно сконвертировать в один статусов выше. Диаграмма ниже описывает общий флоу заказов.
graph LR approved[Подтвержден approved] ready[Готов к выдаче ready] cancelled_by_pharmacy[Отменен аптекой cancelled_by_pharmacy] completed[Выполнен completed] cancelled[Отменен клиентом cancelled] endst((Конечный статус)) newOrder((Новый заказ)) clientCancel((Клиент отменяет заказ)) uteka(Ютека) uteka1(Ютека) newOrder-->uteka uteka-->approved approved--Все позиции заказа собраны-->ready approved--Невозможно собрать заказ-->cancelled_by_pharmacy ready--Клиент не забрал заказ-->cancelled_by_pharmacy ready--Клиент выкупил заказ-->completed clientCancel-->uteka1 uteka1-->cancelled cancelled_by_pharmacy-->endst completed-->endst cancelled-->endst style uteka fill:#68e472,stroke:#008012 style uteka1 fill:#68e472,stroke:#008012
Отмена заказа клиентом
Когда клиент отменяет заказ на сайте Ютеки, Партнёру отправляется запрос с телом
{
"utekaOrderId": "4567",
"partnerOrderId": "xxx",
"status": "cancelled"
}
Обратите внимание, что при отмене заказа Партнёром, Партнёр посылает статус cancelled_by_pharmacy
,
а когда клиент отменяет заказ, то Ютека посылает статус cancelled
.
В ответ на отмену заказа сервер должен ответить текущим статусом заказа (так как мы отменяем заказ, в ответе всегда должно быть cancelled
):
{
"utekaOrderId": "4569",
"partnerOrderId": "xxxxx",
"status": "cancelled"
}
Обновление статуса заказа
URL: https://example.com/srv/ordersrv/api/orders/status
Метод вызывает Партнёр, когда изменяется статус заказа или содержимое корзины.
Параметры запроса:
Параметр | JSON Тип | Обязательное | Описание | Пример |
---|---|---|---|---|
utekaOrderId |
String (и содержит целочисленное число) | Да | Номер заказа в сервисе Ютеки. Передается в запросе создания заказа, в ответе на запрос создания заказа | {"utekaOrderId": 333591} |
partnerOrderId |
String | Да | Номер заказа в сервисе Партнера. Передается в ответе на запрос создания заказа | {"partnerOrderId": "000-5323.ff12"} |
status |
String | Да | Должен принимать одно из возможных значений. См. Возможные статусы заказа | {"status": "ready"} |
comment |
String | Да, если "status": "cancelled_by_pharmacy" |
Причина отмены заказа со стороны аптеки. | {"comment": ""} |
cart |
Array | Список элементов корзины в которых есть несовпадение | {"cart": [{"productId": "12345", "quantity": 2, "price": 123.45}, {"productId": "12345", "quantity": 1, "price": 12}]} |
|
cart .productId |
String | Да | Идентификатор товара Партнёра | {"productId": "12345"} |
cart .quantity |
Number (целочисленный) | Да | Количество товаров. Дробные числа не поддерживаются. | {"quantity": 10} |
cart .price |
Number | Да | Цена товара в рублях. Может содержать дробную часть - копейки. | {"price": 500.12} |
Примеры:
Тестовое окружение Ютеки
Тестовое АПИ расположено по адресу https://example.com/srv/ordersrv/api/
.
Для того, что бы вызвать конкретный метод, нужно добавить его название к АПИ URL.
Например, если название метода orders/status
,
а адрес АПИ https://example.com/srv/ordersrv/api/
,
то запрос нужно будет делать по адресу https://example.com/srv/ordersrv/api/orders/status
.
История изменений
[1.0.1] - 17.09.2020
Добавлено
- Пример ответа и комментарий в методе отмены заказа
[1.0.0] - 10.09.2020
Изменено
- В объекте создания заказа поле
orderId
переименовано вutekaOrderId
, полеpharmacy
переименовано вpharmacyId
. - Во всех методах, где участвует номер заказа, теперь вместо строки с номером нужно посылать объект с полями
utekaOrderId
,partnerOrderId
:{"utekaOrderId":"1", "partnerOrderId:"xxx"}