Перейти к основному содержимому

Общий план интеграционного теста с партнёрами

Общая информация​

Цели тестирования на демо-стенде:

  1. Проверить механизм аутентификации и безопасности.
  2. Проверить основной сценарий передачи заказа из ЗЯ в ВКС.
  3. Проверить жизненный цикл заказа через обмен статусами.
  4. Проверить сценарии переноса сроков доставки.
  5. Проверить сценарии отмены заказа обеими сторонами.
  6. Проверить синхронизацию данных о пунктах выдачи (если они имеются у ВКС).

Как читать сценарии​

Каждый кейс описан тремя блоками: предусловия → шаги → ожидаемый результат. В заголовке кейса указаны направление запроса и проверяемая роль системы ВКС.

ОбозначениеОписание
ЗЯ → ВКСЗапрос выполняет ИС Золотого Яблока, ответ предоставляет ИС ВКС. Авторизация — токеном, выданным ВКС.
ВКС → ЗЯЗапрос выполняет ИС ВКС, ответ предоставляет ИС ЗЯ. Авторизация — токеном, выданным ЗЯ.
[S]Проверяется система ВКС как сервер: реализация эндпоинта, коды ответов, валидация.
[C]Проверяется система ВКС как клиент: корректность исходящих запросов, их порядок, обработка ошибок.

Общие правила взаимодействия​

Правила из спецификации, действующие во всех кейсах:

  • кодировка UTF-8, обмен с типом содержимого "application/json";
  • даты и временные штампы — ISO 8601, UTC с нулевым смещением (например 2025-08-05T23:36:00Z); даты — YYYY-MM-DD, интервалы — HH:mm;
  • отслеживание ведётся по orderNumber — он же трек-номер;
  • любой необязательный параметр может быть пустым или нулевым, но должен быть передан;
  • любой обязательный параметр заполняется в соответствии со своим типом данных;
  • если услуги оказываются в нескольких странах, экземпляры сервиса и эндпоинты различаются доменной зоной; правило действует в обе стороны.

Единые коды ответов защищённых методов​

КодСтатусСообщениеПричина
400Bad RequestMissing or inappropriate required parametersНе переданы или некорректно заполнены обязательные поля
401UnauthorizedToken is invalidОшибка аутентификации
403ForbiddenHas no permissionЗапрещено в текущем контексте
404Not FoundResource not foundТолько для метода истории статусов
500Internal Server ErrorServer unavailableСервер недоступен

1. Механизм аутентификации и безопасности​

auth-1 · Успешная авторизация ВКС в сервисе ЕАПИ ЗЯ · ВКС → ЗЯ · [C]​

ПредусловияЗЯ выдал ВКС валидные username и password; согласован код курьерской службы (deliveryServiceCode).
ШагиВКС отправляет POST /api/v1/auth/login в ЕАПИ ЗЯ с заголовками Host и Content-Type: application/json и учётными данными в теле.
Ожидаемый результат200 Success response; в ответе непустой access_token и expires_in. Токен сохраняется и переиспользуется до истечения срока, а не запрашивается на каждый вызов.

auth-2 · Успешная авторизация ЕАПИ ЗЯ в сервисе ВКС · ЗЯ → ВКС · [S]​

ПредусловияНа стороне ВКС реализован POST /api/v1/auth/login; ВКС выдал ЗЯ логин и пароль (буквы обоих регистров, цифры, спецсимволы, длина > 12 символов).
ШагиЗЯ отправляет запрос авторизации с валидными username и password.
Ожидаемый результат200 Success response; в ответе access_token и expires_in. Токен — JWT, подпись SHA256 ключом от 32 символов; на стороне ВКС валидируется время жизни.

auth-3 · Неуспешная авторизация в сервисе ВКС с неверными учётными данными · ЗЯ → ВКС · [S]​

ШагиЗЯ отправляет запрос авторизации с неверным username или password.
Ожидаемый результат400 Bad Request, в теле поле error. Внутренние детали и подсказки о существовании учётной записи не раскрываются, ответ не 500.

auth-4 · Неуспешная авторизация с отсутствующим обязательным полем · ЗЯ → ВКС · [S]​

ШагиЗЯ отправляет запрос авторизации без поля password.
Ожидаемый результат400 Bad Request с сообщением о недостающих обязательных параметрах.

Пример ответа:

{ "error": "Missing or inappropriate required parameters" }

auth-5 · Вызов защищённого метода с невалидным токеном · ЗЯ → ВКС · [S]​

ПредусловияРеализован любой метод, требующий авторизации (например, создание заказа).
ШагиЗЯ вызывает такой метод с заголовком Authorization: Bearer invalid_token.
Ожидаемый результат401 Token is invalid. Запрос не выполняется, побочных эффектов нет.

auth-6 · Вызов метода с истёкшим токеном · ЗЯ → ВКС · [S]​

