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

Документация по корзинному виджету versta.io v3

Введение

Данный документ описывает интеграцию и использование корзинного виджета versta.io, предназначенного для определения параметров доставки на внешних сайтах и приложениях.

Для демонстрации работы виджета можно воспользоваться демо-страницей - https://docs.versta.io/demo/widget

Установка виджета

Для установки добавьте следующий скрипт на страницу сайта:

<script src="https://widget.versta.io/v3/widgetapi.js"></script>

После загрузки скрипта, на странице будет доступен объект window.verstaWidget, предоставляющий API для работы с виджетом.

API виджета

Инициализация

Для запуска виджета необходимо выполнить его инициализацию, чтобы загрузить iframe с интерфейсом и сконфигурировать виджет:

window.verstaWidget.init({
auth: /* ключ для API Версты */,
sender: {/* данные отправителя */},
receiver: {/* данные получателя */},
cargo: [/* грузоместа */]
});

После вызова этого метода iframe с виджетом будет добавлен на страницу и загружен.

В метод init необходимо передать объект конфигурации виджета. Объект содержит данные отправителя, получателя, груза, а также ключ для API Версты. Определение объекта конфигурации:

{
auth: string;
sender: {
city: {
cityId: string; // Код ФИАС города
};
};
receiver?: {
city: {
cityId: string; // Код ФИАС города
};
contactType?: ContactType; // Режим доставки
};
cargo: CargoItem[]; // Грузоместа
}

В параметре auth необходимо передать данные для аутентификации: это может быть API ключ или bearer token. Значение API ключа передается в строке следующим образом: "apiKey xxxx-xxxx-xxxx-xxxx". Значение berarer токена передается через строку: "bearer xxxx-xxxx-xxxx-xxxx". Так как код инициализации виджета, и следовательно авторизационные данные, как правило доступны на публичной странице интернет магазина для авторизации виджета лучше использовать сгенерированный через API bearer token который имеет ограниченный срок жизни и ограниченный функционал. Подробнее про генерацию ключа можно посмотреть в документации на API - https://api.versta24.ru/docs/v3/#tag/Auth/paths/~1openapi~1v3~1Auth~1byApiKey/get

Данные получателя можно опустить, тогда виджет попробует самостоятельно выяснить у пользователя город и желаемый режим доставки.

Режим доставки

Режим доставки может принимать значения:

enum ContactType {
Door = 1, // Курьерская доставка до двери
PickupPoint = 4, // Доставка до ПВЗ
}

Грузоместо определяется следующим образом:

type CargoItem = {
qty: number; // Количество
weight: number; // Вес в кг
l: number; // Длина в см
w: number; // Ширина в см
h: number; // Высота в см
};

Открытие виджета

Для открытия виджета вызовите метод open. Метод принимает callback-функцию, с помощью которой можно получить и обработать данные о доставке от виджета. Передаваемая callback-функция вызывается при закрытии виджета пользователем.

window.verstaWidget.open((deliveryConfirmation) => {
/* Обработка данных доставки */
});

Виджет открывается поверх основной страницы подобно модальному окну.

Чтобы изменить callback-функцию, необходимо повторно вызвать метод open и передать новую функцию. Можно не передавать функцию в метод, если изменение не требуется.

В callback передается объект подтверждения доставки пользователем deliveryConfirmation.

type DeliveryConfirmation = {
status: ConfirmationStatus; // Статус подтверждения доставки
deliveryData: Delivery; // Данные о доставке
};

Статус подтверждения предназначен для определения того, каким образом пользователь закрыл виджет и в каком состоянии находятся данные о доставке. Статусы могут быть следующие:

enum ConfirmationStatus {
Unfinished = "Unfinished", // Виджет закрыт намеренно, данные о доставке неполные
DoorConfirmed = "DoorConfirmed", // Выбрана доставка курьером, переданы соответствующие данные
PickupPointConfirmed = "PickupPointConfirmed", // Выбрана доставка до ПВЗ, переданы соответствующие данные
}

Данные о доставке

Доставка:

