Vai al contenuto

Widget B2C — visiteur invité et entreprise

Cette section couvre les intégrations où le widget reste en session invité :

  • site public, visiteur inconnu : script et formulaire de contact seulement
  • site ou portail qui connaît déjà le compte : init() avec le profil et les données d'entreprise, formulaire sauté lorsque les données suffisent, contact lié à l'entreprise

L'historique personnel sur un autre navigateur ou appareil est une autre intégration. Voir Widget B2B. Contrat complet des champs, changement de compte dans une SPA, CSP et provisioning : Intégration technique.

Associer une entreprise n'autorise pas l'historique d'une autre personne. Un utilisateur authentifié sur le site reste un invité du widget tant que vous n'envoyez pas external_user_id avec un restore_id valide.


Ce que vous obtenez

  • Un bouton flottant, ou une conversation intégrée dans un conteneur de la page
  • Un formulaire initial pour les inconnus, avec les libellés Téléphone et Nom. Dans init() les champs sont phone et name
  • Une session invité enregistrée par le loader dans le même navigateur, séparée par clé de widget. Si localStorage est bloqué, la continuité peut rester sur la page courante
  • Si vous envoyez external_id, Quoting24 cherche une entreprise avec le même web_code. Avec company_name en plus, il peut créer l'entreprise manquante et y lier le contact
  • Tickets et réponses dans Quoting24, comme sur les autres canaux

La session invité relit sa conversation la plus récente même après la fermeture de l'onglet. Elle ne suit pas la personne sur un autre navigateur.


1. Prérequis dans Quoting24

  1. Canal Widget actif dans Paramètres → Canaux
  2. Logo, couleur, position, accueil, bienvenue et hors horaires configurés
  3. Domaines autorisés à jour, y compris le recettage et localhost
  4. Code d'intégration copié depuis la configuration du canal : URL du script et clé publique

Utilisez l'hôte et la clé du même environnement. Dans les exemples, remplacez HOTE_WIDGET et CLE_PUBLIQUE_WIDGET.

Les domaines sont des noms d'hôte, sans https://, port, chemin ni *.. example.com inclut les sous-domaines. Liste vide : aucune restriction. En local, servez la page en HTTP, pas en file://.

Le company_name de init() est la raison sociale du client. Ce n'est pas le titre du widget et il ne se configure pas depuis ce payload.


2. Installer le bouton flottant

Collez le script une seule fois, avant </body> :

<script
  src="https://HOTE_WIDGET/assets/widget/script.js?key=CLE_PUBLIQUE_WIDGET"
  async
></script>

Le bouton apparaît après le chargement des réglages graphiques. Un nouveau visiteur voit le formulaire de contact. Celui qui revient dans le même navigateur reprend la session invité, si le stockage est disponible.

Le script expose un unique window.Quoting24Widget.


3. Intégrer la conversation dans la page

Créez le conteneur avant le script et donnez-lui une hauteur explicite :

<section aria-labelledby="titre-assistance">
  <h2 id="titre-assistance">Assistance</h2>
  <div id="chat-assistance" style="width: 100%; height: 600px;"></div>
</section>

<script
  src="https://HOTE_WIDGET/assets/widget/script.js?key=CLE_PUBLIQUE_WIDGET&amp;mode=embedded&amp;target=chat-assistance"
  async
></script>
  • target est l'ID de l'élément, sans #
  • L'iframe remplit le conteneur
  • Il n'y a pas de bouton flottant
  • open(), close() et toggle() n'ont pas d'effet
  • Dans ce mode, le site décide de la hauteur et de la largeur. En mode flottant, sur mobile, la conversation peut occuper le viewport

Le mode intégré, à lui seul, n'active pas la restauration de l'historique.


4. Envoyer le profil du client

Lorsque le site connaît le compte, envoyez le profil après le chargement du loader. Les champs sont des chaînes. Omettez ceux qui sont inconnus : n'envoyez pas null, des ID numériques ni un e-mail vide.

window.Quoting24Widget.init({
  external_id: "52",
  company_name: "Ricambi Stella S.r.l.",
  name: "mario.rossi",
  phone: "+393331234567",
  email: "amministrazione@ricambi-stella.example",
});
Donnée dans le site ou le logiciel de gestion Champ Signification
Référence stable de l'entreprise, la même valeur importée dans web_code external_id Comparaison exacte avec companies.web_code, dans l'organisation du widget
Raison sociale company_name Utilisée s'il faut créer l'entreprise
Nom de la personne ou de l'utilisateur name Nom affiché sur le contact
E-mail du compte email Enregistré sur l'entreprise seulement lorsque l'entreprise est créée
Téléphone, si vous le connaissez phone Numéro du contact. Préférez le format international, par exemple +393331234567

Ce payload n'envoie ni external_user_id ni restore_id. Gardez name et company_name séparés : ne concaténez pas la raison sociale au nom d'utilisateur pour obtenir l'association. Le champ public est external_id. N'envoyez pas web_code, l'UUID interne de Quoting24 ni companies.code.

