Pular para o conteúdo

Assinatura incorporada

<bf-signing> renderiza a página de assinatura da Bona Fide em um iframe isolado (sandbox) dentro da sua página, ajusta o tamanho dele ao documento e informa o que o signatário faz por meio de eventos DOM. Ele não depende de framework; wrappers leves para React e Vue estão incluídos.

  1. Crie o envelope com delivery: "embedded", para que os destinatários não recebam e-mail.

  2. Gere uma sessão no seu servidor quando o signatário abrir a página, com a origem do seu site em allowedOrigins. A página incorporada se recusa a se comunicar com qualquer página pai que não esteja listada ali.

    // 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. Renderize o elemento com o token.

    <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. Confirme no seu servidor. Trate o evento do navegador como um sinal para a interface e conte com o webhook envelope.completed (ou com GET /v1/envelopes/{id}) para saber o resultado.

Atributo (prop do React / Vue) Padrão Observações
session O token bfs_…. Alterá-lo recarrega o frame
base-url (baseUrl) https://sign.bonafidesign.com/s/ A rota de assinatura hospedada da implantação
theme auto auto, light ou dark
locale Repassado à página de assinatura
min-height, max-height (minHeight, maxHeight) 480, 90vh Pixels ou vh. O frame cresce com o documento entre os dois valores e depois rola internamente
timeout 30000 Milissegundos de espera pela página antes de um error com o código load_timeout
frame-title Document signing O título acessível do iframe

O elemento também tem um método reload(), por exemplo para usar depois de gerar uma nova sessão.

Os eventos se propagam (bubble), atravessam shadow roots e trazem o payload em event.detail. bf-event é disparado para todos eles.

Evento detail
ready { type: 'ready' }: a página de assinatura carregou
field_completed { type, field }: um campo foi preenchido
signed { type, recipient }: este destinatário enviou
completed { type, envelope }: o envelope está concluído
declined { type, reason? }
session_expiring { type, expiresAt }: gere uma nova sessão em breve
error { type, code, message }, incluindo load_timeout e invalid_base_url

As props do React são onReady, onFieldCompleted, onSigned, onCompleted, onDeclined, onSessionExpiring, onError e onEvent; o Vue emite os nomes dos eventos (@completed, @session_expiring, …) e event.

  • O token trafega no fragmento da URL do iframe (#session=…), que nunca chega a um servidor nem a um cabeçalho Referer. A página de assinatura o lê, o remove da URL e do histórico e o troca por um token de acesso mantido em memória. Nenhum cookie é usado.
  • O iframe é isolado (allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads) com referrerpolicy="strict-origin".
  • A sua página só aceita uma mensagem quando ela vem do próprio iframe do elemento e da origem de base-url e é interpretada como uma mensagem bona-fide.embed/1 com namespace. Todo o resto é ignorado.
  • A página de assinatura envia mensagens para a sua origem exata (nunca *), e só se essa origem estiver nas allowedOrigins da sessão. A API também recusa chamadas de uma sessão incorporada vindas de origens não permitidas.