Tarification vétérinaire — override de prix par relation
Cas d'usage donnée personnalisée + override · Le pattern phare pour illustrer la puissance de ShopiMind : un même produit affiche un prix différent par client parce que chaque client est rattaché à un vétérinaire qui négocie ses propres tarifs.
Le besoin métier
Vous vendez des aliments thérapeutiques et soins vétérinaires pour animaux. Chaque client a été référencé par un vétérinaire prescripteur qui a négocié ses propres tarifs sur tout ou partie de votre catalogue.
Concrètement :
- Le sac de croquettes Veterinary Diet 12 kg coûte 79,90 € au tarif public.
- Le Dr Martin (cabinet à Lyon) le revend à 64 € à ses 230 clients référencés.
- Le Dr Durand (cabinet à Lille) le revend à 71 € à ses 180 clients référencés.
- Mme Dubois (cliente du Dr Martin) doit voir 64 € dans tous les contenus marketing qui lui sont adressés : email post-achat, relance d'abandon de panier, email de recommandation, popin sur le site et smart content.
Géré par codes promo manuels, c'est ingérable (700 vétérinaires × 1 200 produits = 840 000 combinaisons potentielles) et les emails marketing affichent toujours le prix public.
La solution ShopiMind
Trois définitions personnalisées qui se chaînent par relations, et un override qui remplace le prix natif par le prix négocié quand le contact connecté est rattaché à un vétérinaire.
Le modèle de données
Définition « Vétérinaire »
Le référentiel des cabinets prescripteurs.
nom(texte) — clé d'unicité.ville,telephone,email(texte).
Définition « Tarif vétérinaire »
La grille négociée. Une ligne = un prix négocié par un véto sur un produit.
veto_id(number) — relation vers la définition Vétérinaire.product_id(texte) — relation vers l'entité Produit.price(decimal) — le prix négocié.price_discount(decimal) — un éventuel prix promo.- Clé d'unicité :
(veto_id, product_id)— garantit un seul tarif par couple véto / produit.
Définition « Affectation vétérinaire »
Quel véto suit quel client.
contact_id(number) — relation vers l'entité Contact.veto_id(number) — relation vers la définition Vétérinaire.since(date) — début de la relation client / véto.- Clé d'unicité :
contact_id— un client est suivi par au plus un véto.
Override de prix
Le champ products.price reçoit une surcharge prioritaire depuis Tarif vétérinaire.price. À chaque résolution d'un produit pour un contact donné, ShopiMind :
- Lit l'Affectation vétérinaire du contact.
- Cherche dans Tarif vétérinaire une ligne pour ce couple
(veto_id, product_id). - Si elle existe, le prix retourné est celui de la grille véto. Sinon, fallback sur le prix public natif.
Mise en place
1. Créer le catalogue des vétérinaires
curl -X POST 'https://core.shopimind.com/v1/custom-data-definitions' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '{
"name": "Veto",
"description": "Catalogue des vétérinaires prescripteurs",
"unique_keys": ["nom"],
"fields": [
{ "name": "nom", "label": "Nom du veto", "type": "text", "required": true },
{ "name": "ville", "label": "Ville", "type": "text", "required": false },
{ "name": "telephone", "label": "Telephone", "type": "text", "required": false },
{ "name": "email", "label": "Email", "type": "text", "required": false }
]
}'Notez l'id_definition retourné — disons 184.
2. Créer la grille tarifaire véto × produit
C'est le cœur du système : une définition avec deux relations (vers la définition Véto, et vers l'entité Produit).
curl -X POST 'https://core.shopimind.com/v1/custom-data-definitions' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '{
"name": "VetoTarif",
"description": "Prix négocié par un véto sur un produit du catalogue",
"unique_keys": ["veto_id", "product_id"],
"fields": [
{ "name": "veto_id", "label": "Veto", "type": "number", "required": true },
{ "name": "product_id", "label": "Produit (ID)", "type": "text", "required": true },
{ "name": "price", "label": "Prix negocie", "type": "decimal", "required": true },
{ "name": "price_discount", "label": "Prix promo", "type": "decimal", "required": false }
],
"relationships": [
{ "sourceField": "veto_id", "targetSchemaType": "custom", "targetSchema": "184", "targetField": "id" },
{ "sourceField": "product_id", "targetSchemaType": "system", "targetSchema": "products", "targetField": "product_id" }
]
}'id_definition retourné : 185.
3. Créer l'affectation contact → véto
curl -X POST 'https://core.shopimind.com/v1/custom-data-definitions' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '{
"name": "AffectationVeto",
"description": "Quel vétérinaire suit chaque contact",
"unique_keys": ["contact_id"],
"fields": [
{ "name": "contact_id", "label": "Contact", "type": "number", "required": true },
{ "name": "veto_id", "label": "Veto", "type": "number", "required": true },
{ "name": "since", "label": "Depuis", "type": "date", "required": false }
],
"relationships": [
{ "sourceField": "contact_id", "targetSchemaType": "system", "targetSchema": "contacts", "targetField": "id_contact" },
{ "sourceField": "veto_id", "targetSchemaType": "custom", "targetSchema": "184", "targetField": "id" }
]
}'id_definition retourné : 186.
4. Activer l'override de prix
C'est l'étape critique. On dit à ShopiMind : « pour le champ products.price, va chercher en priorité dans VetoTarif.price ».
curl -X PUT 'https://core.shopimind.com/v1/custom-data-definitions/overrides?target_system_schema=products&system_field_name=price' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '{
"overrides": [
{ "id_custom_data_definition": 185, "custom_field_name": "price", "priority": 1 }
]
}'Et la même chose pour price_discount :
curl -X PUT 'https://core.shopimind.com/v1/custom-data-definitions/overrides?target_system_schema=products&system_field_name=price_discount' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '{
"overrides": [
{ "id_custom_data_definition": 185, "custom_field_name": "price_discount", "priority": 1 }
]
}'Effet immédiat
Dès que l'override est actif, tout scénario ShopiMind qui résout un produit pour un contact applique automatiquement le bon prix : emails post-achat, emails de recommandation, relances d'abandon de panier, popins sur le site, smart content. Aucune logique conditionnelle à écrire dans les templates — ShopiMind résout dynamiquement la valeur.
5. Synchroniser les données depuis votre back-office
Vétérinaires (à chaque ajout/modif côté CRM) :
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/184' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '[
{ "nom": "Dr Martin Lyon", "ville": "Lyon", "telephone": "04 78 12 34 56", "email": "contact@vetmartin.fr" },
{ "nom": "Dr Durand Lille", "ville": "Lille", "telephone": "03 20 56 78 90", "email": "contact@drdurand.fr" }
]'L'upsert se fait sur nom (clé d'unicité). Récupérez les id retournés (par exemple Dr Martin = 12, Dr Durand = 13) — ils servent de clés étrangères pour la grille tarifaire et les affectations.
Grille tarifaire (probablement quotidien, batché) :
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/185' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '[
{ "veto_id": 12, "product_id": "VET-DIET-12KG", "price": 64.00, "price_discount": 58.00 },
{ "veto_id": 12, "product_id": "VET-DIET-3KG", "price": 19.50, "price_discount": null },
{ "veto_id": 13, "product_id": "VET-DIET-12KG", "price": 71.00, "price_discount": null }
]'Maximum 50 enregistrements par requête — un push initial pour 700 vétérinaires × 200 produits référencés en moyenne représente ~2 800 requêtes batchées (parallélisable jusqu'à ~10 workers en restant sous le quota de 600 req/min).
Affectations contact → véto :
curl -X POST 'https://core.shopimind.com/v1/custom-data-records/186' \
-H 'spm-api-key: VOTRE_CLE_API' \
-H 'Content-Type: application/json' \
--data '[
{ "contact_id": { "by": "id_customer", "value": "CUST-A4521" }, "veto_id": 12, "since": "2024-03-15" },
{ "contact_id": { "by": "email", "value": "marie.dupont@example.com" }, "veto_id": 12, "since": "2025-09-20" },
{ "contact_id": { "by": "id_customer", "value": "CUST-A4523" }, "veto_id": 13, "since": "2025-11-08" }
]'Référencer un contact sans pré-résolution
Pas besoin de récupérer l'id_contact ShopiMind avant d'écrire : envoyez directement votre id_customer ou l'email, le serveur résout. Voir Référencer un contact.
6. Vérifier l'override dans un email
Créez un scénario simple de récapitulatif post-achat. À l'envoi, ShopiMind résout automatiquement le prix de chaque produit en fonction du contact destinataire et de son affectation vétérinaire.
Pour Mme Dubois (rattachée Dr Martin), le sac de croquettes apparaît à 64 € ; pour M. Bernard (Dr Durand), la même ligne s'affiche à 71 € ; pour un client sans véto, 79,90 €. Aucune logique conditionnelle dans le template — ShopiMind résout dynamiquement la bonne valeur pour chaque destinataire.
Aller plus loin
Refresh automatique des prix
Quand un véto modifie ses tarifs, repush la grille du véto en bulk via saveCustomDataRecords (l'upsert sur la clé (veto_id, product_id) met à jour les lignes existantes sans duplication).
Limitations à connaître
- L'override ne couvre aujourd'hui que
products.priceetproducts.price_discount. Pas (encore) lequantity(stock), lenameou ladescription. - Trois sources priorisées maximum par champ surchargé.
Récapitulatif
| Étape | Endpoint | Quand |
|---|---|---|
| Créer définition Véto | createCustomDataDefinition | Une fois |
| Créer définition VetoTarif (avec 2 relations) | createCustomDataDefinition | Une fois |
| Créer définition AffectationVeto (avec 2 relations) | createCustomDataDefinition | Une fois |
| Activer l'override prix | updateFieldOverridePriorities × 2 | Une fois (price + price_discount) |
| Sync vétos | saveCustomDataRecords | À chaque ajout/modif côté CRM |
| Sync grille tarifaire | saveCustomDataRecords | Quotidien batché OU temps réel sur changement |
| Sync affectations | saveCustomDataRecords | Quotidien OU à chaque création de compte |