ПредусловияИмитировано истечение срока жизни с момента выдачи токена.
ШагиЗЯ выполняет запрос с просроченным токеном.
Ожидаемый результат401 Token is invalid — валидация времени жизни срабатывает.

auth-7 · Вызов метода без заголовка Authorization · ЗЯ → ВКС · [S]​

ШагиЗЯ вызывает защищённый метод без заголовка Authorization.
Ожидаемый результат401. Метод недоступен без авторизации.

auth-8 · Перевыпуск токена после 401 · ВКС → ЗЯ · [C]​

ПредусловияТокен ЗЯ у ВКС просрочен или отозван.
ШагиВКС отправляет запрос в ЕАПИ ЗЯ и получает 401.
Ожидаемый результатВКС перевыпускает токен через /api/v1/auth/login и повторяет запрос. Повторов с заведомо невалидным токеном нет.

auth-9 · Разделение экземпляров по странам · ЗЯ → ВКС · [S]​

ПредусловияВКС работает более чем в одной стране.
ШагиЗЯ выполняет авторизацию и создание заказа на эндпоинтах каждой доменной зоны ВКС.
Ожидаемый результатДля каждой страны предоставлен свой набор эндпоинтов; токен и данные одной зоны не применяются к другой.

2. Основной сценарий передачи заказа из ЗЯ в ВКС​

Все кейсы блока: ЗЯ → ВКС, POST /api/v1/orders, авторизация токеном ВКС, проверяется система ВКС как сервер [S]. Успешный ответ: 200 Order has been created с полями ecsOrderNumber, orderNumber, createdAt. Ошибки: 400, 401, 403, 500; тело ошибки — errorMessage и, при ошибках адресов, errorCode.

order-1 · Успешное создание нового заказа (первая отправка) · ЗЯ → ВКС · [S]​

ПредусловияПолучен валидный access_token от ВКС; согласованы deliveryServiceCode и courierTariffCode.
ШагиЗЯ отправляет POST /api/v1/orders с заголовками Authorization и content-type, передавая обязательные поля: orderNumber, deliveryServiceCode, courierTariffCode, isOrderFirstSend: true, needCustomerNotification, senderName, shippingWarehouse.code, locationFrom (адресный объект), recipient (name, phone), locationTo или pickpointId, массив package (barcode, weight, length, width, height, isPartialBuy, isTryOnAllowed, totalAmount, declaredAmount, items[] с name, warekey, quantity, weight, isPartialBuy, isTryOnAllowed, priceAmount, declaredAmount, vatRate, vatSum), shipmentDate, deliveryDate, deliveryTimeIntervalFrom, deliveryTimeIntervalTo, deliveryPaymentAmount, orderPaymentAmount (declaredAmount, totalAmount, amountToCollect, vatSum, currency).
Ожидаемый результат200 Order has been created; ответ содержит ecsOrderNumber (идентификатор заказа в ВКС), переданный orderNumber и createdAt в формате YYYY-MM-DDThh:mm:ssZ. Заказ виден в системе ВКС со всеми переданными данными.

Пример ответа:

{
"ecsOrderNumber": "f91ae5a4-3b1c-4e7a-8c29-72b1db2025a1",
"orderNumber": "qwe-126543",
"createdAt": "2025-05-10T10:41:22Z"
}

order-2 · Успешное создание заказа с доставкой в ПВЗ (если имеется) · ЗЯ → ВКС · [S]​

ПредусловияpickpointId известного ПВЗ существует в справочнике ВКС и передан в ЕАПИ ЗЯ.
ШагиВыполняются шаги order-1, но вместо адреса доставки передаётся pickpointId (locationTo при этом не заполняется адресом клиента).
Ожидаемый результат200, заказ создан и привязан именно к указанному ПВЗ; в карточке заказа на стороне ВКС виден нужный пункт выдачи.

order-3 · Создание заказа с ошибкой в адресе отправителя (Addr_01) и получателя (Addr_02) · ЗЯ → ВКС · [S]​

ШагиЗЯ отправляет запрос с некорректными данными в locationFrom (например, несуществующий ФИАС-код), затем — с некорректными данными в locationTo или pickpointId.
Ожидаемый результат400 в обоих случаях; тело содержит errorMessage и errorCode: Addr_01 — ошибка в адресе отправителя, Addr_02 — ошибка в адресе получателя. Заказ не создан.

Пример ответа:

{ "errorMessage": "Missing or inappropriate required parameters", "errorCode": "Addr_01" }

order-4 · Попытка создания заказа без обязательного поля · ЗЯ → ВКС · [S]​

ШагиЗЯ отправляет запрос без обязательного поля (например, без orderNumber).
Ожидаемый результат400 Missing or inappropriate required parameters с указанием проблемного поля в errorMessage. Не 500.

order-5 · Создание заказа с разными типами адресов (gar, coord, custom), с которыми работает ВКС · ЗЯ → ВКС · [S]​

