Saltar al contenido principal

Integra el formulario

Integra el formulario

Un mismo formulario puede recibir registros por tres canales en paralelo. Elige el que mejor se adapte a cómo tus usuarios van a interactuar con él.

Soyio aloja cada formulario en una página propia:

URL de producción
https://forms.soyio.id/<companySlug>/<formSlug>
URL de sandbox
https://forms.soyio.id/<companySlug>/<formSlug>?isSandbox=true

Esta opción no requiere código: compartes el link y listo. Ideal para:

  • Campañas de marketing por email o SMS.
  • Códigos QR impresos en oficinas, eventos o sucursales.
  • Procesos asistidos donde tu equipo de soporte envía el link al cliente.

La página standalone muestra el header con tu logo, el formulario y un pie con la marca Powered by Soyio.

Si quieres una URL más corta, puedes apuntar tu propio subdominio con un redirect a forms.soyio.id.

Opción 2: Iframe SDK (ConsentFormBox)​

Para mantener al usuario dentro de tu sitio, embebe el formulario en un iframe usando @soyio/soyio-widget. La diferencia clave con el link standalone es que tu sitio controla qué pasa después del submit: cerrar un modal, avanzar a la siguiente pantalla, disparar analytics, etc.

Instala y monta​

yarn add @soyio/soyio-widget
Estructura HTML
<div id="consent-form-box"></div>
src/consent-form.ts
import { ConsentFormBox } from '@soyio/soyio-widget';

const consentForm = new ConsentFormBox({
consentFormToken: 'cform_<id>',
locale: 'es',
isSandbox: true,
subjectId: 'ent_<entity_id>',
userReference: 'customer-123',
personalizationToken, // Token de corta duración generado por tu backend
onEvent: (event) => {
switch (event.eventName) {
case 'CONSENT_FORM_PAGE_CHANGE':
console.log(`Página ${event.currentPage}/${event.totalPages}`);
break;
case 'CONSENT_FORM_SUBMITTED':
console.log('Registro creado', event.entryToken);
break;
case 'CONSENT_FORM_COMPLETED':
if (event.redirectUrl) window.top!.location.assign(event.redirectUrl);
break;
case 'CONSENT_FORM_LOAD_ERROR':
console.error(event.kind, event.message);
break;
case 'CONSENT_FORM_SUBMIT_ERROR':
console.error(event.message);
break;
}
},
});

consentForm.mount('#consent-form-box');

Opciones disponibles​

  • consentFormToken (requerido): identificador del formulario. Empieza con cform_.
  • locale: 'es' o 'en'. Si lo omites, se usa el idioma del navegador.
  • isSandbox: true apunta al ambiente de sandbox. Por defecto false.
  • subjectId: opcional. Si tu sistema ya tiene un ent_* o id_* asociado al usuario, lo pasas para enlazar el registro a ese subject.
  • userReference: opcional. Referencia interna de tu sistema, persistida con el registro. Usa un identificador propio (por ejemplo customer-123), no datos personales.
  • personalizationToken: opcional. Token de corta duración generado por tu backend para ocultar los consentimientos que el usuario ya tiene vigentes. Sin este token, subjectId y userReference enlazan el registro, pero el formulario muestra todos los consentimientos.
  • formData: opcional. Valores con los que parte el formulario, indexados por la key de cada campo. Revisa Completa los datos que ya conoces.
  • documentViewer: 'newTab' (por defecto) o 'lightbox'. Con 'lightbox', los documentos PDF de los consentimientos se abren sobre tu página, sin salir del formulario. Revisa Abre los documentos sin salir del formulario.
  • appearance: overrides visuales por embed. Revisa Apariencia y comportamiento.
  • onEvent: callback que recibe cada evento del iframe.
  • onReady: callback que se dispara cuando el iframe queda listo.

No uses datos personales (como un email) en userReference: este valor se persiste y se muestra sin enmascarar en el dashboard. Usa un identificador propio de tu sistema, como customer-123.

