PS PrestaShop Intermedio

DataFirefly Push Pro — Guía completa

Instalar, configurar y operar DataFirefly Push Pro para PrestaShop 8 y 9: Web Push VAPID nativo, opt-in inteligente, 9 automatizaciones, constructor de campañas, segmentación, test A/B, atribución de ingresos, topics, bandeja de entrada y webhooks firmados con HMAC.

Actualizado Versión del módulo 1.2.0

DataFirefly Push Pro lleva las notificaciones push web nativas a PrestaShop 8 y 9 sin ningún servicio de terceros como OneSignal ni suscripción mensual. Esta guía cubre la instalación, la configuración inicial, las nueve automatizaciones, el constructor de campañas, la segmentación, el test A/B, la atribución de ingresos, los topics, la bandeja de entrada, los webhooks y la resolución de problemas.

1. Presentación y casos de uso

El módulo implementa de forma nativa el protocolo Web Push VAPID (RFC 8292) con cifrado aes128gcm del lado servidor. Las suscripciones se almacenan en tu base de datos PrestaShop, los envíos salen directamente desde tu alojamiento, ningún dato pasa por un servicio de terceros.

Casos de uso típicos:

  • Recuperación de carritos abandonados: tres recordatorios espaciados (1 h, 24 h, 72 h) sin depender del email del visitante.
  • Alertas de producto: vuelta a stock, bajada de precio, opt-in directamente en la ficha de producto.
  • Transaccional: confirmación de pedido, envío, solicitud de reseña tras la entrega.
  • Reactivación: cumpleaños, clientes inactivos, resumen de nuevos productos.
  • Campañas puntuales: rebajas, lanzamientos, Black Friday, con segmentación y test A/B.

2. Requisitos

  • PrestaShop 8.0 a 9.x
  • PHP 7.4 mínimo, 8.x recomendado
  • MySQL 5.7 mínimo o MariaDB 10.3
  • HTTPS obligatorio: la API Web Push de los navegadores solo funciona en un origen seguro. Solo localhost es la excepción para pruebas en desarrollo.
  • Un cron externo capaz de llamar a una URL HTTP cada 5 minutos (cron Linux, tareas programadas del alojamiento, cron nativo PrestaShop, etc.)
  • OpenSSL activado en PHP (usado para la generación de claves VAPID y el cifrado aes128gcm)

¿Por qué HTTPS? Todos los navegadores (Chrome, Firefox, Safari, Edge) se niegan a registrar un service worker o a conceder el permiso de notificaciones en una página HTTP. Es una limitación de los navegadores, no del módulo.

3. Instalación

  1. Descarga el ZIP dfpushnotifications-v1.2.0-phase3.zip desde tu área de cliente DataFirefly.
  2. Back office PrestaShop → Módulos → Gestor de módulos → Subir un módulo → selecciona el ZIP.
  3. Haz clic en Instalar. La instalación crea 14 tablas con prefijo ps_dfpush_*, genera un token de cron único y registra las pestañas del BO.
  4. Aparece un nuevo menú: Mejorar → DataFirefly Push con 8 pestañas (Dashboard, Campañas, Automatizaciones, Cola, Suscriptores, Topics, Webhooks, Ajustes).

4. Generación de claves VAPID

Las claves VAPID identifican tu servidor ante los push services de los navegadores (FCM, Mozilla autopush, Apple push). Se generan una sola vez y nunca deben cambiar tras la puesta en producción (si no, todos los suscriptores quedan inalcanzables).

  1. Ve a DataFirefly Push → Opt-in y Ajustes.
  2. Haz clic en Generar claves VAPID. El módulo crea un par de claves ECDSA P-256 almacenadas en la configuración PrestaShop.
  3. Introduce un VAPID subject: una URL mailto: con tu dirección de contacto técnico (ej. mailto:admin@tutienda.com). Es el identificador con el que los push services pueden contactar en caso de abuso.
  4. Activa el módulo mediante el interruptor Notificaciones push activadas.

