Разработчикам

Приложения для ez-business

Как сделать своё приложение для Маркета: оно откроется прямо в кабинете компании и будет работать с её клиентами, записями и продажами. Только с теми данными, которые разрешил владелец.

1Как это устроено

Приложение — это ваш сайт, который кабинет открывает у себя внутри, во фрейме. Данные компании вы получаете через API ez-business по токену, который кабинет передаёт при запуске.

  1. Вы делаете страницу на своём домене по https и описываете приложение в портале разработчика: карточка, цена, адрес, нужные права.
  2. Мы проверяем приложение и публикуем его в Маркете. Владельцы компаний видят его в разделе Приложение → Маркет.
  3. Владелец подключает приложение: смотрит, к каким данным оно просит доступ, снимает лишнее и подтверждает кодом из Google Authenticator.
  4. В кабинете появляется кнопка Открыть. Кабинет загружает вашу страницу и сразу передаёт ей токен — дальше вы работаете с API.
Можно сделать приложение только для себяЕсли вы владеете компанией в ez-business и хотите доработку под себя — делайте её как обычное приложение. Цена 0 ₽, в описании так и напишите, что оно для вашей компании.

2Быстрый старт

Всё делается в портале разработчика. Вход тот же, что в кабинет, — через ez-business ID.

  1. Откройте ez-business.ru/dev и войдите. Если аккаунта нет — зарегистрируйтесь, это бесплатно.
  2. Создайте команду: название, почта для связи, сайт. Коллег можно добавить сразу или потом.
  3. Нажмите Новое приложение и заполните карточку: описание, иконку, скриншоты, цену.
  4. На вкладке Подключение и права укажите адрес страницы и отметьте нужные права. Для каждого права коротко объясните, зачем оно вам.
  5. На вкладке Ключи API выпустите секретный ключ, если вашему серверу нужен постоянный доступ.
  6. Нажмите Отправить на модерацию. Когда приложение одобрят, оно появится в Маркете, а вам придёт уведомление в журнал.
Карточка приложения в портале разработчика
Карточка приложения в портале. Справа — как её увидят в Маркете.

3Команда и роли

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

РольЧто может
ВладелецВсё: приложения, ключи, публикация, команда, назначение других владельцев. В команде всегда есть хотя бы один владелец.
АдминистраторПриложения, ключи, снятие с публикации и возврат в каталог, команда — кроме владельцев.
РазработчикРедактирует карточки и права, загружает картинки, отправляет на модерацию. Ключи не выпускает.
НаблюдательТолько смотрит: приложения, установки, запросы к API и журнал.

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

4Карточка в Маркете

По карточке владелец решает, подключать ли приложение. Пишите для владельца салона или магазина, а не для программиста.

  • Название — до 60 символов. Без слов «лучший», «№1» и капса.
  • Коротко, что делает — одна фраза до 120 символов. Её видно в каталоге.
  • Подробное описание — для кого приложение, что умеет, как начать. От 60 символов, переносы строк сохраняются.
  • Иконка — квадратная картинка от 256×256, мы обрежем её по центру.
  • Скриншоты — от 1 до 8, лучше 1600×1000. Показывайте настоящие экраны приложения.
  • Цена — в рублях за месяц. 0 — бесплатно.
  • Почта поддержки — обязательно. Сюда будут писать владельцы компаний.
  • Тарифы — на каких тарифах ez-business показывать приложение. Ничего не отмечено — на всех. Компании без нужного тарифа приложение в каталоге не увидят, а у подключивших раньше оно перестанет открываться, пока тариф не сменят.

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

5Запуск во фрейме

Кабинет открывает адрес приложения во фрейме и общается с ним через postMessage. Токен никогда не передаётся в адресе страницы.

  1. Страница загрузилась — отправьте кабинету { type: 'ez:ready' }.
  2. Кабинет отвечает сообщением ez:init с токеном запуска и адресом API. Он же присылает его сразу после загрузки фрейма, так что ez:ready нужен на случай, если ваш код подписался позже.
  3. Работайте с API, передавая токен в заголовке Authorization: Bearer ….
  4. Токен запуска живёт час. Чтобы получить новый, отправьте { 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' } — запросить новый токен запуска.
Всегда проверяйте event.originПринимайте ez:init только от ez-business.ru и только от родительского окна. Ответы кабинету отправляйте с явным адресом, а не '*'.

Ограничения фрейма

Фрейм открывается с атрибутом 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 ответит ошибкой — так выглядит поведение при просроченном токене.

ez-business.ru/docs/dev/example/
Здесь появятся сообщения от приложения

Код примера — один HTML-файл без библиотек: открыть и посмотреть исходник страницы. Возьмите его за основу: положите на свой домен, укажите адрес в портале — и после модерации он заработает в кабинете с настоящими данными.

7API

Адрес: https://ez-business.ru/api/v1/apps. Все ответы — JSON с полем ok. Токен передаётся в заголовке Authorization: Bearer <токен>.

МетодПравоЧто делает
GET /me—Подключение и выданные права. С правом company — ещё название, телефон и часовой пояс компании.
GET /clientsclients.readКлиенты. Параметры: search (имя, телефон, номер карты), limit до 500, offset.
GET /clients/:idclients.readОдин клиент по id (номер карты).
POST /clientsclients.writeНовый клиент: firstName, lastName, phone, email. Если такой телефон уже есть — вернёт существующего с existed: true.
PATCH /clients/:idclients.writeИзменить имя, почту, день рождения (ГГГГ-ММ-ДД), теги, заметку.
POST /clients/:id/bonusesloyalty.writeНачислить (amount больше 0) или списать (меньше 0) бонусы с комментарием note.
GET /servicesservices.readУслуги: название, категория, цена, длительность.
GET /bookingsbookings.readЗаписи журнала за период: from, to в формате ГГГГ-ММ-ДД, не больше 62 дней.
GET /salessales.readПроведённые продажи за период до 92 дней: позиции, суммы, скидки, бонусы, способ оплаты.
GET /productswarehouse.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Токен для сервера

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

  1. Выпустите секретный ключ в портале: Приложение → Ключи API. Его показывают один раз.
  2. Когда приложение открылось во фрейме, отправьте токен запуска на свой сервер.
  3. Сервер обменивает его на постоянный токен 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Платные приложения

Цену указываете вы — в рублях за месяц. В Маркете она стоит прямо на кнопке подключения.

  1. Владелец подключает приложение, подтверждает кодом и оплачивает первый месяц картой или по СБП на странице банка.
  2. После оплаты приложение начинает работать. В портале, на вкладке Установки, видно, до какого числа оплачено.
  3. Когда срок заканчивается, приложение перестаёт открываться, а API отвечает 402, пока компания не продлит подписку.
Установки приложения
Установки: сколько компаний подключили приложение, кто ждёт оплату, запросы к API по дням.

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

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 или используйте постоянный токен на сервере — см. «Токен для сервера».

Можно ли открыть приложение не во фрейме?

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

Кто видит, какие компании подключили приложение?

Участники вашей команды — на вкладке Установки: название компании, дата и выданные права. Почты и телефоны владельцев не показываем.