Open Badgien myöntäminen WordPressistä (ilman raskasta lisäosaa)
Myönnä Open Badgeja mistä tahansa WordPress-kurssi-/LMS-lisäosasta (LearnDash, LifterLMS, Tutor) kutsumalla Badges Ninja -API:a kurssin suorittamisen yhteydessä — ei erillistä merkkilisäosaa asennettavaksi.
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.
Jos pyörität kursseja WordPressissä, tiedät jo rutiinin: joku suorittaa moduulin LearnDashissa, LifterLMS:ssä tai Tutor LMS:ssä, LMS merkitsee sen “suoritetuksi”, ja sitten… mitään todennettavaa ei tapahdu. Ehkä lähetät PDF:n sähköpostilla. Ehkä asennat erillisen WordPress-merkkilisäosan, joka lisää omat tietokantataulunsa, oman kuvakirjastonsa ja oman käsityksensä siitä, mikä “merkki” on — sellaisen, jota kukaan sivustosi ulkopuolella ei voi todentaa.
On olemassa yksinkertaisempi tie. WordPress-kurssilisäosat laukaisevat jo action-koukun sillä hetkellä, kun joku suorittaa kurssin. Voit ottaa kiinni tuon koukun ja tehdä yhden HTTP-kutsun Badges Ninja -API:in. Ei ylimääräistä lisäosaa, ei ylimääräistä hostausta, ei omistusoikeudellista merkkimuotoa — vain standardinmukainen Open Badge v2.0 -tunniste, jonka vastaanottajasi voi todentaa missä tahansa, lisätä LinkedIniin ja ladata PDF:nä.
Tämä kirjoitus käy kaavan läpi kerran ja näyttää sitten LearnDashin, LifterLMS:n ja Tutor LMS:n omat koukut.
Miksi ei vain käyttää WordPress-merkkilisäosaa?
Erilliset WordPress-merkkilisäosat ratkaisevat suppeamman ongelman kuin miltä ne näyttävät ratkaisevan. Ne ovat hyviä näyttämään kuvan “omat saavutukset” -sivulla sivustollasi. Ne ovat yleensä paljon heikompia asioissa, jotka todella merkitsevät tunnisteen kannalta:
- Siirrettävyys. Merkki, joka on olemassa vain lyhytkoodina WordPress-sivustollasi, ei ole tunniste — se on koriste. Sillä hetkellä, kun vastaanottaja vaihtaa työpaikkaa, vaihtaa sähköpostiaan tai sivustosi kaatuu, “todiste” katoaa mukana.
- Todennettavuus. Kenen tahansa pitäisi voida tarkistaa, että tunniste on aito, kirjautumatta WordPress-hallintapaneeliisi. Open Badge v2.0 antaa sinulle julkisen todennus-URL:n ja koneluettavan JSON-LD:n suunnittelun ansiosta.
- Ylläpitopinta-ala. Jokainen WordPress-lisäosa on vielä yksi asia päivitettäväksi, vielä yksi tietokantataulu varmuuskopioitavaksi, vielä yksi vikapiste ydinpäivityksen aikana.
Ulkoisen API:n kutsuminen kurssin suorittamisen yhteydessä kiertää kaikki kolme. WordPress pysyy vastuussa siitä, missä se on hyvä — sisällön toimittamisesta ja edistymisen seurannasta — ja itse tunniste elää järjestelmässä, joka on rakennettu nimenomaan sen myöntämistä, todentamista ja jakamista varten.
Kaava: yksi koukku, yksi HTTP-kutsu
Jokainen suurempi WordPress-LMS-lisäosa laukaisee toiminnon, kun käyttäjä suorittaa kurssin. Integraatio on aina samat kolme vaihetta:
- Kytkeydy suorittamistoimintoon oman LMS:si osalta.
- Etsi (tai luo) vastaanottajan identiteetti — yleensä vain tämän WordPress-tilin sähköposti ja näyttönimi.
- Kutsu
POST /awardsBadges Ninja -API:ssawp_remote_post()-funktiolla ja välitä mukana merkin ID sekä vastaanottajan tiedot.
Tarvitset ensin API-avaimen. Luo sellainen kojelaudastasi kohdasta API Keys — katso API-avainten opas koko läpikäynnistä. Avaimet näytetään vain kerran luontihetkellä, joten tallenna se wp-config.php-tiedostoon vakiona sen sijaan, että tallentaisit sen tietokantaan:
define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Pidä tämä avain palvelinpuolella. Kaikki tässä oppaassa toimii PHP:llä WordPress-palvelimellasi — wp_remote_post() on palvelinpuolen kutsu, eikä wp-config.php koskaan lähde selaimeen. Juuri sitä haluatkin: avain kulkee palvelimelta palvelimelle HTTPS:n yli, eikä yksikään sivuston kävijä pääse lukemaan sitä. Älä koskaan siirrä tätä kutsua asiakaspuolen JavaScriptiin — selaimesta tehty fetch()-kutsu, jossa avain on upotettuna, paljastaisi sen kenelle tahansa selaimen kehittäjätyökalujen kautta. Kahta tapaa kannattaa vaalia: varmista, että hostingpalvelusi tarjoilee wp-config.php-tiedoston suoritettuna PHP:nä (ei koskaan pelkkänä tekstinä, äläkä jätä wp-config.php.bak-kopiota webjuureen), ja luo tälle integraatiolle oma erillinen API-avain, jotta voit perua sen itsenäisesti, jos se joskus vaarantuu — rikkomatta muita työkalujasi.
Jaettu apufunktio pitää jokaisen LMS-koukun ohuena:
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 );
}
Vastaanottajan sähköposti tiivistetään (hash) SHA-256:lla palvelinpuolella heti, kun se saapuu Badges Ninjaan, ja vastauksen sisältö sisältää palkinnon todennus-URL:n — kätevä, jos haluat näyttää “katso tunnisteesi” -linkin suoraan WordPressissä kutsun onnistuttua.
LearnDash
LearnDash laukaisee learndash_course_completed-toiminnon yhdellä taulukkoargumentilla, joka sisältää user- ja course-arvot:
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 );
} );
Merkin ID:n tallentaminen kurssin metatietoihin (yhden globaalin BADGES_NINJA_BADGE_ID-vakion sijaan) on oikea ratkaisu heti, kun sinulla on useampi kuin yksi kurssi — jokainen kurssi vastaa omaa merkkisuunnitteluaan.
LifterLMS
LifterLMS laukaisee lifterlms_course_completed-toiminnon parametreilla $user_id ja $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 laukaisee tutor_course_complete_after-toiminnon kurssin ID:llä, ja haet nykyisen käyttäjän istunnosta:
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 );
} );
Jos Tutor LMS -asennuksesi laukaisee suorittamisen taustaprosessista (esim. tentin automaattisen arvostelun kautta), vaihda get_current_user_id() käyttäjä-ID:hen, jonka oma koukkusi tarjoaa — tarkista hyötykuorma kerran asennuksen aikana komennolla error_log( print_r( func_get_args(), true ) ) varmistaaksesi argumentit.
Suunnittele merkki ennen kuin kytket koukun
Ennen kuin mikään tästä laukeaa, tarvitset merkin myönnettäväksi. Visuaalinen suunnittelija hoitaa tämän ilman, että tarvitset suunnittelijaa palkkalistoillesi — yli 80 muotomallia, mukautettavat värit, kuvakekirjasto ja logon lataus, kaikki ruudukkoon napsahtaen. Jos suunnittelija on sinulle uusi, Ensimmäisen todennettavan digitaalisen sertifikaatin suunnittelu käy läpi mallin valinnan ja sellaisen tuotoksen julkaisemisen, jota vastaanottajat todella haluavat jakaa.
Kun merkki on olemassa, hae sen ID kojelaudalta (tai GET /badges -kutsulla) ja lisää se kurssisi mukautettuun kenttään.
Mitä vastaanottaja oikeasti saa
Tämä on osa, jota kotikutoinen WordPress-merkkilisäosa ei pysty jäljittelemään. Kun POST /awards onnistuu, vastaanottaja saa:
- Ainutlaatuisen todennus-URL:n, jonka kuka tahansa voi avata — ilman WordPress-kirjautumista — ja joka osoittaa, että tunniste on aito, kuka sen myönsi ja milloin.
- QR-koodin ja A4-PDF-sertifikaatin, jotka luodaan automaattisesti.
- Lisää LinkedIn-profiiliin -painikkeen, jos myöntäjälläsi on asetettu LinkedIn-organisaation ID — katso Lisää LinkedIn “Lisää profiiliin” -painike kertaluonteista asennusta varten.
- Pääsyn omaan vastaanottajaportaaliinsa osoitteessa
badges.ninja/metaikalinkki-kirjautumisen kautta — ei salasanaa unohdettavaksi, ei erillistä tiliä hallittavaksi WordPress-sivustollasi. - Standardinmukaisen Open Badge v2.0 JSON-LD:n, jotta mikä tahansa OB-tietoinen todentaja (ei vain Badges Ninja) voi validoida sen.
Mikään tästä ei ole WordPressin tehtävä rakentaa, eikä minkään siitä pitäisi elää vain WordPress-tietokannassasi.
Virheiden käsittely sulavasti
Kurssin suorittamiskoukut laukeavat käynnissä olevan sivupyynnön aikana, eikä hidas tai epäonnistunut API-kutsu saisi estää oppijan “onneksi olkoon” -näyttöä. Kaksi käytännön säätöä, kun olet edennyt konseptitodistuksen ohi:
Älä anna epäonnistuneen palkinnon estää käyttöliittymää. Yllä oleva apufunktio jo kirjaa lokiin ja palauttaa arvon false sen sijaan, että se heittäisi virheen — LearnDash, LifterLMS ja Tutor jatkavat kaikki normaalia suoritusvirtaansa riippumatta siitä, mitä badges_ninja_issue_award() palauttaa.
Jonota se sen sijaan, että kutsuisit sitä suoraan, suuressa mittakaavassa. Jos ajat suuria ryhmiä yhden kurssin läpi kerralla (ryhmän aloituspäivä, webinaaritallenteen avaus), laukaise koukusta ajastettu WP-Cron-tapahtuma sen sijaan, että kutsuisit API:a synkronisesti:
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 );
Tämä jakaa kuorman ja estää yhtä hidasta pyyntöä muodostumasta oppijan ongelmaksi. Todella suurille erille (koko aiempi ryhmä, siirretty kerralla) ohita WordPress-koukkureitti kokonaan ja käytä joukkomyöntämistä CSV:n kautta — lataa kerran, niin alusta sivuttaa myöntämisen palvelinpuolella sisäänrakennetulla tauko/jatka-toiminnolla.
Huomio idempotenssista
Jos LMS:si joskus laukaisee suorittamiskoukkunsa useammin kuin kerran samalle käyttäjälle (yleinen LearnDash-erikoistapaus tentin uusintayrityksissä tai Tutor LMS -uudelleensynkronoinnissa), et halua myöntää samaa merkkiä kahdesti. Yksinkertaisin suoja on WordPress-käyttäjämeta-lippu, jonka asetat heti onnistuneen kutsun jälkeen:
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 );
}
Jos myönnät todellisia määriä ja haluat tämän käsiteltävän keskitetysti sivustokohtaisen sijaan, katso webhook-pohjaista tapahtumien käsittelyä tai koko API-pikaopas pyyntöjen ja vastausten muodoista jokaisen päätepisteen osalta.
Kun tämä kaava kasvaa yhden kurssin ulkopuolelle
Yllä olevat esimerkit olettavat yhden merkin kurssia kohden. Kun alat ajaa pinottavia tunnisteita — polkumerkkiä, joka avautuu useamman kurssimerkin jälkeen, tai päättötyömerkkiä, joka riippuu useista edellytyksistä — siirrä “mikä merkki, mille suoritukselle” -kartoitus pois artikkelin metatiedoista pieneen hakutauluun tai ohjaa sitä taulukkolaskentapohjaisella automaatiolla (Airtable tai Google Sheets), joka laukaisee saman POST /awards-kutsun. Itse API-kutsu ei muutu; vain se, mikä päättää milloin sitä kutsutaan, muuttuu.
Integraation vianmääritys
Kourallinen ongelmia selittää suurimman osan kitkasta, johon ihmiset törmäävät kytkiessään tätä ensimmäistä kertaa:
Koukku ei koskaan laukea. Varmista, että kytkeydyt oikeaan toimintoon lisäosasi todellisen version mukaan — erityisesti LearnDash on muuttanut suorittamiskoukkujen nimiä pääversioiden välillä (vanhemmat asennukset luottavat joskus yhä siihen, että learndash_course_completed laukeaa eri koodipolusta kuin uudemmissa). Lisää väliaikainen error_log() callbackisi alkuun ja seuraa tiedostoa wp-content/debug.log, kun suoritat testikurssin kertakäyttöisenä käyttäjänä.
wp_remote_post() aikakatkaisee. Jaetut hostausympäristöt estävät joskus lähtevän HTTPS-liikenteen tuntemattomiin osoitteisiin tai rajoittavat pyyntöjen aikakatkaisun alle yllä asetettujen 15 sekunnin. Jos kutsut aikakatkaisevat johdonmukaisesti, tarkista hostingpalveluntarjoajaltasi, sallitaanko lähtevät yhteydet osoitteeseen api.badges.ninja, ja varmista, että PHP:n curl-laajennuksella on ajantasaiset CA-varmenteet — vanhentunut varmennenippu on yleinen hiljainen vika vanhemmissa jaetun hostauksen ympäristöissä.
400 Bad Request. Hyötykuormasta puuttuu pakollinen kenttä tai sen muoto on väärä. POST /awards odottaa badgeId-kenttää, sisäkkäistä recipient-oliota kentillä name ja email, sekä issuedOn-aikaleimaa — yllä oleva apufunktio lähettää juuri sen. Yleisin kompastuskivi on vastaanottajan nimi: sen on oltava vähintään 5 merkkiä pitkä, joten WordPress-näyttönimi kuten “Jo” hylätään. Käytä varalla tilin koko nimeä (tai sähköpostin paikallisosaa), kun näyttönimi on liian lyhyt.
401 Unauthorized. API-avainvakio ei lataudu, tai se generoitiin uudelleen vakion asettamisen jälkeen. Avaimet näytetään vain kerran luontihetkellä, eikä niitä voi hakea uudelleen — jos olet menettänyt seurannan siitä, mikä avain on käytössä, poista vanhentunut ja luo uusi sen sijaan, että arvailisit.
Merkki myönnetty, mutta väärällä merkkisuunnittelulla. Tämä on lähes aina vanhentunut badges_ninja_badge_id-artikkelimeta-arvo, joka on jäänyt testauksesta. Koska kartoitus asuu kurssiartikkelissa, on helppo unohtaa, että muutit sitä kurssin monistamisen jälkeen uudelle ryhmälle — kannattaa tarkistaa nopeasti aina, kun kloonaat kurssin.
Kaksinkertaiset palkinnot samalle henkilölle. Käsitelty yllä käyttäjämeta-suojauksella, mutta on syytä toistaa: LMS:n suorittamiskoukkujen ei ole taattu laukeavan täsmälleen kerran. Kohtele “jo myönnetty” -tilaa normaalina tarkistettavana tapauksena, ei reunatapauksena, joka jätetään huomiotta.
Usein kysytyt kysymykset
Toimiiko tämä WooCommerce-kurssipakettien kanssa? Kyllä — jos paketin ostamisen pitäisi laukaista merkki riippumatta kurssin suorittamisesta (esim. “sertifioitu jäsen” -merkki kaikille, jotka ostavat tietyn paketin), kytkeydy woocommerce_order_status_completed-toimintoon LMS:n suorittamistoiminnon sijaan ja hae merkin ID tuotteen metatiedoista kurssin sijaan.
Voivatko vastaanottajat saada merkin ilman WordPress-tiliä? Kyllä, ja juuri se on tarkoitus. Palkinto on sidottu heidän sähköpostiosoitteeseensa Badges Ninjassa, ei WordPress-käyttäjätietueeseen. Jos sivustosi sallii vierailuostoksen tai anonyymin tentin suorittamisen, varmista vain, että keräät todellisen sähköpostiosoitteen välitettäväksi funktiolle badges_ninja_issue_award().
Entä jos haluan tarkistaa palkinnot ennen niiden lähettämistä? Älä laukaise kutsua suoraan suorittamiskoukusta. Kirjoita sen sijaan odottava palkinto (käyttäjä, kurssi, aikaleima) mukautettuun tauluun tai artikkelityyppiin ja myönnä se ajastetusta tehtävästä tai ylläpitäjän “Hyväksy ja myönnä” -painikkeesta, joka kutsuu samaa apufunktiota tarvittaessa.
Tarvitsenko erillisen merkin jokaista kurssia kohden, vai voiko yksi merkki kattaa useita? Molemmat toimivat. Osa myöntäjistä luo yhden merkin kurssia kohden tarkkuuden vuoksi; toiset luovat yhden “ohjelman suoritus” -merkin ja myöntävät sen vasta, kun kaikki vaaditut kurssit on suoritettu, tarkistaen edellytysten täyttymisen koukun sisällä ennen API:n kutsumista.
Valmis myöntämään ensimmäisen todennettavan tunnisteesi? Aloita ilmaiseksi badges.ninjassa — visuaalinen suunnittelija, julkinen todennussivu, PDF-sertifikaatti, Open Badge v2.0 -tuotos. Ei luottokorttia tarvita.
Miten tämä artikkeli tehtiin
Osa tämän blogin artikkeleista laaditaan tekoälyavustajan avulla, minkä jälkeen Badges Ninja -tiimi tarkistaa, faktantarkistaa ja muokkaa ne ennen julkaisua. Jokainen koodiesimerkki ja hinta tarkistetaan live-tuotteesta. Lue lisää toimituksellisesta ja tekoälyprosessistamme toimitusprosessin sivulla .

Kirjoittajasta
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.
