Documentation

Tout ce qu'il faut savoir pour intégrer le widget Tissova sur votre site.

Lecture : 5 minutes

Prérequis

  • Avoir souscrit un plan Tissova (voir nos tarifs)
  • Avoir uploadé au moins un modèle 3D dans le dashboard marque
  • Récupérer sa clé API depuis le dashboard → onglet Intégration

Installation

Le script s'intègre en une seule balise, à placer une fois dans le template de fiche produit de votre CMS — pas manuellement sur chaque page. Le widget se charge automatiquement partout où ce template est utilisé.

Shopify

<script
  src="https://widget.tissova.fr/tissova.js"
  data-api-key="VOTRE_CLE_API"
  data-produit-id="{{ product.id }}"
></script>

À coller dans product.liquid ou votre section produit.

WooCommerce

<script
  src="https://widget.tissova.fr/tissova.js"
  data-api-key="VOTRE_CLE_API"
  data-produit-id="<?php echo get_the_ID(); ?>"
></script>

À coller dans single-product.php ou via le hook woocommerce_after_add_to_cart_button.

PrestaShop

<script
  src="https://widget.tissova.fr/tissova.js"
  data-api-key="VOTRE_CLE_API"
  data-produit-id="{$product.id}"
></script>

À coller dans le template produit de votre thème.

HTML personnalisé

<script
  src="https://widget.tissova.fr/tissova.js"
  data-api-key="VOTRE_CLE_API"
  data-produit-id="VOTRE_ID_PRODUIT"
></script>

Pour un site sans CMS, renseignez directement votre identifiant produit à la place de VOTRE_ID_PRODUIT.

Détection automatique du produit

Si vous ne renseignez pas data-produit-id, le widget détecte automatiquement l'identifiant produit depuis la balise meta suivante, déjà présente sur la majorité des sites utilisant le Pixel Facebook ou Google Shopping :

<meta property="product:retailer_item_id" content="VOTRE_ID_PRODUIT">

Cet identifiant doit correspondre exactement à celui renseigné pour le modèle 3D dans votre dashboard Tissova — c'est ce lien qui permet au widget de trouver le bon modèle.

Événements JavaScript

Le widget émet des événements personnalisés sur window que vous pouvez écouter pour réagir aux actions de vos visiteurs :

ÉvénementDescription
tissova:readyWidget initialisé et prêt à l'emploi
tissova:openedPopup d'essayage ouverte
tissova:addToCartUtilisateur ajoute au panier
tissova:productNotFoundAucun modèle 3D trouvé pour l'ID produit détecté — permet de masquer le bouton Tissova si le produit n'est pas encore configuré

tissova:ready — widget initialisé

window.addEventListener("tissova:ready", (event) => {
  console.log(event.detail);
});

tissova:opened — popup ouverte

window.addEventListener("tissova:opened", () => {
  console.log("Popup ouverte");
});

tissova:addToCart — utilisateur ajoute au panier

window.addEventListener("tissova:addToCart", (event) => {
  const { produitId, taille, coloris, quantite } = event.detail;
  // Ajoutez l'article à votre panier
});

tissova:productNotFound — aucun modèle 3D trouvé pour ce produit

window.addEventListener("tissova:productNotFound", (event) => {
  console.log(event.detail.produitId);
});

Personnalisation du bouton

Le widget détecte automatiquement le bouton « Ajouter au panier » de votre site (Shopify, WooCommerce, PrestaShop reconnus sans configuration) et insère le bouton Tissova juste avant. Pour contrôler précisément l'emplacement, ajoutez l'attribut data-tissova-anchor sur n'importe quel élément : le bouton Tissova s'insérera juste avant cet élément, en priorité sur toute détection automatique.

<!-- Le bouton Tissova apparaîtra ici -->
<button data-tissova-anchor class="btn-add-to-cart">
  Ajouter au panier
</button>

Si aucune ancre n'est trouvée (ni data-tissova-anchor, ni sélecteur reconnu automatiquement), le bouton apparaît en position fixe, en bas à gauche de l'écran.

