ym88659208ym87991671
Динамический бейдж | Документация для разработчиков

Динамический бейдж

Обновлено 1 сентября 2026

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

Ключевые принципы

  1. Самостоятельная реализация. Визуальная часть и логика отображения динамического бейджа реализуются Партнером собственными силами на основании дизайн-гайда .
  2. Использование SDK. SDK используется исключительно для:
    • Настройки бесшовного перехода.
    • Передачи событий (метрик) об отображении и взаимодействии с бейджем.

Подключение бесшовного перехода

Для обеспечения плавного пользовательского опыта необходимо настроить бесшовный переход из приложения или сайта Партнера на веб-интерфейс без повторной авторизации.

Предварительные требования

Перед началом подключения к SSO ознакомьтесь с общими требованиями:

🔗 Общие требования

Инструкции по платформам

Отправка метрик в SDK

Для дальнейшей транспортировки данных в ClickStream партнеру необходимо уведомлять SDK о событиях, происходящих с динамическим бейджем.

Мобильные приложения (Android и iOS)

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

Метод отправки событий

SID.Events.sendBadgeEvent(
eventType: BadgeEventType, // SHOW, CLICK, ERROR
widgetType: BadgeWidgetType, // BADGE, POPUP (POPUP зарезервировано)
widgetContent: List<String>?, // ["Прайм", "Спасибо"] или null
status: List<String>? // ["ACTIVE", "INACTIVE"] или null
)
  • Максимальный размер любой строки — 128 символов.
  • Метод вызывается столько раз, сколько событий произошло.

Параметры метода

ПараметрТипОписание и правила передачи
eventTypeEnumSHOW (показ), CLICK (клик), ERROR (ошибка).
widgetTypeEnumВсегда BADGE (значение POPUP зарезервировано на будущее).
widgetContentList / ArrayМассив названий бейджей. Обязателен для SHOW и CLICK. Для глобальной ошибки (ERROR) может быть null (Android) или [] / [nil] (iOS).
statusList / ArrayМассив статусов бейджей. Порядок элементов должен строго соответствовать порядку в widgetContent.

Правила и ограничения:

  • Элемент с индексом 0 в widgetContent относится к элементу с индексом 0 в status. Если длины массивов не совпадают, SDK обрежет их по минимальной длине.
  • Особенности iOS - массивы widgetContent и status передаются всегда (не могут быть nil как весь объект), но могут содержать элементы nil. SDK автоматически отфильтрует nil значения и пустые массивы перед отправкой.
  • Пустая строка "" внутри массива допустима и будет передана как есть.

Логика отправки событий

Партнер отправляет события по факту намерения показать бейджи, а не по факту их физического появления на экране. Это ключевой принцип, обеспечивающий корректную сквозную аналитику. Правило одного вызова: Независимо от количества бейджей, запланированных к показу (один, два или больше), Партнер отправляет один вызов SHOW с массивом всех бейджей.

Таблица сценариев

СитуацияДействия ПартнераКакие события отправлять
1Штатный показ. Партнер успешно отобразил все запланированные бейджи.Отправить один SHOW с массивом всех показанных бейджей и их статусов.SHOW
2Намерение показать, но пользователь ушел. Партнер начал рендер, но пользователь закрыл приложение / ушел со страницы до завершения показа.Событие все равно отправляется — факт намерения состоялся.SHOW (с полным массивом запланированных бейджей)
3Глобальная системная ошибка. Из-за ошибки (сетевой, серверной и т.п.), не связанной с действиями пользователя, Партнер не может отобразить ни один бейдж.SHOW не отправляется. Отправляется только ERROR без данных о бейджах.ERROR (глобальная, widgetContent = null / [])
4Частичная ошибка при рендере. Планировался показ нескольких бейджей, но один (или несколько) не отобразился из-за ошибки.Сначала отправить SHOW со всеми запланированными бейджами. Затем следом отправить ERROR с данными конкретного сбойного бейджа.SHOW (полный массив) → ERROR (данные проблемного бейджа)
5Полная ошибка при рендере. Все запланированные бейджи не отобразились из-за ошибки в процессе показа.Сначала отправить SHOW со всеми запланированными бейджами. Затем следом отправить ERROR без данных (глобальная ошибка в процессе показа).SHOW (полный массив) → ERROR (глобальная)

