Документация по корзинному виджету 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,вс, выходной"
}
}
}