Salta ai contenuti

Firma integrata

<bf-signing> visualizza la pagina di firma di Bona Fide in un iframe isolato (sandbox) all’interno della Sua pagina, lo dimensiona in base al documento e comunica le azioni del firmatario come eventi DOM. Non dipende da alcun framework; sono inclusi wrapper leggeri per React e Vue.

  1. Crei la busta con delivery: "embedded", in modo che i destinatari non ricevano e-mail.

  2. Crei una sessione sul Suo server quando il firmatario apre la pagina, con l’origine del Suo sito in allowedOrigins. La pagina integrata si rifiuta di comunicare con qualsiasi pagina contenitore che non sia elencata.

    // 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. Visualizzi l’elemento con il 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. Confermi sul Suo server. Consideri l’evento del browser un segnale per l’interfaccia e, per l’esito, si basi sul webhook envelope.completed (o su GET /v1/envelopes/{id}).

Attributo (prop React / Vue) Predefinito Note
session Il token bfs_…. Cambiarlo ricarica il frame
base-url (baseUrl) https://sign.bonafidesign.com/s/ Il percorso di firma ospitato dell’installazione
theme auto auto, light o dark
locale Passato alla pagina di firma
min-height, max-height (minHeight, maxHeight) 480, 90vh Pixel o vh. Il frame cresce con il documento tra i due valori, poi scorre al suo interno
timeout 30000 Millisecondi di attesa della pagina prima di un error con codice load_timeout
frame-title Document signing Il titolo accessibile dell’iframe

L’elemento dispone anche di un metodo reload(), ad esempio da usare dopo aver creato una nuova sessione.

Gli eventi risalgono il DOM (bubbling), attraversano gli shadow root e contengono il payload in event.detail. bf-event viene emesso per tutti.

Evento detail
ready { type: 'ready' }: la pagina di firma è stata caricata
field_completed { type, field }: un campo è stato compilato
signed { type, recipient }: questo destinatario ha inviato
completed { type, envelope }: la busta è completa
declined { type, reason? }
session_expiring { type, expiresAt }: crei a breve una nuova sessione
error { type, code, message }, compresi load_timeout e invalid_base_url

Le prop React sono onReady, onFieldCompleted, onSigned, onCompleted, onDeclined, onSessionExpiring, onError e onEvent; Vue emette i nomi degli eventi (@completed, @session_expiring, …) ed event.

  • Il token viaggia nel frammento dell’URL dell’iframe (#session=…), che non raggiunge mai un server né un header Referer. La pagina di firma lo legge, lo rimuove dall’URL e dalla cronologia e lo scambia con un token di accesso conservato in memoria. Non vengono usati cookie.
  • L’iframe è in sandbox (allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads) con referrerpolicy="strict-origin".
  • La Sua pagina accetta un messaggio solo se proviene dall’iframe dell’elemento stesso e dall’origine di base-url e può essere interpretato come messaggio bona-fide.embed/1 con namespace. Tutto il resto viene ignorato.
  • La pagina di firma invia i messaggi alla Sua origine esatta (mai *) e solo se tale origine è tra gli allowedOrigins della sessione. Anche l’API rifiuta le chiamate di una sessione integrata provenienti da origini non autorizzate.