Haz copia de seguridad de tus claves. Si regeneras las claves VAPID después del lanzamiento, todos tus suscriptores existentes serán rechazados por los push services con un código 410 Gone. Conserva una copia de seguridad de la base PrestaShop antes de cualquier manipulación de claves.

5. Configuración del opt-in

La pestaña Opt-in y Ajustes controla la visualización de la solicitud de permiso. Hay tres estilos disponibles:

  • Campana: una campana flotante abajo a la derecha. El usuario hace clic y el navegador muestra su solicitud nativa. La menos intrusiva.
  • Banner: un banner persistente arriba o abajo de la página con dos botones (permitir / rechazar).
  • Modal: una ventana modal centrada, más visible pero también más agresiva.

Disparadores

Para no mostrar la solicitud desde el primer segundo (alta tasa de rechazo), elige un disparador:

  • Retardo: mostrar tras X segundos (por defecto 15 s)
  • Scroll: mostrar tras X % de scroll de la página (por defecto 40 %)
  • Páginas: mostrar tras X páginas vistas en la sesión (por defecto 2)

Cooldown

Si el visitante cierra o rechaza la solicitud, un cooldown impide volver a proponerla durante N días (por defecto 7). Evita el efecto «popup acosador» que empuja a los usuarios a bloquear definitivamente el dominio.

Límite diario y horas de silencio

  • Máx por día: número máximo de notificaciones enviadas a un mismo suscriptor por día (por defecto 3). Más allá, la cola de envío rechaza silenciosamente los mensajes excedentes.
  • Horas de silencio: franja horaria durante la cual no se entrega ninguna notificación. Los mensajes en cola durante esa franja se reprograman para la mañana de la primera ventana no-silenciosa.

6. Cron: configuración y token

El cron pilota todas las operaciones diferidas: automatizaciones, cola de envío, vaciado de webhooks, limpieza. Debe llamarse cada 5 minutos mediante una URL HTTP protegida por token.

Token

Se genera un token único en la instalación. Para recuperarlo: DataFirefly Push → Automatizaciones, el banner azul de arriba muestra la URL completa para copiar y pegar en tu cron.

Ejemplo de cron Linux

*/5 * * * * curl -s "https://tutienda.com/module/dfpushnotifications/cron?token=TU_TOKEN" > /dev/null

Tareas ejecutadas en cada tick

  1. Reinicio de los contadores diarios (una vez al día, al cruzar la medianoche)
  2. Ejecución de las automatizaciones con retardo cumplido (carritos abandonados 1 h / 24 h / 72 h, cumpleaños, inactividad, nuevos productos, solicitudes de reseña programadas)
  3. Disparo de las campañas programadas cuya fecha ha llegado
  4. Vaciado de la cola de envío (hasta 50 notificaciones por lote por defecto, configurable)
  5. Vaciado de la cola de webhooks (hasta 100 por lote)
  6. Limpieza de entradas antiguas (sent > 60 días, webhook log > 30 días)

La respuesta del cron es un JSON detallando cada paso:

{
  "success": true,
  "tasks": {
    "reset_counters": "ok",
    "triggers": { "abandoned_1h": 12, "abandoned_24h": 4, "birthday": 2, "inactivity": 38 },
    "scheduled_campaigns": 1,
    "queue": { "processed": 50, "sent": 47, "failed": 2, "expired": 1 },
    "webhooks": { "processed": 8, "sent": 8, "failed": 0, "dropped": 0 },
    "cleanup": "ok"
  },
  "duration_ms": 1842
}

Si tu alojamiento no dispone de cron, configura un servicio gratuito de terceros (cron-job.org, EasyCron, cronless) apuntando a la misma URL cada 5 minutos.

7. Automatizaciones: los 9 disparadores

Desactivadas por defecto, actívalas una por una desde DataFirefly Push → Automatizaciones. Cada tarjeta muestra el título, el cuerpo y las estadísticas. Haz clic en Editar para personalizar el texto y las opciones.

Variables disponibles

Según el disparador, puedes insertar en el título y el cuerpo:

  • {first_name}: nombre del cliente (vacío para visitantes anónimos)
  • {cart_total}: importe del carrito abandonado, formateado con la moneda
  • {order_reference}: referencia del pedido
  • {order_total}: importe total del pedido
  • {product_name}: nombre del producto (vuelta a stock, bajada de precio)
  • {product_price}: precio actual del producto
  • {products_count}: número de nuevos productos (resumen)

