Перейти к содержимому

Встроенное подписание

<bf-signing> отображает страницу подписания Bona Fide в изолированном iframe (sandbox) на вашей странице, подгоняет его размер под документ и сообщает о действиях подписанта через события DOM. Компонент не зависит от фреймворков; в комплекте есть тонкие обёртки для React и Vue.

  1. Создайте конверт с delivery: "embedded", чтобы получатели не получали писем.

  2. Создайте сессию на своём сервере, когда подписант открывает страницу, указав источник (origin) своего сайта в allowedOrigins. Встроенная страница отказывается взаимодействовать с любой родительской страницей, которой нет в этом списке.

    // Your backend (never expose the API key to the browser)
    const res = await fetch(`https://api.bonafidesign.com/v1/envelopes/${envelopeId}/sessions`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.BONA_FIDE_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ recipient: recipientId, mode: 'embedded', allowedOrigins: ['https://app.example.com'] }),
    });
    const { token } = await res.json(); // 'bfs_…', single-use, 10 minutes by default
  3. Отобразите элемент с токеном.

    <script type="module" src="https://js.bonafidesign.com/v1"></script>
    <bf-signing session="bfs_…" theme="auto" min-height="480" max-height="90vh"></bf-signing>
    <script>
    const el = document.querySelector('bf-signing');
    el.addEventListener('completed', (e) => {
    // e.detail = { type: 'completed', envelope: 'env_…' }
    window.location.href = '/onboarding/next';
    });
    el.addEventListener('session_expiring', () => refreshSession());
    el.addEventListener('error', (e) => console.error(e.detail.code, e.detail.message));
    </script>
  4. Подтвердите результат на сервере. Считайте событие в браузере сигналом для интерфейса, а результат определяйте по вебхуку envelope.completed (или по GET /v1/envelopes/{id}).

Атрибут (свойство React / Vue) По умолчанию Примечания
session Токен bfs_…. При его изменении фрейм перезагружается
base-url (baseUrl) https://sign.bonafidesign.com/s/ Маршрут страницы подписания в данном развёртывании
theme auto auto, light или dark
locale Передаётся странице подписания
min-height, max-height (minHeight, maxHeight) 480, 90vh Пиксели или vh. Фрейм растёт вместе с документом в этих пределах, а затем прокручивается внутри
timeout 30000 Сколько миллисекунд ждать страницу, прежде чем выдать error с кодом load_timeout
frame-title Document signing Доступное название iframe

У элемента также есть метод reload(), например для вызова после создания новой сессии.

События всплывают, проходят через границы shadow root и передают данные в event.detail. bf-event срабатывает для каждого из них.

Событие detail
ready { type: 'ready' }: страница подписания загружена
field_completed { type, field }: поле заполнено
signed { type, recipient }: этот получатель отправил подпись
completed { type, envelope }: конверт завершён
declined { type, reason? }
session_expiring { type, expiresAt }: скоро нужно создать новую сессию
error { type, code, message }, в том числе load_timeout и invalid_base_url

Свойства React: onReady, onFieldCompleted, onSigned, onCompleted, onDeclined, onSessionExpiring, onError и onEvent; Vue генерирует события с этими именами (@completed, @session_expiring, …) и event.

  • Токен передаётся во фрагменте URL iframe (#session=…), который никогда не попадает на сервер или в заголовок Referer. Страница подписания считывает его, удаляет из URL и истории и обменивает на токен доступа, который хранится в памяти. Cookie не используются.
  • iframe работает в песочнице (allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads) с referrerpolicy="strict-origin".
  • Ваша страница принимает сообщение, только если оно пришло из iframe самого элемента, и из источника base-url, и разбирается как сообщение в пространстве имён bona-fide.embed/1. Всё остальное игнорируется.
  • Страница подписания отправляет сообщения строго на ваш источник (никогда не на *) и только если этот источник указан в allowedOrigins сессии. API также отклоняет вызовы встроенной сессии с источников, которые не разрешены.