ШагиЗЯ создаёт несколько заказов, используя в locationFrom и locationTo поочерёдно addressType: "gar", "coord", "custom" с соответствующими наборами полей (ФИАС-коды; широта и долгота; части адреса со строковым адресом и координатами).
Ожидаемый результат200 по каждому; во всех трёх случаях адрес корректно распознан и отображается в системе ВКС.

order-6 · Создание заказа с разными видами оплат · ЗЯ → ВКС · [S]​

ШагиЗЯ выполняет два запроса с orderPaymentAmount.amountToCollect = 0 (заказ оплачен) и = 500 (оплата с клиента 500) при заполненном currency по ISO 4217.
Ожидаемый результат200 по обоим; сумма к получению с клиента в ВКС соответствует переданной, для предоплаченного заказа курьеру не выставляется сумма к сбору.

order-7 · Некорректный deliveryServiceCode или courierTariffCode · ЗЯ → ВКС · [S]​

ШагиЗЯ передаёт несогласованный код службы или несуществующий код тарифа.
Ожидаемый результат400 с внятным errorMessage. Заказ не создан.

order-8 · Повторная отправка того же orderNumber (идемпотентность) · ЗЯ → ВКС · [S]​

ПредусловияВыполнен order-1.
ШагиЗЯ повторно отправляет заказ с тем же orderNumber и isOrderFirstSend: true.
Ожидаемый результатДубль не создаётся: либо 200 с тем же ecsOrderNumber, либо 400 / 403 с явной ошибкой о существующем заказе. Поведение предсказуемое и одинаковое при каждом повторе.

order-9 · Необязательные поля переданы пустыми · ЗЯ → ВКС · [S]​

ШагиЗЯ создаёт заказ, передавая необязательные поля (shippingWarehouse.manager, shippingWarehouse.phone, recipient.email, shipmentTimeIntervalFrom, shipmentTimeIntervalTo, courierComment, returnWarehouse) со значениями null или пустыми, но передавая сами поля.
Ожидаемый результат200; ВКС корректно принимает пустые необязательные параметры, не отвечает 400 и не падает в 500.

3. Жизненный цикл заказа через обмен статусами​

status-1 · Успешное обновление статуса заказа ВКС → ЗЯ · [C]​

ПредусловияЗаказ создан в ВКС (есть orderNumber); получен валидный access_token от ЗЯ; на стороне ВКС реализована подписка (webhook) на изменения статусов.
ШагиВКС отправляет PUT /api/v1/orders/{orderNumber} с заголовками Authorization: Bearer <token> и content-type, передавая объект статуса: deliveryServiceCode, actualStatus, statusComment, statusAssignmentDate, hasBeenDelivered, actualDeliveryDate.
Ожидаемый результат200 Status has been updated; статус принят ИС ЗЯ и виден в карточке заказа. statusAssignmentDate — реальное время присвоения статуса в ИС КС, а не время отправки запроса.

Пример ответа:

{
"deliveryServiceCode": "delivery_code",
"actualStatus": "ECS_ORDER_TAKEN_BY_COURIER",
"statusComment": "Заказ выдан на доставку, курьер в пути",
"statusAssignmentDate": "2025-04-05T10:15:30Z",
"hasBeenDelivered": false,
"actualDeliveryDate": null
}

status-2 · Успешное обновление финального статуса (доставлен) · ВКС → ЗЯ · [C]​

ПредусловияЗаказ находится в пути.
ШагиВКС отправляет ECS_ORDER_DELIVERED с hasBeenDelivered: true и заполненным actualDeliveryDate.
Ожидаемый результат200; в ИС ЗЯ заказ переходит в статус «Доставлен». Признак hasBeenDelivered поднимается и при частичной доставке (ECS_ORDER_DELIVERED_PARTIALLY), actualDeliveryDate при этом обязателен. После финального статуса новые статусы по заказу не отправляются.

status-3 · Запрос истории статусов по заказу · ЗЯ → ВКС · [S]​

ПредусловияЗаказу присвоено несколько статусов в ВКС; получен валидный access_token от ВКС.
ШагиЗЯ отправляет GET /api/v1/orders/{orderNumber}/history с заголовками Authorization и content-type.
Ожидаемый результат200 Status history has been sent; в ответе массив statusHistory со всеми присвоенными статусами в хронологическом порядке от нового к старому; каждый элемент — объект статуса с полями deliveryServiceCode, actualStatus, statusComment, statusAssignmentDate, hasBeenDelivered, actualDeliveryDate.

status-4 · История по несуществующему заказу и статус с невалидным кодом · ЗЯ ⇄ ВКС · [S+C]​

ШагиЗЯ выполняет метод истории с несуществующим orderNumber; затем ВКС отправляет статус с actualStatus: "INVALID_STATUS", отсутствующим в справочнике статусов заказа.
Ожидаемый результатНа первый метод — 404 Resource not found (не 200 с пустым массивом и не 500); на второй — 400 Missing or inappropriate required parameters. ВКС корректно обрабатывает отказ: логирует, не зацикливает повторы, не считает статус применённым.

