# DataFirefly Indexing API — Documentation

> Présentation DataFirefly Indexing API soumet automatiquement les produits, catégories et pages CMS de votre boutique PrestaShop aux deux canaux de soumission directe existants : IndexNow via le relais api.indexnow.org, qui…

- Page: <https://www.datafirefly.com/documentation/datafirefly-indexing-api-prestashop/>
- Langue: fr
- Mis à jour le: 2026-07-28
- Autres langues: [en](https://www.datafirefly.com/en/documentation/datafirefly-indexing-api-prestashop/index.md), [es](https://www.datafirefly.com/es/documentation/datafirefly-indexing-api-prestashop/index.md), [de](https://www.datafirefly.com/de/documentation/datafirefly-indexing-api-prestashop/index.md), [it](https://www.datafirefly.com/it/documentation/datafirefly-indexing-api-prestashop/index.md), [pl](https://www.datafirefly.com/pl/documentation/datafirefly-indexing-api-prestashop/index.md), [nl](https://www.datafirefly.com/nl/documentation/datafirefly-indexing-api-prestashop/index.md), [pt](https://www.datafirefly.com/pt/documentation/datafirefly-indexing-api-prestashop/index.md)
- Index: <https://www.datafirefly.com/documentation/llms.txt>

## Présentation

DataFirefly Indexing API soumet automatiquement les produits, catégories et pages CMS de votre boutique PrestaShop aux deux canaux de soumission directe existants : **IndexNow** via le relais `api.indexnow.org`, qui propage vers Bing, Yandex, Naver et Seznam en un seul appel, et **Google Indexing API** (authentification Service Account OAuth2, signature JWT RS256 native). Le module s'accroche aux hooks PrestaShop natifs, enfile chaque modification dans une file d'attente déduplifiée, et un CRON traite le lot toutes les quelques minutes. Vous gardez un journal complet des soumissions et un dashboard du taux d'acceptation.

**À lire avant de configurer Google :** Google restreint officiellement son Indexing API aux pages comportant des données structurées `JobPosting`, ou `BroadcastEvent` intégré dans un `VideoObject`. Une fiche produit ou une page catégorie n'entre dans aucun des deux cas. L'API accepte quand même la soumission et répond 200, mais ce code signifie seulement que la notification a été reçue, pas que l'URL sera crawlée ni indexée. Pour un catalogue e-commerce, **IndexNow est le canal qui produit un effet mesurable** : configurez-le en priorité, et traitez Google comme un canal secondaire journalisé.

**En résumé :** vos nouveaux produits et modifications de fiches sont poussés à Bing, Yandex, Naver et Seznam dans les minutes qui suivent, sans abonnement tiers ni commission par URL. Côté Google, la soumission accélère la découverte sans garantie d'indexation.

## Prérequis

- PrestaShop 8.0 à 8.99, ou PrestaShop 9.x
- PHP 7.4 à 8.3
- Extensions PHP `openssl` (pour la signature JWT RS256 de Google) et `curl` (pour les requêtes HTTP)
- Un CRON système ou un service de CRON externe pour appeler le traitement de la file d'attente toutes les 5 à 15 minutes
- **Optionnel, pour Google :** un compte Google Cloud avec un projet où activer l'Indexing API et créer un Service Account, et une propriété Search Console vérifiée pour votre domaine

## Installation

### Étape 1 : téléchargement

Téléchargez le ZIP `dfindexingapi-1.0.0.zip` depuis votre compte DataFirefly après achat.

### Étape 2 : installation via le back-office

1. Connectez-vous à votre back-office PrestaShop
2. Allez dans **Modules › Gestionnaire de modules › Installer un module**
3. Cliquez sur **Sélectionner un fichier** et choisissez le ZIP téléchargé
4. Validez. PrestaShop décompresse et installe le module
5. Une fois installé, cliquez sur **Configurer**

### Étape 3 : vérifications post-installation

À l'installation, le module crée automatiquement :

- Les deux tables SQL `ps_df_indexapi_queue` (file d'attente) et `ps_df_indexapi_log` (journal)
- Une clé IndexNow alphanumérique de 32 caractères
- Un jeton CRON aléatoire de 32 caractères
- 5 onglets dans le menu admin : parent **DataFirefly Indexing API**, puis **Dashboard**, **File d'attente**, **Journal**, **Configuration**

Ouvrez l'onglet **Configuration** pour passer à l'étape suivante.

## Configuration d'IndexNow

IndexNow est le canal à configurer en premier : pas de Service Account, pas d'OAuth, pas de quota, et aucune restriction sur le type de page. Juste une clé à publier à la racine de votre domaine.

### Comprendre IndexNow

IndexNow est un protocole ouvert poussé par Microsoft Bing et Yandex en 2021, rejoint depuis par Naver et Seznam. Vous générez une clé alphanumérique, vous la publiez à la racine de votre domaine sous la forme d'un fichier accessible publiquement, et vous appelez `api.indexnow.org` avec une liste d'URLs. Le serveur vérifie la clé en lisant le fichier de votre domaine, puis propage les URLs aux moteurs participants. Fiches produits, catégories et pages CMS sont dans son périmètre normal.

### Méthode 1 : récriture .htaccess (recommandée)

C'est la méthode la plus simple : le module sert lui-même le contenu du fichier clé via un contrôleur frontend, et une règle `.htaccess` à la racine de votre boutique réécrit la requête vers ce contrôleur.

1. Dans la configuration du module, ouvrez l'onglet **IndexNow**
2. Cochez **Activer IndexNow**
3. Vérifiez le champ **Hôte**, qui doit correspondre au domaine de votre boutique sans le protocole (par exemple `ma-boutique.fr`)
4. Enregistrez
5. Copiez le snippet `.htaccess` affiché dans la page de configuration, généré dynamiquement avec votre clé courante
6. Collez ce snippet en haut du fichier `.htaccess` à la racine de PrestaShop, juste après le bloc `RewriteEngine on`
7. Cliquez sur **Tester IndexNow** dans la configuration : le module appelle l'URL du fichier clé sur votre domaine et vérifie qu'elle renvoie bien le contenu attendu en `text/plain`

### Méthode 2 : fichier physique

Si vous ne pouvez pas modifier le `.htaccess`, créez manuellement un fichier physique à la racine du domaine.

1. Récupérez votre clé IndexNow depuis la configuration du module (champ **Clé IndexNow**)
2. Créez un fichier dont le nom est exactement **la clé + .txt** (par exemple `a1b2c3d4e5f6.txt`) à la racine de votre domaine
3. Le contenu du fichier doit être uniquement la clé elle-même, sans saut de ligne
4. Vérifiez que `https://votre-domaine.com/a1b2c3d4e5f6.txt` renvoie bien la clé en `text/plain`
5. Cliquez sur **Tester IndexNow**

Vous pouvez régénérer la clé IndexNow à tout moment depuis la configuration (bouton **Régénérer la clé**). N'oubliez pas alors de mettre à jour le snippet `.htaccess` ou le fichier physique en conséquence.

## Configuration de Google Indexing API

**Portée officielle :** cette API est réservée par Google aux pages `JobPosting` ou `BroadcastEvent` dans un `VideoObject`. Sur un catalogue produit, elle reste utilisable techniquement (l'API répond 200 et le module journalise la réponse), mais Google décide seul du crawl et de l'indexation. Cette section est facultative : le module fonctionne parfaitement avec IndexNow seul.

L'API Google Indexing nécessite un Service Account Google Cloud. La procédure prend environ 5 minutes.

### Étape 1 : créer un projet Google Cloud

1. Allez sur [console.cloud.google.com](https://console.cloud.google.com) et connectez-vous
2. En haut, cliquez sur le sélecteur de projet, puis **Nouveau projet**
3. Donnez-lui un nom (par exemple _Indexing API Boutique_) et créez-le
4. Sélectionnez le projet nouvellement créé

### Étape 2 : activer l'Indexing API

1. Dans le menu de gauche, allez dans **APIs et services › Bibliothèque**
2. Recherchez _Indexing API_
3. Cliquez sur **Activer**

### Étape 3 : créer un Service Account

1. Allez dans **APIs et services › Identifiants**
2. Cliquez sur **Créer des identifiants › Compte de service**
3. Donnez-lui un nom (par exemple _indexing-api-prestashop_)
4. Aucun rôle IAM n'est nécessaire : passez à l'étape suivante et finalisez la création
5. Dans la liste des comptes de service, cliquez sur le compte créé
6. Onglet **Clés › Ajouter une clé › Créer une nouvelle clé**
7. Format **JSON**. Téléchargez et conservez le fichier, il ne pourra plus être récupéré ensuite

**Sécurité :** le fichier JSON contient la clé privée du Service Account. Ne le partagez jamais publiquement et ne le commitez pas dans un dépôt Git.

### Étape 4 : ajouter le Service Account à Search Console

1. Copiez l'email du Service Account (forme `nom@projet.iam.gserviceaccount.com`) depuis Google Cloud
2. Allez sur [Google Search Console](https://search.google.com/search-console)
3. Sélectionnez votre propriété (le domaine de votre boutique)
4. Allez dans **Paramètres › Utilisateurs et autorisations**
5. Cliquez sur **Ajouter un utilisateur**, collez l'email du Service Account, sélectionnez le rôle **Propriétaire**
6. Validez

Le rôle **Propriétaire** est requis par Google Indexing API. Le rôle **Lecteur** ou **Pleine autorisation** ne suffit pas, l'API renverra `403 Permission denied`.

### Étape 5 : coller le JSON dans le module

1. Ouvrez le fichier JSON téléchargé dans un éditeur de texte
2. Copiez tout son contenu
3. Dans la configuration du module, section **Google Indexing API**, cochez **Activer Google Indexing API**
4. Collez le JSON complet dans le champ **Service Account JSON**
5. Enregistrez

### Étape 6 : tester la connexion

Cliquez sur le bouton **Tester Google** dans la page de configuration. Le module signe un JWT RS256, l'échange contre un jeton OAuth2, et affiche le résultat. Si tout est correct, vous voyez un message vert _Authentification OK_. Ce test valide l'authentification, pas la prise en compte de vos URLs par Google.

## Configuration du CRON

Le CRON est l'élément qui fait tourner le traitement de la file d'attente. Sans CRON appelé régulièrement, les soumissions s'empilent mais ne partent jamais.

### Action process : traitement de la file d'attente

À appeler **toutes les 5 à 15 minutes**. Le module traite un lot configurable (par défaut 50 jobs) en suivant la déduplication et les filtres d'indexation, puis met à jour le journal et la file.

L'URL exacte est affichée dans la configuration. Elle ressemble à :

```
https://votre-domaine.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=VOTRE_JETON
```

### Action purge : nettoyage du journal

À appeler **une fois par jour**. Le module supprime les jobs et logs traités au-delà de la rétention configurée (par défaut 30 jours).

```
https://votre-domaine.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=VOTRE_JETON
```

### Action key : fichier clé IndexNow

Utilisée uniquement par la récriture `.htaccess`. Vous n'appelez jamais cette URL manuellement.

### Configurer votre CRON système

Sous Linux/cPanel, ajoutez deux lignes dans crontab :

```
# Toutes les 10 minutes : traitement de la file d'attente
*/10 * * * * curl -s "https://votre-domaine.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=process&token=VOTRE_JETON" > /dev/null

# Une fois par jour à 3h : purge du journal
0 3 * * * curl -s "https://votre-domaine.com/index.php?fc=module&module=dfindexingapi&controller=cron&dfaction=purge&token=VOTRE_JETON" > /dev/null
```

### Sécurité du jeton CRON

Le jeton est un secret de 32 caractères généré à l'installation. Sans le bon jeton dans le paramètre `token=`, le contrôleur renvoie HTTP 403. Vous pouvez régénérer le jeton à tout moment depuis la configuration (bouton **Régénérer le jeton CRON**), en pensant alors à mettre à jour vos lignes crontab avec le nouveau jeton.

## Le Dashboard

L'onglet **Dashboard** est votre vue d'ensemble en temps réel. Il mesure la santé technique des appels API, pas l'indexation effective de vos pages.

### Compteurs de file d'attente

Cinq cartes en haut de page :

- **En attente** : jobs créés mais pas encore traités
- **En cours** : jobs verrouillés en traitement par un CRON actif
- **Soumis** : jobs traités avec succès (cumul historique non purgé)
- **Erreur** : jobs ayant échoué après N tentatives maximales
- **Ignoré** : jobs créés mais ignorés par un filtre (par exemple URL_DELETED en IndexNow)

### Diagnostic des providers

Deux cartes affichent l'état de configuration :

- **Google Indexing API** : actif, mal configuré, ou désactivé. Indique si le JSON Service Account est présent et valide
- **IndexNow** : actif, mal configuré, ou désactivé. Indique si la clé et l'hôte sont configurés

### Taux d'acceptation 30 jours

Tableau croisé provider × statut sur les 30 derniers jours, avec coloration sémantique : vert au-dessus de 90 %, orange entre 60 et 90 %, rouge en dessous. Si Google chute sous 90 %, c'est généralement un signe que vous avez dépassé le quota ou que des URLs ne sont plus accessibles. Un taux d'acceptation de 100 % signifie que vos notifications ont été reçues, pas que les URLs ont été indexées.

### Graphique des soumissions quotidiennes

Graphique Chart.js superposant deux courbes par jour : total soumis et total accepté. Utile pour repérer rapidement les chutes ou les pics anormaux.

## La File d'attente

L'onglet **File d'attente** liste tous les jobs (pending, processing, submitted, error, skipped) avec filtres natifs PrestaShop par boutique, type d'objet, ID, provider, statut, date.

### Statuts des jobs

- **pending** : créé, en attente de traitement par le prochain CRON
- **processing** : verrouillé par un CRON actif (transition logique pour éviter le double traitement en parallèle)
- **submitted** : soumission réussie à l'API. Le compteur de tentatives est gelé
- **error** : toutes les tentatives ont échoué. Reste consultable avec le message d'erreur exact retourné par l'API
- **skipped** : créé puis ignoré (par exemple URL_DELETED IndexNow, ou filtre désactivé)

### Actions individuelles

Chaque ligne propose :

- **Relancer** : remet le job en pending et réinitialise le compteur de tentatives
- **Supprimer** : efface le job de la file

### Actions en masse

Boutons en haut de liste :

- **Relancer tous les jobs en erreur** : remet en pending tous les jobs en statut error
- **Purger les jobs traités** : supprime tous les submitted/skipped quel que soit leur âge

## Le Journal

L'onglet **Journal** liste chaque soumission individuelle réalisée : provider, type, ID d'objet, URL soumise, action (URL_UPDATED ou URL_DELETED), code HTTP retourné, indicateur accepté/refusé, message complet de réponse, et date. Filtrable, triable, exportable en CSV via le HelperList PrestaShop standard.

Si Google refuse une URL avec un code HTTP 400 et un message _Unable to fetch URL_, c'est généralement que l'URL n'est pas accessible publiquement (mode maintenance actif, robots.txt qui bloque, redirection en boucle, etc.). Vérifiez l'URL dans un navigateur en navigation privée.

## Filtres d'indexation

Dans la configuration, vous pouvez activer ou désactiver indépendamment trois types d'objets :

- **Produits** : soumission sur création, modification, suppression, désactivation
- **Catégories** : soumission sur création, modification, suppression. La racine catégorie (ID 1 et 2) est ignorée par sécurité
- **Pages CMS** : soumission sur création, modification, suppression

Désactiver un filtre arrête immédiatement l'enfilage pour ce type, mais ne purge pas la file existante. Sur un gros catalogue, restreindre les filtres côté Google est le bon réflexe pour ne pas épuiser le quota de 200 URLs par jour.

## Multi-boutique

Le module est nativement multi-boutique. La configuration (clés Google, clé IndexNow, hôte, activations) est indépendante par sous-boutique. Les jobs et logs sont scopés par `id_shop` : un même produit dans deux sous-boutiques génère deux jobs distincts avec leurs propres URLs canoniques.

Pour configurer indépendamment chaque sous-boutique, utilisez le sélecteur multistore en haut de l'admin avant d'ouvrir la configuration.

## Hooks PrestaShop écoutés

Le module enregistre les hooks suivants à l'installation :

- `actionProductSave` : création ou modification d'un produit. Si actif, enfile URL_UPDATED ; sinon URL_DELETED
- `actionProductDelete` : suppression définitive d'un produit. Enfile URL_DELETED
- `actionObjectCmsAddAfter` : création d'une page CMS
- `actionObjectCmsUpdateAfter` : modification d'une page CMS
- `actionObjectCmsDeleteAfter` : suppression d'une page CMS
- `actionCategoryAdd` : création d'une catégorie
- `actionCategoryUpdate` : modification d'une catégorie
- `actionCategoryDelete` : suppression d'une catégorie
- `displayBackOfficeHeader` : injection d'un fragment CSS pour le styling du dashboard

Chaque hook construit l'URL canonique via l'objet `Link` officiel de PrestaShop, ce qui respecte vos préférences **SEO friendly URL** et les préfixes de langue multilingue.

## Dépannage

### Le test Google échoue avec un code 401

L'authentification a échoué. Vérifiez que :

- Le JSON Service Account collé est complet et bien formé
- L'Indexing API est bien activée dans Google Cloud (bibliothèque)
- L'horloge système du serveur est correcte : un décalage de plus de 5 minutes invalide le JWT

### Le test Google échoue avec un code 403

L'authentification réussit mais Google refuse la requête. Cause habituelle : le Service Account n'a pas été ajouté comme **Propriétaire** de la propriété Search Console. Re-vérifiez l'étape 4 de la configuration Google.

### Le test IndexNow échoue

Le serveur api.indexnow.org n'a pas pu lire le fichier clé sur votre domaine. Causes possibles :

- Le snippet `.htaccess` n'a pas été collé, ou collé au mauvais endroit (il doit être après `RewriteEngine on`)
- Le fichier physique n'a pas été créé, ou n'a pas le bon nom (doit être exactement _la clé + .txt_)
- Le contenu du fichier ne correspond pas à la clé (faute de frappe, saut de ligne supplémentaire)
- Le serveur web sert le fichier avec le mauvais Content-Type (doit être `text/plain`)
- Le pare-feu ou le CDN bloque les requêtes du robot IndexNow

Ouvrez `https://votre-domaine.com/VOTRE_CLE.txt` dans un navigateur en navigation privée : vous devez voir uniquement la clé en texte brut.

### Des jobs restent bloqués en statut processing

Cela signifie qu'un CRON a verrouillé les jobs mais n'a jamais relâché le lock (par exemple le processus a été tué par un timeout PHP). Vous pouvez les débloquer manuellement en passant par phpMyAdmin :

```
UPDATE ps_df_indexapi_queue SET status = 'pending', attempts = 0 WHERE status = 'processing';
```

Si le problème se reproduit régulièrement, augmentez le `max_execution_time` PHP de votre hébergement, ou réduisez la taille du lot dans la configuration du module.

### Le quota Google est dépassé

Google répond avec un code 429 ou un message _Quota exceeded_. Le quota par défaut est de 200 URLs par jour par Service Account.

**Ne comptez pas sur une augmentation de quota.** Google propose bien un formulaire de demande, mais l'approbation est conditionnée à l'usage effectif du balisage `JobPosting` ou `BroadcastEvent` sur le site. Un catalogue e-commerce ne remplit pas ce critère : la demande sera refusée. Traitez les 200 URLs par jour comme un plafond fixe.

Trois options réalistes :

- Attendre 24h, le quota se réinitialisant quotidiennement
- Restreindre les filtres d'indexation côté Google aux types qui comptent vraiment pour vous (par exemple produits seuls, en désactivant catégories et CMS)
- Créer un second Service Account et alterner, chaque Service Account ayant son propre quota de 200 URLs par jour

Rappel : IndexNow n'a pas de quota. Si le volume est votre contrainte principale, c'est le canal sur lequel s'appuyer.

### Réinitialisation complète

Pour repartir de zéro (utile en cas de migration ou de problème complexe) :

1. Désinstaller le module depuis Modules › Gestionnaire
2. Réinstaller : les tables sont recréées, la clé IndexNow et le jeton CRON sont régénérés
3. Reconfigurer Google et IndexNow
4. Mettre à jour le snippet `.htaccess` avec la nouvelle clé
5. Mettre à jour les lignes crontab avec le nouveau jeton

La désinstallation supprime la file d'attente et le journal, mais ne supprime pas les soumissions déjà effectuées côté Google ou IndexNow : elles restent dans leurs historiques respectifs.

## Limites connues

- **Google Indexing API officiellement limitée** aux pages `JobPosting` ou `BroadcastEvent` dans un `VideoObject`. L'API accepte les autres types et répond 200, mais ce code atteste seulement de la réception de la notification. Pour un catalogue produit, IndexNow est le canal principal et Google un complément journalisé
- **Quota Google plafonné** à 200 URLs par jour par Service Account, sans augmentation possible en pratique pour un e-commerce (voir la section Dépannage)
- **IndexNow ne gère pas URL_DELETED** : le protocole considère qu'une 404 ou 410 sur l'URL est la bonne façon de signaler une suppression. Le module ignore donc les jobs IndexNow en URL_DELETED (Google les soumet bien, lui)
- **Variantes produit non soumises individuellement** : l'URL canonique du produit principal suffit, Google consolide naturellement les variantes
- **Racine catégorie ignorée** (ID 1 et 2) pour éviter de soumettre des URLs non pertinentes
- **Le module ne remplace pas un sitemap XML** : le sitemap reste le canal de découverte officiel et doit rester propre et à jour. La soumission directe s'ajoute par-dessus, elle ne s'y substitue pas

## Support

Pour toute question technique : [support@datafirefly.com](mailto:support@datafirefly.com), réponse sous 24h ouvrées en français ou anglais. Inclus pendant 12 mois après l'achat.
