PS PrestaShop Intermédiaire

DataFirefly Push Pro — Guide complet

Installer, configurer et exploiter DataFirefly Push Pro pour PrestaShop 8 et 9 : Web Push VAPID natif, opt-in intelligent, 9 automatisations, builder de campagnes, segmentation, A/B testing, attribution du chiffre d'affaires, topics, inbox et webhooks signés HMAC.

Mis à jour Version du module 1.2.0

DataFirefly Push Pro apporte les notifications push web natives à PrestaShop 8 et 9 sans aucun service tiers de type OneSignal ni abonnement mensuel. Ce guide couvre l’installation, la configuration initiale, les neuf automatisations, le builder de campagnes, la segmentation, l’A/B testing, l’attribution du chiffre d’affaires, les topics, l’inbox, les webhooks et le dépannage.

1. Présentation et cas d’usage

Le module implémente nativement le protocole Web Push VAPID (RFC 8292) avec chiffrement aes128gcm côté serveur. Les abonnements sont stockés dans votre base PrestaShop, les envois partent directement de votre hébergement, aucune donnée ne transite par un service tiers.

Cas d’usage typiques :

  • Récupération de paniers abandonnés : trois relances espacées (1 h, 24 h, 72 h) sans dépendre de l’e-mail du visiteur.
  • Alertes produit : retour en stock, baisse de prix, opt-in directement sur la fiche produit.
  • Transactionnel : confirmation de commande, expédition, demande d’avis après livraison.
  • Réengagement : anniversaire, clients inactifs, digest des nouveaux produits.
  • Campagnes ponctuelles : soldes, lancements, Black Friday, avec segmentation et A/B testing.

2. Pré-requis

  • PrestaShop 8.0 à 9.x
  • PHP 7.4 minimum, 8.x recommandé
  • MySQL 5.7 minimum ou MariaDB 10.3
  • HTTPS obligatoire : l’API Web Push des navigateurs ne fonctionne que sur une origine sécurisée. Seul localhost fait exception pour les tests en développement.
  • Un cron externe capable d’appeler une URL HTTP toutes les 5 minutes (cron Linux, tâches planifiées de l’hébergeur, cron PrestaShop natif, etc.)
  • OpenSSL activé en PHP (utilisé pour la génération des clés VAPID et le chiffrement aes128gcm)

Pourquoi HTTPS ? Tous les navigateurs (Chrome, Firefox, Safari, Edge) refusent d’enregistrer un service worker ou d’accorder la permission notifications sur une page HTTP. C’est une limitation des navigateurs, pas du module.

3. Installation

  1. Téléchargez le ZIP dfpushnotifications-v1.2.0-phase3.zip depuis votre espace client DataFirefly.
  2. Back-office PrestaShop → Modules → Gestionnaire de modules → Téléverser un module → sélectionnez le ZIP.
  3. Cliquez sur Installer. L’installation crée 14 tables sous le préfixe ps_dfpush_*, génère un token cron unique et enregistre les onglets BO.
  4. Un nouveau menu apparaît : Améliorer → DataFirefly Push avec 8 onglets (Dashboard, Campaigns, Automations, Queue, Subscribers, Topics, Webhooks, Settings).

4. Génération des clés VAPID

Les clés VAPID identifient votre serveur auprès des push services des navigateurs (FCM, Mozilla autopush, Apple push). Elles sont générées une seule fois et ne doivent jamais changer après mise en production (sinon tous les abonnés deviennent injoignables).

  1. Allez dans DataFirefly Push → Opt-in & Settings.
  2. Cliquez sur Generate VAPID keys. Le module crée une paire de clés ECDSA P-256 stockée dans la configuration PrestaShop.
  3. Saisissez un VAPID subject : une URL mailto: avec votre adresse de contact technique (ex. mailto:admin@votreshop.com). C’est l’identifiant que les push services peuvent contacter en cas d’abus.
  4. Activez le module via le toggle Push notifications enabled.