status-5 · Связка: создание → статус → история · ЗЯ ⇄ ВКС · [S+C]​

ПредусловияВыполнен order-1; выполнен status-1 (один или несколько раз); выполнен status-2.
ШагиЗЯ запрашивает историю статусов по заказу.
Ожидаемый результат200; история содержит ECS_ORDER_CREATED / ECS_ORDER_ACCEPTED, промежуточные статусы и финальный; порядок корректен, временные метки согласованы, расхождений между данными ВКС и ЗЯ нет. Прогнать на нескольких статусных моделях: курьерская доставка, доставка до ПВЗ, отменённый заказ.

status-6 · Полная статусная модель прямого процесса · ВКС → ЗЯ · [C]​

ПредусловияСогласован маппинг внутренних статусов ВКС на коды справочника.
ШагиВКС прогоняет по одному заказу цепочку статусов курьерской доставки:
  1. ECS_ORDER_ACCEPTED / ECS_ORDER_CREATED
  2. ECS_ORDER_TAKEN_FROM_SHIPMENT_WAREHOUSE
  3. ECS_ORDER_FIRST_ACCEPTANCE
  4. ECS_ORDER_SENT_TO_TRANSIT_CITY
  5. ECS_ORDER_ACCEPTED_IN_TRANSIT_CITY_HUB
  6. ECS_ORDER_READY_FOR_APPOINTMENT
  7. ECS_COURIER_APPOINTED
  8. ECS_ORDER_TAKEN_BY_COURIER
  9. (ECS_DELIVERY_ATTEMPT — если была неуспешная попытка вручения)
  10. ECS_ORDER_DELIVERED
Ожидаемый результат200 по каждому; статусы приходят в хронологическом порядке, statusComment соответствует коду, повторов и пропусков ключевых этапов нет. Транзитные статусы отправляются, если ВКС фактически использует консолидацию и транзит.

status-7 · Статусная модель доставки до ПВЗ · ВКС → ЗЯ · [C]​

ПредусловияЗаказ создан с pickpointId (order-2).
ШагиВКС прогоняет цепочку до ПВЗ:
  1. приёмка и транзит
  2. ECS_ORDER_READY_FOR_APPOINTMENT (заказ прибыл на ПВЗ)
  3. ECS_ORDER_READY_TO_PICK_UP
  4. ECS_ORDER_DELIVERED
Ожидаемый результат200 по каждому; в ИС ЗЯ виден факт прибытия заказа на ПВЗ и готовности к выдаче; выдача фиксируется с hasBeenDelivered: true и actualDeliveryDate.

status-8 · Статусы возвратного процесса · ВКС → ЗЯ · [C]​

ПредусловияЗаказ не вручён и уходит на возврат.
ШагиВКС отправляет метод отмены, а далее цепочку статусов возврата:
  1. ECS_RETURN_FIRST_ACCEPTANCE
  2. ECS_RETURN_SENT_TO_TRANSIT_CITY
  3. ECS_RETURN_ACCEPTED_IN_TRANSIT_CITY_HUB
  4. ECS_RETURN_ON_THE_WAY_TO_WAREHOUSE
  5. ECS_RETURN_DELIVERED_TO_WAREHOUSE
Ожидаемый результат200 по каждому; в ИС ЗЯ виден весь путь возврата вплоть до приёмки на складе возврата; при заполненном returnWarehouse возврат идёт на переданный адрес.

status-9 · Статус по несуществующему заказу · ВКС → ЗЯ · [C]​

ШагиВКС отправляет статус на orderNumber, которого нет в ИС ЗЯ.
Ожидаемый результат404 Resource not found; ВКС обрабатывает ответ и не повторяет запрос бесконечно.

status-10 · Скорость доставки статусов · ВКС → ЗЯ · [C]​

ШагиФиксируется время между фактическим изменением статуса в ИС ВКС и его получением в ЕАПИ ЗЯ.
Ожидаемый результатСтатус доставлен в пределах согласованного SLA (по умолчанию не более 15 минут, финальные статусы — приоритетно). При временной недоступности ЕАПИ ВКС повторяет отправку и не теряет статус.

status-11 · Попытка доставки · ВКС → ЗЯ · [C]​

ПредусловияЗаказ выдан курьеру (ECS_ORDER_TAKEN_BY_COURIER), вручить с первого раза не удалось (клиента нет на месте, недоступен).
ШагиВКС отправляет ECS_DELIVERY_ATTEMPT с hasBeenDelivered: false, пустым actualDeliveryDate и statusComment с причиной; при повторных выездах статус отправляется повторно, затем следует финальный исход — вручение или отмена.
Ожидаемый результат200; в ИС ЗЯ видна каждая попытка доставки с корректным statusAssignmentDate, попытки не схлопываются в одну. После запроса от ВКС заказ уходит в отмену либо в возвратный процесс.

