Firma integrada
<bf-signing> renderiza la página de firma de Bona Fide en un iframe aislado dentro de su página, ajusta su tamaño
al documento e informa lo que hace el firmante mediante eventos del DOM. No depende de ningún framework; incluye
wrappers ligeros para React y Vue.
-
Cree el sobre con
delivery: "embedded", para que no se envíen correos a los destinatarios. -
Genere una sesión en su servidor cuando el firmante abra la página, con el origen de su sitio en
allowedOrigins. La página integrada se niega a comunicarse con cualquier página principal que no figure ahí.// 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 -
Renderice el elemento con el 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>import { BonaFideSigning } from '@bona-fide/embed/react';export function SignContract({ token }: { token: string }) {return (<BonaFideSigningsession={token}theme="auto"minHeight={480}maxHeight="90vh"onCompleted={(e) => console.log('envelope completed', e.envelope)}onDeclined={(e) => console.log('declined', e.reason)}onSessionExpiring={() => refreshSession()}onError={(e) => console.error(e.code, e.message)}/>);}<script setup lang="ts">import { BonaFideSigning } from '@bona-fide/embed/vue';defineProps<{ token: string }>();const done = (e: { envelope: string }) => console.log('envelope completed', e.envelope);</script><template><BonaFideSigning :session="token" theme="auto" :min-height="480" max-height="90vh" @completed="done" /></template> -
Confirme en su servidor. Trate el evento del navegador como una señal para la interfaz y use el webhook
envelope.completed(oGET /v1/envelopes/{id}) para conocer el resultado.
Atributos
Sección titulada “Atributos”| Atributo (prop de React / Vue) | Predeterminado | Notas |
|---|---|---|
session |
El token bfs_…. Si cambia, se vuelve a cargar el marco |
|
base-url (baseUrl) |
https://sign.bonafidesign.com/s/ |
La ruta de firma alojada de la implementación |
theme |
auto |
auto, light o dark |
locale |
Se pasa a la página de firma | |
min-height, max-height (minHeight, maxHeight) |
480, 90vh |
Píxeles o vh. El marco crece con el documento entre ambos valores y luego se desplaza por dentro |
timeout |
30000 |
Milisegundos que se espera a la página antes de un error con el código load_timeout |
frame-title |
Document signing |
El título accesible del iframe |
El elemento también tiene un método reload(), por ejemplo, para usarlo después de generar una sesión nueva.
Eventos
Sección titulada “Eventos”Los eventos se propagan, atraviesan los shadow roots y llevan la carga útil en event.detail. bf-event se
dispara para todos ellos.
| Evento | detail |
|---|---|
ready |
{ type: 'ready' }: la página de firma se cargó |
field_completed |
{ type, field }: se completó un campo |
signed |
{ type, recipient }: este destinatario envió su firma |
completed |
{ type, envelope }: el sobre está completo |
declined |
{ type, reason? } |
session_expiring |
{ type, expiresAt }: genere pronto una sesión nueva |
error |
{ type, code, message }, incluidos load_timeout e invalid_base_url |
Las props de React son onReady, onFieldCompleted, onSigned, onCompleted, onDeclined, onSessionExpiring,
onError y onEvent; Vue emite los nombres de los eventos (@completed, @session_expiring, …) y event.
Modelo de seguridad
Sección titulada “Modelo de seguridad”- El token viaja en el fragmento de la URL del iframe (
#session=…), que nunca llega a un servidor ni a un encabezadoReferer. La página de firma lo lee, lo elimina de la URL y del historial, y lo intercambia por un token de acceso en memoria. No se usan cookies. - El iframe está aislado con sandbox (
allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-downloads) y usareferrerpolicy="strict-origin". - Su página acepta un mensaje solo cuando proviene del propio iframe del elemento, y del origen de
base-url, y se analiza como un mensajebona-fide.embed/1con espacio de nombres. Todo lo demás se ignora. - La página de firma envía mensajes a su origen exacto (nunca a
*), y solo si ese origen figura en losallowedOriginsde la sesión. La API también rechaza las llamadas de una sesión integrada desde orígenes no permitidos.