Sauvegardez vos clés. Si vous régénérez les clés VAPID après le lancement, tous vos abonnés existants seront rejetés par les push services avec un code 410 Gone. Conservez une sauvegarde de la base PrestaShop avant toute manipulation des clés.

5. Configuration de l’opt-in

L’onglet Opt-in & Settings contrôle l’affichage de la demande de permission. Trois styles sont disponibles :

  • Bell : une cloche flottante en bas à droite. L’utilisateur clique, puis le navigateur affiche sa demande native. Le moins intrusif.
  • Banner : une bannière persistante en haut ou en bas de page avec deux boutons (autoriser / refuser).
  • Modal : une fenêtre modale centrée, plus visible mais aussi plus agressive.

Déclencheurs

Pour ne pas afficher la demande dès la première seconde (taux de refus élevé), choisissez un déclencheur :

  • Delay : afficher après X secondes (par défaut 15 s)
  • Scroll : afficher après X % de scroll de la page (par défaut 40 %)
  • Pages : afficher après X pages vues dans la session (par défaut 2)

Cooldown

Si le visiteur ferme ou refuse la demande, un cooldown empêche de la lui repropose pendant N jours (par défaut 7). Ça évite l’effet « popup harceleur » qui pousse les utilisateurs à bloquer définitivement le domaine.

Plafond journalier et heures de silence

  • Max per day : nombre maximum de notifications envoyées à un même abonné par jour (par défaut 3). Au-delà, la file d’envoi rejette silencieusement les messages excédentaires.
  • Quiet hours : plage horaire pendant laquelle aucune notification n’est délivrée. Les messages enfilés pendant cette plage sont reprogrammés au matin de la première fenêtre non-silencieuse.

6. Cron : configuration et token

Le cron pilote toutes les opérations différées : automatisations, file d’envoi, drainage des webhooks, nettoyage. Il doit être appelé toutes les 5 minutes via une URL HTTP sécurisée par token.

Token

Un token unique est généré à l’installation. Pour le récupérer : DataFirefly Push → Automations, le bandeau bleu en haut affiche l’URL complète à copier-coller dans votre cron.

Exemple de cron Linux

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

Tâches exécutées à chaque tick

  1. Réinitialisation des compteurs journaliers (une fois par jour, au franchissement de minuit)
  2. Exécution des automatisations à délai mature (paniers abandonnés 1 h / 24 h / 72 h, anniversaire, inactivité, nouveaux produits, demandes d’avis programmées)
  3. Déclenchement des campagnes programmées dont la date est arrivée
  4. Drainage de la file d’envoi (jusqu’à 50 notifications par batch par défaut, configurable)
  5. Drainage de la file des webhooks (jusqu’à 100 par batch)
  6. Nettoyage des entrées anciennes (sent > 60 jours, webhook log > 30 jours)

La réponse du cron est un JSON détaillant chaque étape :

