> ## Documentation Index
> Fetch the complete documentation index at: https://knowledge.nufi.mx/llms.txt
> Use this file to discover all available pages before exploring further.

# PostMessage Events

> Recibe eventos en tiempo real desde el iframe de KYB para actualizar tu interfaz

## Descripcion

Cuando integras KYB mediante iframe, tu aplicacion puede escuchar eventos `postMessage` para:

* Saber cuando el iframe esta listo
* Recibir actualizaciones de status de cada seccion en tiempo real
* Detectar cuando el usuario final envia su expediente

Todos los eventos se envian desde el iframe hacia la ventana padre usando `window.parent.postMessage()`.

***

## Configuracion

Agrega un listener en tu pagina que contiene el iframe:

```javascript theme={null}
window.addEventListener('message', (event) => {
  // Filtrar solo eventos de KYB
  if (!event.data?.type?.startsWith('kyb_')) return;

  switch (event.data.type) {
    case 'kyb_ready':
      // El iframe cargo correctamente
      break;
    case 'kyb_section_updated':
      // Una seccion cambio de status
      break;
    case 'kyb_document_submitted':
      // El expediente fue enviado
      break;
  }
});
```

<Note>
  Los eventos solo se envian cuando el iframe se carga con el parametro `?isiframe=true` en la URL del guest.
  Ejemplo: `https://app.nufi.mx/guest/{accessToken}?isiframe=true`
</Note>

***

## Eventos disponibles

<CardGroup cols={2}>
  <Card title="kyb_ready" icon="circle-check">
    Se dispara cuando el iframe termino de cargar y esta listo para interactuar.
  </Card>

  <Card title="kyb_section_updated" icon="arrows-rotate-reverse">
    Se dispara cuando una seccion cambia de status (por ejemplo, un analista aprobo un documento).
  </Card>

  <Card title="kyb_document_submitted" icon="paper-plane">
    Se dispara cuando el usuario final envia el expediente completo.
  </Card>
</CardGroup>

***

### `kyb_ready`

Se envia una sola vez al terminar la carga inicial del iframe. Contiene el estado completo de todas las secciones.

```json theme={null}
{
  "type": "kyb_ready",
  "folio": "NF-2026-001234",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "externalId": "EXT-999",
  "progress": {
    "percentage": 25,
    "total": 4,
    "completed": 1,
    "pending": 2,
    "inReview": 0,
    "requiresAttention": 1,
    "rejected": 0
  },
  "allSections": [
    {
      "name": "Acta Constitutiva",
      "type": "ArticleIncorporation",
      "status": "Completado",
      "comments": ""
    },
    {
      "name": "Estado de Cuenta",
      "type": "BankStatement",
      "status": "RequiereAtencion",
      "comments": "El estado de cuenta tiene una antiguedad mayor a 3 meses"
    }
  ]
}
```

<ResponseField name="folio" type="string">
  Folio del expediente asignado por KYB. Puede estar vacio si el expediente aun no ha sido enviado.
</ResponseField>

<ResponseField name="id" type="string (GUID)">
  Identificador unico del expediente dentro de KYB.
</ResponseField>

<ResponseField name="externalId" type="string">
  Identificador externo proporcionado por tu sistema al crear el expediente.
</ResponseField>

<ResponseField name="progress" type="object">
  Resumen numerico del progreso del expediente.
</ResponseField>

<ResponseField name="allSections" type="array">
  Lista completa de todas las secciones del expediente con su status actual.
</ResponseField>

***

### `kyb_section_updated`

Se envia cada vez que una seccion cambia de status. Incluye un array `changes` que indica exactamente que seccion cambio y de que status a cual.

```json theme={null}
{
  "type": "kyb_section_updated",
  "folio": "NF-2026-001234",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "externalId": "EXT-999",
  "changes": [
    {
      "name": "Estado de Cuenta",
      "type": "BankStatement",
      "previousStatus": "Pendiente",
      "newStatus": "RequiereAtencion",
      "comments": "El estado de cuenta tiene una antiguedad mayor a 3 meses"
    }
  ],
  "progress": {
    "percentage": 25,
    "total": 4,
    "completed": 1,
    "pending": 1,
    "inReview": 0,
    "requiresAttention": 2,
    "rejected": 0
  },
  "allSections": [...]
}
```

<ResponseField name="changes" type="array">
  Lista de secciones que cambiaron de status en esta actualizacion. Cada elemento contiene:

  * `name`: Nombre legible de la seccion
  * `type`: Tipo tecnico de la seccion (ver tabla de tipos)
  * `previousStatus`: Status anterior
  * `newStatus`: Status nuevo
  * `comments`: Comentarios del analista (si aplica)
</ResponseField>

<Note>
  El array `changes` puede contener multiples secciones si varias cambiaron al mismo tiempo.
  Si `changes` esta vacio, significa que la notificacion no produjo cambios visibles en los status.
</Note>

***

### `kyb_document_submitted`

Se envia cuando el usuario final hace clic en "Enviar" y el expediente se entrega exitosamente. Este es el evento mas importante para tu flujo: indica que puedes proseguir con los siguientes pasos de tu lado.

```json theme={null}
{
  "type": "kyb_document_submitted",
  "folio": "NF-2026-001234",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "externalId": "EXT-999",
  "submittedAt": "2026-04-14T15:30:00.0000000Z"
}
```

