Приложения для ez-business
Как сделать своё приложение для Маркета: оно откроется прямо в кабинете компании и будет работать с её клиентами, записями и продажами. Только с теми данными, которые разрешил владелец.
1Как это устроено
Приложение — это ваш сайт, который кабинет открывает у себя внутри, во фрейме. Данные компании вы получаете через API ez-business по токену, который кабинет передаёт при запуске.
- Вы делаете страницу на своём домене по https и описываете приложение в портале разработчика: карточка, цена, адрес, нужные права.
- Мы проверяем приложение и публикуем его в Маркете. Владельцы компаний видят его в разделе Приложение → Маркет.
- Владелец подключает приложение: смотрит, к каким данным оно просит доступ, снимает лишнее и подтверждает кодом из Google Authenticator.
- В кабинете появляется кнопка Открыть. Кабинет загружает вашу страницу и сразу передаёт ей токен — дальше вы работаете с API.
2Быстрый старт
Всё делается в портале разработчика. Вход тот же, что в кабинет, — через ez-business ID.
- Откройте ez-business.ru/dev и войдите. Если аккаунта нет — зарегистрируйтесь, это бесплатно.
- Создайте команду: название, почта для связи, сайт. Коллег можно добавить сразу или потом.
- Нажмите Новое приложение и заполните карточку: описание, иконку, скриншоты, цену.
- На вкладке Подключение и права укажите адрес страницы и отметьте нужные права. Для каждого права коротко объясните, зачем оно вам.
- На вкладке Ключи API выпустите секретный ключ, если вашему серверу нужен постоянный доступ.
- Нажмите Отправить на модерацию. Когда приложение одобрят, оно появится в Маркете, а вам придёт уведомление в журнал.