{
  "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 votre hébergeur ne dispose pas de cron, configurez un service tiers gratuit (cron-job.org, EasyCron, cronless) en pointant sur la même URL toutes les 5 minutes.

7. Automatisations : les 9 triggers

Désactivées par défaut, à activer une par une depuis DataFirefly Push → Automations. Chaque carte affiche le titre, le corps et les stats. Cliquez sur Edit pour personnaliser le wording et les options.

Variables disponibles

Selon le trigger, vous pouvez insérer dans le titre et le corps :

  • {first_name} : prénom du client (vide pour les visiteurs anonymes)
  • {cart_total} : montant du panier abandonné, formaté avec la devise
  • {order_reference} : référence de commande
  • {order_total} : montant total de la commande
  • {product_name} : nom du produit (retour en stock, baisse de prix)
  • {product_price} : prix actuel du produit
  • {products_count} : nombre de nouveaux produits (digest)

Panier abandonné (3 relances)

Trois triggers indépendants : abandoned_cart_1h, abandoned_cart_24h, abandoned_cart_72h. Le module enregistre chaque modification de panier dans ps_dfpush_cart_watch et marque le panier converti dès la validation d’une commande. Le cron envoie chaque relance à maturité, sauf si le panier a été converti entre-temps.

Retour en stock

Sur la fiche produit, un bouton Notify me when back in stock apparaît automatiquement quand le produit est en rupture. L’abonné clique, son opt-in push est demandé si nécessaire, puis le module enregistre un watcher dans ps_dfpush_product_watch. Dès qu’une modification de stock ramène la quantité disponible au-dessus de 0, le watcher est notifié et marqué comme traité.

Baisse de prix

Même principe avec le bouton Notify me on price drop. Le watcher stocke le prix de référence au moment de l’opt-in. La notification est envoyée dès qu’une mise à jour produit fait passer le prix sous 99 % du prix de référence (un seuil qui évite les déclenchements parasites lors des arrondis).

Confirmation de commande

Déclenchée par le hook actionValidateOrder. Envoyée immédiatement, sans respect des heures de silence (transactionnel). Lien direct vers la page de détail de la commande.

Expédition

Déclenchée par actionOrderStatusUpdate dès que le statut passe à un état marqué shipped dans PrestaShop. Lien vers le détail de commande (qui contient le tracking si vous utilisez un module de suivi).

Demande d’avis

Programmée X jours après le passage de la commande à un état delivery (par défaut 7 jours, configurable dans le JSON config du trigger). La notification est enfilée avec un scheduled_at futur, le cron la délivre quand l’heure arrive.

Anniversaire

Le cron lit le champ birthday du client PrestaShop et envoie la notification le jour J à l’heure configurée. Un dédoublonneur évite plusieurs envois la même année.

Inactivité

Identifie les abonnés dont last_visit remonte à plus de N jours (par défaut 30). Pour éviter le harcèlement, un même abonné n’est notifié au maximum qu’une fois tous les 30 jours via ce trigger.

Nouveaux produits

Digest quotidien envoyé à une heure configurable (par défaut 10 h). Le module agrège les produits créés dans les 24 dernières heures et envoie une notification mentionnant le nom du premier et le nombre total. Idéal pour une boutique qui ajoute régulièrement du catalogue.

8. Builder de campagnes

Pour les opérations ponctuelles : DataFirefly Push → Campaigns → New campaign. Le formulaire est divisé en cinq sections.

Contenu

  • Campaign name : nom interne (jamais affiché aux abonnés)
  • Notification title : 80 caractères max
  • Body : 250 caractères max
  • Click URL : où le clic redirige
  • Icon URL : petit logo (par défaut votre logo boutique)
  • Large image URL : image hero, 1024 × 512 recommandé (Chrome uniquement)
  • Badge URL : PNG monochrome 72 × 72 (Android)

Boutons d’action

Jusqu’à deux boutons avec leur libellé et URL. Ils apparaissent sous la notification sur Chrome desktop et Android. Idéal pour proposer plusieurs CTA (Voir l’offre / Ignorer).

Audience

Voir la section Segmentation ci-après.

Schedule & delivery

  • Send at : date / heure de l’envoi. Vide = immédiat (à la prochaine drainage du cron).
  • Urgency : very-low, low, normal, high. Influe sur la priorité côté push service.
  • TTL : temps de vie en secondes (par défaut 86400 = 24 h). Si le navigateur de l’abonné est hors ligne plus longtemps, la notification expire.
  • Require interaction : notification persistante jusqu’à clic ou fermeture manuelle (Chrome uniquement).

9. Segmentation

Combinable avec ET logique. Tous les critères vides = aucune restriction.

Critère Effet
Languages L’abonné parle au moins une de ces langues (cases cochées)
Countries Pays détecté à l’inscription (basé sur la langue / IP / geo)
Devices mobile / desktop / tablet (détecté à l’inscription)
Browsers Chrome, Firefox, Safari, Edge, Opera, Samsung Internet
Customer groups L’abonné est lié à un client PrestaShop dans au moins un des groupes
Purchase history Any (défaut), Has bought, Never bought
Active within N days Dernière visite il y a moins de N jours (basé sur ps_dfpush_customer_activity)

Le bouton Preview audience size calcule en AJAX le nombre exact d’abonnés correspondants. Utile pour vérifier qu’un ciblage n’est pas trop restrictif avant l’envoi.

10. A/B testing

Sur chaque campagne, le champ % of audience for variant B définit la part de l’audience qui reçoit la variante B (de 0 à 50). La répartition est déterministe : pour un id_subscriber donné, l’abonné reçoit toujours la même variante (basé sur id_subscriber % 100 < split).

La variante B override seulement les champs renseignés. Vous pouvez par exemple ne changer que le titre, ou ne tester qu’une image. Les statistiques sont stockées séparément :

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

Les colonnes apparaissent dans la liste des campagnes avec un badge A/B à côté du nom.

11. Attribution du chiffre d’affaires

Mécanisme clé du module : relier les commandes aux notifications qui les ont déclenchées.

Flux

  1. Le module envoie une notification avec un track_token unique (32 caractères hex) en payload.
  2. Le service worker intercepte le clic et redirige vers /module/dfpushnotifications/track?t=TOKEN&click=1&u=URL.
  3. Le contrôleur track pose un cookie dfpush_attr=TOKEN (30 jours, SameSite=Lax) et redirige vers l’URL finale.
  4. Le client navigue, ajoute au panier, valide la commande.
  5. Au hook actionValidateOrder, l’AttributionService lit le cookie, retrouve la notification dans ps_dfpush_notifications, écrit id_order + revenue + currency sur la ligne.
  6. Le service incrémente stats_revenue (ou stats_b_revenue selon la variante) sur la campagne ou le trigger, déclenche le webhook order.attributed, puis efface le cookie.

Limites de l’attribution

  • Fenêtre fixe à 30 jours. Au-delà, l’attribution n’a plus lieu.
  • Un seul cookie par abonné. Si l’utilisateur clique sur une seconde notification avant de commander, c’est la dernière qui est créditée (modèle last click).
  • L’attribution exige que le clic et la commande aient lieu sur le même navigateur (le cookie est lié au navigateur).
  • Une commande déjà attribuée ne peut pas être réattribuée (champ id_order > 0 bloque la double comptabilisation).

12. Topics

Les topics sont des canaux d’abonnement thématiques que les clients activent depuis leur compte. Exemple : Promotions, Nouveaux produits, Alertes stock. Un abonné qui ne coche que Promotions ne recevra que les campagnes ciblant ce topic.

Créer un topic

  1. DataFirefly Push → Topics → New topic
  2. Code : identifiant interne sans espaces (ex. flash_deals)
  3. Display order : position dans la liste affichée au client
  4. Active : visible des clients
  5. Default opt-in : pré-coché au moment de l’inscription
  6. Translations : un nom et une description par langue installée

Cibler un topic dans une campagne

La segmentation inclut un critère Topics dans le résolveur. Pour l’activer depuis l’UI : actuellement uniquement via JSON personnalisé (la case à cocher Topics arrive dans une mise à jour mineure). Les abonnés sans aucun topic souscrit reçoivent tout (rétrocompatibilité).

13. Inbox in-app

L’endpoint /module/dfpushnotifications/inbox retourne les 20 dernières notifications du subscriber courant en JSON. Le frontend ouvre cette inbox via la modale unifiée accessible depuis le compte client (tile Push notifications).

La modale affiche aussi le statut de souscription (avec bouton subscribe / unsubscribe) et la liste des topics. Pour l’appeler manuellement depuis votre thème :

// Ouvrir la modale
window.dfpush.openManagePopup();

// Vérifier l'état d'abonnement
const isOn = window.dfpush.isSubscribed();

14. Webhooks

Les webhooks envoient les événements du module vers Zapier, Make, n8n ou votre propre backend. Chaque webhook est signé HMAC-SHA256 sur le corps brut de la requête.

Créer un webhook

  1. DataFirefly Push → Webhooks → New webhook
  2. URL : votre endpoint (HTTPS recommandé)
  3. Secret : généré automatiquement, copiez-le côté receveur
  4. Events : cochez les événements à délivrer parmi les 8 disponibles
  5. Cliquez sur Send test ping pour vérifier que votre endpoint répond bien 2xx

Événements disponibles

  • subscriber.subscribed : nouvel opt-in
  • subscriber.unsubscribed : désabonnement
  • subscriber.expired : push service a renvoyé 410 Gone
  • notification.sent : notification délivrée avec succès
  • notification.clicked : clic enregistré
  • notification.failed : échec définitif après 3 tentatives
  • campaign.sent : campagne terminée
  • order.attributed : commande reliée à une notification

Format du 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://votreshop.com/promotions",
    "ab_variant": "A"
  }
}