Важно:

  • Пользовательские действия (уход со страницы, закрытие приложения) не являются ошибкой. Если намерение показать бейджи было — отправляйте SHOW.
  • ERROR без данных (widgetContent = null) означает, что Партнер не смог отобразить бейджи до отправки SHOW (сценарий №3).
  • ERROR с данными конкретного бейджа означает, что SHOW уже был отправлен, но в процессе рендера возникла проблема с одним из бейджей (сценарий №4).

Примеры вызовов

// 1. Штатный показ нескольких бейджей
SID.Events.sendBadgeEvent(BadgeEventType.SHOW, BadgeWidgetType.BADGE, listOf("Прайм", "Спасибо"), listOf("ACTIVE", "INACTIVE"))

// 2. Клик по конкретному бейджу
SID.Events.sendBadgeEvent(BadgeEventType.CLICK, BadgeWidgetType.BADGE, listOf("Прайм"), listOf("ACTIVE"))

// 3. Глобальная ошибка ДО показа (ни один бейдж не загрузился)
SID.Events.sendBadgeEvent(BadgeEventType.ERROR, BadgeWidgetType.BADGE, null, null)

// 4. Ошибка конкретного бейджа в процессе рендера
SID.Events.sendBadgeEvent(BadgeEventType.ERROR, BadgeWidgetType.BADGE, listOf("Прайм"), null)

Web и mWeb

Приложение партнера самостоятельно отправляет метрики в ClickStream Сбер ID по следующим событиям:

  • Отображение бейджа
  • Клик на бейдж
  • Ошибка показа бейдж

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

Для передачи метрик необходимо инициализировать clickstream:

export const clickstreamParams = {
url: 'https://ext.clickstream.sbrf.ru/metrics/inner-partners/sber-id',
apiKey: '5b63c7457b46f2e2c0c81062da0efbd628c62940db7590f9e97aecac87a43f05',
applicationName: '[clientId партнера]'
};

Формат передаваемого события

ПараметрПоказ бейджа Прайм/СпасибоОшибка отображения бейджаКлик по бейджу Прайм/Спасибо
eventCategoryELKELKELK
eventActionSID_ELK_Badge screenSID_ELK_Badge errorSID_ELK_Badge button
eventTypebusiness (обычные события: клики, изменения, открытие страниц, диалоговых окон и пр.)business (обычные события: клики, изменения, открытие страниц, диалоговых окон и пр.)business (обычные события: клики, изменения, открытие страниц, диалоговых окон и пр.)
valuetimeStamp (время формирования метрик)timeStamp (время формирования метрик)timeStamp (время формирования метрик)

Свойства (properties)

КлючПоказ бейджа Прайм/СпасибоОшибка отображения бейджаКлик по бейджу Прайм/Спасибо
widget_contentЕсли бонусы Спасибо: "Баланс"
Если значок Прайма: "Прайм"
Если бонусы Спасибо: "Баланс"
Если значок Прайма: "Прайм"
event_typeShow (отображение экрана пользователю)Error (отображение ошибки пользователю)Click (нажатие на кнопку/чекбокс/подсказку)
sourceЕсли бонусы Спасибо: "Баланс"
Если значок Прайма: "Прайм"
Код ошибки (не совпадает с текстом ошибки на экране, http-код ошибки)Если бонусы Спасибо: "Баланс"
Если значок Прайма: "Прайм"
channelweb / mWebweb / mWebweb / mWeb
partner_nameНаименование партнераНаименование партнераНаименование партнера
logIdИдентификатор сессии пользователяИдентификатор сессии пользователяИдентификатор сессии пользователя

Пример запроса:

{
"meta": {
"apiKey": "5b63c7457b46f2e2c0c81062da0efbd628c62940db7590f9e97aecac87a43f05",
"applicationName": "40c1d5da-1532-11eb-adc1-0242ac-disk",
"platform": "WEB",
"browser": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 SberBrowser/39.0.0.0",
"timeStamp": "2026-08-24T12:51:12.842+03:00",
"screenSize": "1680x1050",
"systemLanguage": "ru-RU"
},
"profile": {
"applicationLanguage": "en",
"deviceId": "SA1.3590e0b5-5301-4c46-9f89-e3e2737f578f.1786517005",
"sessionId": "SA1.3590e0b5-5301-4c46-9f89-e3e2737f578f.1786517005.1787565072",
"cookie": [
{
"key": "_ym_uid",
"value": "1783693885483729367"
}
],
"hashUserLoginId": ""
},
"data": [
{
"url": "https://ci02440297-ift-sberid-elk-ext-static.apps.a9s6tc15.k8s.delta.sbrf.ru/profile/external_partners/storybook/iframe.html",
"pageName": "partners-disk--disk",
"connectionType": "UNKNOWN",
"timeStamp": "2026-08-24T12:51:12.843+03:00",
"eventAction": "SID_ELK_Badge screen",
"eventCategory": "ELK",
"eventType": "business",
"value": "",
"properties": [
{
"key": "event_type",
"value": "Show"
},
{
"key": "source",
"value": "Баланс"
},
{
"key": "channel",
"value": "web"
},
{
"key": "partner_name",
"value": "Диск"
},
{
"key": "logId",
"value": "6b5174dcb14a48aaacd96d2e58102f45"
},
{
"key": "widget_content",
"value": "Баланс"
}
]
}
]
}

Пример реализации:

import {
logDir,
logUidSessionStorageName,
} from '@front-static-partners/shared';
import { sendEventClickStream } from '@sberid/click-stream';
import { getSessionStorageItem } from '../utils/getSessionStorageItem';

type DefaultParamsProps = {
eventCategory: string;
system: string;
metricEventType?: 'technical' | 'business';
};

export type EventParamsProps = {
eventAction: string;
value: string;
event_type: string;
partner_name: string;
source: string;
templateId?: string;
error_type?: string;
abName?: string;
widget_content?: string;
widget_download_start_time?: number;
widget_download_end_time?: number;
popupType?: string;
actionPlace?: string;
actionType?: string;
};

export function setDefaultParams(defaultProps: DefaultParamsProps) {
const isMobile = window.innerWidth < 480;
const channel = isMobile ? 'mWeb' : 'web';

return function (eventProps: EventParamsProps) {
const { eventCategory, metricEventType } = defaultProps;
const {
eventAction,
value,
event_type,
partner_name,
source,
templateId,
error_type,
abName,
widget_content,
widget_download_start_time,
widget_download_end_time,
popupType,
actionPlace,
actionType,
} = eventProps;

let ab;
if (abName) {
ab = window.elkAB?.[abName];
}

const analyticData = {
eventAction,
eventCategory,
value,
eventType: metricEventType || 'business',
properties: [
{
key: 'event_type',
value: event_type,
},
{
key: 'source',
value: source,
},
{
key: 'channel',
value: channel,
},
{
key: 'partner_name',
value: partner_name,
},
],
};

const hashUserLog = getSessionStorageItem(logUidSessionStorageName);
const logId = hashUserLog?.logId;

if (logId) {
analyticData.properties.push({
key: 'logId',
value: logId,
});
}

if (ab) {
analyticData.properties.push({
key: 'ab_experiment',
value: ab
.map((experiment: { name: string; group: string }) => experiment.name)
.join('|'),
});

analyticData.properties.push({
key: 'ab_variant',
value: ab
.map(
(experiment: { name: string; group: string }) => experiment.group,
)
.join('|'),
});
}

if (widget_download_start_time) {
analyticData.properties.push({
key: 'widget_download_start_time',
value: Math.trunc(widget_download_start_time).toString(),
});
}

if (widget_download_end_time) {
analyticData.properties.push({
key: 'widget_download_end_time',
value: Math.trunc(widget_download_end_time).toString(),
});
}

if (widget_content) {
analyticData.properties.push({
key: 'widget_content',
value: widget_content,
});
}

if (templateId) {
analyticData.properties.push({
key: 'templateId',
value: templateId,
});
}

if (error_type) {
analyticData.properties.push({
key: 'error_type',
value: error_type,
});
}

if (popupType) {
analyticData.properties.push({
key: 'popupType',
value: popupType,
});
}

if (actionPlace) {
analyticData.properties.push({
key: 'actionPlace',
value: actionPlace,
});
}

if (actionType) {
analyticData.properties.push({
key: 'actionType',
value: actionType,
});
}

return analyticData;
};
}

export const sendAnalytics = setDefaultParams({
eventCategory: 'ELK',
metricEventType: 'business',
system: 'SBERID',
});

export const sendTechAnalytics = setDefaultParams({
eventCategory: 'ELK',
metricEventType: 'technical',
system: 'SBERID',
});
Заметили ошибку?
Выделите текст и нажмите
Ctrl
+
Enter
, чтобы сообщить нам об ошибке