3Команда и роли
Приложения принадлежат команде. Добавляйте коллег по почте их ez-business ID и выдавайте роль. Все действия видны в журнале команды.
| Роль | Что может |
|---|---|
| Владелец | Всё: приложения, ключи, публикация, команда, назначение других владельцев. В команде всегда есть хотя бы один владелец. |
| Администратор | Приложения, ключи, снятие с публикации и возврат в каталог, команда — кроме владельцев. |
| Разработчик | Редактирует карточки и права, загружает картинки, отправляет на модерацию. Ключи не выпускает. |
| Наблюдатель | Только смотрит: приложения, установки, запросы к API и журнал. |
В журнале записывается всё: кто создал и поменял приложение, кто выпустил ключ, кого добавили в команду, результат модерации, а также подключения и отключения в компаниях и оплаты.
4Карточка в Маркете
По карточке владелец решает, подключать ли приложение. Пишите для владельца салона или магазина, а не для программиста.
- Название — до 60 символов. Без слов «лучший», «№1» и капса.
- Коротко, что делает — одна фраза до 120 символов. Её видно в каталоге.
- Подробное описание — для кого приложение, что умеет, как начать. От 60 символов, переносы строк сохраняются.
- Иконка — квадратная картинка от 256×256, мы обрежем её по центру.
- Скриншоты — от 1 до 8, лучше 1600×1000. Показывайте настоящие экраны приложения.
- Цена — в рублях за месяц. 0 — бесплатно.
- Почта поддержки — обязательно. Сюда будут писать владельцы компаний.
- Тарифы — на каких тарифах ez-business показывать приложение. Ничего не отмечено — на всех. Компании без нужного тарифа приложение в каталоге не увидят, а у подключивших раньше оно перестанет открываться, пока тариф не сменят.
Пока приложение не в каталоге, карточку можно менять сколько угодно. После публикации правки сохраняются как черновик: клиенты видят прежнюю версию, пока вы не отправите изменения на модерацию.
5Запуск во фрейме
Кабинет открывает адрес приложения во фрейме и общается с ним через postMessage. Токен никогда не передаётся в адресе страницы.
- Страница загрузилась — отправьте кабинету
{ type: 'ez:ready' }. - Кабинет отвечает сообщением
ez:initс токеном запуска и адресом API. Он же присылает его сразу после загрузки фрейма, так чтоez:readyнужен на случай, если ваш код подписался позже. - Работайте с API, передавая токен в заголовке
Authorization: Bearer …. - Токен запуска живёт час. Чтобы получить новый, отправьте
{ type: 'ez:token' }— кабинет пришлёт свежийez:init.
Что приходит в ez:init
{
type: 'ez:init',
version: 1,
token: 'ezl_…', // токен запуска, живёт 60 минут
expiresAt: '2026-10-02T12:00:00.000Z',
apiBase: 'https://ez-business.ru/api/v1/apps',
scopes: ['company', 'clients.read'], // права, которые выдал владелец
company: { name: 'Салон «Лён»' },
theme: 'light'
}
Минимальный код
const CABINETS = ['https://ez-business.ru', 'https://www.ez-business.ru'];
window.addEventListener('message', async (event) => {
if (!CABINETS.includes(event.origin) || event.source !== window.parent) return;
if (event.data?.type !== 'ez:init') return;
const { token, apiBase } = event.data;
const res = await fetch(apiBase + '/me', { headers: { Authorization: 'Bearer ' + token } });
console.log(await res.json());
});
window.parent.postMessage({ type: 'ez:ready' }, '*');
Что ещё можно отправить кабинету
{ type: 'ez:notify', text: 'Сохранено' }— короткое уведомление внизу кабинета, до 200 символов.{ type: 'ez:token' }— запросить новый токен запуска.
'*'.Ограничения фрейма
Фрейм открывается с атрибутом sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads". Камера, микрофон и геолокация недоступны. Ссылки на сторонние сайты открывайте в новой вкладке (target="_blank"). Страница не должна запрещать встраивание: уберите X-Frame-Options или разрешите frame-ancestors https://ez-business.ru.
6Живой пример
Ниже — настоящая страница примера во фрейме. Нажмите Отправить ez:init: эта страница сыграет роль кабинета и передаст приложению сообщение. Токен здесь ненастоящий, поэтому API ответит ошибкой — так выглядит поведение при просроченном токене.
Код примера — один HTML-файл без библиотек: открыть и посмотреть исходник страницы. Возьмите его за основу: положите на свой домен, укажите адрес в портале — и после модерации он заработает в кабинете с настоящими данными.
7API
Адрес: https://ez-business.ru/api/v1/apps. Все ответы — JSON с полем ok. Токен передаётся в заголовке Authorization: Bearer <токен>.
| Метод | Право | Что делает |
|---|---|---|
GET /me | — | Подключение и выданные права. С правом company — ещё название, телефон и часовой пояс компании. |
GET /clients | clients.read | Клиенты. Параметры: search (имя, телефон, номер карты), limit до 500, offset. |
GET /clients/:id | clients.read | Один клиент по id (номер карты). |
POST /clients | clients.write | Новый клиент: firstName, lastName, phone, email. Если такой телефон уже есть — вернёт существующего с existed: true. |
PATCH /clients/:id | clients.write | Изменить имя, почту, день рождения (ГГГГ-ММ-ДД), теги, заметку. |
POST /clients/:id/bonuses | loyalty.write | Начислить (amount больше 0) или списать (меньше 0) бонусы с комментарием note. |
GET /services | services.read | Услуги: название, категория, цена, длительность. |
GET /bookings | bookings.read | Записи журнала за период: from, to в формате ГГГГ-ММ-ДД, не больше 62 дней. |
GET /sales | sales.read | Проведённые продажи за период до 92 дней: позиции, суммы, скидки, бонусы, способ оплаты. |
GET /products | warehouse.read | Товары склада с ценой и остатком. limit, offset. |
Ошибки
401— токен недействителен или истёк. Во фрейме запросите новый черезez:token.402— подписка на платное приложение не оплачена или приложение заблокировано.403сerror: 'scope'— владелец не дал нужное право. В полеscope— какое именно. Покажите человеку понятное сообщение, а не пустой экран.403сerror: 'review'— приложение открыто на модерации, запись недоступна.429— больше 120 запросов в минуту на одно подключение. Подождите столько секунд, сколько в заголовкеRetry-After.
const res = await fetch(apiBase + '/clients?search=7900', {
headers: { Authorization: 'Bearer ' + token }
});
const { clients, total } = await res.json();
8Токен для сервера
Если вашему серверу нужен доступ без открытого кабинета — например, ночная рассылка или синхронизация, — обменяйте токен запуска на постоянный токен подключения.
- Выпустите секретный ключ в портале: Приложение → Ключи API. Его показывают один раз.
- Когда приложение открылось во фрейме, отправьте токен запуска на свой сервер.
- Сервер обменивает его на постоянный токен
eza_…и хранит у себя.
curl -X POST https://ez-business.ru/api/v1/apps/token \
-H 'Content-Type: application/json' \
-d '{"client_id":"app_…","client_secret":"ezs_…","launch_token":"ezl_…"}'
# ответ
{ "ok": true, "access_token": "eza_…", "install_id": 42, "scopes": ["clients.read"] }
Постоянный токен работает, пока компания не отключила приложение. Права проверяются при каждом запросе: если владелец снимет право, метод начнёт отвечать 403. На одно подключение хранится пять последних токенов, старые перестают работать.
9Права
Просите только то, без чего приложение не работает, и объясните зачем. Лишние права — частая причина вернуть приложение на доработку.
| Право | Название для владельца | Что открывает |
|---|---|---|
company | Название и контакты компании | Название, телефон и часовой пояс в GET /me |
clients.read | Смотреть клиентов | Имя, телефон, почта, карта, бонусы, теги |
clients.write | Добавлять и менять клиентов | Новые клиенты и правки карточек |
services.read | Услуги и цены | Список услуг |
bookings.read | Записи журнала | Кто, когда и к кому записан |
sales.read | Продажи и чеки | Продажи с позициями и оплатой |
loyalty.write | Начислять и списывать бонусы | Изменение бонусного баланса |
warehouse.read | Товары и остатки | Каталог товаров склада |
Каждое право вы отмечаете как обязательное или по желанию. Владелец при подключении видит обязательные права уже отмеченными и может снять любое. Если он снял обязательное, кабинет предупредит, что приложение будет работать нестабильно, — а ваш код должен спокойно пережить ответ 403.