Headers HTTP envoyés

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

Vérifier la signature côté receveur

Exemple PHP :

$body     = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, $YOUR_SECRET);
$received = explode('=', $_SERVER['HTTP_X_DFPUSH_SIGNATURE'])[1] ?? '';
if (!hash_equals($expected, $received)) {
    http_response_code(401);
    exit;
}
// Signature valide, traiter la payload
$payload = json_decode($body, true);

Retry et drop

Si votre endpoint répond autre chose que 2xx, le module retente avec un backoff exponentiel jusqu’à 5 tentatives. Après quoi, le log est marqué dropped et l’événement est perdu. Les logs sent et dropped sont purgés après 30 jours.

15. Multi-boutique et multilingue

Tous les abonnés, campagnes, automatisations, topics et webhooks sont rattachés à un id_shop. En multi-boutique :

  • Sélectionnez la boutique cible dans le sélecteur du back-office avant de créer une campagne ou une automatisation
  • Le cron est unique mais filtre automatiquement par boutique
  • Les clés VAPID sont partagées entre boutiques (une seule paire pour toutes)

Côté langue : le module est livré en FR, EN, ES, DE et IT. La langue de l’abonné est détectée à l’inscription et stockée. Vous pouvez segmenter par langue dans les campagnes.

16. RGPD et bonnes pratiques

  • Consentement : la souscription repose sur l’opt-in natif du navigateur, qui est une preuve de consentement RGPD-compatible.
  • Données personnelles : le module stocke l’endpoint Web Push, l’IP au moment de l’inscription, le user-agent, la langue et le pays. Aucune transmission vers un tiers.
  • Désinscription : un clic sur le bouton Unsubscribe de la modale ou la désactivation des notifications dans le navigateur met l’abonné en statut revoked.
  • Droit à l’effacement : la suppression d’un compte client en BO supprime aussi ses subscribers liés.
  • Heures de silence : par défaut 22 h – 8 h. Adaptez à votre cible (B2B = horaires bureau, B2C = soirée).
  • Plafond journalier : par défaut 3 / jour. Au-delà, taux de désabonnement très élevé.