Carrito abandonado (3 recordatorios)

Tres disparadores independientes: abandoned_cart_1h, abandoned_cart_24h, abandoned_cart_72h. El módulo registra cada modificación de carrito en ps_dfpush_cart_watch y marca el carrito como convertido en cuanto se valida un pedido. El cron envía cada recordatorio al madurar el plazo, salvo si el carrito se convirtió entretanto.

Vuelta a stock

En la ficha de producto aparece automáticamente un botón Avísame cuando vuelva a estar disponible cuando el producto está agotado. El suscriptor hace clic, se le solicita el opt-in push si es necesario, luego el módulo registra un watcher en ps_dfpush_product_watch. En cuanto un cambio de stock hace que la cantidad disponible supere 0, el watcher es notificado y marcado como procesado.

Bajada de precio

Mismo principio con el botón Avísame si baja el precio. El watcher guarda el precio de referencia en el momento del opt-in. La notificación se envía en cuanto una actualización de producto hace que el precio caiga por debajo del 99 % del precio de referencia (un umbral que evita disparos parasitarios por redondeos).

Confirmación de pedido

Disparada por el hook actionValidateOrder. Enviada inmediatamente, sin respetar las horas de silencio (transaccional). Enlace directo a la página de detalle del pedido.

Envío

Disparada por actionOrderStatusUpdate en cuanto el estado pasa a uno marcado como shipped en PrestaShop. Enlace al detalle del pedido (que contiene el tracking si usas un módulo de seguimiento).

Solicitud de reseña

Programada X días tras el paso del pedido a un estado de entrega (por defecto 7 días, configurable en el JSON config del disparador). La notificación se encola con un scheduled_at futuro y el cron la entrega cuando llega la hora.

Cumpleaños

El cron lee el campo birthday del cliente PrestaShop y envía la notificación el día D a la hora configurada. Un deduplicador evita varios envíos el mismo año.

Inactividad

Identifica los suscriptores cuya last_visit supera los N días (por defecto 30). Para evitar el acoso, un mismo suscriptor se notifica como máximo una vez cada 30 días por este disparador.

Nuevos productos

Resumen diario enviado a una hora configurable (por defecto 10 h). El módulo agrega los productos creados en las últimas 24 horas y envía una notificación mencionando el nombre del primero y el total. Ideal para una tienda que añade catálogo con regularidad.

8. Constructor de campañas

Para operaciones puntuales: DataFirefly Push → Campañas → Nueva campaña. El formulario se divide en cinco secciones.

Contenido

  • Nombre de campaña: nombre interno (nunca se muestra a los suscriptores)
  • Título de notificación: 80 caracteres máx
  • Cuerpo: 250 caracteres máx
  • URL de clic: a dónde redirige el clic
  • URL del icono: logo pequeño (por defecto el logo de tu tienda)
  • URL de imagen grande: imagen hero, 1024 × 512 recomendado (solo Chrome)
  • URL del badge: PNG monocromo 72 × 72 (Android)

Botones de acción

Hasta dos botones con su etiqueta y URL. Aparecen bajo la notificación en Chrome desktop y Android. Ideal para ofrecer varios CTA (Ver la oferta / Ignorar).

Audiencia

Ver la sección Segmentación más abajo.

Programación y entrega

  • Enviar el: fecha / hora del envío. Vacío = inmediato (en el próximo vaciado del cron).
  • Urgencia: very-low, low, normal, high. Influye en la prioridad del lado push service.
  • TTL: tiempo de vida en segundos (por defecto 86400 = 24 h). Si el navegador del suscriptor está offline más tiempo, la notificación expira.
  • Requerir interacción: notificación persistente hasta clic o cierre manual (solo Chrome).

9. Segmentación

Combinable con Y lógico. Todos los criterios vacíos = sin restricción.