Le formulaire affiche Nom et Téléphone. Dans init() ces champs s'appellent name et phone. L'e-mail s'appelle email. Nom, Téléphone et Email ne sont pas des clés : le loader les ignore, comme il ignore web_code à la place de external_id.

Exemples

Nom et téléphone, les mêmes données que le formulaire. La conversation démarre et ne cherche pas d'entreprise.

widget.init({
  name: "Mario Rossi",
  phone: "+393331234567",
});

Profil avec entreprise. name est la personne, phone le numéro du contact, email est écrit sur l'entreprise seulement si cet appel la crée.

widget.init({
  external_id: "52",
  company_name: "Ricambi Stella S.r.l.",
  name: "Mario Rossi",
  phone: "+393331234567",
  email: "mario.rossi@ricambi-stella.example",
});

E-mail seul. Une adresse valide dans email suffit pour ouvrir la session.

widget.init({
  email: "mario.rossi@ricambi-stella.example",
});

Si un champ dépasse les limites ou si l'e-mail est mal formé, la requête est refusée. Limites et comportement de chaque champ : Intégration technique.

Attendre le loader

Un script async peut ne pas encore être exécuté lorsque le code suivant appelle init(). Pour les données préremplies, utilisez un module de chargement à la place de la balise statique, importé une seule fois dans la structure principale :

// /assets/quoting24-loader.js
const widgetScriptUrl =
  "https://HOTE_WIDGET/assets/widget/script.js?key=CLE_PUBLIQUE_WIDGET";

let widgetPromise;

export function loadWidget() {
  if (window.Quoting24Widget) {
    return Promise.resolve(window.Quoting24Widget);
  }
  if (widgetPromise) return widgetPromise;

  widgetPromise = new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.id = "quoting24-widget-script";
    script.src = widgetScriptUrl;
    script.async = true;
    script.onload = () => {
      if (window.Quoting24Widget) resolve(window.Quoting24Widget);
      else {
        script.remove();
        reject(new Error("API du widget indisponible"));
      }
    };
    script.onerror = () => {
      script.remove();
      reject(new Error("Échec du chargement du widget"));
    };
    document.body.appendChild(script);
  }).catch((error) => {
    widgetPromise = undefined;
    throw error;
  });

  return widgetPromise;
}
import { loadWidget } from "/assets/quoting24-loader.js";

const widget = await loadWidget();
widget.init({
  external_id: "52",
  company_name: "Ricambi Stella S.r.l.",
  name: "mario.rossi",
  phone: "+393331234567",
  email: "amministrazione@ricambi-stella.example",
});

Importez le module depuis le bundler, ou chargez le fichier d'entrée avec <script type="module" src="/assets/assistance.js"></script>. Pour le mode intégré, ajoutez &mode=embedded&target=chat-assistance à l'URL et montez d'abord le conteneur.

loadWidget() signale seulement que l'API JavaScript est disponible. init() renvoie void : il met le profil en file si l'iframe n'est pas prêt et n'attend pas la session. Pour le résultat, utilisez isReady() et hasSessionError().

init() remplace le profil mémorisé. Il ne le fusionne pas avec le précédent. Passez tous les champs qui doivent rester.

Un changement de page dans une SPA ne demande ni un nouveau script ni un reset(). Au changement de personne ou de compte, et à la déconnexion, appelez reset() avant le nouveau profil : changer seulement les champs ne détache pas la session invité précédente. Schéma complet : Connexion, déconnexion et changement de compte.


5. Comment l'entreprise est associée ou créée

Quoting24 exécute ce flux à l'initialisation, même si le visiteur n'a pas encore envoyé de message :

  1. Avec un external_id non vide, il cherche une entreprise de la même organisation dont le web_code est égal à cette valeur
  2. S'il la trouve, il lie le contact. Le nom et l'e-mail de l'entreprise existante restent inchangés
  3. S'il ne la trouve pas et qu'un company_name non vide est aussi présent, il crée l'entreprise avec name = company_name, web_code = external_id et l'e-mail éventuel, puis lie le contact
  4. S'il ne peut ni trouver ni créer l'entreprise, il continue avec le profil disponible. Si cela ne suffit pas pour un nouvel invité, il affiche le formulaire. Les erreurs de base ou la limite de requêtes font échouer l'initialisation
Données envoyées Situation dans Quoting24 Résultat
external_id: "52", company_name: "Ricambi Stella S.r.l." web_code = "52" existe Utilise l'entreprise existante et n'en modifie pas le nom
Mêmes données, plus un e-mail valide web_code = "52" n'existe pas Crée l'entreprise avec le code web 52, la raison sociale et l'e-mail, et associe le contact
external_id: "52", name: "mario.rossi" Aucune correspondance Démarre l'invité sans nouvelle association d'entreprise
external_id: "52", sans autres données Une correspondance existe Démarre l'invité associé à l'entreprise, avec le nom par défaut Visitatore
external_id: "52", sans autres données Aucune correspondance Affiche le formulaire de contact
company_name sans external_id, plus name Quelconque Démarre le visiteur. Ne cherche pas et ne crée pas d'entreprise

