API d'opportunité de vente
Pour commencer
L'API des opportunités de vente est liée à la gestion des pistes de vente. L'architecture de l'API des opportunités de vente est inhabituelle car elle appelle votre CRM pour envoyer des opportunités de vente.
L'objectif de l'API des opportunités de vente est d'envoyer rapidement des opportunités de vente aux concessionnaires, permettant un suivi rapide avec les clients et une mise à jour facile du statut vers BRP.
La section Comprendre les opportunités de vente fournit des informations sur la gestion des pistes de vente et l'utilisation de l'API des opportunités de vente.
Terminologie de BRP
Avant de commencer, définissons quelques termes.
- Une piste de vente : un client potentiel intéressé par un produit BRP. Certaines informations sur ce client potentiel sont disponibles, y compris son nom, son numéro de téléphone ou son adresse e-mail, ainsi que le produit qui l'intéresse.
- Opportunité de vente : Une piste de vente validée et qualifiée a été assignée à un concessionnaire.
- Disposition: C'est le résultat de l'opportunité de vente traitée par le concessionnaire. L'opportunité de vente peut aboutir à contacter le client, à une vente d'unité ou à un abandon.
Par où commencer ? Lisez-moi en premier !
Avant de commencer à travailler sur cette API, vous devez lire les sections suivantes si vous ne les avez pas déjà consultées :
- Informations techniques pour des informations techniques générales sur l'API et les environnements.
- Authentification et informations d’identification pour des détails sur l'authentification et les identifiants.
- Processus de Certification pour des détails sur le processus de certification et Jira.
- Obtenir de l'aide pour des détails sur la façon d'obtenir de l'aide et Jira.
Résumé de l'entreprise
Sujet | Description |
|---|---|
Portée | Prospects de vente dans toutes les régions |
Scénarios |
|
Fonctionnalités principales |
|
Processus d'affaires pris en charge |
|
Avantages pour les concessionnaires |
|
Avantages pour BRP |
|
Informations techniques
Caractéristiques
Type d’API | Type de DSP | Version DCP | Complexité |
|---|---|---|---|
Obtenir des données depuis le BRP | DMS | V3 - International | Faible |
Envoyer des données au BRP | CRM | V4 - Amérique du Nord | Un peu plus |
Transaction avec le BRP | | | Un peu plus encore |
Authentification
L'API utilise Authentification de l'application.
Vous avez besoin d’un jeton d’accès valide avant d’appeler cette API, ou vous devez appeler l’API d'authentification d'application pour en obtenir un.
Le jeton d’accès est valide pendant 30 minutes ! (1799 secondes)
URL de base
Test | https://qa-cloud-api.brp.com/dcp/v4 |
|---|---|
Production | https://cloud-api.brp.com/dcp/v4 |
Ressource : Opportunité de vente
La ressource Opportunité de vente fournit des informations de base sur les opportunités de vente BRP. Elle inclut des informations sur le consommateur, l’unité qui l’intéresse et le statut du consommateur.
Représentation JSON
{
"sales_opportunity_id": "00Q6s000001TQcaEAG",
"dealer_no": "0000695896",
"language": "en",
"consumer": {
"first_name": "Mike3",
"last_name": "Debrush",
"culture_code": "en-US",
"phone_no": "819 532-1234",
"mobile_no": "819 532-1278",
"email": "[email protected]",
"address": {
"street": "458 Main Street",
"city": "Orlando",
"state": "FL",
"country": "US",
"postal_code": "12562-12345"
}
},
"product_interest": {
"category": "Contest/Events/Demo",
"model": "SSV all track",
"brand": "canam_side_by_side"
},
"status": [
{
"code": "new",
"set_on": "2025-05-20T19:19:00Z"
}
],
"model_number": "0008HSB00",
"comments": "I want a tough SSV",
"assignment_date": "2025-05-20T15:19:00Z",
"start_date": "2025-05-20T19:19:00Z",
"byo_uri": "https://can-am.brp.com/off-road/ca/fr/configuration-et-prix/app.html?platform=SSV_SSP_2_MAX&package=4X4_X&unitid=0008HSB00",
"campaign_name": "",
"event_description": "SD054_FB_CONTEST___ECOMM-WIN-A-PFD-US-EN",
"intent_to_buy": "4-6 months",
"lead_score": "Medium",
"questions_answers" : [
{ "question": "What are you looking for in a SSV?",
"answer": "Sun and fun"
},
{ "question": "Who will use the SSV?",
"answer": "Me and my dog"
}
],
"ownership": {
"brand": "Polaris RZR Trail",
"trade_in": 1000.00
}
}
Propriétés
Property | Type | Definition | Notes |
|---|---|---|---|
sales_opportunity_id | string | Sales opportunity identifier | Length:18 |
dealer_no | string | The BRP dealer number is assigned to the sales opportunity. | Length:10 |
language | string | The language of the customer in ISO language code (ISO-639-1) | Format xx |
consumer | object | consumer information | |
consumer .first_name | string | Consumer's first name | Length:40 |
consumer .last_name | string | Consumer's last name | Length:40 |
consumer .culture_code | string | The communication language of the consumer in the ISO language code (ISO-639-1 + ISO 3166-1) | Length:80 |
consumer .phone_no | string | Consumer phone number | Length:40 |
consumer .mobile_no | string | Consumer mobile phone | Length:40 |
consumer .email | string | Consumer email | Length:80 |
consumer .address | object | consumer address | |
consumer.address .street | string | Address of the consumer | Length:255 |
consumer.address .city | string | City of the consumer | Length:40 |
consumer.address .state | string | Code that uniquely identifies a province/state in a country. 👉 The property contains the second part of the subdivision code of the ISO 3166-2 format. For example, the complete subdivision code for Oregon is "US-OR". The property contains "OR". | Length:2 |
consumer.address .country | string | Code that uniquely identifies a country, in ISO 3166-1 format. | Length:2 |
consumer.address .postal_code | string | Postal code of the consumer. | Length:20 |
product_interest | object | product interest selected by the consumer | |
product_interest .category | string | The category of the product in which the consumer is interested. Free text field. | Max Length:100 |
product_interest .model | string | Model of the product in which the consumer is interested. | Max Length:100 |
product_interest .brand | string | The product brand the consumer is interested in.
| Max Length:100 |
status* | list of objects | List of statuses attached to the sales opportunity | |
status.code* | string | Status code of the consumer
| |
status.set_on* | datetime | Date and time at which the status has been set, in ISO 8601 format. | Format: YYYY-MM-DDTHH:MM:SSZ |
model_no | string | The model in which the customer is interested. | 9 characters, format 000xxxx00 |
comment | string | Any comments left by the user. | Max Length:4000 |
assignment_date | string | Date and time the lead was assigned to the dealer, in UTC. In ISO 8601 format. | Format: YYYY-MM-DDTHH:MM:SSZ |
start_date | string | Date and time when the 2-hour timer started, in UTC. In ISO 8601 format. | Format: YYYY-MM-DDTHH:MM:SSZ |
byo_uri | string | URI (Uniform Resource Identifier) to the Build-Your-Own prepared by the customer | Max Length:255 |
campaign_name | string | Name of the promotion campaign linked to the customer request. | Max Length:50 |
event_description | string | The event description is created to track the campaign results. Each event description respects a nomenclature and has the following information: - Unique ID - Source (e.g. Web, Facebook...) - Category (e.g. Contest, Promo, Demo, Request a quote...) - Free-text (optional) for having more info Example of an event description: SD054_FB_CONTEST___ECOMM-WIN-A-PFD-US-EN | Max Length:100 |
intent_to_buy | string | Indicates the customer’s intention to buy a unit soon. Possible values:
| Max Length:50 |
lead_score | string | Indicates the lead score based on information available to BRP.
👉 Can be empty | Max Length:50 |
questions_answers | list of objects | List of questions and answers. | |
questions_answers. question | string | Free text used by BRP’s marketing team to ask a question to the potential customer. | Max Length:255 |
questions_answers. answer | string | Customer response, free text. | Max Length:255 |
ownership | object | Information on the unit currently owned by the customer. | |
ownership.brand
| string | Brand of the unit. | Max Length:50 |
ownership.trade_in | number | The trade-in value of the unit. | Precision: 0.01 |
Ressource : Mise à jour d’opportunité de vente
Un CRM utilise la ressource Mise à jour d’opportunité de vente pour envoyer des mises à jour de statut pour les opportunités de vente.
Représentation JSON
{
"sales_opportunity_id": "00Q6s000001WNwGEAW",
"status": [
{
"code": "contacted",
"set_on": "2020-06-13T14:48:12Z"
}
]
}Propriétés
Propriété | Type | Définition | Notes |
|---|---|---|---|
sales_opportunity_id | string | Identifiant de l’opportunité commerciale | Longueur : 18 |
status* | liste d’objets | La liste des statuts associés à l’opportunité commerciale | |
status.code* | string | Code de statut du consommateur
| |
status.set_on* | datetime | Date et heure auxquelles le statut a été défini, au format ISO 8601. | Format : AAAA-MM-JJTHH:MM:SST |
Limitations et contraintes
Méthodes d'authentification CRM
L'API Sales Opportunity prend en charge deux méthodes d'authentification :
- Authentification OAuth 2.0 utilisant des identifiants client, comme utilisé par l'API d'authentification d'application.
- Signature Webhook utilisant SHA256.
❗ L'API Sales Opportunity ne prend pas en charge et ne prendra pas en charge d'autres méthodes d'authentification ❗
Reportez-vous à la section Informations techniques sur les méthodes d'authentification pour plus d'informations.
Exigences de sécurité
- Toute communication doit se faire via HTTPS.
- Les points de terminaison de jetons OAuth et les points de terminaison de rappel doivent utiliser HTTPS.
- TLS 1.2 ou supérieur doit être pris en charge.
- Les certificats SSL doivent être valides et émis par une autorité de certification (CA) reconnue.
- Les certificats auto-signés ne sont pas autorisés dans les environnements de production.
Comprendre l'opportunité de vente
Vue d'ensemble du processus
Le processus de pistes de vente et d’opportunités de vente à haut niveau est présenté ci-dessous.
Le traitement des pistes de vente est géré par le système de gestion des pistes (LMS) de BRP.