17. Dépannage

L’opt-in ne s’affiche pas

  • Vérifiez que votre site est en HTTPS (pas HTTP).
  • Vérifiez que les clés VAPID sont générées (Settings).
  • Vérifiez que le toggle Push notifications enabled est activé.
  • Ouvrez la console du navigateur (F12) et cherchez des erreurs côté dfpush-frontend.js.
  • Si vous avez déjà refusé ou ignoré la demande, le cooldown bloque pendant N jours. Effacez les cookies du domaine pour réinitialiser, ou changez de navigateur pour tester.

Le cron ne s’exécute pas

  • Appelez l’URL manuellement dans votre navigateur : vous devriez voir un JSON avec success: true. Si vous voyez un 403 invalid_token, le token est mal recopié.
  • Vérifiez la dernière exécution dans le tableau de bord (Dashboard, bloc System).
  • Sur certains hébergeurs, le timeout cURL des crons est de 30 s. Si la file est très grosse, augmentez la fréquence du cron à toutes les 1 ou 2 minutes pour traiter par plus petits batches.

Les notifications ne partent pas

  • Onglet Queue : si les lignes sont en pending, c’est que le cron n’a pas tourné depuis leur création.
  • Si elles sont en failed, cliquez sur la ligne pour voir le code HTTP et le message d’erreur du push service.
  • 410 Gone = l’abonnement n’est plus valide (utilisateur s’est désabonné ou a effacé son navigateur). Le module marque automatiquement le subscriber en expired.
  • 429 Too Many Requests = rate limit côté push service. Le module retente automatiquement avec backoff.