4. Сценарии переноса сроков доставки​

Метод переноса даты — PATCH /api/v1/orders/{orderNumber}, успешный ответ 200 Delivery date has been updated.

data-1 · Успешный перенос даты по инициативе ЗЯ · ЗЯ → ВКС · [S]​

ПредусловияЗаказ создан, статус позволяет перенос.
ШагиЗЯ отправляет PATCH /api/v1/orders/{orderNumber} с Authorization от ВКС и телом deliveryDate, deliveryTimeIntervalFrom, deliveryTimeIntervalTo.
Ожидаемый результат200 Delivery date has been updated; дата и интервал доставки обновлены в ИС ВКС, изменение доводится до курьера или ПВЗ.

Пример ответа:

{ "deliveryDate": "2025-05-10", "deliveryTimeIntervalFrom": "10:00", "deliveryTimeIntervalTo": "12:00" }

data-2 · Успешный перенос даты по инициативе ВКС · ВКС → ЗЯ · [C]​

ПредусловияЗаказ создан, статус позволяет перенос.
ШагиВКС отправляет PATCH /api/v1/orders/{orderNumber} с Authorization от ЗЯ и телом deliveryServiceCode, deliveryDate, deliveryTimeIntervalFrom, deliveryTimeIntervalTo, dateChangeReason.
Ожидаемый результат200; дата доставки обновлена в ИС ЗЯ, причина переноса сохранена. Перенос даты отправляется именно этим методом, а не через изменение статуса.

data-3 · Неуспешный перенос даты по инициативе ЗЯ · ЗЯ → ВКС · [S]​

ПредусловияЗаказ создан, статус позволяет перенос.
ШагиЗЯ передаёт deliveryDate в прошлом, либо дату, на которую перенос невозможен (нет слотов, вне графика ПВЗ), либо интервал с deliveryTimeIntervalTo раньше deliveryTimeIntervalFrom.
Ожидаемый результат403 Has no permission — на эту дату смена невозможна (либо 400, если дата не проходит формальную валидацию). Дата в ИС ВКС не изменена.

data-4 · Отказ в переносе даты (некорректный статус заказа) · ЗЯ ⇄ ВКС · [S+C]​

ПредусловияЗаказ в финальном статусе (ECS_ORDER_DELIVERED) или отменён.
ШагиВыполняются data-1 и data-2.
Ожидаемый результат400 в обоих случаях. Обе стороны корректно обрабатывают отказ, дата не меняется.

data-5 · Перенос даты ВКС без указания причины · ВКС → ЗЯ · [C]​

ШагиВКС отправляет запрос data-2 без обязательного поля dateChangeReason.
Ожидаемый результат400 Missing or inappropriate required parameters. Проверяется, что в штатном режиме ВКС всегда заполняет dateChangeReason.

data-6 · Согласованность данных после переноса · ЗЯ ⇄ ВКС · [S+C]​

ПредусловияВыполнен data-1 или data-2.
ШагиДанные заказа запрашиваются с обеих сторон.
Ожидаемый результатdeliveryDate и интервалы совпадают в ИС ЗЯ и ИС ВКС; перенос не порождает лишних статусов в истории.

5. Сценарии отмены заказа обеими сторонами​

Методы: POST /api/v1/orders/{orderNumber}/cancel (в обе стороны) и POST /api/v1/orders/{orderNumber}/reopen (ВКС → ЗЯ). Срок на отказ от отмены — 24 часа, если иное не установлено договором; на демо-стенде таймер сокращён до 2 часов.

cancel-1 · Успешная отмена заказа по инициативе ЗЯ · ЗЯ → ВКС · [S]​

ПредусловияЗаказ создан, статус позволяет отмену.
ШагиЗЯ отправляет POST /api/v1/orders/{orderNumber}/cancel с Authorization от ВКС; тело запроса не требуется.
Ожидаемый результат200 Order has been canceled; заказ отменён в ИС ВКС, факт принятия запроса залогирован. После получения отмены ВКС отправляет методом изменения статуса статус GA_CANCEL_REQUEST. Доставка фактически останавливается.

cancel-2 · Успешная отмена заказа по инициативе ВКС · ВКС → ЗЯ · [C]​

ПредусловияЗаказ создан.
ШагиВКС отправляет POST /api/v1/orders/{orderNumber}/cancel с Authorization от ЗЯ и телом dateTime (ISO 8601, UTC) и comment.
Ожидаемый результат200 Order has been marked for cancellation; заказ помечен на отмену в ИС ЗЯ, запущен таймер 2 часов (на демо-стенде). Причина отмены передаётся отдельным статусом из справочника статусов отмен (например CUSTOMER_DECLINED, CUSTOMER_UNAVAILABLE, CUSTOMER_EXPIRED_ON_HOLD, ECS_ORDER_NOT_DELIVERED, ECS_LOGISTIC_ERROR, ECS_WAREHOUSE_DAMAGED, PAYMENT_UNAVAILABLE_DUE_TO_ECS, UNTRANSPORTABLE_WEATHER). Прогнать не менее трёх разных причин отмены, включая внутреннюю причину ВКС, отказ клиента и проблему с оплатой.

