Page de présentation du programme
Le widget "Page de présentation du programme" d'Enkore met à disposition des consommateurs les éléments du programme de fidélité de la boutique (solde, historique, récompenses, parrainage).
Objectif du widget
La page de présentation du programme poursuit quatre objectifs :
- Présenter le fonctionnement du programme : comment gagner des points, à quoi ils donnent droit, quelles sont les règles.
- Renforcer l'univers du programme : bannière, textes, couleurs et CSS personnalisé permettent d'aligner la page sur l'identité de la marque.
- Informer le consommateur de l'état de son compte fidélité : solde de points et historique des mouvements encore valides.
- Lui permettre d'échanger ses points : conversion du solde en récompense (bon d'achat, réduction) et parrainage d'un ami.
Deux modes d'intégration sont possibles : l'intégration par script javascript, où Enkore fournit le rendu complet de la page, et l'intégration par API, où la boutique construit son propre affichage à partir des endpoints de l'API.
Intégration à l'aide du script
Le widget est un bundle JavaScript autonome, chargé par une balise <script>. Il cherche dans la page l'élément d'ancrage, s'y monte, et lit dans le HTML les informations que le back-end de la boutique a ajoutées.
Ce que le back-end doit exposer dans le HTML
| Élément | Rôle | Obligatoire |
|---|---|---|
<div id="enkore-loyalty-program"></div> | Point de montage du widget | Oui |
<div id="enkore-loyalty-hash" hidden>…</div> | HMAC-SHA512 du client, en innerText | Oui pour un client connecté |
<div id="enkore-loyalty-id" hidden>…</div> | Identifiant du client dans la plateforme e-commerce (externalId), en innerText | Oui pour un client connecté |
<div id="enkore-language" hidden data-enkore-language-iso="fr"></div> | Code ISO de la langue de la page | Non |
<div id="enkore-store-domain" data-enkore-domain="https://monstore.com"></div> | Domaine du store déclaré chez Enkore | Non |
Quelques précisions :
- Le hash et l'
externalIdvont de pair. Ils identifient le client auprès de l'API sans session ni cookie. Le hash est calculé côté serveur à partir de la référence du store et de sa clé API — voir la page Authentification par hash. La clé API ne doit jamais être exposée au navigateur. - Client non connecté : les deux éléments sont laissés vides (ou absents). Le widget se rend alors en mode non authentifié — il affiche le programme et les récompenses, mais ni le solde, ni l'historique, ni les actions d'échange.
- Langue : le widget choisit sa langue dans l'ordre suivant — langue de la page (
data-enkore-language-iso), puis langue par défaut du store configurée au back-office, puis français. Les langues gérées sontfr,en,es,de,it,nl,pl; un code régional (fr-FR) est ramené à sa langue (fr), etgb— l'iso_codesous lequel PrestaShop installe l'anglais britannique — est traité commeen. - Domaine : en son absence, le widget utilise le domaine du navigateur (
protocol + hostname). L'élément n'est donc utile que lorsque la page est servie sur un domaine différent de celui déclaré chez Enkore (préproduction, domaine multi-boutique).
Exemple de page
<!-- Point de montage -->
<div id="enkore-loyalty-program"></div>
<!-- Identification du client, rendue côté serveur -->
<div id="enkore-loyalty-hash" hidden>708e3f96061caf0af6…</div>
<div id="enkore-loyalty-id" hidden>8924</div>
<!-- Facultatif -->
<div id="enkore-language" hidden data-enkore-language-iso="fr"></div>
<div id="enkore-store-domain" data-enkore-domain="https://monstore.com"></div>
<!-- Chargement du widget -->
<script src="https://program-presentation-widget.enkore.io/enkore-presentation-default-1-0.js"></script>
Comportements pris en charge par le script
- L'emplacement de la page est donné par le point de montage : le widget se rend dans
#enkore-loyalty-program. - Le CSS personnalisé défini au back-office est injecté dans le
<head>sous forme de balise<style id="enkore-custom-css">. Les styles du widget sont préfixés par.enkore-widgetpour ne pas déborder sur la page hôte. - Les identifiants de section (
#enkore-point-system-section,#enkore-redeem-section,#enkore-history-section,#enkore-faq-section) sont stables : ils servent de cibles aux boutons de la bannière et peuvent être ciblés depuis le CSS personnalisé. - L'échange d'une récompense passe par une modale de confirmation, qui rappelle le coût en points et la valeur de la récompense, puis son montant minimum d'achat et sa durée de validité dans un encart. Ses éléments portent des identifiants stables, détaillés ci-dessous.
- Le lien de parrainage est géré automatiquement : si l'URL de la page contient
?referral-hash=…, le widget récupère le code du filleul, l'affiche dans une modale, puis retire le paramètre de l'URL.
Apparence : ce que la page hérite de la boutique
La page prend la typographie de l'endroit où elle est placée : police, couleur, taille et interligne du texte sont ceux du thème de la boutique. Le widget n'impose ni couleur ni taille de texte, ni ombre, ni fond blanc. Les titres gardent seulement une échelle relative (2em, 1.5em, 1.17em), si bien qu'un thème qui grossit son texte grossit aussi les titres. Les paragraphes n'ont pas de marge basse, quelle que soit la règle p { margin-bottom: … } du thème.
Le widget ne garde que des bordures neutres d'un pixel (cartes, questions de la FAQ, tableau de l'historique) et un bouton plein, que la plupart des boutiques recolorent par le CSS personnalisé.
Fonds de section : chaque section (bannière, système de points, échange, historique, parrainage, FAQ) a sa propre couleur de fond, réglée sur la page du widget au back-office. Une couleur vide laisse la section transparente : elle prend alors le fond de la page. La charte graphique de la boutique n'est plus lue par ce widget.
Personnaliser la page avec le CSS personnalisé
Le CSS personnalisé doit viser les identifiants et les classes stables du widget, les seules accroches garanties d'une version à l'autre :
| Identifiant ou classe | Élément |
|---|---|
#enkore-hero-section | La bannière |
.enkore-hero-container | Son conteneur (image et contenu) |
#enkore-hero-image, #enkore-hero-overlay | L'image de fond et son voile |
.enkore-hero-content | Le bloc qui place le texte et les boutons |
#enkore-hero-section-text | Le texte de la bannière |
.enkore-hero-card | Le même texte quand il est posé sur une carte (option du back-office) |
#enkore-hero-primary-button, #enkore-hero-secondary-button | Les deux boutons |
.enkore-section | Chaque section sous la bannière (marges intérieures) |
.enkore-section-container | Le conteneur centré d'une section (largeur maximale) |
#enkore-point-system-section, .enkore-point-system-text | La section « système de points » et son texte |
#enkore-redeem-section, .enkore-redeem-text | La section d'échange et son texte |
#enkore-redeem-rewards-list | La liste des récompenses |
.enkore-redeem-empty | Le message affiché quand la boutique n'a aucune récompense |
.enkore-reward-card | Une carte de récompense |
.enkore-reward-card-header, .enkore-reward-card-title | Son en-tête et son titre |
.enkore-reward-card-content | Son contenu |
.enkore-reward-card-picto | Le cercle qui affiche la valeur du bon |
.enkore-reward-card-points-value | Le coût en points |
.enkore-reward-card-error | Le message d'un échange refusé |
.enkore-reward-card-redeem-button | Le bloc du bouton d'échange (le bouton est son button) |
.enkore-reward-card-redeem-button--unavailable | Le bouton en retrait : visiteur non connecté ou solde insuffisant |
#enkore-history-section, #enkore-history-text | La section historique et son texte |
#enkore-history-table | Le tableau des mouvements |
#enkore-history-header, #enkore-history-body | Son en-tête et son corps |
.enkore-history-row | Une ligne du tableau |
.enkore-history-head-cell, .enkore-history-cell | Une cellule d'en-tête, une cellule de mouvement |
#enkore-history-more | Le bouton « voir plus » |
#enkore-referral-section | La section de parrainage |
.enkore-referral-container | Son conteneur centré |
.enkore-referral-text | Son texte |
.enkore-referral-form | Le formulaire |
.enkore-referral-input, .enkore-referral-submit | Le champ e-mail et le bouton d'envoi |
.enkore-referral-error | Le message d'un parrainage refusé |
.enkore-referral-success-title, .enkore-referral-success-text | Le titre et le texte affichés après l'envoi |
.enkore-referral-share-again | Le bouton pour parrainer un autre ami |
#enkore-faq-section, .enkore-faq-title | La section FAQ et son titre |
.enkore-faq-list, .enkore-faq-item | La liste des questions, une question avec sa réponse |
.enkore-faq-question, .enkore-faq-answer | Le bouton de la question, le bloc de la réponse |
.enkore-code | Le cadre du code de réduction à copier, dans la fenêtre du code obtenu |
La racine du widget porte aussi enkore-authenticated ou enkore-anonymous, selon que le client est connecté.
#enkore-faq-section .enkore-faq-item {
border-color: #103548;
}
.enkore-reward-card-redeem-button button:not(.enkore-reward-card-redeem-button--unavailable) {
background-color: #103548;
}
.enkore-reward-card-redeem-button--unavailable {
background-color: #e8eded;
}
Les autres classes portées par le widget (ek:py-5, ek:max-w-3xl…) sont des détails d'implémentation, susceptibles de changer à chaque version : un CSS qui les vise peut cesser de s'appliquer sans préavis. Le préfixe ek: les met en outre à l'abri des utilitaires du thème (les .py-5, .border… de Bootstrap) : il n'est plus nécessaire de les contrer.
Personnaliser la fenêtre d'échange avec le CSS personnalisé
La fenêtre de confirmation d'échange porte ces identifiants, les mêmes que dans le widget panier — un CSS écrit pour l'un s'applique à l'autre :
| Identifiant | Élément |
|---|---|
#enkore-dialog-redeem-content | La fenêtre |
#enkore-dialog-redeem-title | Le titre (« Êtes-vous sûr ? ») |
#enkore-dialog-redeem-description | La phrase de confirmation (coût en points et valeur du bon) |
#enkore-dialog-redeem-conditions | L'encart des conditions du bon (absent si le bon n'en a aucune) |
#enkore-dialog-redeem-min-purchase | La ligne du montant minimum d'achat (absente si le bon n'en a pas) |
#enkore-dialog-redeem-min-purchase-icon | Sa pastille d'icône |
#enkore-dialog-redeem-min-purchase-label | Son libellé |
#enkore-dialog-redeem-min-purchase-value | Sa valeur (30 €) |
#enkore-dialog-redeem-validity | La ligne de la durée de validité (absente si le bon n'en a pas) |
#enkore-dialog-redeem-validity-icon | Sa pastille d'icône |
#enkore-dialog-redeem-validity-label | Son libellé |
#enkore-dialog-redeem-validity-value | Sa valeur (365 jours) |
#enkore-dialog-redeem-annuler | Le bouton « Annuler » |
#enkore-dialog-redeem-validation | Le bouton « Obtenir la réduction » |
Les deux lignes de l'encart portent aussi des classes communes, pour les styler d'une seule règle : enkore-dialog-redeem-condition (la ligne), enkore-dialog-redeem-condition-icon, enkore-dialog-redeem-condition-label et enkore-dialog-redeem-condition-value. La pastille d'icône prend la couleur principale du widget ; une boutique qui a recoloré ses boutons la recolore de la même façon :
.enkore-dialog-redeem-condition-icon {
background-color: rgb(0 188 212 / 0.12);
color: #00838f;
}
Aucun appel HTTP n'est à écrire : le script contacte l'API lui-même, avec les mêmes endpoints que ceux listés ci-dessous.
Intégration par API
Une boutique qui souhaite construire son propre affichage appelle directement les endpoints de l'API. Chaque endpoint est décrit — paramètres, schémas de réponse, exemples de code — dans la référence d'API.
Au chargement de la page
| Endpoint | Rôle | Authentification |
|---|---|---|
GET /store/widget/program-presentation | Configuration visuelle et textuelle de la page telle que définie au back-office (sections, couleurs, textes, CSS personnalisé, traductions) | domain |
GET /point/user-history/{externalId} | Solde de points du client, historique des mouvements encore valides et palier de club | domain + hash |
GET /reward/list | Récompenses de la boutique et nombre de points requis pour chacune | domain |
L'appel de configuration n'a d'intérêt que si l'on souhaite piloter l'apparence de la page depuis le back-office Enkore. Une intégration entièrement maîtrisée côté boutique peut s'en passer.
Sur action du consommateur
| Endpoint | Rôle | Authentification |
|---|---|---|
POST /reward/claim/{externalId} | Échange les points du client contre une récompense et retourne le code de réduction à afficher | domain + hash |
POST /point/referral | Enregistre le parrainage d'un ami à partir de son email et retourne le hash de parrainage à diffuser. Le parrain doit avoir passé au moins une commande : sinon l'API répond 400 avec le motif referral-order-required | domain + hash |
POST /reward/referral/get-referee-code | Côté filleul : échange le hash de parrainage lu dans l'URL (?referral-hash=…) contre son code de réduction | Aucune |
Le dernier endpoint n'est à implémenter que si le parrainage de la boutique est de type "bon d'achat".
Authentification
Les endpoints qui opèrent au nom d'un client (hash) exigent les paramètres domain, externalId et hash — voir Authentification par hash. Les autres n'ont besoin que du paramètre domain et sont publics.
Quelle intégration choisir ?
Par défaut, l'intégration par script. Elle demande moins de travail : il suffit d'exposer quelques éléments dans le HTML et de charger le script. Elle donne accès à la configuration de la page depuis le back-office Enkore, et la boutique profite automatiquement des mises à jour du widget — nouvelles sections, corrections, nouvelles langues — sans redéploiement de son côté.
L'intégration par API est réservée aux boutiques qui veulent un contrôle total de l'affichage : intégration profonde dans un design system, parcours sur mesure, framework front spécifique. En contrepartie, tout le rendu et son évolution restent à la charge de la boutique.