Recettes par plateforme

WooCommerce

Deux hooks dans le functions.php de votre thème enfant suffisent pour un contrôle de majorité au passage en caisse : l'un redirige vers la page hébergée si le panier est concerné, l'autre confirme le résultat au retour.

add_action('template_redirect', function () {
  if (!is_checkout() || !panier_concerne()) { return; }
  if (WC()->session->get('todis_verifie')) { return; }
  $r = wp_remote_post('https://verify.todis.eu/hosted/sessions', [
    'headers' => ['Authorization' => 'Bearer ' . TODIS_JETON,
                  'Content-Type' => 'application/json'],
    'body' => wp_json_encode([
      'check' => 'age_over_18', 'country_code' => 'FR',
      'locale' => 'fr',
      'success_url' => wc_get_checkout_url() . '?todis_retour=1',
    ]),
  ]);
  $parcours = json_decode(wp_remote_retrieve_body($r), true);
  WC()->session->set('todis_session_id', $parcours['session_id']);
  wp_redirect($parcours['hosted_url']);
  exit;
});

// Priorité 9 : confirmer AVANT le hook de redirection ci-dessus.
add_action('template_redirect', function () {
  if (!isset($_GET['todis_retour'])) { return; }
  $r = wp_remote_get('https://verify.todis.eu/verify/sessions/'
      . WC()->session->get('todis_session_id'),
    ['headers' => ['Authorization' => 'Bearer ' . TODIS_JETON]]);
  $corps = json_decode(wp_remote_retrieve_body($r), true);
  // « verified » veut dire vérification réussie, pas majeur : lire la valeur.
  if (($corps['status'] ?? '') === 'verified'
      && ($corps['claims']['age_over_18'] ?? false) === true) {
    WC()->session->set('todis_verifie', true);
  }
}, 9);

Le jeton reste côté serveur (constante ou variable d'environnement), jamais dans une page. success_url signifie vérification réussie, jamais que l'utilisateur est majeur : une preuve d'âge qui vaut false y renvoie aussi, comme tout résultat vérifié. Lisez le résultat côté serveur (claims.age_over_18 avec le raccourci age_over_18) et appliquez-y votre propre règle.

PrestaShop

Même logique, dans un petit module maison : le hook actionFrontControllerSetMedia (ou un contrôleur front dédié) crée le parcours et redirige quand le panier contient un produit soumis au contrôle, puis votre contrôleur de retour confirme le status et la valeur de claims.age_over_18 via l'API avant de laisser la commande se poursuivre. Stockez le session_id dans le cookie de session PrestaShop, et le jeton dans la configuration du module, jamais dans le template.

Shopify

Shopify n'autorise pas de code arbitraire au checkout : le pattern passe par une petite app custom (celle que votre agence Shopify vous a probablement déjà faite) qui expose deux routes via un App Proxy : l'une crée le parcours et redirige, l'autre reçoit le retour et confirme. Le déclenchement se fait avant le checkout (page panier) ou après l'achat (page de statut de commande), selon votre contrainte réglementaire. Il n'existe pas encore d'app Todis sur l'App Store : dites-nous si elle vous manque.

Les trois règles qui ne changent jamais. Le jeton de licence reste côté serveur. Le résultat se confirme par GET /verify/sessions/{id} authentifié, jamais sur la foi d'un paramètre d'URL ou d'un événement navigateur. Et il n'y a rien à stocker : pas de copie de pièce d'identité, pas de photo, seulement la réponse vérifiée que vous avez demandée, comme expliqué dans la FAQ.