La recherche n'utilise pas la raison sociale, l'e-mail, le téléphone, le numéro de TVA ni companies.code. "052" et "52" sont des valeurs différentes ; les espaces dans external_id ne sont pas retirés. Si vous importez le fichier clients avant, écrivez dans web_code la même valeur que le site enverra dans external_id. Voir aussi Entreprises → Code web.

Un nouvel invité démarre s'il y a au moins un nom, un téléphone, un e-mail valide ou un external_user_id, ou une entreprise trouvée ou créée via external_id. init({}) et company_name seul ne démarrent pas de session.

Pour un contact déjà lié, un nouveau code valide peut changer son entreprise. Omettre le code, ou en envoyer un qui ne se résout pas, n'efface pas l'association précédente. Le changement de personne ou de compte exige reset().

Limites

web_code n'est pas unique. Avec plusieurs correspondances, l'initialisation publique prend la première par date de création croissante. Des requêtes simultanées qui ne trouvent pas encore l'entreprise peuvent en créer plusieurs : la création n'est pas atomique et ne remplace pas un import ou une synchronisation depuis le logiciel de gestion.

La création implicite est limitée à 20 tentatives par fenêtre de 60 secondes et par adresse IP, dans le processus backend qui traite la requête. Au-delà, l'initialisation échoue avec TOO_MANY_REQUESTS : réessayez avec une attente, sans boucles continues de init().

Les données partent du navigateur et le visiteur peut les altérer. Le lien ne prouve pas l'appartenance à l'entreprise et n'accorde pas l'historique de l'entreprise. Envoyez company_name seulement si vous voulez autoriser cette création publique. Pour mettre à jour des entreprises déjà présentes, utilisez les outils de Quoting24 ou une intégration de gestion autorisée.

L'e-mail de l'initialisation publique n'est enregistré que sur la nouvelle entreprise. Il n'est pas écrit sur le contact et ne met pas à jour une entreprise déjà présente. Un téléphone déjà utilisé par un autre contact ne fusionne ni les contacts ni les conversations.


6. Comportement sur le site

Situation Comportement attendu
Premier visiteur, script seul Bouton, puis formulaire, puis conversation
init() avec un profil suffisant Formulaire sauté
external_id déjà présent comme web_code Contact associé ; nom et e-mail de l'entreprise inchangés
Nouvel external_id avec company_name Entreprise créée et contact associé
Nouveau code et nom, sans company_name Conversation sans nouvelle entreprise
Nouveau code seul Formulaire de contact
Raison sociale et nom seulement Aucune recherche ni création par nom
Rechargement dans le même navigateur Session invité reprise, si le stockage est disponible
Autre navigateur ou appareil Nouvelle session invité
Hors horaires Bannière hors horaires ; la saisie reste utilisable
Mobile, bouton flottant La conversation peut occuper le viewport

Pièces jointes : PDF, DOC, DOCX, JPG/JPEG, PNG. Maximum 10 MiB par fichier et 100 MiB de pièces référencées par conversation.


7. Contrôles utiles

Lorsque le bouton flottant est visible, vous pouvez relier un bouton du site à window.Quoting24Widget?.open().

Méthode Usage
init(profile) Définit ou remplace le profil courant
open() / close() / toggle() Widget flottant seulement. Fermer n'est pas une déconnexion
isReady() Session visiteur démarrée. Reste faux sur le formulaire de contact
hasSessionError() Erreur de session signalée par l'iframe
reset() Efface le profil, la session locale, le credential invité enregistré et les non-lus de cette instance
dispose() Démonte l'interface et les écouteurs. N'efface pas le credential invité enregistré ni l'objet API global

N'attendez pas isReady() pour laisser un nouvel invité ouvrir le formulaire. Il n'y a pas d'événement public de disponibilité. Ces indicateurs ne décrivent pas tout l'état du réseau.


Liste de contrôle avant mise en production

  • [ ] Hôte et clé du même environnement
  • [ ] Domaines du site et du staging dans la liste, uniquement comme noms d'hôte
  • [ ] Logo, couleur, accueil, bienvenue et hors horaires vérifiés
  • [ ] Navigateur neuf, script seul : formulaire, message, ticket dans Quoting24
  • [ ] external_id déjà dans web_code : association, fiche entreprise inchangée
  • [ ] Nouveau code avec company_name : entreprise créée avec ce code web
  • [ ] Nouveau code sans company_name : aucune entreprise créée
  • [ ] E-mail vide, ID numérique ou raison sociale trop longue : payload refusé, à corriger
  • [ ] Rechargement et navigation SPA : une seule instance, session invité conservée
  • [ ] Changement de compte : reset() tout de suite, réponses tardives écartées
  • [ ] Mobile : saisie utilisable
  • [ ] Domaine non autorisé : widget refusé

Problèmes fréquents : Résolution des problèmes.