Completa los datos que ya conoces​

Si el usuario ya está identificado en tu sitio, pasa en formData los datos que ya tienes para que no tenga que escribirlos de nuevo. El usuario ve los campos completos y puede editarlos antes de enviar.

src/consent-form.ts
const consentForm = new ConsentFormBox({
consentFormToken: 'cform_<id>',
userReference: 'customer-123',
formData: {
full_name: 'Jane Doe',
email: 'jane@soyio.id',
rut: '12.345.678-5',
},
onEvent: (event) => { /* ... */ },
});

Cada clave de formData corresponde a la key de un campo del formulario. El valor depende del tipo de campo:

  • Texto, nombre, correo, teléfono, RUT y texto largo: string
  • Selección: string igual a una de las opciones del campo
  • Fecha: string en formato YYYY-MM-DD
  • Casilla: boolean

Ten en cuenta lo siguiente:

  • Las claves que no corresponden a un campo del formulario se ignoran. Lo mismo ocurre con un valor que no corresponde a su tipo de campo, por ejemplo una opción que no existe o una fecha en otro formato.
  • Los valores pasan por las mismas validaciones que lo que escribe el usuario. Si un valor es inválido, por ejemplo un correo mal formado, el formulario muestra el error en ese campo para que el usuario lo corrija.
  • Si los valores llegan cuando el usuario ya empezó a completar el formulario, solo se completan los campos que siguen vacíos.

formData solo está disponible con ConsentFormBox. Los valores viajan al iframe después de que carga y nunca forman parte de su URL, así que no quedan en logs ni en el historial del navegador. El link standalone no acepta valores iniciales para los campos visibles.

Pasa valores a los campos ocultos​

Los campos ocultos no se muestran a la persona, así que su valor siempre lo entrega tu integración. Puedes hacerlo de dos formas:

  • Con ConsentFormBox: inclúyelos en formData, junto a los valores de los campos visibles.

    formData: {
    client_id: 'customer-123',
    email: 'jane@soyio.id',
    },
  • Con el link standalone: agrega un parámetro formData[<key>] por cada campo oculto. Este parámetro solo aplica a campos ocultos; los campos visibles lo ignoran.

    https://forms.soyio.id/<companySlug>/<formSlug>?formData[client_id]=customer-123

No uses datos personales, como un RUT, un nombre o un email, en los parámetros del link: la URL queda guardada en el historial del navegador y puede quedar en logs de terceros. Usa identificadores propios de tu sistema, como customer-123. Si necesitas pasar datos personales, usa formData en ConsentFormBox.

Los valores pasan por las mismas validaciones que los de un campo visible. Si un campo oculto obligatorio no recibe valor, o un campo oculto recibe un valor inválido, la persona ve un error en lugar del formulario y ConsentFormBox emite CONSENT_FORM_LOAD_ERROR con kind: 'invalidFormData' y las key de los campos afectados en keys.

Personaliza los consentimientos pendientes​

Genera el personalizationToken desde tu backend con una API key que tenga el permiso consent.api.read o consent.api.manage. Nunca envíes la API key de Soyio al navegador.

Backend
const response = await fetch(
'https://api.soyio.id/api/v1/consent_forms/cform_<id>/personalization_token',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SOYIO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ user_reference: 'customer-123' }),
},
);

const { personalization_token: personalizationToken } = await response.json();

Entrega ese token al frontend y pásalo al crear ConsentFormBox. El token vence 15 minutos después de emitirse y solo sirve para la versión del formulario y el subject indicados.

Consulta el API Reference para revisar los permisos, parámetros y respuestas del endpoint.

Eventos del ConsentFormBox​

Todos los eventos llegan vía onEvent. La forma de cada uno es:

CONSENT_FORM_LOAD_ERROR
{
eventName: 'CONSENT_FORM_LOAD_ERROR',
kind: 'notFound' | 'hostNotAllowed' | 'loadFailed' | 'invalidFormData',
message?: string,
keys?: string[], // Solo con kind 'invalidFormData'
}
CONSENT_FORM_PAGE_CHANGE
{
eventName: 'CONSENT_FORM_PAGE_CHANGE',
currentPage: number, // 1-indexed
totalPages: number,
}
CONSENT_FORM_SUBMITTED
{
eventName: 'CONSENT_FORM_SUBMITTED',
entryToken: string,
redirectUrl: string | null,
}
CONSENT_FORM_COMPLETED
{
eventName: 'CONSENT_FORM_COMPLETED',
entryToken: string,
redirectUrl: string | null,
}
CONSENT_FORM_SUBMIT_ERROR
{
eventName: 'CONSENT_FORM_SUBMIT_ERROR',
message: string,
}

CONSENT_FORM_SUBMITTED se dispara cuando el registro se persiste. CONSENT_FORM_COMPLETED se dispara cuando el usuario hace clic en el botón final de la pantalla de éxito. Si tu integración necesita esperar al usuario, escucha CONSENT_FORM_COMPLETED.

Para ver estos eventos junto al resto de los que emite Soyio, revisa el catálogo de eventos.

Dominios permitidos​

Por seguridad, el iframe solo puede cargarse desde dominios incluidos en la lista blanca de tu compañía. Configúralos en Configuración > Acceso y seguridad del dashboard, en la tarjeta Seguridad de módulos.

  • El origen forms.soyio.id siempre está permitido (modo standalone).
  • Si embebes en app.miempresa.cl, agrega ese hostname exacto.

Revisa el formato de dominios permitidos antes de guardar el valor.

Si el host no está permitido, el iframe muestra el error CONSENT_FORM_LOAD_ERROR con kind: 'hostNotAllowed' y no carga el formulario.

Opción 3: API directa​

Si construyes tu propia UI (por ejemplo, una app móvil nativa o un flujo legacy), puedes capturar los action_tokens y crear el registro directamente vía API. Esta es la misma mecánica que el módulo de consentimiento usa para integraciones sin SDK.

Flujo​

Registro​

El endpoint público no requiere autenticación: usa el cform_ token del formulario en la URL y los action_tokens para acreditar el consentimiento.

POST /api/v1/consent_forms/cform_<id>/entries
{
"version": 2,
"subject_id": "ent_<entity_id>",
"user_reference": "customer-123",
"data": {
"full_name": "Jane Doe",
"email": "jane@soyio.id"
},
"consent_actions": [
{ "action_token": "<action_token_1>" },
{ "action_token": "<action_token_2>" }
]
}
CampoTipoRequeridoDescripción
versionintegerNoVersión específica del formulario. Si la omites, se usa la última publicada.
subject_idstringNoToken ent_* o id_* para enlazar el registro a un subject existente.
user_referencestringNoReferencia interna del usuario en tu sistema. Usa un identificador propio (no datos personales como el email); se guarda y se muestra sin enmascarar.
dataobjectSíValores de los campos del formulario, indexados por key.
consent_actionsarraySíaction_tokens (mínimo uno) de los consentimientos aceptados.

Todos los action_tokens deben corresponder a plantillas declaradas en el formulario. Los obligatorios deben estar todos presentes. De lo contrario el endpoint responde 400.

Consulta el API Reference para el detalle de validaciones y posibles respuestas.

¿Qué pasa con el Agreement?​

Independiente del canal, cada registro genera:

  • Un ConsentFormEntry con los datos y el subject.
  • Un ConsentAction (un consentimiento) o un ConsentCommit (varios).
  • Una actualización del Agreement del usuario.

Para reaccionar al cambio de permisos en tiempo real, suscríbete a los webhooks agreement.created y agreement.updated. Son los eventos que reflejan el estado vigente de consentimiento del usuario, así no tienes que reconstruirlo a partir de los consent_action o consent_commit individuales.

Próximos pasos​