Criterio Efecto
Idiomas El suscriptor habla al menos uno de estos idiomas (casillas marcadas)
Países País detectado en la inscripción (basado en idioma / IP / geo)
Dispositivos móvil / escritorio / tablet (detectado en la inscripción)
Navegadores Chrome, Firefox, Safari, Edge, Opera, Samsung Internet
Grupos de clientes El suscriptor está vinculado a un cliente PrestaShop en al menos uno de los grupos
Historial de compra Cualquiera (por defecto), Ha comprado, Nunca ha comprado
Activo en los últimos N días Última visita hace menos de N días (basado en ps_dfpush_customer_activity)

El botón Previsualizar tamaño de audiencia calcula vía AJAX el número exacto de suscriptores que coinciden. Útil para comprobar que la segmentación no es demasiado restrictiva antes del envío.

10. Test A/B

En cada campaña, el campo % de audiencia para la variante B define la parte de audiencia que recibe la variante B (de 0 a 50). El reparto es determinista: para un id_subscriber dado, el suscriptor siempre recibe la misma variante (basado en id_subscriber % 100 < split).

La variante B sobrescribe solo los campos rellenados. Por ejemplo, puedes cambiar solo el título o probar solo una imagen. Las estadísticas se almacenan por separado:

  • stats_delivered / stats_clicked / stats_revenue: variante A
  • stats_b_delivered / stats_b_clicked / stats_b_revenue: variante B

Las columnas aparecen en la lista de campañas con un badge A/B junto al nombre.

11. Atribución de ingresos

Mecanismo clave del módulo: vincular los pedidos con las notificaciones que los desencadenaron.

Flujo

  1. El módulo envía una notificación con un track_token único (32 caracteres hex) en el payload.
  2. El service worker intercepta el clic y redirige a /module/dfpushnotifications/track?t=TOKEN&click=1&u=URL.
  3. El controlador track deposita una cookie dfpush_attr=TOKEN (30 días, SameSite=Lax) y redirige a la URL final.
  4. El cliente navega, añade al carrito, valida el pedido.
  5. En el hook actionValidateOrder, el AttributionService lee la cookie, encuentra la notificación en ps_dfpush_notifications, escribe id_order + revenue + currency en la fila.
  6. El servicio incrementa stats_revenue (o stats_b_revenue según la variante) en la campaña o el disparador, dispara el webhook order.attributed, luego borra la cookie.

Límites de la atribución

  • Ventana fija de 30 días. Más allá, la atribución ya no se aplica.
  • Una sola cookie por suscriptor. Si el usuario hace clic en una segunda notificación antes de comprar, es la última la que se atribuye (modelo last click).
  • La atribución requiere que el clic y el pedido ocurran en el mismo navegador (la cookie está ligada al navegador).
  • Un pedido ya atribuido no puede volver a atribuirse (el campo id_order > 0 bloquea la doble contabilización).

12. Topics

Los topics son canales de suscripción temáticos que los clientes activan desde su cuenta. Ejemplo: Promociones, Nuevos productos, Alertas de stock. Un suscriptor que solo marca Promociones únicamente recibirá las campañas dirigidas a ese topic.

Crear un topic

  1. DataFirefly Push → Topics → Nuevo topic
  2. Código: identificador interno sin espacios (ej. flash_deals)
  3. Orden de visualización: posición en la lista mostrada al cliente
  4. Activo: visible para los clientes
  5. Opt-in por defecto: premarcado al inscribirse
  6. Traducciones: un nombre y una descripción por idioma instalado

Apuntar a un topic en una campaña

La segmentación incluye un criterio Topics en el resolvedor. Para activarlo desde la UI: actualmente solo vía JSON personalizado (la casilla Topics llega en una actualización menor). Los suscriptores sin ningún topic suscrito reciben todo (compatibilidad retroactiva).

13. Bandeja de entrada in-app

El endpoint /module/dfpushnotifications/inbox devuelve las 20 últimas notificaciones del suscriptor actual en JSON. El frontend abre esta bandeja mediante la modal unificada accesible desde la cuenta del cliente (tarjeta Notificaciones push).

La modal también muestra el estado de suscripción (con botón suscribir / desuscribir) y la lista de topics. Para llamarla manualmente desde tu plantilla:

// Abrir la modal
window.dfpush.openManagePopup();

// Comprobar el estado de suscripción
const isOn = window.dfpush.isSubscribed();

14. Webhooks

Los webhooks envían los eventos del módulo a Zapier, Make, n8n o tu propio backend. Cada webhook está firmado con HMAC-SHA256 sobre el cuerpo bruto de la solicitud.

Crear un webhook

  1. DataFirefly Push → Webhooks → Nuevo webhook
  2. URL: tu endpoint (HTTPS recomendado)
  3. Secret: generado automáticamente, cópialo del lado receptor
  4. Eventos: marca los eventos a entregar entre los 8 disponibles
  5. Haz clic en Enviar ping de prueba para comprobar que tu endpoint responde 2xx

Eventos disponibles

  • subscriber.subscribed: nuevo opt-in
  • subscriber.unsubscribed: cancelación de suscripción
  • subscriber.expired: el push service devolvió 410 Gone
  • notification.sent: notificación entregada con éxito
  • notification.clicked: clic registrado
  • notification.failed: fallo definitivo tras 3 intentos
  • campaign.sent: campaña finalizada
  • order.attributed: pedido vinculado a una notificación

Formato del payload

{
  "event": "notification.clicked",
  "timestamp": "2026-05-28T14:32:18+00:00",
  "shop": 1,
  "data": {
    "id_subscriber": 482,
    "id_campaign": 12,
    "id_trigger": 0,
    "id_notification": 9182,
    "track_token": "abc123...",
    "url": "https://tutienda.com/promociones",
    "ab_variant": "A"
  }
}

Cabeceras HTTP enviadas

  • Content-Type: application/json
  • X-DfPush-Event: notification.clicked
  • X-DfPush-Signature: sha256=<hex>
  • X-DfPush-Timestamp: 1748443938
  • User-Agent: DataFireflyPush/1.2

Verificar la firma del lado receptor

Ejemplo PHP:

$body     = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, $TU_SECRET);
$received = explode('=', $_SERVER['HTTP_X_DFPUSH_SIGNATURE'])[1] ?? '';
if (!hash_equals($expected, $received)) {
    http_response_code(401);
    exit;
}
// Firma válida, procesar el payload
$payload = json_decode($body, true);

Reintentos y drop

Si tu endpoint responde algo distinto de 2xx, el módulo reintenta con backoff exponencial hasta 5 intentos. Tras lo cual, el log se marca dropped y el evento se pierde. Los logs sent y dropped se purgan tras 30 días.

15. Multi-tienda y multilingüe

Todos los suscriptores, campañas, automatizaciones, topics y webhooks están vinculados a un id_shop. En multi-tienda:

  • Selecciona la tienda destino en el selector del back-office antes de crear una campaña o automatización
  • El cron es único pero filtra automáticamente por tienda
  • Las claves VAPID se comparten entre tiendas (un único par para todas)

Del lado idioma: el módulo se entrega en ES, EN, FR, DE e IT. El idioma del suscriptor se detecta en la inscripción y se almacena. Puedes segmentar por idioma en las campañas.

16. RGPD y buenas prácticas

  • Consentimiento: la suscripción se basa en el opt-in nativo del navegador, que es una prueba de consentimiento compatible con el RGPD.
  • Datos personales: el módulo almacena el endpoint Web Push, la IP en el momento de la inscripción, el user-agent, el idioma y el país. Ninguna transmisión a terceros.
  • Cancelación de suscripción: un clic en el botón Desuscribir de la modal o la desactivación de las notificaciones en el navegador pone al suscriptor en estado revoked.
  • Derecho al olvido: la supresión de una cuenta de cliente en el BO también elimina sus suscriptores vinculados.
  • Horas de silencio: por defecto 22 h – 8 h. Adapta a tu objetivo (B2B = horario de oficina, B2C = tarde).
  • Límite diario: por defecto 3/día. Más allá, tasa de baja muy elevada.

17. Resolución de problemas

