Guide d'intégration
Intégrer la disponibilité et les délais de livraison JDM Distribution dans votre site ou votre outil, pas à pas.
Authentification
Chaque application créée sur le portail possède sa clé
(format jdmdd_…), à passer dans l'en-tête HTTP de chaque requête :
Authorization: Bearer jdmdd_votre_cle
La clé n'est affichée qu'une fois, à sa génération. En cas de perte ou de fuite, régénérez-la depuis le portail : l'ancienne est révoquée immédiatement.
Premier appel
curl -H "Authorization: Bearer jdmdd_votre_cle" \ "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262"
Réponse :
{
"results": {
"cts-hw-262": {
"found": true,
"priority": 1,
"source": "stock_odoo",
"stock_qty": 3,
"delivery_date": "2026-07-09",
"show_disclaimer": false,
"supplier_name": "",
"production_date": "",
"is_past_cutoff": false,
"cutoff_hour": "14:30",
"stock_capped": false,
"data_age_minutes": 1,
"extra_shipping_ht": 55.15,
"computed_at": "2026-07-08 15:30:24"
}
}
}
Paramètres de la requête
| Paramètre | Rôle | Défaut |
|---|---|---|
refs | Références produit (default_code) séparées par des virgules. Jusqu'à 200 par appel. | obligatoire |
max_stock | Plafond du stock affiché : au-dessus, stock_qty est ramené à cette valeur et stock_capped passe à true. Utile pour ne pas révéler votre stock exact (« 24+ » plutôt que « 312 »). Mettez 0 pour renvoyer le stock réel sans plafond. | 24 |
carrier | none : date de PRÉPARATION sans expédition (vous gérez votre propre transport). Vide : transporteur JDM le plus rapide inclus. | default |
carrier_id | Calculer la date avec un transporteur précis de la liste /v1/carriers. | - |
carrier_days (+ carrier_saturday, carrier_sunday) | Calculer avec VOTRE transporteur : nombre de jours de livraison, et s'il livre le week-end. | - |
Choisir l'expédition
Par défaut, delivery_date est la date d'arrivée chez le client final,
expédition incluse (transporteur JDM le plus rapide). Trois autres modes :
# la liste des transporteurs JDM et leurs délais curl -H "Authorization: Bearer jdmdd_votre_cle" "https://product-api.jdm-distribution.fr/v1/carriers" # date de préparation SANS expédition (vous expédiez vous-même) curl ... "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262&carrier=none" # avec un transporteur JDM précis curl ... "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262&carrier_id=50" # avec VOTRE transporteur : 4 jours, livre le samedi curl ... "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262&carrier_days=4&carrier_saturday=1"
Transporteurs disponibles
La liste ci-dessous est celle renvoyée par /v1/carriers, toujours à jour :
| carrier_id | Transporteur | Délai | Livre samedi | Livre dimanche |
|---|---|---|---|---|
62 | DHL Express Livraison avant 09H | 1 jour | non | non |
63 | DHL Express Livraison avant 12h | 1 jour | non | non |
61 | DHL Express Livraison avant 18H | 1 jour | non | non |
54 | Colissimo Domicile avec signature | 2 jours | oui | non |
50 | Colissimo Domicile sans signature | 2 jours | oui | non |
53 | Colissimo ECO Outre Mer | 2 jours | non | non |
52 | Colissimo Points de retrait | 2 jours | oui | non |
60 | Livraison palettes | 2 jours | non | non |
64 | DHL Economy Livraison sous 48h/96h | 3 jours | non | non |
47 | Stockage Palette | 90 jours | non | non |
Chaque réponse indique le mode appliqué dans carrier_applied
(default, none, carrier_id ou custom, avec le
délai retenu). Les jours de livraison sautent les week-ends non couverts, les jours fériés et les
fermetures JDM, comme le calcul standard.
# plafonner l'affichage à 50 pièces curl -H "Authorization: Bearer jdmdd_votre_cle" \ "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262&max_stock=50"
Le plafond ne change QUE le nombre affiché : la disponibilité, la priorité et la date de livraison restent calculées sur le stock réel. Le plafond s'applique par appel, donc à toutes les références (et donc marques) de la requête.
Lire la réponse
Le champ central est priority : il indique d'où vient la disponibilité
et comment présenter l'information à votre client.
| priority | Signification | Affichage conseillé |
|---|---|---|
| 1 | En stock chez JDM Distribution (stock_qty renseigné). Expédition immédiate,
le jour même avant l'heure limite. |
« En stock », vert, avec la quantité |
| 2 | Réassort en cours : commande fournisseur confirmée, arrivée planifiée
(purchase_date_planned). |
« Réassort en cours », bleu, avec la date |
| 25 | Commandé chez le fournisseur pour une vente en attente. | Comme 2 |
| 3 | Disponible chez le fournisseur (supplier_name) : la date intègre
commande, préparation, transit et livraison. |
« Disponible sur commande », avec la date |
| 35 | Connu du fournisseur mais en fabrication ou réapprovisionnement.
production_date peut donner la prochaine production. |
« Délai fabricant », orange, avec la date |
| 36 | Arrêté par le fabricant : plus disponible (delivery_date vide). |
« Produit arrêté », gris |
| 4 | Aucune donnée temps réel : estimation par défaut, prudente. | « Délai estimé », avec la date et une réserve |
| Champ | Contenu |
|---|---|
found | false : la référence n'est pas au catalogue JDM Distribution (tous les autres champs sont vides). N'affichez rien pour cette référence. true dans tous les autres cas. |
delivery_date | Date de livraison estimée, format AAAA-MM-JJ. Vide pour priority 36 et si found est false. |
stock_qty | Quantité en stock (priority 1 et parfois 3), plafonnée à la valeur de max_stock (24 par défaut). 0 sinon. |
stock_capped | true : le stock réel dépasse max_stock et a été plafonné. Affichez par exemple « 24+ en stock » au lieu du nombre exact. |
show_disclaimer | true : afficher une mention « estimation » (tout sauf le stock réel). |
is_past_cutoff | true : l'heure limite d'expédition du jour est passée, la date en tient compte. |
cutoff_hour | Heure limite d'expédition du jour, format HH:MM (ex. 14:30). null si aucune heure limite n'est définie. Utile pour afficher « Commandez avant 14:30 pour une expédition aujourd'hui ». |
price_ht / discount_pct / customer_price_ht | Prix HT catalogue, votre remise professionnelle (%) et votre prix HT remisé. Présents uniquement pour les comptes clients professionnels JDM Distribution dont l'email est vérifié (voir la section Prix et remise). null si la référence n'a pas de prix. |
palette_stock | Quantité disponible sur VOS propres palettes stockées chez JDM Distribution (module Ma Palette) pour cette référence. Présent uniquement si votre compte est rattaché à un client JDM (email vérifié) ET que vous avez du stock sur palette pour cette référence. Strictement privé : vous ne voyez QUE vos palettes. Indépendant de found : vos produits hors catalogue JDM sont aussi comptés. |
extra_shipping_ht | Frais de port supplémentaires HT (en €) qui s'ajoutent au transport habituel pour cette référence (marques volumineuses/importées, ex. Scorpion). Présent uniquement quand un supplément s'applique : produit concerné ET non disponible en stock local (priority ≠ 1). Absent sinon (aucun supplément à afficher). S'applique à tous les comptes. |
computed_at | Horodatage de la dernière vérification de la donnée (heure de Paris). Vide pour priority 4. |
data_age_minutes | Âge de la donnée en minutes, prêt à afficher (« stock vérifié il y a {X} min »). Moins de 3 minutes en conditions normales pour les données fournisseur. null pour priority 4 et les références hors catalogue. |
is_stale / stale_age | Donnée servie en mode dégradé et son âge en minutes (rare). |
Playbook 1 : badge de disponibilité sur une fiche produit
Un appel par produit affiché, au chargement de la page (ou en AJAX). Mettez la
réponse en cache local 5 minutes. Côté JDM, chaque flux fournisseur est relevé toutes les 2 minutes et les délais recalculés dans la foulée : la donnée fournisseur servie a moins de 3 minutes en conditions normales. Le champ data_age_minutes vous donne l'âge exact à afficher.
# PHP $ch = curl_init("https://product-api.jdm-distribution.fr/v1/delivery/" . rawurlencode($reference)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer " . $cle]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $d = json_decode(curl_exec($ch), true); $labels = [1 => "En stock", 2 => "Réassort en cours", 25 => "Réassort en cours", 3 => "Disponible sur commande", 35 => "Délai fabricant", 36 => "Produit arrêté", 4 => "Délai estimé"]; if ($d && ($d["found"] ?? true)) { echo $labels[$d["priority"]] . " : livré le " . $d["delivery_date"]; if (isset($d["data_age_minutes"])) { echo " (vérifié il y a " . $d["data_age_minutes"] . " min)"; } } // 404 ou found=false : référence hors catalogue JDM, ne rien afficher
Playbook 2 : panier multi-références
Un seul appel pour tout le panier (jusqu'à 200 références), jamais un appel par ligne :
# Python import requests refs = ["cts-hw-262", "0-1850s", "fm210cch-blu"] r = requests.get( "https://product-api.jdm-distribution.fr/v1/delivery", params={"refs": ",".join(refs)}, headers={"Authorization": f"Bearer {cle}"}, timeout=10, ) results = r.json()["results"] # date globale du panier = la plus tardive des lignes connues du catalogue date_panier = max(v["delivery_date"] for v in results.values() if v.get("found") and v["delivery_date"])
Playbook 3 : parcourir un catalogue complet
Pour rafraîchir la disponibilité de tout votre catalogue, découpez en lots de 200 et lissez sur la durée en respectant les quotas :
# JavaScript (Node) const lots = []; for (let i = 0; i < refs.length; i += 200) lots.push(refs.slice(i, i + 200)); for (const lot of lots) { const r = await fetch( `https://product-api.jdm-distribution.fr/v1/delivery?refs=${encodeURIComponent(lot.join(","))}`, { headers: { Authorization: `Bearer ${cle}` } }); const { results } = await r.json(); // … enregistrer, puis respirer pour rester sous 300 req/min await new Promise(ok => setTimeout(ok, 250)); }
Playbook 4 : boutique complète
Pour équiper une boutique entière, rien de plus à configurer côté API : les délais
par marque (jours de commande fabricant, acheminement, retour en stock) sont gérés
centralement par JDM Distribution et déjà intégrés aux dates renvoyées. Interrogez
simplement /v1/delivery pour chaque page (fiche produit, listing, panier)
comme dans les playbooks 1 à 3.
Astuce d'affichage : combinez la réponse avec vos propres règles de vente. Si votre produit est marqué « non disponible à la vente » ou « rupture avec commandes refusées » dans votre back-office, affichez cet état plutôt que le délai renvoyé par l'API.
- Vous expédiez vous-même ? Appelez avec
carrier=nonepour obtenir la date de préparation, oucarrier_days=Navec le délai de votre transporteur (voir la section Paramètres). - Client professionnel JDM ? Vos réponses incluent vos prix remisés
(
customer_price_ht) : de quoi afficher marge et prix d'achat dans votre back-office (voir Prix et remise pro). - Fraîcheur visible : affichez « stock vérifié il y a
data_age_minutesmin » sous vos délais, comme le fait la boutique JDM : c'est un vrai argument de réassurance.
Playbook 5 : gérer les erreurs
| Code | Cause | Réaction conseillée |
|---|---|---|
400 | Requête invalide (plus de 200 références, paramètre refs vide) | Découper en lots de 200 maximum |
401 | Clé absente, invalide ou révoquée | Vérifier la clé ; la régénérer depuis le portail |
402 | Licence de l'application inactive (impayé, résiliation) | Régulariser l'abonnement depuis le portail |
404 | Référence hors catalogue JDM (appel unitaire /v1/delivery/{ref} uniquement) | Ne pas réessayer ; masquer le bloc délai pour ce produit |
403 | Adresse IP hors liste autorisée | Contactez JDM Distribution pour ajuster la liste d'IP autorisées |
429 | Quota dépassé (300/min ou 1 200/h) | Attendre et réessayer avec un backoff exponentiel |
5xx | Incident côté service | Servir votre cache local ; réessayer plus tard |
Playbook 6 : frais de port supplémentaires (marques importées)
Certaines références de marques volumineuses ou importées (par exemple les échappements
Scorpion) entraînent un supplément de transport qui s'ajoute
aux frais de livraison habituels. L'API vous le signale via le champ
extra_shipping_ht (montant HT en euros).
Règle d'affichage, identique à la boutique JDM :
- Le champ n'est présent que lorsqu'un supplément s'applique réellement :
référence concernée et non disponible en stock local (
priority≠ 1). - Quand le produit est en stock chez JDM (
priority= 1), il n'y a pas de supplément : le champ est absent, n'affichez rien. - Une référence sans supplément configuré n'a jamais ce champ : testez simplement sa présence.
- Le montant est HT : appliquez votre propre TVA pour un affichage TTC.
# PHP : fiche produit if (isset($d["extra_shipping_ht"])) { $ht = $d["extra_shipping_ht"]; $ttc = round($ht * 1.20, 2); // votre taux de TVA echo "Supplément de frais de port : " . $ttc . " € TTC " . "(cette référence est importée et expédiée séparément)"; } // sinon : aucun supplément, ne rien afficher # Panier : additionner les suppléments des lignes concernées $supplement = 0; foreach ($lignesPanier as $ref => $qte) { $r = $reponse["results"][$ref] ?? []; if (isset($r["extra_shipping_ht"])) { $supplement += $r["extra_shipping_ht"]; // une fois par référence concernée } } // $supplement s'ajoute HT à vos frais de transport, avant TVA
Playbook 7 : votre stock sur palette (Ma Palette)
Si vous êtes client de JDM Distribution et que vous stockez vos propres marchandises
sur des palettes dans notre entrepôt (service « Ma Palette »), l'API vous
indique, pour chaque référence, la quantité que vous avez sur vos palettes
via le champ palette_stock. Vous pouvez ainsi afficher une disponibilité sur
votre propre site même lorsque le stock général JDM est à zéro.
- Strictement privé et sécurisé : le champ est calculé à partir de l'adresse email vérifiée de votre compte. Vous ne voyez QUE vos propres palettes ; aucun autre client ne peut voir les vôtres.
- Présent uniquement si vous avez du stock sur palette pour la référence demandée (absent sinon).
- Indépendant de
found: si vous stockez une référence qui n'est pas au catalogue JDM,palette_stockest tout de même renvoyé (c'est votre produit). - Rattachement : votre compte doit être créé avec l'email de votre compte client JDM et cet email doit être vérifié (voir la section Prix et remise pour le même mécanisme).
# PHP : disponibilité combinée entrepôt JDM + votre palette $d = $reponse["results"][$ref]; if (!empty($d["stock_qty"])) { echo "En stock : " . $d["stock_qty"]; // stock général JDM } elseif (isset($d["palette_stock"])) { echo "Disponible immédiatement : " . $d["palette_stock"] . " (votre stock sur palette)"; // votre marchandise } else { echo "Sur commande : livré le " . $d["delivery_date"]; }
Gérer vos clés et vos licences
Chaque application créée dans le portail porte sa propre clé API et sa propre licence (abonnement 49,99 € HT/mois). Vous gérez tout en autonomie depuis le portail.
Clé API
- À la création d'une application, vous déclarez le domaine du site qui l'utilisera,
et le prouvez une seule fois, au choix : un enregistrement DNS TXT
chez votre registrar, ou un fichier
jdm-dd-verify.txtdéposé à la racine du site (par FTP par exemple), contenant le jeton fourni par le portail (une licence = un site). La preuve est re-contrôlée périodiquement : laissez-la en place. - La clé se génère une fois la licence active et le domaine vérifié, et n'est affichée qu'une seule fois. Copiez-la aussitôt.
- Régénérer une clé (bouton sur l'application) révoque immédiatement l'ancienne et en émet une nouvelle : à faire en cas de perte ou de fuite.
- Une application a une seule clé active à la fois. Pour cloisonner deux intégrations, créez deux applications.
Licence et abonnement
- Le paiement d'une application se fait par Stripe (TVA calculée selon votre pays de facturation). Tant que la licence n'est pas active, aucune clé ne peut être générée et l'API répond
402. - Gérer mes abonnements ouvre l'espace Stripe : changer la carte, télécharger les factures, résilier. La résiliation prend effet en fin de période.
- Vos factures apparaissent aussi dans la page Facturation du portail (numéro, montant TTC, PDF).
Supprimer une application et réutiliser une licence
- La zone de danger d'une application permet de la supprimer même si elle est payée (confirmation par recopie du nom). Sa clé cesse aussitôt de fonctionner ; votre historique de facturation reste conservé.
- Par défaut, la licence reste active et libre : la prochaine application que vous créez la réutilise sans nouveau paiement. Vous pouvez ainsi réorganiser vos applications tant que vous avez des licences actives.
- Si vous cochez « résilier aussi l'abonnement » à la suppression, la licence n'est pas conservée et la facturation s'arrête en fin de période.
Prix et remise professionnelle
Si vous êtes client professionnel JDM Distribution, l'API renvoie en plus,
pour chaque référence, votre tarif : price_ht (prix catalogue HT),
discount_pct (votre remise) et customer_price_ht (votre prix HT remisé),
identiques à ceux de votre compte sur la boutique JDM.
Comment l'activer
- Créez votre compte développeur avec la même adresse email que votre compte client professionnel JDM Distribution.
- Confirmez votre adresse via l'email de vérification : c'est cette confirmation qui rattache vos conditions tarifaires (personne ne peut utiliser votre adresse sans accès à votre boîte mail).
- Vos appels
/v1/deliveryincluent alors automatiquement les trois champs de prix.
La réponse avec vos tarifs
curl -H "Authorization: Bearer jdmdd_votre_cle" \ "https://product-api.jdm-distribution.fr/v1/delivery?refs=cts-hw-262"
{
"results": {
"cts-hw-262": {
"found": true,
"priority": 1,
"stock_qty": 3,
"delivery_date": "2026-07-17",
"price_ht": 227.68,
"discount_pct": 30.0,
"customer_price_ht": 159.38
}
}
}
| Champ | Contenu |
|---|---|
price_ht | Prix public catalogue, hors taxes. Celui affiché aux visiteurs de la boutique JDM. |
discount_pct | Votre remise professionnelle sur CETTE référence, en pourcentage. Elle varie selon les produits et les marques (elle n'est pas uniforme sur tout le catalogue). |
customer_price_ht | Votre prix d'achat HT : price_ht × (1 - remise). C'est le même prix que sur votre compte boutique. |
Playbook : fiche produit avec prix d'achat et marge
Cas type d'un revendeur : afficher sur votre back-office le prix d'achat JDM à côté de votre prix de vente, pour surveiller votre marge en temps réel.
# PHP : dispo + prix d'achat + marge en un seul appel $r = json_decode(file_get_contents($url), true)['results']['cts-hw-262']; if ($r['found'] && isset($r['customer_price_ht'])) { $achat = $r['customer_price_ht']; // 159.38 $marge = $mon_prix_vente_ht - $achat; echo "Achat JDM : {$achat} € HT (remise {$r['discount_pct']} %)"; echo "Marge : {$marge} € | Livrable le {$r['delivery_date']}"; }
Playbook : décider quoi commander
Croisez les trois informations que renvoie chaque référence : votre prix, la disponibilité et le délai. Exemple de règles d'achat automatisables :
| Situation dans la réponse | Lecture business |
|---|---|
priority 1 + bonne remise | En stock JDM à votre tarif : commande sûre, livraison rapide. Priorisez ces références dans vos réassorts. |
priority 3 (stock usine) | Disponible sur commande : le prix est ferme, le délai intègre l'acheminement. Utile pour les ventes sur devis. |
priority 35 avec production_date | Rupture fabricant datée : vous pouvez prendre la commande client en connaissant votre prix ET la date de production. |
discount_pct élevé + priority 1 | Marge maximale et stock immédiat : bon candidat pour vos promotions. |
Bonnes pratiques
- Testez la présence des champs, pas leur valeur : ils sont absents pour un
compte non rattaché, et
nullquand la référence n'a pas de prix catalogue. Votre code doit fonctionner dans les trois cas. - Tout est hors taxes : appliquez votre propre TVA selon votre pays et votre régime. Aucun prix TTC n'est renvoyé.
- Fraîcheur : les prix et remises sont synchronisés depuis la boutique JDM au fil de la journée. Un changement de tarif ou de groupe se propage en une heure au plus : inutile de re-vérifier plus souvent, un cache local de 1 h est adapté pour les prix (gardez 5 min pour la disponibilité).
- Votre remise n'est pas un pourcentage unique : elle est définie produit par produit. Ne l'extrapolez pas d'une référence à l'autre, lisez-la dans chaque réponse.
- Confidentialité :
customer_price_htest VOTRE tarif négocié. Ne l'affichez jamais côté public (fiches produit, JS front) : réservez-le à votre back-office ou vos outils internes.
Sans compte professionnel JDM rattaché, ces champs sont simplement absents de la réponse : le reste de l'API fonctionne à l'identique. Vous êtes client pro et vos tarifs n'apparaissent pas ? Vérifiez que l'email de votre compte développeur est bien celui de votre compte boutique, puis contactez JDM Distribution.
Limites
- 600 requêtes par minute et 6 000 par heure, par application. Un email automatique
vous prévient dès 80 % de la limite horaire ; au-delà de la limite, l'API répond
429jusqu'à la fenêtre suivante. Besoin de plus ? La limite de votre application peut être relevée : contactez [email protected]. - 200 références maximum par appel
- Les références sont insensibles à la casse (
CTS-HW-262etcts-hw-262sont équivalents) - Une référence hors catalogue JDM renvoie
found: falseen appel groupé (les autres champs sont vides : n'affichez rien) et404en appel unitaire. Vos références propres qui ne correspondent pas au catalogue JDM ne reçoivent donc jamais de date inventée.
Congés et fermetures
GET /v1/vacation indique si une fermeture est en cours ou approche.
Les dates de livraison renvoyées par /v1/delivery intègrent déjà ces
périodes : cet endpoint sert uniquement à afficher un bandeau d'information.
{ "is_currently_on_vacation": false,
"current_or_next": { "start": "2026-08-01", "end": "2026-08-15",
"is_current": false, "return_date": null } }
Référence technique complète : documentation OpenAPI. Une question sur les données ou votre licence ? Contactez JDM Distribution.
