Emetre Open Badges des de WordPress (sense un plugin pesat)
Emet Open Badges des de qualsevol plugin de curs/LMS de WordPress (LearnDash, LifterLMS, Tutor) trucant a l'API de Badges Ninja en completar-se — sense haver d'instal·lar cap plugin d'insígnies a part.
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.
Si gestiones cursos a WordPress, ja coneixes la rutina: algú acaba un mòdul a LearnDash, LifterLMS o Tutor LMS, el LMS el marca com a «completat» i… no passa res verificable. Potser envies un PDF per correu. Potser instal·les un plugin d’insígnies dedicat per a WordPress que afegeix les seves pròpies taules de base de dades, la seva pròpia biblioteca d’imatges i la seva pròpia idea del que és una «insígnia» — una que ningú fora del teu lloc pot verificar.
Hi ha un camí més senzill. Els plugins de cursos de WordPress ja disparen un «action hook» en el moment en què algú completa un curs. Pots capturar aquest hook i fer una única trucada HTTP a l’API de Badges Ninja. Sense plugin addicional, sense allotjament addicional, sense format d’insígnia propietari — només una credencial Open Badge v2.0 conforme als estàndards que el destinatari pot verificar a qualsevol lloc, afegir a LinkedIn i descarregar en PDF.
Aquest article explica el patró una vegada i després mostra el hook específic per a LearnDash, LifterLMS i Tutor LMS.
Per què no utilitzar simplement un plugin d’insígnies de WordPress?
Els plugins d’insígnies dedicats per a WordPress resolen un problema més limitat del que sembla. Són bons renderitzant una imatge en una pàgina de «els meus assoliments» dins del teu lloc. Solen ser molt més febles en allò que realment importa per a una credencial:
- Portabilitat. Una insígnia que només existeix com a shortcode al teu lloc de WordPress no és una credencial — és una decoració. En el moment en què el destinatari canvia de feina, canvia de bústia de correu o el teu lloc deixa de funcionar, la «prova» desapareix amb ell.
- Verificació. Qualsevol hauria de poder comprovar que una credencial és real sense iniciar sessió al teu panell d’administració de WordPress. Open Badge v2.0 et proporciona, per disseny, una URL de verificació pública i JSON-LD llegible per màquina.
- Superfície de manteniment. Cada plugin de WordPress és una cosa més a pedaçar, una taula de base de dades més de la qual fer còpia de seguretat, un punt de fallada més durant una actualització del nucli.
Cridar una API externa en completar el curs evita els tres problemes. WordPress continua sent responsable del que fa bé — l’entrega de contingut i el seguiment del progrés — i la credencial en si viu en un sistema dissenyat específicament per emetre-la, verificar-la i compartir-la.
El patró: un hook, una trucada HTTP
Tots els grans plugins LMS de WordPress disparen una acció quan un usuari completa un curs. La integració sempre consta dels mateixos tres passos:
- Enganxa’t a l’acció de finalització del teu LMS específic.
- Localitza (o crea) la identitat del destinatari — normalment només el correu electrònic i el nom visible del seu compte de WordPress.
- Crida
POST /awardsa l’API de Badges Ninja ambwp_remote_post(), passant l’ID de la insígnia i les dades del destinatari.
Primer necessitaràs una clau API. Genera’n una des del teu tauler a API Keys — consulta la guia de claus API per al recorregut complet. Les claus es mostren només una vegada en crear-les, així que desa-la a wp-config.php com a constant en lloc de a la base de dades:
define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Mantén aquesta clau al servidor. Tot el que hi ha en aquesta guia s’executa en PHP al teu servidor de WordPress — wp_remote_post() és una trucada del costat del servidor, i wp-config.php mai s’envia al navegador. Això és exactament el que vols: la clau viatja de servidor a servidor per HTTPS, i cap visitant del lloc la pot llegir. Mai traslladis aquesta trucada a JavaScript del costat del client — un fetch() des del navegador amb la clau incrustada l’exposaria a qualsevol persona a través de les eines de desenvolupament del seu navegador. Dos hàbits que val la pena mantenir: assegura’t que el teu allotjament serveix wp-config.php com a PHP executat (mai com a text pla, i no deixis una còpia wp-config.php.bak al webroot), i crea una clau API dedicada per a aquesta integració perquè puguis revocar-la de manera independent si mai es veu compromesa — sense trencar les teves altres eines.
Una funció auxiliar compartida manté cada hook de LMS prim:
function badges_ninja_issue_award( $recipient_email, $recipient_name, $badge_id ) {
$response = wp_remote_post( 'https://api.badges.ninja/awards', array(
'headers' => array(
'X-Api-Key' => BADGES_NINJA_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'badgeId' => $badge_id,
'recipient' => array(
'name' => $recipient_name, // must be at least 5 characters
'email' => $recipient_email,
),
'issuedOn' => round( microtime( true ) * 1000 ), // epoch milliseconds
) ),
'timeout' => 15,
) );
if ( is_wp_error( $response ) ) {
error_log( 'Badges Ninja award failed: ' . $response->get_error_message() );
return false;
}
$code = wp_remote_retrieve_response_code( $response );
if ( $code >= 400 ) {
error_log( 'Badges Ninja award failed with HTTP ' . $code . ': ' . wp_remote_retrieve_body( $response ) );
return false;
}
return json_decode( wp_remote_retrieve_body( $response ), true );
}
El correu electrònic del destinatari es hasheja amb SHA-256 al costat del servidor una vegada arriba a Badges Ninja, i la resposta inclou la URL de verificació de l’atorgament — pràctic si vols mostrar un enllaç «veure la teva credencial» just allà a WordPress després que la trucada tingui èxit.
LearnDash
LearnDash dispara learndash_course_completed amb un únic argument de tipus array que conté user i course:
add_action( 'learndash_course_completed', function( $data ) {
$user = $data['user'];
$course = $data['course'];
// Map LearnDash course ID → your Badges Ninja badge ID.
// A simple approach: store the badge ID in a course custom field.
$badge_id = get_post_meta( $course->ID, 'badges_ninja_badge_id', true );
if ( ! $badge_id ) {
return; // no badge configured for this course
}
badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
} );
Emmagatzemar l’ID de la insígnia com a metadada del curs (en lloc d’una única constant global BADGES_NINJA_BADGE_ID) és la decisió encertada quan tens més d’un curs — cada curs es correspon amb el seu propi disseny d’insígnia.
LifterLMS
LifterLMS dispara lifterlms_course_completed amb $user_id i $course_id:
add_action( 'lifterlms_course_completed', function( $user_id, $course_id ) {
$user = get_userdata( $user_id );
$badge_id = get_post_meta( $course_id, 'badges_ninja_badge_id', true );
if ( ! $user || ! $badge_id ) {
return;
}
badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
}, 10, 2 );
Tutor LMS
Tutor LMS dispara tutor_course_complete_after amb l’ID del curs, i obtens l’usuari actual des de la sessió:
add_action( 'tutor_course_complete_after', function( $course_id ) {
$user_id = get_current_user_id();
$user = get_userdata( $user_id );
$badge_id = get_post_meta( $course_id, 'badges_ninja_badge_id', true );
if ( ! $user || ! $badge_id ) {
return;
}
badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
} );
Si la teva configuració de Tutor LMS dispara la finalització des d’un procés en segon pla (per exemple, mitjançant una correcció automàtica de qüestionaris), substitueix get_current_user_id() per l’ID d’usuari que proporciona el teu hook específic — comprova la càrrega útil amb error_log( print_r( func_get_args(), true ) ) una vegada durant la configuració per confirmar els arguments.
Dissenyar la insígnia abans de connectar el hook
Abans que res d’això es dispari, necessites una insígnia per atorgar. El dissenyador visual ho cobreix sense necessitat de tenir un dissenyador a la plantilla — més de 80 plantilles de formes, colors personalitzats, biblioteca d’icones i pujada de logotip, tot amb ajust a la graella. Si ets nou en el dissenyador, Dissenyar el teu primer certificat digital verificable et guia per triar una plantilla i llançar alguna cosa que els destinataris realment voldran compartir.
Un cop existeix la insígnia, agafa el seu ID des del tauler (o mitjançant GET /badges) i posa’l al camp personalitzat del teu curs.
Què rep realment el destinatari
Aquesta és la part que un plugin d’insígnies de WordPress fet a casa no pot replicar. Quan POST /awards té èxit, el destinatari rep:
- Una URL de verificació única que qualsevol pot obrir — sense necessitat d’iniciar sessió a WordPress — que mostra que la credencial és real, qui l’ha emès i quan.
- Un codi QR i un certificat PDF en A4, generats automàticament.
- Un botó Afegir al perfil de LinkedIn, si el teu emissor té configurat un ID d’organització de LinkedIn — consulta Afegir un botó «Afegir al perfil» de LinkedIn per a la configuració única.
- Accés al seu propi portal del destinatari a
badges.ninja/me, mitjançant inici de sessió amb enllaç màgic — sense contrasenya per oblidar, sense compte separat a gestionar al teu lloc de WordPress. - Open Badge v2.0 JSON-LD conforme als estàndards, de manera que qualsevol verificador compatible amb OB (no només Badges Ninja) pot validar-lo.
Res d’això és feina de WordPress per construir, i res d’això hauria de viure només dins de la teva base de dades de WordPress.
Gestionar els errors amb elegància
Els hooks de finalització de curs es disparen durant una sol·licitud de pàgina en directe, i una trucada API lenta o fallida no hauria de bloquejar la pantalla de «felicitats» de l’alumne. Dos ajustos pràctics un cop superes la prova de concepte:
No deixis que un atorgament fallit bloquegi la interfície. La funció auxiliar de dalt ja registra i retorna false en lloc de llançar una excepció — LearnDash, LifterLMS i Tutor continuen tots el seu flux normal de finalització independentment del que retorni badges_ninja_issue_award().
Posa-ho en cua en lloc de cridar-ho en línia, a gran escala. Si estàs fent passar grans cohorts per un únic curs alhora (una data d’inici de cohort, un desbloqueig de repetició de webinar), dispara un esdeveniment programat de WP-Cron des del hook en lloc de cridar l’API de manera síncrona:
add_action( 'learndash_course_completed', function( $data ) {
wp_schedule_single_event( time() + 30, 'badges_ninja_deferred_award', array(
$data['user']->user_email,
$data['user']->display_name,
get_post_meta( $data['course']->ID, 'badges_ninja_badge_id', true ),
) );
} );
add_action( 'badges_ninja_deferred_award', 'badges_ninja_issue_award', 10, 3 );
Això reparteix la càrrega i evita que una única sol·licitud lenta es converteixi en el problema de l’alumne. Per a lots genuïnament grans (una cohort sencera del passat, migrada d’una vegada), salta’t completament el camí del hook de WordPress i utilitza atorgaments massius via CSV — puja’t-ho una vegada, i la plataforma pagina l’emissió al servidor amb pausa/represa incorporades.
Una nota sobre la idempotència
Si el teu LMS mai dispara el seu hook de finalització més d’una vegada per al mateix usuari (un cas límit comú de LearnDash amb repeticions de qüestionaris, o una re-sincronització de Tutor LMS), no vols atorgar la mateixa insígnia dues vegades. La protecció més senzilla és un indicador de metadada d’usuari de WordPress que estableixes just després d’una trucada amb èxit:
if ( get_user_meta( $user_id, 'badges_ninja_awarded_' . $course_id, true ) ) {
return; // already issued
}
$result = badges_ninja_issue_award( $user->user_email, $user->display_name, $badge_id );
if ( $result ) {
update_user_meta( $user_id, 'badges_ninja_awarded_' . $course_id, true );
}
Si estàs emetent a un volum real i vols gestionar-ho de manera centralitzada en lloc de per lloc, consulta la gestió d’esdeveniments basada en webhooks o la guia d’inici ràpid de l’API completa per a les formes de sol·licitud/resposta de tots els punts finals.
Quan aquest patró supera un únic curs
Els exemples de dalt assumeixen una insígnia per curs. Un cop estàs executant credencials apilables — una insígnia de trajectòria que es desbloqueja després de diverses insígnies de curs, o una insígnia final que depèn de múltiples requisits previs — mou el mapatge de «quina insígnia, per a quina finalització» fora de la metadada del post i cap a una petita taula de consulta, o impulsa’l des d’una automatització basada en full de càlcul (Airtable o Google Sheets) que dispari la mateixa trucada POST /awards. La trucada API en si no canvia; només canvia què decideix quan fer-la.
Resolució de problemes de la integració
Un grapat de problemes expliquen la major part de la fricció que la gent troba en connectar això per primera vegada:
El hook mai es dispara. Confirma que estàs enganxant l’acció correcta per a la versió real del teu plugin — LearnDash en particular ha canviat els noms dels hooks de finalització entre versions principals (algunes instal·lacions més antigues encara depenen de learndash_course_completed disparant-se des d’un camí de codi diferent al de les més recents). Afegeix temporalment un error_log() a l’inici de la teva funció de retorn de trucada i observa wp-content/debug.log mentre completes un curs de prova com a usuari descartable.
wp_remote_post() s’esgota per temps. Els entorns d’allotjament compartit de vegades bloquegen HTTPS sortint cap a hosts desconeguts, o limiten els temps d’espera de sol·licitud per sota dels 15 segons establerts a dalt. Si les trucades s’esgoten per temps de manera consistent, comprova amb el teu allotjador si les connexions sortints cap a api.badges.ninja estan permeses, i confirma que la teva extensió PHP curl té certificats CA actuals — un paquet de certificats desactualitzat és una fallada silenciosa habitual en piles d’allotjament compartit més antigues.
400 Bad Request. A la càrrega útil li falta un camp requerit o té la forma incorrecta. POST /awards espera badgeId, un objecte niat recipient amb name i email, i una marca de temps issuedOn — l’ajudant de dalt envia exactament això. L’ensopegada més comuna és el nom del destinatari: ha de tenir com a mínim 5 caràcters, així que un nom visible de WordPress com «Jo» es rebutja. Recorre al nom complet del compte (o a la part local del correu electrònic) quan el nom visible sigui massa curt.
401 Unauthorized. La constant de la clau API no es carrega, o es va regenerar després que la constant s’establís. Les claus es mostren una sola vegada en crear-les i no es poden recuperar de nou — si has perdut el rastre de quina clau està activa, elimina l’obsoleta i emet-ne una de nova en lloc d’endevinar.
Insígnia emesa, però amb el disseny equivocat. Això gairebé sempre és un valor obsolet de la metadada del post badges_ninja_badge_id que ha quedat de les proves. Com que el mapatge viu al post del curs, és fàcil oblidar que el vas canviar després de duplicar un curs per a una nova cohort — val la pena una comprovació ràpida cada vegada que clones un curs.
Atorgaments duplicats per a la mateixa persona. Cobert a dalt amb la protecció de metadada d’usuari, però val la pena repetir-ho: els hooks de finalització del LMS no tenen garantit dispara’s-se exactament una vegada. Tracta «ja atorgat» com un cas normal a comprovar, no com un cas límit a ignorar.
Preguntes freqüents
Funciona amb paquets de cursos de WooCommerce? Sí — si una compra de paquet hauria de disparar una insígnia independentment de la finalització del curs (per exemple, una insígnia de «membre certificat» per a qualsevol que compri un paquet específic), enganxa woocommerce_order_status_completed en lloc d’una acció de finalització del LMS, i cerca l’ID de la insígnia des de la metadada del producte en lloc d’un curs.
Els destinataris poden obtenir la insígnia sense un compte de WordPress? Sí, i aquest és precisament el sentit. L’atorgament està vinculat a la seva adreça de correu electrònic a Badges Ninja, no a un registre d’usuari de WordPress. Si el teu lloc permet compra com a convidat o finalització anònima de qüestionaris, només assegura’t de capturar una adreça de correu electrònic real per passar-la a badges_ninja_issue_award().
I si vull revisar els atorgaments abans que surtin? Salta’t disparar la trucada directament des del hook de finalització. En lloc d’això, escriu l’atorgament pendent (usuari, curs, marca de temps) a una taula personalitzada o tipus de post, i emet’l des d’una tasca programada o un botó d’administració «Aprovar i atorgar» que cridi la mateixa funció auxiliar sota demanda.
Necessito una insígnia separada per curs, o una insígnia pot cobrir-ne diversos? Ambdues opcions funcionen. Alguns emissors creen una insígnia per curs per a granularitat; d’altres creen una única insígnia de «finalització del programa» i només l’atorguen un cop cada curs requerit està fet, comprovant la finalització dels requisits previs dins del hook abans de cridar l’API.
Preparat per emetre la teva primera credencial verificable? Comença gratis a badges.ninja — dissenyador visual, pàgina de verificació pública, certificat PDF, sortida Open Badge v2.0. No cal targeta de crèdit.
Com es va fer aquest article
Alguns articles d'aquest blog es redacten amb l'ajuda d'un assistent d'IA i després són revisats, verificats i editats per l'equip de Badges Ninja abans de publicar-los. Cada mostra de codi i preu es verifica amb el producte real. Llegeix més sobre el nostre procés editorial i d'IA a la nostra pàgina del procés editorial .

Sobre l'autor
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.
Més de Nacho Coll
- Salesforce Open Badges: emet credencials verificables des de desencadenants del CRM1 d’oct. del 2026 · 10min de lectura
- Emet insígnies Open Badges amb l'API REST de Badges Ninja: guia d'inici ràpid28 de set. del 2026 · 10min de lectura
- Insereix la verificació d’insígnies al teu web (sense iframe ni SDK)24 de set. del 2026 · 11min de lectura