cancel-3 · Отказ от отмены заказа (reopen) · ВКС → ЗЯ · [C]​

ПредусловияВыполнен cancel-2, прошло менее 2 часов (на демо-стенде).
ШагиВКС отправляет POST /api/v1/orders/{orderNumber}/reopen с телом comment.
Ожидаемый результат200 Order has been reopened; пометка на отмену снята, доставка продолжается, последующие статусы принимаются. Ранее переданный статус отмены исключён из истории статусов, логических разрывов в истории нет.

cancel-4 · Автоматическая отмена после таймаута · ВКС → ЗЯ · [C]​

ПредусловияВыполнен cancel-2, прошло более 2 часов (на демо-стенде), reopen не вызывался.
ШагиПроверяется состояние заказа в ИС ЗЯ.
Ожидаемый результатЗаказ переведён в «Отменён»; ВКС отправляет статусы возвратного потока. Проверяется, что система ВКС корректно завершает работу с таким заказом.

cancel-5 · Отмена уже доставленного заказа · ЗЯ ⇄ ВКС · [S+C]​

ПредусловияЗаказ в статусе ECS_ORDER_DELIVERED.
ШагиВыполняются попытки cancel-1 и cancel-2.
Ожидаемый результат403 Has no permission — отмена в текущем контексте запрещена. Состояние заказа не меняется.

cancel-6 · Статус отмены без вызова метода отмены · ВКС → ЗЯ · [C]​

ПредусловияЗаказ создан.
ШагиВКС отправляет статус отмены, не вызвав предварительно метод /cancel.
Ожидаемый результат403 Has no permission. Проверяется, что в штатном сценарии ВКС соблюдает порядок: /cancel → статус отмены.

cancel-7 · Повторная отмена уже отменённого заказа · ЗЯ → ВКС · [S]​

ПредусловияЗаказ уже отменён.
ШагиЗЯ повторно вызывает /cancel.
Ожидаемый результат400 Bad Request. Не 500, дублирующих событий не создаётся.

cancel-8 · Reopen после отмены по инициативе ЗЯ · ВКС → ЗЯ · [C]​

ПредусловияВыполнен cancel-1, прошло менее 2 часов (на демо-стенде), ВКС готова возобновить доставку.
ШагиВКС отправляет POST /api/v1/orders/{orderNumber}/reopen с comment.
Ожидаемый результат200; пометка на отмену снята, доставка возобновляется, статусы принимаются в штатном режиме.

cancel-9 · Reopen после истечения 2 часов · ВКС → ЗЯ · [C]​

ПредусловияВыполнен cancel-2, прошло более 2 часов, заказ уже отменён.
ШагиВКС отправляет reopen.
Ожидаемый результат400 Bad Request; отменённый заказ к доставке не возвращается, ВКС корректно обрабатывает отказ.

6. Синхронизация данных о пунктах выдачи (если они имеются у ВКС)​

PVZ-1 · Успешное получение полного справочника ПВЗ · ЗЯ → ВКС · [S]​

ПредусловияПолучен access_token от ВКС.
ШагиЗЯ отправляет GET /api/v1/pickpoints с заголовками Authorization и content-type.
Ожидаемый результат200 Success; в ответе countryISOCode (ISO 3166-1 alpha-2), deliveryServiceCode и массив pickpointsList. Каждый ПВЗ содержит id, type, address (адресный объект), openingHours (dayOfWeek, workingDay, opens, closes), phoneNumber, isAvailable, orderStoragePeriod, options (orderIssuing, orderReturning, haveTryOn, havePartialBuy, весогабаритные ограничения) и paymentOptions (haveCashPayment, haveCardPayment, haveQrCodePayment).

PVZ-2 · Успешное добавление нового ПВЗ в справочник · ВКС → ЗЯ · [C]​

ШагиВКС отправляет POST /api/v1/pickpoints/add с Authorization от ЗЯ, передавая данные одного ПВЗ: id, type, адресный объект, openingHours, isAvailable, orderStoragePeriod, options, paymentOptions.
Ожидаемый результат200 A new pickpoint has been created; в ответе подтверждающий id, новый ПВЗ появляется в справочнике ЗЯ. Один запрос — один ПВЗ.

Пример ответа:

{ "id": "PVZ-SPB-001" }

PVZ-3 · Успешное изменение данных существующего ПВЗ · ВКС → ЗЯ · [C]​