Новые права в опубликованном приложении появятся после модерации. У тех, кто уже подключил приложение, их не будет, пока владелец не выдаст их сам в разделе Маркет → Подключённые → Права.
10Модерация
Ни одно приложение не попадает в Маркет без модерации. После кнопки Отправить на модерацию мы открываем приложение у себя и спокойно смотрим, что оно делает. Обычно отвечаем в течение рабочего дня.
На модерации приложение запускается так же, как в кабинете, но на данных демо-компании и только на чтение: запросы на запись получат ответ 403 с error: 'review'. Покажите в этом случае понятное сообщение — без падений и пустого экрана.
- Приложение открывается по указанному адресу, не ломается во фрейме и делает то, что написано в описании.
- Права соответствуют функциям: нет лишнего доступа «на всякий случай».
- Скриншоты настоящие, описание честное, цена указана.
- Есть рабочая почта поддержки.
Если что-то не так, приложение вернётся со статусом Нужны правки и комментарием — его видно в портале. Исправьте и отправьте снова.
Опубликованное приложение можно снять с публикации: оно пропадёт из каталога, но продолжит работать у тех, кто уже подключил. Вернуть в каталог можно без новой модерации.
Отзывы
Компании, которые подключили приложение, ставят оценку и пишут отзывы. Они видны в карточке в Маркете и на вкладке Отзывы в портале. Там же можно ответить — ответ увидят все. Средняя оценка и число установок показываются в каталоге.
11Платные приложения
Цену указываете вы — в рублях за месяц. В Маркете она стоит прямо на кнопке подключения.
- Владелец подключает приложение, подтверждает кодом и оплачивает первый месяц картой или по СБП на странице банка.
- После оплаты приложение начинает работать. В портале, на вкладке Установки, видно, до какого числа оплачено.
- Когда срок заканчивается, приложение перестаёт открываться, а API отвечает
402, пока компания не продлит подписку.

Условия выплат разработчику обсуждаем при первой публикации платного приложения — напишите на почту, указанную в письме о модерации.
12Правила для разработчиков
- Данные компании используются только для работы приложения. Их нельзя продавать, передавать третьим лицам и использовать для рекламы вне приложения.
- Персональные данные клиентов храните и обрабатываете по 152-ФЗ. Если сохраняете их у себя — вы оператор этих данных и отвечаете за их защиту.
- Когда компания отключает приложение, перестаньте обращаться к её данным и удалите сохранённые копии, если она попросит.
- Секретные ключи и токены храните на сервере. Об утечке сообщите нам сразу.
- Нельзя выдавать приложение за часть ez-business, подделывать интерфейс входа и просить у людей пароли.
- Мы можем снять приложение с публикации или заблокировать его, если оно нарушает правила или вредит компаниям. Блокировка сразу отключает доступ к API.
Маркет и портал разработчика предоставляет ООО «ОРВИО». Общие условия — в пользовательском соглашении.
?Частые вопросы
Можно ли сделать приложение на Vue, React или чём-то ещё?
Да. Кабинету всё равно, чем собрана страница: важно, чтобы она открывалась по https, принимала ez:init и не запрещала встраивание во фрейм.
Как отлаживать до публикации?
Возьмите пример со страницы, положите на свой домен и проверьте обмен сообщениями. Для полной проверки с данными подключите приложение в своей компании, когда оно пройдёт модерацию: цену можно поставить 0 ₽, а потом изменить.
Приложение открывается пустым
Чаще всего сайт запрещает встраивание заголовком X-Frame-Options или Content-Security-Policy: frame-ancestors. Разрешите https://ez-business.ru.
Почему API отвечает 401 через час?
Токен запуска живёт 60 минут. Отправьте кабинету ez:token или используйте постоянный токен на сервере — см. «Токен для сервера».
Можно ли открыть приложение не во фрейме?
Можно ссылками на свой сайт, но данные кабинета приложение получит только через токен — значит, хотя бы раз его должны открыть из Маркета.
Кто видит, какие компании подключили приложение?
Участники вашей команды — на вкладке Установки: название компании, дата и выданные права. Почты и телефоны владельцев не показываем.