<ResponseField name="folio" type="string">
  Folio definitivo asignado al expediente.
</ResponseField>

<ResponseField name="submittedAt" type="string (ISO 8601)">
  Fecha y hora UTC en que se envio el expediente.
</ResponseField>

***

## Tipos de seccion (`type`)

Cada seccion tiene un `type` que indica el tipo de documento o informacion que contiene.

| Tipo                        | Nombre visible                 | Descripcion                        |
| --------------------------- | ------------------------------ | ---------------------------------- |
| `ArticleIncorporation`      | Acta Constitutiva              | Acta constitutiva de la empresa    |
| `BankStatement`             | Estado de Cuenta               | Estado de cuenta bancario          |
| `ConditionsLetter`          | Carta Condiciones              | Carta de condiciones               |
| `PersonaFisica`             | Personas Fisicas               | Informacion de persona fisica      |
| `LegalRepresentative`       | Representantes Legales         | Datos del representante legal      |
| `ProofAddress`              | Comprobante de Domicilio       | Comprobante de domicilio           |
| `TaxInformations`           | Informacion Fiscal             | Constancia de situacion fiscal     |
| `Sucursal`                  | Sucursales                     | Informacion de sucursales          |
| `Extra`                     | Adicional                      | Documentos adicionales             |
| `Formulario`                | Formulario                     | Formularios personalizados         |
| `InformacionCrediticia`     | Informacion Crediticia         | Informacion crediticia             |
| `TermsCondition`            | Terminos y Condiciones         | Aceptacion de terminos             |
| `Facturacion`               | Facturacion                    | Informacion de facturacion         |
| `PoderesRepresentanteLegal` | Poderes de Representante Legal | Poderes notariales                 |
| `Accionistas`               | Accionistas                    | Informacion de accionistas         |
| `OrganosInternos`           | Organos Internos               | Organos internos de la empresa     |
| `PuntosContacto`            | Puntos de Contacto             | Puntos de contacto                 |
| `Docflow`                   | Docflow                        | Documentos gestionados por Docflow |

***

## Status de seccion (`status`)

Cada seccion pasa por los siguientes estados durante el proceso de validacion:

| Status             | Descripcion                                                           |
| ------------------ | --------------------------------------------------------------------- |
| `Pendiente`        | La seccion aun no ha sido cargada por el usuario                      |
| `EnRevision`       | El documento fue cargado y esta siendo procesado o revisado           |
| `RequiereAtencion` | El documento fue revisado y necesita correccion por parte del usuario |
| `Completado`       | El documento fue cargado y validado exitosamente                      |
| `Aceptado`         | El documento fue aceptado definitivamente por el analista             |
| `Rechazado`        | El documento fue rechazado                                            |

<Info>
  Los status `Completado` y `Aceptado` se consideran "terminados" para el calculo de progreso.
  Los status `Pendiente` y `EnRevision` se consideran "pendientes".
</Info>

***

## Objeto `progress`

El objeto `progress` aparece en los eventos `kyb_ready` y `kyb_section_updated`. Resume el avance general del expediente:

| Campo               | Tipo     | Descripcion                                  |
| ------------------- | -------- | -------------------------------------------- |
| `percentage`        | `number` | Porcentaje de completado (0-100)             |
| `total`             | `number` | Total de secciones en el expediente          |
| `completed`         | `number` | Secciones con status Completado o Aceptado   |
| `pending`           | `number` | Secciones con status Pendiente o EnRevision  |
| `inReview`          | `number` | Secciones en revision                        |
| `requiresAttention` | `number` | Secciones que requieren atencion del usuario |
| `rejected`          | `number` | Secciones rechazadas                         |

***

## Ejemplo completo de integracion

```html theme={null}
<iframe
  id="kyb-iframe"
  src="https://app.nufi.mx/guest/ACCESS_TOKEN?isiframe=true"
  style="width: 100%; height: 800px; border: none;">
</iframe>

<script>
  window.addEventListener('message', (event) => {
    if (!event.data?.type?.startsWith('kyb_')) return;

    const { type, folio, id, externalId, progress, changes, allSections, submittedAt } = event.data;

    switch (type) {
      case 'kyb_ready':
        console.log('KYB iframe listo');
        console.log(`Progreso inicial: ${progress.percentage}%`);

        // Renderizar estado inicial de secciones
        allSections.forEach(section => {
          updateSectionUI(section.name, section.status);
        });
        break;

      case 'kyb_section_updated':
        console.log('Seccion actualizada');

        // Actualizar solo las secciones que cambiaron
        changes.forEach(change => {
          console.log(`${change.name}: ${change.previousStatus} -> ${change.newStatus}`);
          updateSectionUI(change.name, change.newStatus);

          if (change.comments) {
            showComment(change.name, change.comments);
          }
        });

        // Actualizar barra de progreso
        updateProgressBar(progress.percentage);
        break;

      case 'kyb_document_submitted':
        console.log(`Expediente enviado. Folio: ${folio}`);
        console.log(`External ID: ${externalId}`);
        console.log(`Enviado: ${submittedAt}`);

        // Habilitar siguiente paso en tu flujo
        enableNextStep(folio, externalId);
        break;
    }
  });
</script>
```
