Open Badges et Salesforce : émettre des certifications vérifiables depuis des déclencheurs CRM
Déclenchez l’émission d’un Open Badge à partir de n’importe quel événement d’objet Salesforce (Lead gagné, Account promu, étape de formation franchie) grâce à un callout Apex vers l’API Badges Ninja.
Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure.
La plupart des équipes de formation enregistrent déjà dans Salesforce qui a terminé quoi. Une inscription à un cours passe à « Completed », un compte partenaire atteint un palier de certification, un client termine son onboarding. L’enregistrement change, puis quelqu’un exporte une liste et envoie les certificats par e-mail, à la main, une semaine plus tard.
Ce guide montre comment combler cet écart : quand un enregistrement atteint le statut qui vous intéresse, Salesforce appelle l’API de https://badges.ninja, un justificatif Open Badge v2.0 est émis, et le lien de vérification est réécrit sur l’enregistrement. Vous pouvez ensuite glisser ce lien dans un modèle d’e-mail, un rapport ou une page Experience Cloud.
Il vous faudra un administrateur Salesforce (ou une sandbox de développement), un badge déjà conçu sur https://badges.ninja et une clé d’API. Si vous n’avez jamais appelé l’API, lisez d’abord le guide de démarrage rapide de l’API ; il prend dix minutes.
Quand un déclencheur CRM est le bon outil
Avant d’écrire de l’Apex, vérifiez que vous en avez besoin. Si vous émettez vos justificatifs par lots, une fois par semestre ou par trimestre, l’import CSV du tableau de bord est plus rapide et ne demande aucun code. La voie Salesforce se justifie quand :
- L’émission doit avoir lieu dès qu’un enregistrement change, sans intervention humaine.
- Les données sur « qui l’a obtenu » vivent déjà dans Salesforce et vous ne voulez pas d’une seconde source de vérité.
- Vous voulez stocker le lien du justificatif sur le Contact, le Lead ou l’enregistrement de formation personnalisé pour vos rapports.
Si votre outil de workflow est Zapier plutôt qu’Apex, le même appel d’API fonctionne aussi là-bas ; consultez l’automatisation des Open Badges avec Zapier.
Ce que vous allez construire
Le flux comporte quatre éléments :
- Un badge conçu dans le concepteur visuel. Copiez son identifiant (l’
idrenvoyé parGET /badges). - Une clé d’API créée dans la page API Keys de votre tableau de bord. La clé n’est affichée qu’une fois, alors conservez-la tout de suite.
- Un Named Credential dans Salesforce qui contient la clé, pour qu’elle n’apparaisse jamais dans le code.
- Un déclencheur Apex et une classe Queueable qui émettent l’attribution et réécrivent le lien de l’attribution sur l’enregistrement.