type Delivery = {
receiver?: Contact; // Обновленные данные о получателе
option?: DeliveryOption; // Выбранный вариант доставки
pickupPoint: PickupPoint; // Пункт выдачи (при доставке до ПВЗ)
comments?: string; // Дополнительный комментарий (при курьерской доставке)
unloadingRequired?: boolean; // Требуется ли услуга поднятия на этаж (при курьерской доставке)
};

Получатель:

type Contact = {
contactType?: ContactType; // Режим доставки
city?: GeoInfo; // Географические данные города
address?: GeoInfo; // Географические данные адреса, включая улицу, дом и квартиру (при курьерской доставке)
};

Режим доставки.

Географические данные:

type GeoInfo = {
name?: string;
address?: string;
itemId?: string;
countryId?: string;
countryCode?: string;
cityId?: string;
cityName?: string;
pureCityName?: string;
streetName?: string;
house?: string;
houseType?: string;
flatNumber?: string;
postalCode?: string;
addressWithCity?: string;
};

В географических данных, в зависимости от адреса, могут отсутствовать значения тех или иных полей. Некоторые поля имеют схожие значения, которые могут присутствовать в разных комбинациях. Например, в данных о городе название города может содержаться в полях address, cityName, pureCityName.

Данные варианта доставки:

type DeliveryOption = {
vendorInfo?: VendorInfo; // Компания, выполняющая доставку
delivery?: DeliveryInfo; // Параметры доставки, связанные со временем
tariff?: TariffInfo; // Параметры тарифа доставки
price?: PriceInfo; // Параметры стоимости доставки
tags?: string[]; // Теги, указывающие дополнительные указания к доставке
deliveryType?: number; // Тип доставки
reqDeliveryDate?: string; // Желаемая дата доставки
reqDeliveryTimeFrom?: string; // Желаемое начальное время доставки
reqDeliveryTimeTo?: string; // Желаемое конечное время доставки
};

Более подробное описание данных варианта доставки можно найти здесь (секция Responses->200->options).

Компания, выполняющая доставку:

type VendorInfo = {
vendorId: number; // Идентификатор компании
vendorName: string; // Наименование компании
vendorContractType: number; // Тип договора с поставщиком. 0 - договор versta24, 1 - клиентский договор
};

Параметры доставки, связанные со временем:

type DeliveryInfo = {
takeDate: string; // Дата забора
deliveryDateFrom: string; // Планируемые дата и время доставки (от)
deliveryDateTo: string; // Планируемые дата и время доставки (до)
minDays?: number; // Минимальное количество дней доставки
maxDays?: number; // Максимальное количество дней доставки
formattedDeliveryDate?: string; // Отформатированная дата доставки (от) (например, "4 апреля")
};

Параметры тарифа доставки:

type TariffInfo = {
tariffId: string; // Идентификатор тарифа
tariffName: string; // Наименование тарифа
};

Параметры стоимости доставки:

type PriceInfo = {
price: number; // Полная стоимость доставки в рублях, включая сервисы и НДС
tariffPriceOnly: number; // Цена тарифа без сервисов, включая НДС
isApproximatePrice: boolean; // Признак того, что стоимость является примерной
priceString: string; // Цена с валютой (например, 600 ₽)
};

Пункт выдачи (при доставке до ПВЗ):

type PickupPoint = {
pickupPointId: string | null; // Идентификатор ПВЗ
addressInfo?: {
latitude?: number; //
longitude?: number;
address: string; // Адрес ПВЗ без города
};
services?: {
code?: PickupPointServiceCode; // Код услуги
isProvided?: boolean; // Оказывается ли услуга
}[]; // Услуги
type?: PickupPointType; // Тип ПВЗ
vendorInfo?: {
id?: number; // Идентификатор компании, владеющей ПВЗ
name?: string; // Наименовение компании, владеющией ПВЗ
logo?: {
rounded?: string; // Ссылка на круглый логотип компании, владеющей ПВЗ
};
};
workTimeInfo?: string; // Режим работы ПВЗ
};

Код услуги:

