Расширение описания API
Расширение описание документации сервиса.
Дерево условий скидок
Передача и хранение
Дерево условий скидок хранится отдельно для каждой скидки. Дерево представляет собой рекуррентную структуру, состоящую из узлов трех типов:
- Группа условий
- Контейнер условий скидок
- Условие скидки
Начальным корневым узлом структуры может быть только группа условий. Внутри группы могут находиться только контейнеры условий, а уже в контейнерах условий содержатся массивы условий.
Дерево описывается вложенными узлами, с указанием соответствующего типа объекта:
"type": "group", // Определяет тип объекта
"container": {
// Состав полей зависит от типа объекта (см. ниже)
}
Каждый объект имеет свою структуру полей. При разборе объектов сервис выполняет отложенный разбор поля container
, в зависимости от типа указанного в поле type
Группа условий
Определяет взаимодействие вложенных результатов вычисленных условий.
{
"type": "group",
"container": {
"rule": "max", // Правило взаимодействия значений скидки подчиненных элементов
"operator": "or", // Правило взаимодействия срабатывания подчиненных элементов
"items": [] // Подчиненные элементы - группы или контейнеры условий
}
Контейнер условий
Определяет множество условий, значение скидки при срабатывании контейнера и правило взаимодействия сработавших скидок внутри контейнера.
{
"type": "conditions",
"container": {
"rule": "and", // Правило взаимодействия условий
"value": 1.5, // Значение скидки, переопределяющее основное значение
"conditions": [] // Набор условий контейнера
}
Условие
Определяет утверждение, при срабатывании которого условие считается выполненным.
{
"type":"some-type", // Тип условия, от типа зависит состав полей объекта `container`
"container": {} // Объект описывающий состав условия, зависит от типа условия(см. ниже)
}
Типы условий
Булево
Описывает простое булево условие, если значение в поле `operand` == true, условие считается всегда выполненным, в противном случае не выполненным.
{
"type":"boolean,
"container": {
"operand": true
}
}
Уровень карты
Выполняется, если уровень карты равен или не равен установленному
{
"type":"card-level",
"container": {
// Оператор
"operator":"==",
// Идентификатор уровня карт
"operand": 1
}
}
Номер позиции
Выполняется, если номера позиций чека соответствуют условию
{
"type":"row-number",
"container": {
// Оператор
"operator":"==",
// Номер строки
"operand": 1
}
}
Дни недели
Выполняется, если дата документа выпадает на указанные в маске дни недели
{
"type":"week-day",
"container": {
// Маска дней недели, каждый бит отвечает за день недели пн-вс слева направо
"operand": "0010101"
}
}
День рождения
Выполняется, если день рождения клиента попадает в диапазон дат от даты документа
{
"type":"birthday",
"container": {
// Период перед днем рождения в днях, когда скидка может сработать
"days_before": 2,
// Период после дня рождения в днях, когда скидка может сработать
"days_after": 2
}
}
Сумма без учета скидки
Выполняется, если сумма без учета скидки соответствует условию. Возможно уточнение сегмента товаров, для которого условие будет проверяться
{
"type":"sum-without-discounts",
"container": {
"area":"document|position",
"operator":">=",
"operand": 100.50,
"segments": [1, 2, 3, 4]
}
}
Сумма c учетом скидки
Выполняется, если сумма с учетом скидок соответствует условию. Возможно уточнение сегмента товаров, для которого условие будет проверяться
{
"type":"sum-with-discounts",
"container": {
"area":"document|position",
"operator":">=",
"operand": 100.50,
"segments": [1, 2, 3, 4]
}
}
Количество товара
Выполняется, если количество товара соответствует условию. Возможно уточнение сегмента товаров, для которого условие будет проверяться
{
"type":"quantity",
"container": {
"area":"document|position",
"operator":">=",
"operand": 100.50,
"segments": [1, 2, 3, 4]
}
}
Первая покупка по карте
Выполняется, текущий документ первый по карте
{
"type":"first-purchase",
"container": {
"operand": true
}
}
Сумма покупок по карте
Выполняется, если сумма покупок по карте соответствует условию
{
"type":"card-purchase-sum",
"container": {
"operator":">="
"operand": 100500.99
}
}
Группа ассортимента
Выполняется, если товар входит в группу ассортимента
{
"type":"catalog-group",
"container": {
"operator":"in"
// Идентификатор группа товаров
"operand": 42
}
}
Сумма покупок по карте за период
Выполняется, сумма покупок по карте за указанный период соответствует условию
{
"type":"card-purchase-sum-over",
"container": {
"operator":">",
"operand": 50000,
"step": "days|month|month-aligned|year|year-aligned|quarter-aligned",
"steps_before": 1,
"steps_after": 1
}
}
Комплект
Выполняется, если в документе есть комплекты
{
"type":"product-set",
"container": {
"price_sorting":"asc|desc",
"no_intersection": false,
"segments":[
{
"id": 1,
"calculate": true,
"distribute":true,
"quantity":10
}
],
}
}
Группа промокодов
Выполняется, если промокод был передан и входит в группу
{
"type":"promo-group",
"container": {
"operand": 1 // Идентификатор группы промокодов
}
}
Маска промокода
Выполняется, если промокод подходит под переданную маску. Возможно использование регулярных выражений.
{
"type":"promo-mask",
"container": {
"operand": "%PROMO-202%" // Маска, символы % будут инерпретироваться как 0 или более любых символов
}
}
Двухфакторная авторизация операций
Описание механизма
Методы использующие двухфакторное подтверждение операций отмечены в документации красным тэгом 2FA
.
В качестве второго фактора выступает фактор владения покупателем частного ресурса(телефон, почта). Настройка 2FA выполняется в личном кабинете и состоит из двух частей:
- Галка для событий, при которых необходимо выполнить проверку второго фактора
- Список каналов которыми будет доставлен код подтверждения фактора
- В карточке магазина признак отключения проверки фактора, который совсем отключает механизм в конкретных магазинах
Каждое событие проверяется отдельно. Попытка отправки кода выполняется через канал в порядке указания его в списке каналов, в зависимости от наличия канала в конкретном запросе или в профиле клиента.
Пример: Установлена настройка проверки фактора владения при регистрации клиента. Порядок каналов отправки: Телефон -> Почта. В запросе регистрации телефон не передан, но есть адрес электронной почты. При таких вводных отправка кода будет выполняться на почту, т.к. определить телефон не представляется возможным. При тех же настройках и выполнении запроса идентификации клиента, если в карточке клиента есть телефон, отправка произойдет на телефон, как более приоритетный канал отправки.
Описание протокола
Протокол построен на сессионной модели. Любой защищенный запрос(запрос требующий 2FA) при установленной настройке для соответствующей операции будет начинать сессию работы с пользователем в определенном магазине.
Если для защищенного метода установлена настройка и список каналов отправки не пустой, выполняется проверки:
- Этот вызов является началом или продолжением сессии? Проверка выполняется по наличию специального заголовка
x-totp-session-id
. - Если передан заголовок
x-totp-channel
, попытка отправки кода будет выполняться на этот канал - Если заголовок
x-totp-session-id
не передан, начинается новая сессия, сервис генерирует и отправляет на первый доступный канал отправки временный код подтверждения фактора владения и отвечает специальными инструкциями для клиентского приложения:
{
"success": true,
"message": "OK",
"data": {
"session": {
"id": "081ff88e5d1f925d33926fb0f580e49485fd231b", // Идентификатор сессии
"issuer": "79030000001",
"issuer_location": "",
"confirmed": false,
"created_at": null,
"updated_at": null
},
"instruction": {
"channel": "phone", // Канал, на который выполнилась отправка кода подтверждения
"reciever": "79030000001", // Идентификатор получателя(зависит от канала)
"secret": "dummy-secret", // Секрет клиентского приложения, используется для проверки введенного кода подтверждения
"duration": 120, // Время жизни кода подтверждения в секундах
"available_channels": [ // Доступные в текущем контексте каналы отправки кодов подтверждения
"phone"
]
}
}
}
- Если заголовок
x-totp-session-id
передан, считается, что это очередной вызов в рамках начатой ранее сессии- В таком случае выполняется проверка подтверждения фактора владения(было ли подтверждение) в рамках сессии.
- Если сессия не была подтверждена ранее, выполняется проверка заголовков
x-totp-code
иx-totp-secret
, если проверка прошла успешно - код верный, сессия помечается как подтвержденная и защищенный запрос возвращает свое тело ответа(зависит от конкретного запроса) - Если сессия уже была подтверждена - запрос просто возвращает свое тело ответа
- Если сессия не была подтверждена ранее, выполняется проверка заголовков
- В таком случае выполняется проверка подтверждения фактора владения(было ли подтверждение) в рамках сессии.
- Клиентское приложение может завершить сессию любым запросом в сессии с передачей заголовка
x-totp-expire
.
Таким образом начинаться сессия может любым методом, подтверждаться любым методом, любой метод в цепочке вызовов после подтверждения больше не требует подтверждения.
Описание развертывания
Сервис использует переменные окружения связанные с отправкой SMS4B. Также используются две переменные окружения:
TOTP_SESSION_TTL_MIN
Время жизни сессии подтвержденной сессии в минутах. Не менее 10 минут, если указано значение меньше - сессия будет жить 10 минут. Значение по-умолчанию: 10 минут.
TOTP_SESSION_VACUUM_INTERVAL_MIN
Интервал, с которым сервис выполняет очистку просроченных сессий. Не менее 10 минут, если указано значение меньше - сессия будет жить 10 минут. Значение по-умолчанию: 10 минут.