Étape 1 : stocker la clé dans un Named Credential
Coder une clé d’API en dur dans l’Apex est l’erreur à éviter. Dans Setup, créez un External Credential avec un en-tête personnalisé, puis un Named Credential qui pointe vers l’hôte de l’API :
- URL :
https://api.badges.ninja - Nom de l’en-tête personnalisé :
X-Api-Key - Valeur de l’en-tête personnalisé : votre clé, sous la forme
bws_YOUR_KEY_HERE - Nom du Named Credential :
BadgesNinja
Donnez à l’ensemble de permissions qui exécute votre automatisation l’accès au principal de l’External Credential. Avec un Named Credential en place, vous n’avez pas besoin d’un Remote Site Setting distinct ; Salesforce autorise le callout via le credential. Si votre organisation utilise encore des Named Credentials hérités ou un simple endpoint, ajoutez https://api.badges.ninja comme Remote Site Setting et envoyez l’en-tête depuis le code.
Étape 2 : ajouter des champs à l’enregistrement
Sur l’objet qui représente la réussite (nous utiliserons un objet personnalisé appelé Training_Enrollment__c), ajoutez :
Badge_Id__c(Texte) : le badge à émettre. Le stocker par cours permet à un seul déclencheur de servir de nombreux badges.Badge_Award_Id__c(Texte, unique) : l’identifiant d’attribution renvoyé par l’API.Badge_Url__c(URL) : la page de vérification publique.Badge_Error__c(Texte long) : la dernière erreur, pour que les administrateurs voient les échecs sans ouvrir les journaux de débogage.
Le champ Badge_Award_Id__c joue un double rôle. C’est votre garde-fou contre les doublons : le déclencheur n’émet que lorsqu’il est vide.
Étape 3 : le callout Apex
Un déclencheur ne peut pas effectuer de callout directement, car les callouts ne sont pas autorisés dans la même transaction qu’un DML non validé. Confiez le travail à un Queueable qui implémente Database.AllowsCallouts.
Le contrat d’API de POST /awards est court. Le corps contient badgeId, un objet recipient imbriqué avec name et email, et un issuedOn obligatoire. Un appel réussi renvoie un HTTP 200 avec { "awardId": "..." }. Le nom du destinataire doit comporter au moins cinq caractères : un Contact nommé « Al Li » serait donc rejeté. Validez avant d’appeler.
public class BadgeIssueJob implements Queueable, Database.AllowsCallouts {
private Id enrollmentId;
public BadgeIssueJob(Id enrollmentId) { this.enrollmentId = enrollmentId; }
public void execute(QueueableContext ctx) {
Training_Enrollment__c e = [
SELECT Id, Badge_Id__c, Badge_Award_Id__c, Contact__r.Name, Contact__r.Email
FROM Training_Enrollment__c WHERE Id = :enrollmentId LIMIT 1
];
if (e.Badge_Award_Id__c != null) { return; } // already issued
Map<String, Object> recipient = new Map<String, Object>{
'name' => e.Contact__r.Name,
'email' => e.Contact__r.Email
};
Map<String, Object> body = new Map<String, Object>{
'badgeId' => e.Badge_Id__c,
'recipient' => recipient,
'issuedOn' => Datetime.now().getTime()
};
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:BadgesNinja/awards');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/json');
req.setBody(JSON.serialize(body));
HttpResponse res = new Http().send(req);
if (res.getStatusCode() == 200) {
Map<String, Object> out = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
String awardId = (String) out.get('awardId');
e.Badge_Award_Id__c = awardId;
e.Badge_Url__c = 'https://badges.ninja/awards/' + awardId;
e.Badge_Error__c = null;
} else {
e.Badge_Error__c = res.getStatusCode() + ': ' + res.getBody();
}
update e;
}
}
Deux détails méritent l’attention. Premièrement, issuedOn est en millisecondes epoch, ce qui correspond exactement à ce que renvoie Datetime.getTime(). Deuxièmement, la réponse n’inclut pas l’URL de vérification : le code la construit donc à partir de l’identifiant d’attribution, https://badges.ninja/awards/<awardId>.
Étape 4 : le déclencheur
Gardez le déclencheur léger. Il décide seulement quels enregistrements sont éligibles et met en file un job par enregistrement.
trigger TrainingEnrollmentBadge on Training_Enrollment__c (after insert, after update) {
for (Training_Enrollment__c e : Trigger.new) {
Boolean completed = e.Status__c == 'Completed';
Boolean wasCompleted = Trigger.isUpdate && Trigger.oldMap.get(e.Id).Status__c == 'Completed';
if (completed && !wasCompleted && e.Badge_Award_Id__c == null && e.Badge_Id__c != null) {
System.enqueueJob(new BadgeIssueJob(e.Id));
}
}
}
La vérification wasCompleted est importante. Sans elle, toute modification ultérieure d’un enregistrement terminé relancerait la logique. Combinée au garde-fou de l’identifiant d’attribution vide dans le job, elle garantit qu’un enregistrement ne peut jamais produire qu’un seul justificatif.
Une limite à respecter : Salesforce n’autorise qu’un petit nombre de jobs Queueable mis en file depuis une même transaction (50 en contexte synchrone). Si vous chargez des achèvements en masse, par exemple un import de 2 000 lignes, le déclencheur ci-dessus atteindra ce plafond. Pour les chargements en masse, téléversez plutôt la liste via l’attribution en masse par CSV du tableau de bord, ou passez à une classe Batchable avec Database.AllowsCallouts qui traite quelques enregistrements par portée.