ПредусловияПВЗ с этим id существует в справочнике ЗЯ.
ШагиВКС отправляет PUT /api/v1/pickpoints/{pickpointId}/update, изменяя, например, isAvailable: false (закрытие на ремонт), график работы или весогабаритные ограничения.
Ожидаемый результат200 Pickpoint has been updated; данные ПВЗ обновлены в справочнике ЗЯ, недоступный ПВЗ перестаёт предлагаться клиенту.

PVZ-4 · Попытка добавить ПВЗ с уже существующим id · ВКС → ЗЯ · [C]​

ПредусловияПВЗ с таким id уже есть в справочнике ЗЯ.
ШагиВКС выполняет PVZ-2 с id существующего ПВЗ.
Ожидаемый результат400 с сообщением в поле error; дубликат в справочнике не создаётся, ВКС корректно обрабатывает отказ.

PVZ-5 · Изменение несуществующего ПВЗ · ВКС → ЗЯ · [C]​

ШагиВКС выполняет PVZ-3 с несуществующим pickpointId.
Ожидаемый результат400 с сообщением в поле error (код 404 для этого метода спецификацией не предусмотрен — фактическое поведение фиксируется и согласуется). Изменения не применяются.

PVZ-6 · Заказ в закрытый или недоступный ПВЗ · ЗЯ → ВКС · [S]​

ПредусловияВыполнен PVZ-3 с isAvailable: false.
ШагиЗЯ пытается создать заказ на этот ПВЗ.
Ожидаемый результат400 с errorCode: "Addr_02" либо иной явной ошибкой о недоступности ПВЗ. Заказ не создан.

PVZ-7 · Соответствие ограничений ПВЗ параметрам заказа · ЗЯ → ВКС · [S]​

ПредусловияУ ПВЗ заданы packageMinWeight, packageMaxWeight и предельные габариты.
ШагиЗЯ создаёт заказ на этот ПВЗ с посылкой, выходящей за ограничения по весу или габаритам.
Ожидаемый результат400 с внятным сообщением. Заказ не создан, ограничения справочника реально применяются.

Приложение А: Что должно быть готово до старта​

  1. Доступен демо-стенд, известен базовый URL по каждой стране присутствия, наши IP разрешены.
  2. Реализован POST /api/v1/auth/login, выданы логин и пароль для ЗЯ (пароль: буквы обоих регистров, цифры, спецсимволы, > 12 символов).
  3. Получены от нас учётные данные для доступа к ЕАПИ ЗЯ.
  4. Согласован код курьерской службы deliveryServiceCode (короткая регистрозависимая строка) и коды тарифов courierTariffCode.
  5. Реализованы методы на стороне ВКС: POST /api/v1/orders, GET /api/v1/orders/{orderNumber}/history, PATCH /api/v1/orders/{orderNumber} (перенос даты), POST /api/v1/orders/{orderNumber}/cancel, GET /api/v1/pickpoints.
  6. Настроена отправка в ЕАПИ ЗЯ: PUT /api/v1/orders/{orderNumber} (статусы), PATCH /api/v1/orders/{orderNumber} (перенос даты), POST /api/v1/orders/{orderNumber}/cancel и /reopen, POST /api/v1/pickpoints/add, PUT /api/v1/pickpoints/{pickpointId}/update.
  7. Согласован маппинг внутренних статусов ВКС на коды справочника статусов заказа и справочника статусов отмен, включая транзитные и возвратные.
  8. Подготовлены тестовые данные: 2 адреса отправителя, 1–3 адреса получателя (gar, coord, custom — в зависимости от того, какие реализует ВКС), минимум 2 действующих ПВЗ.
  9. Назначен ответственный инженер на стороне ВКС и канал оперативной связи на период прогона.

Приложение Б: Общие требования к интеграции​

Коды и формат ошибок400 — не переданы или некорректно заполнены обязательные поля; 401 — Token is invalid; 403 — Has no permission; 404 — Resource not found (метод истории статусов); 500 — только реальные сбои. Тело ошибки при создании заказа — errorMessage (+ errorCode для адресных ошибок), в остальных методах — error.
Время ответаСинхронные методы (авторизация, создание заказа, справочник ПВЗ) — в пределах согласованного SLA.
Устойчивость к повторамПовторная отправка одного запроса не приводит к дублям заказов, статусов или ПВЗ; при 5xx и таймаутах повтор выполняется с задержкой.
Недоступность партнёраПри недоступности ЕАПИ ЗЯ статусы и события ставятся в очередь и досылаются после восстановления, без потерь и нарушения хронологии.
Часовые поясаВсе временные штампы — UTC с нулевым смещением; сдвигов дат на границе суток нет.

Приложение В: Порядок проведения и критерии завершения​

Порядок​

  1. входной чек-лист (Приложение А);
  2. auth-1 … auth-9;
  3. order-1 … order-9;
  4. status-1 … status-11;
  5. data-1 … data-6 и cancel-1 … cancel-9;
  6. PVZ-1 … PVZ-7;
  7. сквозные прогоны status-5 на трёх моделях (курьер, ПВЗ, отмена);
  8. разбор дефектов и повторный прогон затронутых кейсов.