enum PickupPointServiceCode {
CHECK = "CHECK", // Проверка/примерка
PARTIAL_PAY = "PARTIAL_PAY", // Частичный выкуп
PAYMENT_BY_CARD = "PAYMENT_BY_CARD", // Оплата картой
PAYMENT_BY_CASH = "PAYMENT_BY_CASH", // Оплата наличными
}

Тип ПВЗ:

enum PickupPointType {
LOCKER = "Постамат",
MARKETPLACE = "Маркетплейс",
PO_BOX = "Абонентский ящик",
PVZ = "Пункт выдачи",
}

Закрытие виджета

API предоставляет возможность закрыть (скрыть) виджет с помощью метода close. Закрытие виджета осуществляется автоматически после завершения работы с ним пользователем, явный вызов метода закрытия из вашего кода не требуется.

Пример интеграции

Здесь представлен простейший пример интеграции виджета по шагам.

Шаг 1. Установка

Встроим на страницу тег script с указанием ссылки на API виджета:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Пример интеграции виджета</title>
</head>
<body>
<script src="https://widget.versta.io/v3/widgetapi.js"></script>
</body>
</html>

Шаг 2. Инициализация

Вызовем метод init на объекте window.verstaWidget, передав объект конфигурации:

// Объект конфигурации виджета
const widgetConfig = {
auth: "<ключ API версты>",
sender: {
city: {
cityId: "c2deb16a-0330-4f05-821f-1d09c93331e6", // Санкт-Петербург (ФИАС)
},
},
cargo: [{ weight: 0.5, qty: 1, l: 10, h: 10, w: 10 }],
};

// Инициализация виджета
window.verstaWidget.init(widgetConfig);

Важно сделать это после загрузки API виджета, иначе объект не будет доступен.

Данные получателя опущены для наглядности. Перед началом выбора доставки, виджет отобразит элементы управления для выбора города и режима доставки.

Рекомендуется инициализировать виджет как можно раньше и, по возможности, передавать ФИАС код города получателя. В таком случае виджет начнет фоновую загрузку данных о возможных вариантах доставки еще до открытия виджета. Это позволит пользователям не замечать этой загрузки и сразу переходить к выбору доставки после открытия виджета.

Шаг 3. Открытие виджета

Добавим на страницу кнопку и привяжем к ней метод открытия виджета:

<button id="openButton">Выбрать доставку</button>
const openButton = document.getElementById("openButton");
openButton.onclick = () => {
window.verstaWidget.open();
};

При нажатии на кнопку откроется окно виджета.

На данном этапе функции виджета уже полностью доступны. Однако, данные, которые виджет собирает и передает после закрытия, не обрабатываются.

Шаг 4. Обработка данных виджета

Создадим функцию для обработки данных виджета и передадим ее в качестве callback-функции в метод open:

// Функция для обработки данных доставки, собираемых виджетом
const handleDeliveryConfirmation = (deliveryConfirmation) => {
console.log(deliveryConfirmation);
};

const openButton = document.getElementById("openButton");
openButton.onclick = () => {
// Открытие виджета с передачей callback-функции
window.verstaWidget.open(handleDeliveryConfirmation);
};

В показаном примере данные просто выводятся в консоль, но их можно сохранить и использовать при оформлении доставки.

Финальный код примера

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Пример интеграции виджета</title>
</head>
<body>
<button id="openButton">Выбрать доставку</button>

<script src="https://widget.versta.io/v3/widgetapi.js"></script>
<script>
// Объект конфигурации виджета
const widgetConfig = {
auth: "<ключ API версты>",
sender: {
city: {
cityId: "c2deb16a-0330-4f05-821f-1d09c93331e6", // Санкт-Петербург (ФИАС)
},
},
cargo: [{ weight: 0.5, qty: 1, l: 10, h: 10, w: 10 }],
};

// Инициализация виджета
window.verstaWidget.init(widgetConfig);

// Функция для обработки данных доставки, собираемых виджетом
const handleDeliveryConfirmation = (deliveryConfirmation) => {
console.log(deliveryConfirmation);
};

const openButton = document.getElementById("openButton");
openButton.onclick = () => {
// Открытие виджета с передачей callback-функции
window.verstaWidget.open(handleDeliveryConfirmation);
};
</script>
</body>
</html>

