Издавање Open Badges кредибилитета из WordPress-а (без тешког додатка)
Издајте Open Badges из било ког WordPress додатка за курсеве/LMS (LearnDash, LifterLMS, Tutor) позивањем Badges Ninja API-ја при завршетку курса — без потребе за посебним додатком за значке.
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.
Ако водите курсеве на WordPress-у, већ знате поступак: неко заврши модул у LearnDash-у, LifterLMS-у или Tutor LMS-у, LMS га означи као „завршио”, а онда… ништа проверљиво се не догоди. Можда пошаљете PDF имејлом. Можда инсталирате посебан WordPress додатак за значке који додаје сопствене табеле у бази података, сопствену библиотеку слика и сопствену представу о томе шта је „значка” — такву коју нико ван вашег сајта не може да провери.
Постоји једноставнији пут. WordPress додаци за курсеве већ покрећу action hook у тренутку када неко заврши курс. Можете да прихватите тај hook и направите један HTTP позив ка Badges Ninja API-ју. Без додатног додатка, без додатног хостинга, без сопственог формата значке — само стандардизован Open Badge v2.0 сертификат који прималац може да провери било где, дода на LinkedIn и преузме као PDF.
Овај текст најпре разматра модел уопштено, а затим показује конкретан hook за LearnDash, LifterLMS и Tutor LMS.
Зашто једноставно не користити WordPress додатак за значке?
Посебни WordPress додаци за значке решавају ужи проблем него што на први поглед изгледа. Добри су у приказивању слике на страници „моја достигнућа” унутар вашег сајта. Обично су много слабији у стварима које заиста имају значај за сертификат:
- Преносивост. Значка која постоји само као shortcode на вашем WordPress сајту није сертификат — она је украс. Онога тренутка када прималац промени посао, промени пријемно сандуче или ваш сајт престане да ради, „доказ” нестаје заједно с њим.
- Верификација. Свако треба да може да провери да ли је сертификат стваран, без пријављивања у администрацију вашег WordPress-а. Open Badge v2.0 вам по дефолту даје јавни URL за верификацију и машински читљив JSON-LD.
- Одржавање. Сваки WordPress додатак је још једна ствар коју треба закрпити, још једна табела у бази за резервну копију, још једна тачка отказа приликом велике надоградње.
Позивање спољашњег API-ја при завршетку курса заобилази сва три проблема. WordPress остаје задужен за оно у чему је добар — испоруку садржаја и праћење напретка — а сам сертификат живи у систему изграђеном посебно за његово издавање, верификацију и дељење.
Модел: један hook, један HTTP позив
Сваки већи WordPress LMS додатак покреће action када корисник заврши курс. Интеграција увек има иста три корака:
- Прихватите action завршетка за ваш конкретан LMS.
- Пронађите (или креирајте) идентитет примаоца — обично само имејл и приказано име његовог WordPress налога.
- Позовите
POST /awardsна Badges Ninja API-ју прекоwp_remote_post(), прослеђујући ID значке и податке о примаоцу.
Прво ће вам требати API кључ. Генеришите га на свом контролном панелу под API Keys — погледајте водич за API кључеве за потпуно упутство. Кључеви се приказују само једном приликом креирања, зато га сачувајте у wp-config.php као константу, а не у бази података:
define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Чувајте овај кључ на страни сервера. Све у овом водичу извршава се у PHP-у на вашем WordPress серверу — wp_remote_post() је позив на страни сервера, а wp-config.php се никада не шаље у претраживач. То је тачно оно што желите: кључ путује од сервера до сервера преко HTTPS-а и ниједан посетилац сајта не може да га прочита. Никада не премештајте овај позив у клијентски JavaScript — fetch() из претраживача са уграђеним кључем изложио би га свакоме преко алата за развојне програмере у претраживачу. Две навике вреди задржати: уверите се да ваш хостинг служи wp-config.php као извршени PHP (никада као обичан текст, и не остављајте копију wp-config.php.bak у webroot-у), и креирајте посебан API кључ за ову интеграцију како бисте могли независно да га опозовете ако икада буде компромитован — без нарушавања осталих алата.
Заједничка помоћна функција одржава сваки LMS hook једноставним:
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 );
}
Имејл примаоца се SHA-256 хешира на страни сервера чим стигне до Badges Ninja-е, а повратни payload садржи URL за верификацију награде — згодно ако желите да одмах у WordPress-у, после успешног позива, прикажете линк „погледајте свој сертификат”.
LearnDash
LearnDash покреће learndash_course_completed са једним аргументом типа низ који садржи user и 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 );
} );
Чување ID-ја значке као course meta (уместо једне глобалне константе BADGES_NINJA_BADGE_ID) исправан је потез чим имате више од једног курса — сваки курс се мапира на сопствени дизајн значке.
LifterLMS
LifterLMS покреће lifterlms_course_completed са $user_id и $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 покреће tutor_course_complete_after са ID-јем курса, а ви узимате тренутног корисника из сесије:
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 );
} );
Ако ваша Tutor LMS поставка покреће завршетак из позадинског процеса (нпр. преко аутоматског оцењивања теста), замените get_current_user_id() ID-јем корисника који ваш конкретан hook обезбеђује — проверите payload помоћу error_log( print_r( func_get_args(), true ) ) једном приликом подешавања како бисте потврдили аргументе.
Пројектовање значке пре повезивања hook-а
Пре него што било шта од овога буде покренуто, потребна вам је значка коју ћете додељивати. Визуелни дизајнер то покрива без потребе за дизајнером у тиму — преко 80 шаблона облика, прилагођене боје, библиотека икона и отпремање логотипа, све са прилепљивањем на мрежу. Ако сте нови у дизајнеру, Пројектовање вашег првог проверљивог дигиталног сертификата води вас кроз избор шаблона и креирање нечега што ће примаоци заиста желети да поделе.
Када значка постоји, преузмите њен ID са контролног панела (или преко GET /badges) и убаците га у прилагођено поље вашег курса.
Шта прималац заиста добија
Ово је део који домаћи WordPress додатак за значке не може да реплицира. Када POST /awards успе, прималац добија:
- Јединствен URL за верификацију који свако може да отвори — без потребе за пријавом на WordPress — који показује да је сертификат стваран, ко га је издао и када.
- QR код и A4 PDF сертификат, аутоматски генерисане.
- Дугме Add to LinkedIn Profile, ако ваш издавалац има подешен LinkedIn organization ID — погледајте Додавање LinkedIn дугмета „Add to Profile” за једнократно подешавање.
- Приступ сопственом порталу за примаоце на
badges.ninja/me, преко пријаве magic-link-ом — без лозинке коју треба памтити, без посебног налога који треба управљати на вашем WordPress сајту. - Стандардизован Open Badge v2.0 JSON-LD, тако да било који verifier који подржава OB (не само Badges Ninja) може да га потврди.
Ништа од овога није посао WordPress-а да изгради, нити треба да живи искључиво унутар ваше WordPress базе података.
Елегантно руковање неуспесима
Hook-ови за завршетак курса покрећу се током активног захтева за страницу, а спор или неуспешан API позив не сме да блокира полазников екран „честитамо”. Два практична подешавања чим пређете фазу доказа концепта:
Не дозволите да неуспела награда блокира интерфејс. Помоћна функција изнад већ бележи и враћа false уместо да баца изузетак — LearnDash, LifterLMS и Tutor настављају свој уобичајени ток завршетка без обзира на то шта врати badges_ninja_issue_award().
Ставите је у ред чекања уместо да позивате inline, при обиму. Ако у једном тренутку водите велике групе кроз један курс (датум почетка групе, откључавање снимка вебинара), покрените заказани WP-Cron догађај из hook-а уместо да позивате API синхроно:
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 );
Ово распоређује оптерећење и спречава да један спор захтев постане полазников проблем. За заиста велике серије (читава прошла група, мигрирана у једном потезу), потпуно прескочите пут преко WordPress hook-а и користите масовно додељивање преко CSV-а — отпремите једном, а платформа странично обрађује издавање на страни сервера са уграђеном паузом/наставком.
Напомена о идемпотентности
Ако ваш LMS икада покрене hook завршетка више од једном за истог корисника (уобичајен гранични случај код LearnDash-а са поновним полагањем теста, или поновна синхронизација код Tutor LMS-а), не желите да доделите исту значку двапут. Најједноставнија заштита је WordPress user-meta застава коју подешавате одмах после успешног позива:
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 );
}
Ако издајете у стварно великом обиму и желите да се то обрађује централизовано уместо по сајту, погледајте руковање догађајима покренуто webhook-ом или потпун API quickstart за облике захтева/одговора за сваку крајњу тачку.
Када овај модел прерасте један курс
Примери изнад претпостављају једну значку по курсу. Чим почнете да радите са степенованим сертификатима — значком за трасу која се откључава након неколико значки за курсеве, или капстон значком која зависи од више предуслова — преместите мапирање „која значка, за који завршетак” из post meta у малу референтну табелу, или га покрените из аутоматизације заснованe на табели (Airtable или Google Sheets) која покреће исти позив POST /awards. Сам API позив се не мења; мења се само оно што одлучује када ће бити упућен.
Решавање проблема с интеграцијом
Неколико проблема објашњава већину потешкоћа на које људи наилазе када ово повезују по први пут:
Hook се никада не покреће. Потврдите да прихватате прави action за стварну верзију вашег додатка — LearnDash је посебно мењао имена hook-ова за завршетак кроз главна издања (старије инсталације понекад још увек зависе од тога да learndash_course_completed буде покренут из друге путање кода у односу на новије). Додајте привремени error_log() на почетак вашег callback-а и пратите wp-content/debug.log док завршавате тестни курс као једнократни корисник.
wp_remote_post() истиче. Окружења дељеног хостинга понекад блокирају одлазни HTTPS ка непознатим хостовима, или ограничавају време чекања захтева испод горе постављених 15 секунди. Ако позиви доследно истичу, проверите код вашег хостинг провајдера да ли су дозвољене одлазне везе ка api.badges.ninja, и потврдите да PHP curl екстензија има актуелне CA сертификате — застарели пакет сертификата чест је тих узрок отказа на старијим дељеним хостинг стековима.
400 Bad Request. Payload-у недостаје обавезно поље или има погрешан облик. POST /awards очекује badgeId, угнежђени објекат recipient са name и email, и timestamp issuedOn — помоћна функција изнад шаље тачно то. Најчешћи камен спотицања је име примаоца: мора имати бар 5 знакова, тако да WordPress приказано име попут „Jo” бива одбијено. Ослоните се на пуно име налога (или локални део имејла) када је приказано име прекратко.
401 Unauthorized. Константа API кључа се не учитава, или је кључ регенерисан после подешавања константе. Кључеви се приказују само једном приликом креирања и не могу се поново преузети — ако сте изгубили траг који кључ је активан, обришите застарели и издајте нов уместо да нагађате.
Значка је издата, али са погрешним дизајном. Ово је готово увек застарела вредност post-meta поља badges_ninja_badge_id остала од тестирања. Пошто мапирање живи на запису курса, лако је заборавити да сте га променили после дуплирања курса за нову групу — вреди брзо проверити сваки пут када клонирате курс.
Дуплиране награде за исту особу. Обрађено изнад путем user-meta заштите, али вреди поновити: hook-ови за завршетак у LMS-у нису гарантовано покренути тачно једном. Третирајте „већ додељено” као уобичајен случај који треба проверити, а не гранични случај који треба игнорисати.
Често постављана питања
Да ли ово ради са WooCommerce пакетима курсева? Да — ако куповина пакета треба да покрене значку независно од завршетка курса (нпр. значка „сертификовани члан” за свакога ко купи одређени пакет), прихватите woocommerce_order_status_completed уместо action-а за завршетак у LMS-у, и потражите ID значке из meta производа, а не курса.
Могу ли примаоци да добију значку без WordPress налога? Да, и то је поента. Награда је повезана са њиховом имејл адресом у Badges Ninja-и, а не са записом WordPress корисника. Ако ваш сајт дозвољава куповину као гост или анонимно завршавање теста, само се уверите да прикупљате стварну имејл адресу коју прослеђујете у badges_ninja_issue_award().
Шта ако желим да прегледам награде пре него што буду послате? Прескочите директно покретање позива из hook-а за завршетак. Уместо тога, запишите награду на чекању (корисник, курс, временска ознака) у прилагођену табелу или тип записа, и издајте је из заказаног задатка или административног дугмета „Approve & Award” које по потреби позива исту помоћну функцију.
Да ли ми је потребна посебна значка по курсу, или једна значка може да покрије више њих? Обоје функционише. Неки издаваоци креирају по једну значку по курсу ради веће гранулације; други креирају једну значку „завршетак програма” и додељују је тек када су сви потребни курсеви завршени, проверавајући завршетак предуслова унутар hook-а пре позивања API-ја.
Спремни да издате свој први проверљив сертификат? Почните бесплатно на badges.ninja — визуелни дизајнер, јавна страница за верификацију, PDF сертификат, Open Badge v2.0 излаз. Није потребна кредитна картица.
Како је овај чланак настао
Неки текстови на овом блогу настају уз помоћ ВИ асистента, а затим их проверава, чињенично потврђује и уређује тим Badges Ninja пре објављивања. Сваки код и цена се проверавају у односу на актуелни производ. Више о нашем уредничком и ВИ процесу прочитајте на нашој страници о уредничком процесу .

О аутору
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.