Tester l'intégration

  1. 1Vérifiez que la clé API est correcte dans le dashboard.
  2. 2Vérifiez que la balise meta product:retailer_item_id est présente.
  3. 3Vérifiez que l'ID produit correspond à un modèle 3D uploadé dans le dashboard.
  4. 4Ouvrez la console du navigateur et vérifiez l'événement tissova:ready.
  5. 5Testez sur la page /demo de Tissova pour confirmer que le widget fonctionne.

Vitrine Tissova

La vitrine publique (tissova.fr/vitrine) présente les vêtements de vos collections aux utilisateurs de Tissova : ils les essaient sur leur avatar, puis se rendent sur votre page produit (lien suivi de ?ref=tissova). Les clics vers votre site sont comptés dans vos statistiques.

  1. Activez « Participer à la vitrine Tissova » dans Paramètres.
  2. Cochez « Afficher sur la vitrine Tissova » sur vos modèles (à l'upload ou dans Mes modèles 3D) et renseignez l'URL de la page produit.
  3. Tenez prix et stocks à jour avec le webhook ci-dessous : un produit en rupture sur toutes les tailles est masqué automatiquement.

Le prix affiché est celui renseigné à l'upload ou transmis par le webhook ; en cas de promotion, le prix barré et le prix promotionnel apparaissent sur la vitrine.

Webhook stock & prix

Envoyez à Tissova chaque changement de stock ou de prix d'une taille : POST /api/marque/webhook/stock, appelé depuis votre serveur (jamais depuis le navigateur, la clé API y serait exposée).

  • Authentification : en-tête x-tissova-api-key avec votre clé API (Intégration). Le produit doit appartenir à la marque de la clé.
  • produitId : l'ID produit de votre site (celui de data-produit-id) ou l'identifiant Tissova du modèle ; taille : XS, S, M, L, XL ou XXL.
  • enStock (obligatoire), stock (quantité, facultatif), prix (prix en boutique, facultatif), prixPromo (prix promotionnel, null pour terminer la promotion).
  • Si toutes les tailles passent en rupture, le produit est masqué de la vitrine et vous recevez un email.

Exemple de requête

POST https://api.tissova.fr/api/marque/webhook/stock
x-tissova-api-key: VOTRE_CLE_API
Content-Type: application/json

{
  "produitId": "SKU-MANTEAU-001",
  "taille": "M",
  "enStock": true,
  "stock": 12,
  "prix": 329,
  "prixPromo": 279
}

Réponse

Statut mis à jour de toutes les tailles du produit (401 : clé invalide, 404 : produit ou taille introuvable, 400 : champs invalides).

200 OK
{
  "produitId": "SKU-MANTEAU-001",
  "modeleId": "m3a1f…",
  "prix": 329,
  "ruptureTotale": false,
  "visibleVitrine": true,
  "tailles": [
    { "taille": "S", "enStock": false, "stock": 0, "prixPromo": null },
    { "taille": "M", "enStock": true, "stock": 12, "prixPromo": 279 }
  ]
}

Exemple Shopify

Webhook « Mise à jour de produit » de Shopify reçu par une fonction serverless, qui transmet chaque variante (option taille) à Tissova.

// Shopify → Tissova : webhook "products/update" (Settings › Notifications ›
// Webhooks, format JSON), reçu par une fonction serverless (Node 18+).
import crypto from "node:crypto";

const TISSOVA_API_KEY = process.env.TISSOVA_API_KEY;
const SHOPIFY_WEBHOOK_SECRET = process.env.SHOPIFY_WEBHOOK_SECRET;

export async function POST(request) {
  const body = await request.text();
  // Authenticity check (HMAC signature sent by Shopify)
  const hmac = crypto.createHmac("sha256", SHOPIFY_WEBHOOK_SECRET).update(body).digest("base64");
  if (hmac !== request.headers.get("x-shopify-hmac-sha256")) {
    return new Response("Invalid signature", { status: 401 });
  }

  const product = JSON.parse(body);
  for (const variant of product.variants) {
    // Sale price: price below compare_at_price
    const onSale = variant.compare_at_price && Number(variant.price) < Number(variant.compare_at_price);
    await fetch("https://api.tissova.fr/api/marque/webhook/stock", {
      method: "POST",
      headers: { "Content-Type": "application/json", "x-tissova-api-key": TISSOVA_API_KEY },
      body: JSON.stringify({
        produitId: String(product.id), // same ID as data-produit-id
        taille: variant.option1, // size option (XS … XXL)
        enStock: variant.inventory_quantity > 0,
        stock: Math.max(0, variant.inventory_quantity),
        prix: Number(onSale ? variant.compare_at_price : variant.price),
        prixPromo: onSale ? Number(variant.price) : null,
      }),
    });
  }
  return new Response("OK");
}

Exemple WooCommerce

Hooks WooCommerce qui transmettent chaque variation (attribut « taille ») à Tissova à chaque changement de stock ou de prix.

<?php
// WooCommerce → Tissova : à ajouter dans le functions.php du thème (ou une
// extension). Chaque variation (attribut "taille") est envoyée à Tissova à la
// mise à jour du produit ou de son stock.
const TISSOVA_API_KEY = 'VOTRE_CLE_API';

function tissova_sync_variation( $variation_id ) {
    $variation = wc_get_product( $variation_id );
    if ( ! $variation || ! $variation->is_type( 'variation' ) ) {
        return;
    }
    $regular = (float) $variation->get_regular_price();
    $sale    = $variation->get_sale_price();

    wp_remote_post( 'https://api.tissova.fr/api/marque/webhook/stock', array(
        'timeout' => 10,
        'headers' => array(
            'Content-Type'      => 'application/json',
            'x-tissova-api-key' => TISSOVA_API_KEY,
        ),
        'body'    => wp_json_encode( array(
            'produitId' => (string) $variation->get_parent_id(), // same ID as data-produit-id
            'taille'    => $variation->get_attribute( 'pa_taille' ),
            'enStock'   => $variation->is_in_stock(),
            'stock'     => max( 0, (int) $variation->get_stock_quantity() ),
            'prix'      => $regular,
            'prixPromo' => $sale !== '' ? (float) $sale : null,
        ) ),
    ) );
}

// Stock change of a variation (order, manual edit)
add_action( 'woocommerce_variation_set_stock', function ( $variation ) {
    tissova_sync_variation( $variation->get_id() );
} );
add_action( 'woocommerce_variation_set_stock_status', 'tissova_sync_variation' );

// Product saved from the admin (price, sale price…)
add_action( 'woocommerce_update_product', function ( $product_id ) {
    $product = wc_get_product( $product_id );
    if ( $product && $product->is_type( 'variable' ) ) {
        foreach ( $product->get_children() as $variation_id ) {
            tissova_sync_variation( $variation_id );
        }
    }
} );

FAQ technique

Le script se charge une seule fois avec la page, mais le rendu 3D (Three.js, chargement du modèle .glb) ne démarre que lorsque le visiteur clique sur le bouton « Essayer avec Tissova ». Avant ce clic, l'impact est minimal : aucune police externe n'est chargée, et la boucle de rendu se met en pause dès que la popup n'est plus visible à l'écran.

Oui. La popup passe automatiquement en plein écran sur petits écrans, et la rotation du modèle 3D fonctionne au doigt (tactile) exactement comme à la souris.

Le widget reste discret : il affiche un message « Bientôt disponible » à la place du viewer 3D plutôt que de planter, et émet l'événement tissova:productNotFound. Vous pouvez écouter cet événement pour masquer complètement le bouton Tissova sur les fiches produit non configurées.

Depuis l'onglet « Mes modèles 3D » de votre dashboard, remplacez le fichier .glb de la taille concernée. La mise à jour est effective immédiatement, sans validation manuelle de notre équipe.

En production, votre site doit être servi en HTTPS. Les fonctionnalités liées au compte (sauvegarde d'avatar, connexion) reposent sur un cookie cross-site qui exige une connexion sécurisée. Nous recommandons HTTPS dans tous les cas, y compris pour la simple visualisation 3D.

Depuis votre dashboard, onglet Intégration, cliquez sur « Régénérer la clé ». L'ancienne clé est invalidée immédiatement : pensez à mettre à jour la balise script sur votre site juste après.