Демонстрация работы с виджетом

Изначально на странице отображатся только кнопка:

кнопка открытия виджета

Инициализация виджета происходит сразу после загрузки страницы.

Нажатие на кнопку после инициалиации виджета открывает окно виджета:

Поскольку код ФИАС города и режим доставки не были переданы при конфигурации виджета, сначала отображается окно выбора города, а затем окно выбора режима доставки.

окно выбора города

окно выбора режима доставки

При доставке в пункт выдачи, отображается окно с картой города отправителя. Здесь пользователь выбирает подходящий ему ПВЗ:

окно выбора пвз

Как только пользователь нажмет кнопку "Выбрать", выбранный ПВЗ сохранится, виджет закроется и вызовет callback-функцию, определенную при открытии в методе open. В callback-функцию передается подтверждение доставки, которое выводится в консоль, как это и было определено при интеграции.

Данные, полученные от виджета:

{
"status": "PickupPointConfirmed",
"deliveryData": {
"receiver": {
"city": {
"regionName": null,
"region": null,
"regionFull": null,
"kadIn": null,
"districtType": null,
"districtName": null,
"districtFullName": null,
"stead": null,
"steadType": null,
"streetName": null,
"streetFullName": null,
"streetType": null,
"streetTypeFull": null,
"streetId": null,
"house": null,
"houseType": null,
"buildingNumber": null,
"buildingType": null,
"flat": null,
"flatType": null,
"cityName": null,
"cityId": "c2deb16a-0330-4f05-821f-1d09c93331e6",
"address": "Санкт-Петербург г",
"addressWithCity": "Санкт-Петербург г",
"name": "Санкт-Петербург г",
"itemId": "c2deb16a-0330-4f05-821f-1d09c93331e6",
"countryCode": "RU",
"regId": "c2deb16a-0330-4f05-821f-1d09c93331e6",
"parentId": null,
"parentName": null,
"pureCityName": "Санкт-Петербург",
"postalCode": "190000",
"latitude": 59.939084,
"longitude": 30.315879,
"requestedAdditionalInfo": false,
"isLocationAccurate": false
},
"cityId": "c2deb16a-0330-4f05-821f-1d09c93331e6",
"contactType": 4,
"pickupPointId": "RusPost:917683:c2deb16a-0330-4f05-821f-1d09c93331e6"
},
"option": {
"vendorInfo": {
"vendorId": 32,
"vendorName": "Почта России",
"vendorLogoUrl": "https://my.versta24.ru/img/vendors/Почта России.png",
"vendorContractType": 0
},
"delivery": {
"takeDate": "2025-04-09T00:00:00",
"deliveryDateFrom": "2025-04-11T18:00:00",
"deliveryDateTo": "2025-04-11T18:00:00",
"minDays": 2,
"maxDays": 2,
"formattedDeliveryDate": "11 апреля"
},
"tariff": {
"tariffId": "BANDEROL|SIMPLE",
"tariffName": "Бандероль простая",
"comments": "<br/><b>Почтовое отправление с бумажной продукцией и печатными изданиями (книги, журналы, блокнот, документы в коробках). Допустимый вес отправления не более 5 килограмм.</b>"
},
"price": {
"price": 186.3,
"tariffPriceOnly": 186.3,
"isApproximatePrice": false,
"priceString": "186 ₽"
},
"tags": ["land"],
"deliveryType": 1,
"services": null,
"weightCalc": 0.5
},
"pickupPoint": {
"addressInfo": {
"address": "остров Канонерский 22",
"description": "Почтомат расположен в отделении почтовой связи"
},
"services": [
{
"code": "CHECK",
"isProvided": false
},
{
"code": "PARTIAL_PAY",
"isProvided": false
},
{
"code": "PAYMENT_BY_CARD",
"isProvided": false
},
{
"code": "PAYMENT_BY_CASH",
"isProvided": false
}
],
"type": "LOCKER",
"vendorInfo": {
"name": "Почта России"
},
"workTimeInfo": "пн, выходной,вт-сб, открыто: 10:00 - 18:00,вс, выходной"
}
}
}