La piste de vente est envoyée au système de gestion des prospects (LMS) de BRP.
LMS valide la piste de vente. Si elle est valide, LMS tente de trouver le concessionnaire le plus proche offrant la gamme de produits demandée par le client potentiel.
Si aucun n’est trouvé, la piste de vente est abandonnée.
Si un concessionnaire est trouvé, la piste de vente devient une opportunité de vente.
Si un concessionnaire est trouvé, l’opportunité de vente est envoyée à BOSSWeb.
Si le concessionnaire possède un CRM certifié DCP et a activé l’intégration LMS (voir la section Configuration du CRM dans BOSSWeb ci-dessous), l’opportunité de vente est envoyée au CRM du concessionnaire.
Si le concessionnaire n’a pas de CRM certifié DCP ou si l’intégration LMS n’est pas active, aucune action n’est effectuée.
Si l’opportunité de vente est correctement envoyée au CRM du concessionnaire, LMS envoie un SMS et un courriel au concessionnaire avec les informations sur l’opportunité de vente.
Le concessionnaire contacte le client potentiel pour discuter de la demande.
Le concessionnaire met à jour le statut de l’opportunité de vente dans son CRM.
Si l’intégration LMS est active, le CRM envoie le statut de l’opportunité de vente à LMS. Le statut de l’opportunité de vente est envoyé à BOSSWeb.
Sinon, le concessionnaire met à jour le statut de l’opportunité de vente dans BOSSWeb.
Configuration CRM dans BOSSWeb
Pour que LMS envoie des opportunités de vente au CRM du concessionnaire, celui‑ci doit d’abord activer l’intégration LMS.
👉Vous pouvez partager ce document avec vos concessionnaires.
L’intégration LMS est gérée dans BOSSWeb sous Administration -> Concession, comme illustré ci-dessous.