Gestion des erreurs et nouvelles tentatives
L’API renvoie des codes de statut standard, et chacun appelle une réponse différente de votre code :
| Statut | Signification | Que faire |
|---|---|---|
| 400 | Un champ était manquant ou invalide, y compris un nom de destinataire de moins de cinq caractères | Ne réessayez pas. Corrigez les données et écrivez le message dans Badge_Error__c. |
| 401 | Clé d’API incorrecte ou absente | Vérifiez le Named Credential. Réessayer ne servira à rien tant que ce n’est pas corrigé. |
| 402 | Plus de justificatifs ou de quota pour votre formule | Arrêtez l’émission et alertez un administrateur ; réessayez après une mise à niveau ou la réinitialisation du quota. |
| 404 | Le badgeId n’existe pas | Corrigez Badge_Id__c sur l’enregistrement ou le cours. |
| 5xx ou délai dépassé | Défaillance transitoire | Vous pouvez réessayer plus tard sans risque. |
Comme le job écrit l’erreur sur l’enregistrement et laisse Badge_Award_Id__c vide, une nouvelle tentative se résume à cocher une case ou à réenregistrer l’enregistrement. Une petite classe Apex planifiée qui recherche les inscriptions terminées sans identifiant d’attribution et avec une erreur transitoire, puis les remet en file, vous offre une file de nouvelles tentatives automatique sans infrastructure supplémentaire. Plafonnez le nombre de tentatives avec un champ compteur pour qu’un enregistrement définitivement défectueux ne boucle pas indéfiniment.
Vérifiez votre formule avant de passer en production. La formule Free couvre 1 200 justificatifs par an ; Starter coûte $9 par mois et Pro $29 par mois. Un déclencheur qui s’active sur chaque Lead épuiserait vite une petite formule, alors limitez les critères aux vraies réussites.
Rendre le justificatif visible dans Salesforce
Une fois Badge_Url__c renseigné, vous pouvez l’utiliser partout :
- Alertes e-mail et modèles : fusionnez le champ dans un e-mail « Félicitations, voici votre justificatif ».
- Rapports : un rapport sur
Badge_Award_Id__c != nullvous donne le nombre d’émissions par cours, par région ou par propriétaire de compte. - Experience Cloud : affichez le lien sur la page de certification d’un partenaire pour que les acheteurs puissent le vérifier eux-mêmes.
- Mises en page : ajoutez le champ URL pour que le support puisse répondre à « a-t-elle reçu son badge ? » d’un coup d’œil.
La page de vérification est publique et ne demande aucune inscription, et c’est tout l’intérêt. Un destinataire, un recruteur ou l’équipe achats d’un client peut ouvrir le lien et confirmer qui a émis le justificatif, ce qu’il certifie et quand. Pour des vérifications lisibles par machine, le JSON-LD Open Badge v2.0 de n’importe quelle attribution est disponible à l’adresse https://api.badges.ninja/certify-badge/award/<awardId>.
Les destinataires bénéficient aussi des extras habituels : une URL de vérification unique, un code QR, un certificat PDF au format A4 et une option Add to LinkedIn depuis le portail destinataire, où l’on se connecte par lien magique plutôt que par mot de passe.
Pourquoi c’est préférable à un plugin de badges AppExchange
Les plugins de badges d’AppExchange sont souvent facturés par siège Salesforce ou par licence de package géré. Ce coût évolue avec la taille de votre équipe Salesforce, et non avec le nombre de justificatifs que vous émettez ; une équipe de formation de dix personnes et un programme de dix mille apprenants paient donc très différemment pour le même résultat.
Une intégration par API inverse ce modèle. Vous payez au volume de justificatifs avec une formule forfaitaire, le code du déclencheur est à vous pour le lire et le modifier, et le résultat est du Open Badge v2.0 standard : les destinataires ne sont donc pas enfermés dans une visionneuse propriétaire. Vous gardez aussi votre liberté de conception : le concepteur visuel propose plus de 80 modèles, des formes, des icônes et des téléversements personnalisés, plutôt qu’une mise en page figée dans un package.
Le compromis, en toute honnêteté : un plugin s’installe en un clic et ne demande pas d’Apex. Si personne dans votre équipe ne peut maintenir quelques dizaines de lignes de code, un plugin ou un connecteur no-code conviendra peut-être mieux. Si vous comparez des plateformes en général plutôt que des intégrations, la comparaison de l’alternative à Credly détaille côte à côte les différences de prix et de fonctionnalités.
Tester avant la mise en production
Exécutez d’abord tout le flux dans une sandbox.
- Créez un badge de test et un destinataire de test avec une adresse e-mail que vous contrôlez.
- Dans les tests Apex, implémentez un
HttpCalloutMockqui renvoie le statut 200 et{"awardId":"test-award-id"}; Salesforce n’autorise pas les vrais callouts en contexte de test, et cette couverture est nécessaire pour déployer. - Dans la sandbox, passez une inscription à Completed et vérifiez que
Badge_Award_Id__cetBadge_Url__cse remplissent en moins d’une minute. - Ouvrez l’URL dans une fenêtre de navigation privée pour confirmer que la page de vérification publique s’affiche sans connexion.
- Provoquez un échec (videz l’identifiant du badge, ou utilisez un nom de destinataire de moins de cinq caractères) et confirmez que l’erreur arrive dans
Badge_Error__c.
Renouvelez la clé d’API si elle fuite un jour dans un journal de débogage ou une capture d’écran. La révocation est immédiate depuis la page API Keys, et vous n’avez qu’à mettre à jour l’External Credential, pas votre code.
En résumé
Le schéma est simple : un déclencheur léger décide du moment, un Queueable effectue le callout, un Named Credential garde la clé, et trois champs sur l’enregistrement stockent le résultat. Il fonctionne pour les étapes de formation, les paliers partenaires, la présence à des événements, ou tout changement d’état que vous pouvez exprimer dans Salesforce.
Commencez par un objet et un badge, observez le résultat pendant une semaine, puis étendez-le quand le comportement des nouvelles tentatives convient à vos données.
Prêt à émettre votre première certification vérifiable ? Commencez gratuitement sur badges.ninja — concepteur visuel, page de vérification publique, certificat PDF, sortie Open Badge v2.0. Aucune carte bancaire requise.
Comment cet article a été créé
Certains articles de ce blog sont rédigés avec l'aide d'un assistant IA, puis relus, vérifiés et édités par l'équipe Badges Ninja avant publication. Chaque exemple de code et chaque prix est vérifié sur le produit réel. Pour en savoir plus sur notre processus éditorial et d'IA, consultez notre page sur le processus éditorial .

À propos de l'auteur
Nacho Coll
Founder & Engineer at Badges Ninja
Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure. Writes about the Open Badges spec, credential verification, and running a credentialing platform serverless on AWS, from the operator side of the wire.
Plus de Nacho Coll
- Émettre des Open Badges via l’API REST de Badges Ninja : guide de démarrage rapide28 sept. 2026 · 11min de lecture
- Intégrer la vérification de badges à votre site web (sans iframe, sans SDK)24 sept. 2026 · 11min de lecture
- Certifier vs Accredible : comparatif des plateformes de certificats (2026)21 sept. 2026 · 10min de lecture