Les commandes ne sont pas attribuées

  • Vérifiez que les cookies tiers ne sont pas bloqués par le navigateur du client (mode privé, certains anti-trackers).
  • Le cookie expire à 30 jours : une commande passée 31 jours après le clic ne sera pas attribuée.
  • Si vous voyez id_order = 0 dans ps_dfpush_notifications alors que la commande a été passée, vérifiez que les hooks actionValidateOrder sont bien enregistrés (Modules → Hooks → actionValidateOrder).

Erreur SQL avec « LIMIT 1 LIMIT 1 »

Bug interne corrigé en 1.2.0 (Db::getValue et Db::getRow ajoutent automatiquement leur propre LIMIT 1). Si vous voyez encore cette erreur, vérifiez que vous avez bien la dernière version du module installée.

18. FAQ

Combien d’abonnés peut gérer le module ?

Le module n’a pas de limite codée. En pratique, le facteur limitant est le temps d’exécution du cron : sur un hébergement mutualisé standard, comptez environ 50 envois par minute (limité par les push services). Pour 10 000 abonnés, prévoyez un cron toutes les 1 ou 2 minutes pendant l’envoi d’une grosse campagne.

Safari iOS est-il vraiment exclu ?

Safari iOS supporte le Web Push depuis iOS 16.4 mais uniquement pour les sites installés comme PWA sur l’écran d’accueil. Sur un Safari classique, l’API Notification renvoie undefined. C’est une limitation Apple, pas du module.

Puis-je migrer mes abonnés depuis OneSignal ou Firebase ?

Non. Les endpoints push sont liés à la paire de clés VAPID utilisée à l’inscription. Si vous changez de paire, les abonnements existants deviennent invalides. Une migration nécessiterait une réinscription des utilisateurs.

Le module fonctionne-t-il sur PrestaShop 1.7 ?

Non, uniquement PrestaShop 8.0 à 9.x. La version 1.7 utilise une architecture admin différente qui nécessiterait un fork dédié.

Puis-je customiser le service worker ?

Oui, le fichier views/js/sw-template.js est rendu par le contrôleur swjs.php et peut être étendu. Attention : toute modification du service worker nécessite une nouvelle register() côté client. Les anciens visiteurs garderont la version précédente jusqu’à ce que le navigateur détecte le changement (généralement 24 h).

Comment exporter les abonnés ?

Onglet Subscribers, bouton Export CSV. Le fichier contient endpoint, browser, device, langue, pays, date d’inscription et compteurs d’envoi / clics.

Support

Pour toute question non couverte par ce guide, contactez le support DataFirefly. Pour signaler un bug, joignez le détail de votre version PrestaShop, PHP et le contenu de la réponse JSON du cron.

Cette page vous a-t-elle été utile ?

Toujours bloqué ? Contactez le support