Критерии завершения​

  • все кейсы разделов 1–6 выполнены, результат зафиксирован;
  • 100% пройденных кейсов по блокам auth, order, status;
  • блокирующие и критичные дефекты закрыты и перепроверены;
  • расхождений в данных заказа между ИС ЗЯ и ИС ВКС по сквозным прогонам нет;
  • согласован и подтверждён маппинг статусов и кодов ошибок.

Приложение Г: Справочник статусов заказа​

Таблица ниже содержит допустимые (обрабатываемые ИС Золотого Яблока) статусы заказов курьерской службы, v1.9.

Описание статусаКод статуса
Общие статусы доставки и оформления
Заказ создан в ИС ВКС, требует дополнительной валидацииECS_ORDER_CREATED
Заказ принят к исполнению, валидации пройденыECS_ORDER_ACCEPTED
Заказ прибыл в город назначения (или на ПВЗ), ожидает назначения курьераECS_ORDER_READY_FOR_APPOINTMENT
Курьер назначен на заказECS_COURIER_APPOINTED
Заказ выдан на доставку, курьер в путиECS_ORDER_TAKEN_BY_COURIER
Зафиксирована попытка доставки заказа (новое в v1.9)ECS_DELIVERY_ATTEMPT
Заказ выдан курьером на примеркуECS_ORDER_GIVEN_TO_TRY_ON
Заказ готов к выдаче клиенту на ПВЗECS_ORDER_READY_TO_PICK_UP
Заказ доставлен клиенту полностьюECS_ORDER_DELIVERED
Заказ доставлен клиенту частичноECS_ORDER_DELIVERED_PARTIALLY
Консолидация и транзит (прямой процесс)
Сдан перевозчику ВКС на складе отгрузкиECS_ORDER_TAKEN_FROM_SHIPMENT_WAREHOUSE
Первая фактическая приёмка на складе ВКСECS_ORDER_FIRST_ACCEPTANCE
Отправлен на транзитный хаб ВКСECS_ORDER_SENT_TO_TRANSIT_CITY
Зарегистрирован в транзитном хабе ВКСECS_ORDER_ACCEPTED_IN_TRANSIT_CITY_HUB
Возвратный процесс
Заказ возвращён на склад ВКСECS_RETURN_FIRST_ACCEPTANCE
Отправлен на транзитный хаб ВКСECS_RETURN_SENT_TO_TRANSIT_CITY
Зарегистрирован в транзитном хабе ВКСECS_RETURN_ACCEPTED_IN_TRANSIT_CITY_HUB
Направляется на склад возвратаECS_RETURN_ON_THE_WAY_TO_WAREHOUSE
Доставлен на склад возвратаECS_RETURN_DELIVERED_TO_WAREHOUSE

Приложение Д: Справочник статусов отмен​

Таблица ниже содержит допустимые статусы отмен заказов для курьерской службы, v1.9.

Причина отменыСообщение об отмене
Повреждение товара или посылки на складе оператораECS_WAREHOUSE_DAMAGED
Ошибка при доставке: неверный адрес или получательECS_LOGISTIC_ERROR
Невозможность доставки в срокECS_FAILED_FORWARDING
Проблема с курьером (болезнь, забастовка и т.д.). Только для экспресс-заказов.ECS_COURIER_UNAVAILABLE
Отказ по инициативе Золотого Яблока через АПИGA_CANCEL_REQUEST
Клиент отменил заказ явно или неявно (перенесён из статусов заказа в v1.9)ECS_ORDER_NOT_DELIVERED
Клиент отказался до отгрузки в КСCUSTOMER_CANCELED
Клиент отказался от получения во время доставкиCUSTOMER_DECLINED
Превышено количество попыток доставкиCUSTOMER_UNAVAILABLE
Просрочен срок хранения у оператораCUSTOMER_EXPIRED_ON_HOLD
ВКС не смогла провести платёж (терминал)PAYMENT_UNAVAILABLE_DUE_TO_ECS
Клиент отозвал платёжPAYMENT_CANCELED_BY_CUSTOMER
Невозможность доставки из-за погодыUNTRANSPORTABLE_WEATHER
Авария или ЧП на транспортной точкеTRANSPORT_EMERGENCY_STOP

Приложение Е: Коды ошибок адресов​

Коды ошибок, передаваемые курьерской службой при проблемах с созданием заказа на их стороне, v1.9.

Код ошибкиТип данныхОбязательностьОписаниеПример
Addr_01stringпри наступлении событияОшибка в адресе отправителя, переданном в ВКС"errorCode": "Addr_01"
Addr_02stringпри наступлении событияОшибка в адресе получателя, переданном в ВКС"errorCode": "Addr_02"