El opt-in no aparece

  • Comprueba que tu sitio está en HTTPS (no HTTP).
  • Comprueba que las claves VAPID están generadas (Ajustes).
  • Comprueba que el interruptor Notificaciones push activadas está encendido.
  • Abre la consola del navegador (F12) y busca errores del lado dfpush-frontend.js.
  • Si ya has rechazado o ignorado la solicitud, el cooldown bloquea durante N días. Borra las cookies del dominio para reiniciar, o cambia de navegador para probar.

El cron no se ejecuta

  • Llama a la URL manualmente en tu navegador: deberías ver un JSON con success: true. Si ves un 403 invalid_token, el token está mal copiado.
  • Comprueba la última ejecución en el panel (Dashboard, bloque Sistema).
  • En algunos alojamientos, el timeout cURL de los crones es de 30 s. Si la cola es muy grande, aumenta la frecuencia del cron a cada 1 o 2 minutos para procesar lotes más pequeños.

Las notificaciones no se envían

  • Pestaña Cola: si las filas están en pending, es que el cron no se ha ejecutado desde su creación.
  • Si están en failed, haz clic en la fila para ver el código HTTP y el mensaje de error del push service.
  • 410 Gone = la suscripción ya no es válida (el usuario se ha dado de baja o ha borrado su navegador). El módulo marca automáticamente al suscriptor como expired.
  • 429 Too Many Requests = rate limit del lado push service. El módulo reintenta automáticamente con backoff.

Los pedidos no se atribuyen

  • Comprueba que las cookies de terceros no están bloqueadas por el navegador del cliente (modo privado, algunos anti-trackers).
  • La cookie expira a los 30 días: un pedido realizado 31 días después del clic no se atribuirá.
  • Si ves id_order = 0 en ps_dfpush_notifications mientras se ha realizado el pedido, comprueba que los hooks actionValidateOrder estén bien registrados (Módulos → Hooks → actionValidateOrder).

Error SQL con «LIMIT 1 LIMIT 1»

Bug interno corregido en 1.2.0 (Db::getValue y Db::getRow añaden automáticamente su propio LIMIT 1). Si sigues viendo este error, verifica que tienes instalada la última versión del módulo.

18. Preguntas frecuentes

¿Cuántos suscriptores puede gestionar el módulo?

El módulo no tiene límite codificado. En la práctica, el factor limitante es el tiempo de ejecución del cron: en un alojamiento compartido estándar, cuenta con unos 50 envíos por minuto (limitado por los push services). Para 10 000 suscriptores, prevé un cron cada 1 o 2 minutos durante el envío de una gran campaña.

¿Safari iOS está realmente excluido?

Safari iOS soporta Web Push desde iOS 16.4 pero solo para sitios instalados como PWA en la pantalla de inicio. En un Safari clásico, la API Notification devuelve undefined. Es una limitación de Apple, no del módulo.

¿Puedo migrar mis suscriptores desde OneSignal o Firebase?

No. Los endpoints push están ligados al par de claves VAPID utilizado en la inscripción. Si cambias el par, las suscripciones existentes quedan inválidas. Una migración requeriría reinscripción de los usuarios.

¿El módulo funciona en PrestaShop 1.7?

No, solo PrestaShop 8.0 a 9.x. La versión 1.7 utiliza una arquitectura admin diferente que requeriría un fork dedicado.

¿Puedo personalizar el service worker?

Sí, el archivo views/js/sw-template.js es renderizado por el controlador swjs.php y puede extenderse. Atención: cualquier modificación del service worker requiere un nuevo register() del lado cliente. Los visitantes antiguos conservarán la versión anterior hasta que el navegador detecte el cambio (generalmente 24 h).

¿Cómo exportar los suscriptores?

Pestaña Suscriptores, botón Exportar CSV. El archivo contiene endpoint, navegador, dispositivo, idioma, país, fecha de inscripción y contadores de envío / clics.

Soporte

Para cualquier pregunta no cubierta por esta guía, contacta con el soporte DataFirefly. Para reportar un bug, adjunta el detalle de tu versión PrestaShop, PHP y el contenido de la respuesta JSON del cron.

¿Te ha resultado útil esta página?

¿Sigues atascado? Contacta con soporte