Skip to main content
Esta guía es específica de Magento 2. Para entender el widget en general —qué es, cómo se crea el canal, qué hace la identidad firmada— empezá por la guía base:

Widget de chat web

El canal Web de punta a punta: snippet, identidad JWT y personalización.

Los dos niveles de integración

Magento admite las dos formas, y conviene decidir cuál necesita el proyecto antes de escribir una línea de código:
Si el objetivo es sólo atender consultas, el Nivel 1 alcanza. El Nivel 2 se justifica cuando querés que el chat del sitio y el de WhatsApp sean la misma persona, o que un cliente retome su conversación desde otro dispositivo.

Nivel 1 — Instalación sin código

1

Crear el canal Web en MINDO

En MINDO, Configuración → Canales → Widget de chat web → + Agregar canal Web. Copiá el snippet que te muestra.
Si el Magento tiene varios store views (por marca, país o idioma), creá un canal por store view. Cada uno tiene su color, su agente y su bandeja, y las conversaciones no se mezclan.
2

Pegarlo en el admin de Magento

En el admin: Content → Design → Configuration. Editá la fila del store view donde querés el chat (no el default, si vas a diferenciar por store view) y abrí HTML Head → Scripts and Style Sheets.
Si preferís que cargue al final del documento, usá Footer → Miscellaneous HTML en lugar de HTML Head. Da lo mismo para el widget: el script es async y autocontenido.
3

Limpiar caché y verificar

Entrá al sitio y mirá la burbuja abajo a la derecha. Si no aparece, abrí la consola del navegador: el error más común es un data-mindo-token mal copiado.
Con esto ya está: cada visitante que escriba crea un chat con canal Web en el Inbox.

Nivel 2 — Identificar clientes logueados

Acá es donde Magento tiene una particularidad que hay que respetar, y es la razón por la que este nivel necesita un módulo.

Por qué no se puede hacer de la forma simple

La guía base explica que la identidad viaja en un atributo del <script>:
En Magento eso está mal y es peligroso. Magento sirve el catálogo y las páginas CMS desde Full Page Cache / Varnish: el mismo HTML para todos los visitantes. Si renderizás el token en un .phtml, se cachea el JWT del primer cliente que pasó y se le sirve a todos los siguientes.El modo de falla es silencioso: la firma es válida —la generó tu servidor, con el secreto correcto—, así que MINDO no tiene forma de detectarlo. Simplemente trata a todos los visitantes como el mismo cliente y mezcla las conversaciones en un solo contacto. Sin un error en los logs.
Es el mismo motivo por el que Magento no renderiza “Bienvenido, Ana” directo en el HTML. Y la solución es la misma que ya usa Magento para eso.

La solución: private content (customer data sections)

Magento tiene un mecanismo pensado exactamente para esto: datos por cliente sobre páginas cacheadas. El HTML se cachea igual para todos; los datos personales llegan después, por una petición aparte que nunca se cachea.

El módulo, archivo por archivo

Todo vive en app/code/Mindo/ChatWidget/.
1

Guardar el secreto del canal

El Secret HMAC del canal es un secreto de servidor. Nunca en el theme, nunca en un .phtml, nunca en un repositorio.La forma limpia es una config encriptada. Declarala en etc/adminhtml/system.xml con el backend model de Magento para valores encriptados:
Y cargalo por CLI, sin que quede en la base en claro:
Con --lock-env el valor queda en app/etc/env.php, que normalmente está fuera del repositorio. Es la opción más simple si no querés armar el system.xml.
2

Instalar la librería de JWT

MINDO espera HS256, que es lo que esta librería usa por defecto con un secreto de texto.
3

La clase que firma

app/code/Mindo/ChatWidget/CustomerData/MindoIdentity.php
El teléfono tiene que estar en formato internacional (+5491122334455). Es el campo que une este contacto con el de WhatsApp, y MINDO lo descarta si no logra normalizarlo. Magento guarda el telephone tal como lo tipeó el cliente, así que si el checkout no lo valida, conviene normalizarlo acá antes de firmarlo.
4

Registrar la section

app/code/Mindo/ChatWidget/etc/frontend/di.xml — le dice a Magento qué clase responde por esta section:
app/code/Mindo/ChatWidget/etc/frontend/sections.xml — cuándo se invalida:
Sin el sections.xml la section queda cacheada del lado del cliente y el token no se refresca al iniciar o cerrar sesión: el chat seguiría mostrando al cliente anterior hasta que venza el token.
5

El JavaScript que se lo pasa al widget

app/code/Mindo/ChatWidget/view/frontend/web/js/identity.js
Y el template que lo engancha, view/frontend/templates/identity.phtml:
declarado en view/frontend/layout/default.xml:
6

Habilitar y verificar

Para verificar, con un cliente logueado:
  1. En la consola del navegador, window.Mindo tiene que existir.
  2. En la pestaña Network, buscá /customer/section/load/: la respuesta debe traer mindo-identity con un identity que empiece en eyJ.
  3. En MINDO, escribí un mensaje desde el chat: el contacto tiene que aparecer con nombre real, no como “Visitante ####”.
Si hiciste el Nivel 1 y después el módulo, sacá el snippet del admin o hacé que el módulo no lo renderice. Con los dos activos se cargan dos widgets y aparecen dos burbujas.

Preguntas frecuentes

Todo el lado PHP es idéntico: la clase que firma, el di.xml y el sections.xml no cambian, porque las sections son un mecanismo del backend de Magento, no del theme.Lo que cambia es el JavaScript: Hyvä no usa Knockout ni el módulo Magento_Customer/js/customer-data, así que la lectura de la section se hace con su propio helper sobre Alpine. La lógica es la misma —leer mindo-identity y llamar a window.Mindo.setUser()— pero confirmá la API contra la versión de Hyvä del proyecto antes de escribirlo.Como alternativa independiente del theme, Magento dispara el evento private-content-loaded en el documento cuando las sections se actualizan; podés engancharte ahí y leer el valor del storage del navegador.
El Nivel 1 sí, igual que en cualquier sitio: es un <script> en el layout.El Nivel 2 también es posible, pero no hay sections: habría que exponer un endpoint propio que devuelva el JWT del cliente logueado y llamarlo desde el front. Tené en cuenta que Magento 1 está fuera de soporte desde 2020.
Porque lo cachea el Full Page Cache y termina sirviéndole el token de un cliente a todos los demás. Está explicado arriba, en “Por qué no se puede hacer de la forma simple”. Es el único punto de esta guía que, si se ignora, produce un problema de privacidad real y silencioso.
El sections.xml invalida mindo-identity en el logout, la section vuelve con identity: null y el JS llama a window.Mindo.clearUser(). El visitante pasa a anónimo y el chat sigue funcionando.
No es obligatorio. Podés dejar el snippet cargado desde el admin (Nivel 1) y que el módulo se ocupe únicamente de la identidad. Es incluso más cómodo: quien administra la tienda puede cambiar de canal sin tocar código.
En el ejemplo dura 24 horas, y se emite de nuevo en cada refresco de la section. No hay que renovarlo a mano.El único límite duro es que MINDO rechaza cualquier exp a más de 7 días: un token con vencimiento más lejano se considera inválido y el visitante queda anónimo, sin ningún error visible.
La firma falla en silencio a propósito —un widget caído es peor que un dato faltante—. Revisá en este orden:
  1. Que el secreto sea el del mismo canal que el token del snippet.
  2. Que /customer/section/load/ devuelva identity con un valor, y no null.
  3. Que el exp esté en segundos y a menos de 7 días.
  4. Que el claim se llame sub y el algoritmo sea HS256.