Le concessionnaire clique sur le lien Termes et Conditions indiqué par la flèche verte dans l’image, et la page ci‑dessous s’affiche.

Le concessionnaire coche la case et sélectionne l’un des outils CRM répertoriés.

❗❗ Le concessionnaire doit sélectionner le CRM qui est en opération dans sa concession ❗❗
Si le concessionnaire sélectionne un CRM au hasard parce qu’il n’a pas de CRM certifié DCP (comme nous le voyons souvent), l’intégration LMS ne fonctionnera pas❗
Le concessionnaire clique sur Enregistrer pour activer l’intégration LMS, et le CRM du concessionnaire commence à recevoir des opportunités de vente.

👉 À tout moment, le concessionnaire peut retourner à la page Conditions générales et décocher la case pour désactiver l’intégration LMS.
Dans ce cas, le CRM cesse de recevoir des opportunités de vente.
Configuration du point de terminaison CRM
Le processus d’envoi d’une opportunité de vente à un CRM est présenté ci-dessous.
Votre CRM doit fournir un endpoint pour que l’API Sales Opportunity puisse envoyer des opportunités de vente.

LMS trouve un concessionnaire pour envoyer l’opportunité de vente et récupère le CRM configuré par le concessionnaire pour l’intégration LMS.
L’opportunité de vente est envoyée à l’API Sales Opportunity, incluant le nom du CRM dans la requête.
L’API Sales Opportunity recherche dans sa configuration le CRM auquel l’opportunité de vente doit être envoyée.
Si le CRM n’est pas trouvé, une erreur est renvoyée à LMS.
Si le CRM est trouvé, la configuration du CRM est récupérée.
L’API Sales Opportunity détermine si le CRM utilise l’authentification d’application ou une signature de webhook.
Si le CRM utilise l’authentification d’application, l’API Sales Opportunity appelle l’endpoint d’authentification du CRM pour obtenir un jeton Bearer.
Si le CRM utilise une signature de webhook, l’API Sales Opportunity calcule la signature et l’ajoute au payload.
L’API Sales Opportunity appelle l’endpoint du CRM en utilisant les identifiants configurés pour envoyer l’opportunité de vente.
Le CRM accuse réception de l’opportunité de vente. En cas d’erreur, elle est renvoyée à LMS.
Le concessionnaire met à jour le statut de l’opportunité de vente dans son CRM. Le CRM envoie le statut à l’API Sales Opportunity.
L’API Sales Opportunity envoie le statut à LMS.
Pour chaque CRM certifié DCP, l’API Sales Opportunity requiert les paramètres suivants :
- Le point de terminaison à appeler pour envoyer l’opportunité de vente.
- Un nom d’utilisateur (ID client).
- Un mot de passe (secret client).
- Le point de terminaison à appeler pour obtenir un jeton d’accès OAuth 2.0 Bearer, si le CRM utilise une authentification OAuth 2.0.
❗❗ L’API Sales Opportunity requiert qu’une authentification par jeton OAuth 2.0 ou une signature webhook soit utilisée par le CRM pour le point de terminaison fourni ❗❗
Gestion des erreurs
Si votre CRM détecte une erreur lors du traitement de l’opportunité de vente, il doit renvoyer une plage de codes d’état standard RFC 9110 et une charge utile JSON décrivant l’erreur.
Vous pouvez consulter la section Code d’état de la réponse pour obtenir des lignes directrices.
La charge utile JSON d’erreur doit être basée sur la charge utile décrite dans la section Charge utile de la réponse . Votre charge doit contenir au minimum un champ texte décrivant l’erreur.
Résumé de ce que vous devez fournir
Lorsque vous commencez à travailler sur l’API Sales Opportunity, vous devez fournir les informations listées ci-dessous.
Pour fournir les informations :
- Téléchargez le fichier Excel.
- Remplissez la feuille correspondant à la méthode d’authentification utilisée par votre CRM.
- Envoyez le fichier par e-mail à [email protected] ou joignez-le à votre ticket de certification Jira de l’API Sales Opportunity.
Environnement | Méthode d'authentification | Information |
|---|---|---|
Test | Tous | L’URL utilisée pour envoyer les opportunités de vente à votre CRM dans votre environnement de test. |
Test | OAuth | ID Client |
Test | OAuth | Secret Client |
Test | OAuth | URL utilisée pour obtenir un jeton Bearer. |
Test | Signature | Secret d’application pour signer le payload. |
Test | Tous | Un ou plusieurs numéros de concessionnaire BRP valides pour envoyer des opportunités de vente. |
Production | Tous | L’URL utilisée pour envoyer les opportunités de vente à votre CRM dans votre environnement de production. |
Production | OAuth | ID Client |
Production | OAuth | Secret Client |
Production | OAuth | URL utilisée pour obtenir un jeton Bearer. |
Production | Signature | Secret d’application pour signer le payload. |
Informations techniques sur les méthodes d'authentification
L'API Sales Opportunity prend en charge deux méthodes d'authentification :
- Authentification OAuth 2.0 utilisant des identifiants client, comme utilisée par DCP API d'authentification d'application.
- Signature de webhook utilisant SHA256.
❗ L'API Sales Opportunity ne prend pas en charge et ne prendra pas en charge d'autres méthodes d'authentification ❗
Authentification d’Application (OAuth 2.0)
Supposons que votre CRM utilise une méthode d’Authentification d’Application (OAuth 2.0) pour autoriser les requêtes de l’API Sales Opportunity vers votre CRM. Dans ce cas, votre plateforme CRM doit exposer un endpoint de jeton OAuth 2.0 conforme prenant en charge le Client Credentials Grant .
L'API Sales Opportunity utilisera cet endpoint pour récupérer un jeton Bearer, qui sera utilisé dans l’en-tête Authorization des appels API suivants vers votre système CRM.
Exigences
Vous devez fournir :
- URL du jeton OAuth2 (HTTPS) Un endpoint HTTPS publiquement accessible prenant en charge le client credentials grant, un pour les environnements de test et de production.
- Identifiants Client pour les environnements de test et de production.
- Un identifiant client unique
- Un secret client sécurisé
- Format de réponse du jeton La réponse doit renvoyer un access_token valide et un champ expires_in au format JSON.
curl --request POST 'https:{Your OAuth2 Token Endpoint}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=REMPLACEZ_MOI_CLIENT_ID' \
--data-urlencode 'client_secret=REMPLACEZ_MOI_CLIENT_SECRET'Meilleures pratiques de sécurité
- Le point de terminaison du jeton doit utiliser HTTPS
- Les jetons doivent être limités dans le temps (expires_in) et ne doivent pas être de longue durée
- Éviter d'exposer des identifiants sensibles dans les journaux ou les messages d'erreur
Spécification du point de terminaison de la charge utile
Votre système doit exposer un point de terminaison HTTP(S) qui accepte des charges utiles JSON envoyées par l’API des opportunités de vente. Toutes les requêtes vers ce point de terminaison seront authentifiées à l’aide d’un jeton Bearer préalablement obtenu via votre service de jetons OAuth2.
Authentification
- Toutes les requêtes incluront le jeton Bearer dans l’en-tête Authorization :
Authorization: Bearer {access_token}- Votre système doit valider le jeton avant de traiter la charge utile.
Exigences du point de terminaison
- URL : [votre_url_de_point_de_terminaison] (par ex., https://api.external-system.com/data/receive)
- Méthode : POST
- Content-Type : application/json
- Authentification : Jeton Bearer (Flux d’identifiants client OAuth2)
Corps de réponse
Votre point de terminaison CRM doit utiliser la plage standard de codes d’état RFC 9110 :
- 2xx (Succès) : La requête a été reçue, comprise et acceptée avec succès
- 4xx (Erreur client) : La requête contient une syntaxe incorrecte ou ne peut pas être satisfaite
- 5xx (Erreur du serveur) : Le serveur n'a pas réussi à exécuter une requête apparemment valide
Votre point de terminaison doit renvoyer au moins les codes d'état de réponse suivants.
Code d’état | Description |
|---|---|
200 OK | Indique que la requête a réussi et que l’opportunité de vente est en cours de traitement. Aucune charge utile n’est renvoyée. |
400 Mauvaise requête | Indique que le serveur ne peut pas ou ne veut pas traiter la requête en raison de ce qui est perçu comme une erreur du client (par exemple, une syntaxe de requête mal formée, un cadrage invalide du message de requête ou un routage trompeur). IMPORTANT: La charge utile de la réponse doit indiquer les champs de la charge utile de la requête ou les paramètres de requête en erreur. |
401 Non autorisé | Indique que la requête n’a pas été appliquée car elle ne comporte pas d’identifiants d’authentification valides. |
404 Introuvable | Indique que le serveur n’a pas pu trouver les objets demandés, par exemple si le concessionnaire est introuvable. |
500 Erreur interne du serveur | Indique que le serveur sait qu’il a commis une erreur ou qu’il est incapable d’exécuter la méthode demandée. |
504 Délai d’expiration de la passerelle | Indique que l’API n’a pas reçu en temps voulu une réponse d’un serveur en amont nécessaire pour compléter la requête. |
Pour les codes d'état d'erreur 4xx et 5xx, une charge utile de réponse doit être renvoyée pour fournir des informations sur l'erreur. La charge utile de réponse utilise la structure présentée dans le tableau ci-dessous.
Propriété | Type | Définition |
|---|---|---|
titre | chaîne de caractères | Code qui identifie l’erreur ou la phrase de raison L’un de
|
message | chaîne de caractères | Une description de l’erreur. |
Par exemple, si l’opportunité de vente concerne un revendeur non trouvé dans votre CRM, la réponse suivante serait renvoyée avec le code d’état 404.
{
"title": "not_found",
"message": "Dealer 0000690006 not found"
}Sécurité
- Le point de terminaison doit utiliser HTTPS
- Le jeton Bearer doit être validé de manière sécurisée
- Tous les contenus doivent être enregistrés de manière sécurisée et traités conformément à votre politique de gouvernance des données.
Signature Webhook
L’approche de signature du webhook est simple.
Pour garantir l’authenticité et l’intégrité des contenus envoyés depuis l’API Sales Opportunity vers votre application CRM, nous les signons avec un HMAC utilisant votre clé d’application unique.
La clé d’application que vous fournissez est utilisée pour calculer une signature sur l’ensemble du contenu en utilisant l’algorithme SHA-256.
La signature est ensuite ajoutée à l’en-tête dans le champ X-Hub-Signature-256 avant que le contenu ne soit envoyé à votre CRM.
Lorsque vous recevez la charge utile, utilisez la même clé d’application et l’algorithme SHA-256 pour calculer la signature, puis comparez-la avec celle figurant dans l’en-tête X-Hub-Signature-256 .
Si la signature correspond, vous pouvez procéder au traitement de l’opportunité commerciale. Si elles ne correspondent pas, rejetez la charge utile et renvoyez une erreur 401 Unauthorized.
Définition de la clé d’application
La clé d’application (également appelée « secret de signature ») est une chaîne aléatoire générée de manière sécurisée et associée à votre CRM.
Format | Chaîne hexadécimale de 64 caractères. Au moins 32 octets (256 bits), plus c’est long, mieux c’est. Exemple : f7d9a47e143a4b298b819f48b3b77e4b24ae746f55c7c35b2c09c1ec3adbe7c2 |
|---|---|
Sécurité | Traitez votre clé d’application comme un mot de passe. Stockez-la en toute sécurité sur votre serveur. Ne l’exposez jamais au code côté client ni à des tiers. Aléatoire sécurisé cryptographiquement. Elle ne doit PAS être un mot de passe ou une phrase lisible par un humain. Elle ne doit PAS être une clé courte ou une chaîne devinable. |
La clé d’application peut être générée à l’aide des bibliothèques disponibles.
import secrets
key = secrets.token_hex(32) # 64-char hex string (32 bytes) )Signature de la charge utile
Nous calculons le HMAC du corps brut de la requête en utilisant SHA-256 et la clé de votre application comme secret.
La signature obtenue est envoyée dans l’en-tête X-Hub-Signature-256.
X-Hub-Signature-256: sha256=<signature>
<signature> est la représentation hexadécimale en minuscules du hachage HMAC.
Ci-dessous figure un exemple du calcul de la signature avec une charge utile d’opportunité de vente exemple et une clé d’application aléatoire.
const crypto = require('crypto');
// Application key (hexadecimal string, must match the receiver's expectation)
const appKeyHex = 'f7d9a47e143a4b298b819f48b3b77e4b24ae746f55c7c35b2c09c1ec3adbe7c2';
// Sales Opportunity payload
const payloadObj = { "sales_opportunity_id": "yVg0i5ULZnCJ5IKi8k", "language": "en", "consumer": { "first_name": "John", "last_name": "Doe", "culture_code": "en-US", "phone_no": "555 555-1234", "mobile_no": "555 555-1278", "email": "[email protected]", "address": { "street": "123 Random Street", "city": "Orlando", "state": "FL", "country": "US", "postal_code": "12562-12345" } }, "product_interest": { "category": "Contest/Events/Demo", "model": "SSV all track", "brand": "canam_side_by_side" }, "status": [{ "code": "new", "set_on": "2025-05-20T19:19:00Z" }], "model_number": "0008HSB00", "comments": "I want a tough SSV", "assignment_date": "2025-05-20T15:19:00Z", "start_date": "2025-05-20T19:19:00Z", "byo_uri": "https://can-am.brp.com/off-road/ca/fr/configuration-et-prix/app.html?platform=SSV_SSP_2_MAX&package=4X4_X&unitid=0008HSB00", "campaign_name": "", "event_description": "SD054_FB_CONTEST___ECOMM-WIN-A-PFD-US-EN", "intent_to_buy": "4-6 months", "lead_score": "Medium", "questions_answers": [{ "question": "What are you looking for in a SSV?", "answer": "Sun and fun" }, { "question": "Who will use the SSV?", "answer": "Me and my dog" }], "ownership": { "brand": "Polaris RZR Trail", "trade_in": 1000 }, "customer_no": "0000691232" };
const rawBody = Buffer.from(JSON.stringify(payloadObj), 'utf8');
// Compute the HMAC SHA256 signature (hex digest)
const signature = crypto
.createHmac('sha256', appKeyHex)
.update(rawBody)
.digest('hex');
// Prepare the signature header
const headers = {
'Content-Type': 'application/json',
'X-Hub-Signature-256': `sha256=${signature}`
};
// signature = "1f91bc0b914dd833968daff615988dae63ea177b9a52fb7f5268df20f9e6a824"
console.log(signature);Validation de la charge utile
Pour valider la signature de la charge utile reçue, votre CRM doit exécuter les étapes suivantes :
- Récupérez votre clé d’application (sous forme de tableau d’octets).
- Lisez le corps brut envoyé par notre CRM.
- Calculez le hachage HMAC-SHA256 du corps en utilisant votre clé d’application.
- Comparez votre hachage calculé à la valeur de l’en-tête X-Hub-Signature-256 (après avoir retiré le préfixe sha256=).
Ci-dessous figure un exemple de vérification de signature, accompagné d'une charge utile d'opportunité de vente et d'une clé d'application générée aléatoirement.
const crypto = require('crypto');
// --- Payload and key (same as signature creation) ---
const payloadObj = { "sales_opportunity_id": "yVg0i5ULZnCJ5IKi8k", "language": "en", "consumer": { "first_name": "John", "last_name": "Doe", "culture_code": "en-US", "phone_no": "555 555-1234", "mobile_no": "555 555-1278", "email": "[email protected]", "address": { "street": "123 Random Street", "city": "Orlando", "state": "FL", "country": "US", "postal_code": "12562-12345" } }, "product_interest": { "category": "Contest/Events/Demo", "model": "SSV all track", "brand": "canam_side_by_side" }, "status": [{ "code": "new", "set_on": "2025-05-20T19:19:00Z" }], "model_number": "0008HSB00", "comments": "I want a tough SSV", "assignment_date": "2025-05-20T15:19:00Z", "start_date": "2025-05-20T19:19:00Z", "byo_uri": "https://can-am.brp.com/off-road/ca/fr/configuration-et-prix/app.html?platform=SSV_SSP_2_MAX&package=4X4_X&unitid=0008HSB00", "campaign_name": "", "event_description": "SD054_FB_CONTEST___ECOMM-WIN-A-PFD-US-EN", "intent_to_buy": "4-6 months", "lead_score": "Medium", "questions_answers": [{ "question": "What are you looking for in a SSV?", "answer": "Sun and fun" }, { "question": "Who will use the SSV?", "answer": "Me and my dog" }], "ownership": { "brand": "Polaris RZR Trail", "trade_in": 1000 }, "customer_no": "0000691232" };
// Convert to compact JSON as sent (matches JSON.stringify in Node.js and compact Python)
const rawBody = Buffer.from(JSON.stringify(payloadObj), 'utf8');
// Secret key
const appKeyHex = 'f7d9a47e143a4b298b819f48b3b77e4b24ae746f55c7c35b2c09c1ec3adbe7c2';
// Calculate expected signature
const expectedSig = crypto.createHmac('sha256', appKeyHex).update(rawBody).digest('hex');
// What would be in the X-Hub-Signature-256 header (from the siganture example)
const headerSignature = 'sha256=1f91bc0b914dd833968daff615988dae63ea177b9a52fb7f5268df20f9e6a824';
// --- Simulate receiver: extract signature from header and verify ---
const receivedHeader = headerSignature; // From header in real request
const providedSig = receivedHeader.split('=')[1];
const expectedBuf = Buffer.from(expectedSig, 'hex');
const providedBuf = Buffer.from(providedSig, 'hex');
const isValid = expectedBuf.length === providedBuf.length &&
crypto.timingSafeEqual(expectedBuf, providedBuf);
if (isValid) {
console.log('Signature is valid!');
} else {
console.log('Signature is INVALID!');
}❗ Si la signature calculée ne correspond pas à la signature reçue, renvoyez un statut 401 Unauthorized et consignez l’erreur pour faciliter le diagnostic ❗
Référence API
curl --request POST 'https://cloud-api.brp.com/dcp/v4/dealer/0000690885/opportunity/update' \
--header 'Authorization: Bearer REPLACE_ME'
--data '
{
"sales_opportunity_id": "00Q4R00001dBg21",
"status": [
{
"code": "contacted",
"set_on": "2024-07-25T14:48:12Z"
}
]
}'Gestion des erreurs
Cette section présente divers scénarios d’appels incorrects qui entraînent des messages d’erreur et des résultats inexacts.
400 Requête Incorrecte
Le code d’état 400 est généralement rencontré durant le développement et l’intégration, et ne devrait pas apparaître lors des opérations normales. La réponse renvoyée contient les informations nécessaires pour corriger le problème.
De nombreux problèmes peuvent entraîner un code d’état 400, et les plus courants sont listés dans le tableau ci‑dessous.
Réponse | Résolution |
|---|---|
Renvoyé si une propriété est manquante. {
"status": 400,
"errors": [
{
"code": "schema_error",
"title": "Le contenu fourni ne correspond pas au schéma JSON attendu",
"meta": [
{
"keyword": "enum",
"dataPath": ".status[0].code",
"schemaPath": "#/properties/status/items/properties/code/enum",
"params": {
"allowedValues": [
"contacted",
"unit_sold",
"abandoned"
]
},
"message": "doit être égal à l'une des valeurs autorisées"
}
]
}
]
} | Ajouter la propriété manquante au contenu envoyé. |
Renvoyé si une date a un format invalide. {
"status": "400",
"id": "rrt-0eb1275f0947eeef3-d-ea-3040725-18600050-2",
"title": "bad_request",
"meta": {
"service": "01",
"detail": "échec de la validation de la requête",
"payload": {
"details": [
{
"message": "[Path '.status[0].set_on'] La chaîne \"25-11-2023T15:18:58Z\" est invalide selon le(s) format(s) de date requis [yyyy-MM-dd'T'HH:mm:ssZ, yyyy-MM-dd'T'HH:mm:ss.[0-9]{1,12}Z] : []"
}
]
}
}
} | Modifier le format de la date pour correspondre au format attendu. |
401 Non autorisé
Le code d’erreur 401 Unauthorized est renvoyé lorsque vous essayez d’appeler l’API avec unaccess_tokenexpiré.
Vous devez obtenir un nouveauaccess_tokenavec un appel à l’API d'authentification d'application.
Le code d’erreur 401 Unauthorized est également renvoyé si vous n’avez pas demandé l’accès à l’API en créant un ticket dans le Jira du DCP.
Lorsque vous êtes prêt à commencer à travailler sur une API, vous devez créer un ticket de certification dans Jira, comme décrit dans la section Activités de certification avec Jira.
Si vous avez déjà commencé à travailler sur une API et perdu l’accès, créez un ticket de support comme décrit dans la section Ouvrir un ticket de support.
404 Non trouvé
Renvoyé lorsque l’identifiant de l’opportunité commerciale reçu dans le payload de Disposition de l’opportunité commerciale est inconnu.
Tests de certification
Phases
Les tests sont effectués en trois phases.
- Phase 1: L’objectif de la première phase est de valider votre CRM en effectuant des appels directs, c’est‑à‑dire sans passer par l’API des opportunités de vente. Dans cette phase, la disposition n’est pas vérifiée. Des appels sont effectués pour vérifier la gestion des erreurs par votre CRM.
- Phase 2: Durant cette phase, des opportunités de vente sont envoyées à votre CRM via l’API des opportunités de vente, et votre CRM envoie des dispositions en appelant Envoyer le statut de l’opportunité.
- Phase 3: La dernière phase consiste à envoyer des opportunités de vente à votre CRM en utilisant le flux complet, depuis un prospect dans Salesforce jusqu’à votre CRM. Votre CRM envoie des dispositions qui sont vérifiées dans Salesforce.
👉 Les étapes de test spécifiques sont listées dans la section ValidationsValidations ci‑dessous.
Architecture de test
Cette section présente l’architecture de test pour chaque phase.
👉 Pour effectuer des tests, vous devez identifier, pour chaque phase, un concessionnaire BRP valide dans votre environnement de test qui sera utilisé pour envoyer l’opportunité de vente.
Phase 1
Pendant la phase 1, des requêtes Postman sont utilisées pour appeler votre CRM afin d’envoyer des opportunités de vente, mais aussi pour envoyer des charges utiles invalides afin de valider la gestion des erreurs de votre CRM.

Les requêtes Postman sont utilisées pour valider votre méthode d’authentification CRM.
Si votre CRM utilise l’Authentification d'application (OAuth 2.0)application, des appels seront effectués pour récupérer un jeton Bearer, et d’autres appels seront effectués pour créer des erreurs.
Si votre CRM utilise la Signature Webhookaaa méthode, les appels seront effectués avec une signature invalide.
Les requêtes sont utilisées pour envoyer une opportunité de vente, et d’autres appels servent à envoyer des charges utiles invalides.
Phase 2
Dans la phase 2, les opportunités de vente sont envoyées par des requêtes Postman à votre CRM via l’API d’Opportunité de Vente.
Votre CRM peut également envoyer une mise à jour du statut d’une opportunité de vente (disposition) à l’API d’Opportunité de Vente, qui est ensuite transférée à un serveur mock dans Postman.

Phase 3
Dans la phase 3, des prospects de vente sont envoyés à Salesforce via des requêtes Postman. Salesforce envoie ensuite l’opportunité de vente à votre CRM et reçoit une mise à jour du statut.

Exigences DSP
Exigences Fonctionnelles
ID | Type | Exigence |
|---|---|---|
1 | Obligatoire | Votre CRM doit fournir l’une des méthodes d’authentification décrites dans laInformations techniques sur les méthodes d’authentification section. |
2 | Obligatoire | Votre CRM doit afficher toutes les propriétés d’opportunité de vente dans l’interface utilisateur. 👉 Si votre CRM ne possède pas certaines propriétés, elles peuvent être regroupées et affichées dans un champ texte. |
3 | Obligatoire | Lorsque vous envoyez la mise à jour du statut de l’opportunité de vente, mappez l’état de votre CRM à l’un des états listés dans laRessource : Mise à jour d’Opportunité de Vente section. |
Activités de certification
Cette section présente toutes les activités de certification et les validations nécessaires pour certifier l'API.
Tests de la phase 1
Les tests répertoriés dans le tableau ci-dessous doivent être effectués dans l’environnement de test avant que vous puissiez commencer les tests de la phase 2.
Authentification d'application (OAuth 2.0)
ID | Test | Résultat attendu |
|---|---|---|
1 | Demander un jeton Bearer. | Le CRM renvoie un jeton Bearer valide. |
2 | Demander un jeton Bearer sans client_id. | Le CRM renvoie un statut de réponse 401. |
3 | Demander un jeton Bearer avec un client_id invalide. | Le CRM renvoie un statut de réponse 401. |
4 | Envoyer une opportunité commerciale avec un jeton Bearer valide. | Le CRM renvoie un statut 200. |
5 | Envoyer une opportunité commerciale avec un jeton Bearer invalide. | Le CRM renvoie un statut de réponse 401. |
6 | Envoyer une opportunité commerciale avec un numéro de concessionnaire invalide. | Le CRM renvoie un statut de réponse 404. |
7 | Envoyer une opportunité commerciale avec un payload invalide. | Le CRM renvoie un statut de réponse 400. |
Signature de webhook
ID | Test | Résultat attendu |
|---|---|---|
1 | Envoyer une opportunité de vente avec une signature valide. | Le CRM renvoie un statut 200. |
2 | Envoyer une opportunité de vente avec une signature invalide. | Le CRM renvoie un statut de réponse 401. |
3 | Envoyer une opportunité de vente avec un numéro de concessionnaire invalide. | Le CRM renvoie un statut de réponse 404. |
4 | Envoyer une opportunité de vente avec une charge utile invalide. | Le CRM renvoie un statut de réponse 400. |
Tests de la phase 2
Les tests répertoriés dans le tableau ci-dessous doivent être effectués dans l’environnement de test avant que vous puissiez commencer les tests de la phase 3.
ID | Test | Résultat attendu |
|---|---|---|
1 | Réception d'une opportunité de vente. | Afficher l’opportunité de vente reçue dans votre CRM. Fournir une capture d’écran de l’interface utilisateur montrant toutes les informations disponibles sur l’opportunité de vente. |
2 | Envoyer une mise à jour du statut de l’opportunité. | Mettre à jour l’état de l’opportunité de vente dans le CRM et vérifier que la modification est envoyée à l’API. |
Tests de la phase 3
Les tests répertoriés dans le tableau ci-dessous doivent être effectués dans l’environnement de test avant que vous puissiez commencer la phase pilote concessionnaire.
ID | Test | Résultat attendu |
|---|---|---|
1 | Réception d’une opportunité commerciale. | Afficher l’opportunité commerciale reçue dans votre CRM. Fournir une capture d’écran de l’interface utilisateur montrant toutes les informations disponibles sur l’opportunité commerciale. |
2 | Envoyer une mise à jour du statut de l’opportunité. | Mettre à jour l’état de l’opportunité commerciale dans le CRM et vérifier que la modification est envoyée à l’API. |
Pilote Détaillant
Le tableau ci-dessous présente les paramètres du pilote détaillant et leurs validations correspondantes.
Paramètre | Valeur |
|---|---|
Environnement | Production |
Nombre de détaillants | 1 à 3 |
Durée | 2 semaines |
Validation 1 | Vérifier que les opportunités de vente envoyées par BRP sont disponibles dans le CRM. |
Validation 2 | Vérifier que BRP a reçu les mises à jour de statut concernant l’opportunité de vente. |
Postman
Cette section décrit ce qui est disponible dans Postman pour explorer l’API.
Environnements
Un environnement Postman est disponible pour tester l’API Sales Opportunity. Cet environnement Postman contient des variables utilisées par les requêtes et configurées pour se connecter à l’environnement de test.
Collections
La collection CRM - Sales Opportunity contient des exemples d’appels API pour envoyer une disposition d’opportunité de vente.
Il existe également des exemples d’appels directs vers vos endpoints CRM pour vous aider à tester l’intégration.
Il existe un exemple pour un CRM utilisant l’authentification oAuth, et un autre pour la méthode par signature.
👉 Pour utiliser les requêtes, vous devez définir les variables de la collection avec les informations de votre endpoint CRM.