Pag-isyu ng Open Badges mula sa WordPress (Walang Mabigat na Plugin)
Mag-issue ng Open Badges mula sa kahit anong WordPress course/LMS plugin (LearnDash, LifterLMS, Tutor) sa pamamagitan ng pag-call sa Badges Ninja API pag-complete — walang kailangang i-install na hiwalay na badge plugin.
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.
Kung nagpapatakbo ka ng mga course sa WordPress, alam mo na ang drill: may nag-finish ng module sa LearnDash, LifterLMS, o Tutor LMS, mina-mark ito ng LMS bilang “complete,” at pagkatapos… wala namang mangyayaring maverify. Baka nag-eemail ka ng PDF. Baka nag-iinstall ka ng dedicated WordPress badge plugin na nagdadagdag ng sarili nitong database tables, sariling image library, at sariling ideya kung ano ang isang “badge” — na hindi naman maverify ng kahit sino sa labas ng site mo.
May mas simpleng paraan. Ang mga WordPress course plugin ay may action hook na nagfire agad sa sandaling may mag-complete ng course. Puwede mong i-catch ang hook na iyon at gumawa ng isang HTTP call papunta sa Badges Ninja API. Walang extra plugin, walang extra hosting, walang proprietary badge format — isang standards-compliant Open Badge v2.0 credential lang na kayang i-verify ng recipient mo kahit saan, idagdag sa LinkedIn, at i-download bilang PDF.
Ipapakita ng post na ito ang pattern nang isang beses, tapos ipapakita ang specific hook para sa LearnDash, LifterLMS, at Tutor LMS.
Bakit hindi na lang gumamit ng WordPress badge plugin?
Ang mga dedicated WordPress badge plugin ay sumosolve ng mas makitid na problema kaysa sa mukhang sinosolve nila. Magaling sila sa pag-render ng image sa isang “my achievements” page sa loob ng site mo. Pero mas mahina sila sa mga bagay na talagang importante para sa isang credential:
- Portability. Ang badge na shortcode lang sa WordPress site mo ang existence ay hindi credential — decoration lang ito. Sa sandaling magpalit ng trabaho ang recipient, magpalit ng inbox, o mawala ang site mo, mawawala rin ang “proof.”
- Verification. Dapat kayang i-check ng kahit sino na totoo ang isang credential nang hindi kailangang mag-log in sa WordPress admin mo. Ang Open Badge v2.0 ay nagbibigay sa iyo ng public verification URL at machine-readable JSON-LD by design.
- Maintenance surface. Bawat WordPress plugin ay isa pang bagay na kailangang i-patch, isa pang database table na kailangang i-back up, isa pang point of failure sa panahon ng core update.
Ang pag-call sa external API kapag na-complete ang course ay nakaka-sidestep sa lahat ng tatlong ito. Nananatiling responsable ang WordPress sa kung ano ang magaling dito — content delivery at progress tracking — at ang credential mismo ay nabubuhay sa isang system na binuo specifically para i-issue, i-verify, at i-share ito.
Ang pattern: isang hook, isang HTTP call
Bawat major WordPress LMS plugin ay nagfire ng action kapag nag-complete ang isang user ng course. Palaging parehong tatlong hakbang ang integration:
- Mag-hook sa completion action para sa specific LMS mo.
- Hanapin (o gawin) ang identity ng recipient — karaniwan ay ang WordPress account email at display name lang nila.
- I-call ang
POST /awardssa Badges Ninja API gamit angwp_remote_post(), ipinapasa ang badge ID at recipient details.
Kakailanganin mo muna ng API key. Mag-generate ka ng isa mula sa dashboard mo, sa ilalim ng API Keys — tingnan ang API keys guide para sa buong walkthrough. Ipinapakita lang minsan ang keys pag na-create, kaya i-store ito sa wp-config.php bilang constant sa halip na sa database:
define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Panatilihin ang key na ito sa server-side. Lahat ng nasa guide na ito ay tumatakbo sa PHP sa WordPress server mo — ang wp_remote_post() ay isang server-side call, at ang wp-config.php ay hindi kailanman naipapadala sa browser. Iyan mismo ang gusto mo: naglalakbay ang key server-to-server sa HTTPS, at walang site visitor na makakabasa nito. Huwag kailanman ilipat ang call na ito papunta sa client-side JavaScript — ang fetch() mula sa browser na may inline na key ay mag-e-expose nito sa kahit sino gamit ang dev tools ng browser nila. Dalawang habit na sulit panatilihin: siguraduhing sine-serve ng host mo ang wp-config.php bilang executed PHP (hindi bilang plaintext, at huwag mag-iwan ng wp-config.php.bak copy sa webroot), at gumawa ng dedicated API key para sa integration na ito para kaya mo itong i-revoke nang independent kung ma-compromise man ito — nang hindi masisira ang ibang tools mo.
Ang isang shared helper function ay pinapanatiling manipis ang bawat 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 );
}
Ang email ng recipient ay SHA-256 hashed sa server-side sa sandaling makarating ito sa Badges Ninja, at kasama sa return payload ang verification URL ng award — kapaki-pakinabang kung gusto mong magpakita ng “view your credential” link doon mismo sa WordPress pagkatapos magtagumpay ang call.
LearnDash
Ang LearnDash ay nagfire ng learndash_course_completed na may isang array argument na naglalaman ng user at 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 );
} );
Ang pag-store ng badge ID bilang course meta (sa halip na iisang global na BADGES_NINJA_BADGE_ID constant) ang tamang gawin kapag mayroon ka nang higit sa isang course — bawat course ay naka-map sa sarili nitong badge design.
LifterLMS
Ang LifterLMS ay nagfire ng lifterlms_course_completed na may $user_id at $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
Ang Tutor LMS ay nagfire ng tutor_course_complete_after na may course ID, at kukunin mo ang current user mula sa session:
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 );
} );
Kung ang Tutor LMS setup mo ay nagfire ng completion mula sa isang background process (halimbawa sa pamamagitan ng quiz auto-grade), palitan ang get_current_user_id() ng user ID na ibinibigay ng specific hook mo — i-check ang payload gamit ang error_log( print_r( func_get_args(), true ) ) nang isang beses habang nagse-setup para i-confirm ang mga arguments.
Pag-design ng badge bago i-wire ang hook
Bago pa magfire ang kahit alin dito, kailangan mo muna ng badge na iaaward. Ang visual designer ay sakop na ito nang hindi na kailangan ng designer sa staff — 80+ shape templates, custom colors, icon library, at logo upload, lahat snap-to-grid. Kung bago ka pa lang sa designer, ang Designing Your First Verifiable Digital Certificate ay ipapakita kung paano pumili ng template at maglabas ng isang bagay na talagang gugustuhing i-share ng mga recipient.
Kapag nag-exist na ang badge, kunin ang ID nito mula sa dashboard (o sa pamamagitan ng GET /badges) at ilagay ito sa custom field ng course mo.
Ano talaga ang natatanggap ng recipient
Ito ang parteng hindi kayang i-replicate ng homegrown na WordPress badge plugin. Kapag nagtagumpay ang POST /awards, natatanggap ng recipient ang:
- Isang unique na verification URL na kayang buksan ng kahit sino — walang kailangang WordPress login — na nagpapakita na totoo ang credential, sino ang nag-issue nito, at kailan.
- Isang QR code at A4 PDF certificate, na automatic na na-generate.
- Isang Add to LinkedIn Profile button, kung may naka-set na LinkedIn organization ID ang issuer mo — tingnan ang Add a LinkedIn “Add to Profile” Button para sa one-time setup.
- Access sa sarili nilang recipient portal sa
badges.ninja/me, sa pamamagitan ng magic-link sign-in — walang password na dapat tandaan, walang hiwalay na account na dapat i-manage sa WordPress site mo. - Standards-compliant na Open Badge v2.0 JSON-LD, kaya kahit anong OB-aware na verifier (hindi lang Badges Ninja) ay kayang i-validate ito.
Wala sa mga iyan ang trabaho ng WordPress na buuin, at wala sa mga iyan ang dapat nabubuhay lang sa loob ng WordPress database mo.
Pag-handle ng failures nang maayos
Nagfifire ang course-completion hooks habang live pa ang page request, at ang isang mabagal o failed na API call ay hindi dapat mag-block sa “congratulations” screen ng learner. Dalawang practical na adjustment kapag lumagpas ka na sa proof of concept:
Huwag hayaang mag-block sa UI ang isang failed award. Ang helper function sa itaas ay naglo-log na at nagre-return ng false sa halip na mag-throw — ang LearnDash, LifterLMS, at Tutor ay lahat nagpapatuloy sa normal na completion flow nila anuman ang ire-return ng badges_ninja_issue_award().
I-queue ito sa halip na tawagin nang inline, sa scale. Kung nagpapatakbo ka ng malalaking cohort sa isang course nang sabay-sabay (isang cohort start date, isang webinar replay unlock), mag-fire ng WP-Cron scheduled event mula sa hook sa halip na tawagin ang API nang synchronous:
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 );
Ikinakalat nito ang load at pinipigilan ang isang mabagal na request na maging problema ng learner. Para sa genuinely malalaking batches (isang buong past cohort, na na-migrate nang sabay), laktawan na lang ang WordPress hook path at gamitin ang bulk awards via CSV — mag-upload nang isang beses, at pi-paginate ng platform ang issuance sa server-side na may built-in na pause/resume.
Isang note tungkol sa idempotency
Kung minsan ay nagfire ang LMS mo ng completion hook nito nang higit sa isang beses para sa parehong user (isang common na LearnDash edge case sa quiz retakes, o isang Tutor LMS re-sync), ayaw mong ma-award ang parehong badge nang dalawang beses. Ang pinakasimpleng guard ay isang WordPress user-meta flag na ise-set mo agad pagkatapos ng successful na call:
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 );
}
Kung nag-i-issue ka sa totoong volume at gusto mong i-handle ito nang centralized sa halip na per-site, tingnan ang webhook-driven event handling o ang buong API quickstart para sa request/response shapes sa bawat endpoint.
Kapag lumampas na ang pattern na ito sa isang course
Ang mga halimbawa sa itaas ay ina-assume na isang badge bawat course. Kapag nagpapatakbo ka na ng stackable credentials — isang track badge na na-unlock pagkatapos ng ilang course badges, o isang capstone na dependent sa maraming prerequisites — ilipat ang “which badge, for which completion” mapping palabas ng post meta at papunta sa isang maliit na lookup table, o i-drive ito mula sa isang spreadsheet-backed automation (Airtable o Google Sheets) na nagfire ng parehong POST /awards call. Ang API call mismo ay hindi nagbabago; ang nagbabago lang ay kung ano ang nagdedesisyon kung kailan ito gagawin.
Pag-troubleshoot ng integration
Ilang issues ang dahilan ng karamihan sa friction na nararanasan ng mga tao kapag una nilang ini-wire ito:
Hindi nagfifire ang hook. I-confirm na tama ang action na hina-hook mo para sa aktwal na version ng plugin mo — ang LearnDash lalo na ay nagbago ng completion-hook names sa iba’t ibang major releases (may mga mas lumang install na kung minsan ay umaasa pa rin sa learndash_course_completed na nagfifire mula sa ibang code path kumpara sa mas bagong mga install). Magdagdag ng pansamantalang error_log() sa taas ng callback mo at bantayan ang wp-content/debug.log habang nagco-complete ka ng test course bilang throwaway user.
Nag-ti-timeout ang wp_remote_post(). Ang shared hosting environments kung minsan ay nagbo-block ng outbound HTTPS papunta sa mga unfamiliar na host, o naglilimita ng request timeouts sa mas mababa sa 15 seconds na naka-set sa itaas. Kung consistent na nagti-timeout ang mga call, i-check sa host mo kung pinapayagan ang outbound connections papunta sa api.badges.ninja, at i-confirm na may current CA certificates ang PHP curl extension mo — ang outdated cert bundle ay common na silent failure sa mas lumang shared-hosting stacks.
400 Bad Request. May kulang na required field ang payload o mali ang shape nito. Ang POST /awards ay umaasa ng badgeId, isang nested na recipient object na may name at email, at isang issuedOn timestamp — ipinapadala ng helper sa itaas nang eksakto iyon. Ang pinaka-common na trip-up ay ang name ng recipient: dapat itong at least 5 characters, kaya tinatanggihan ang WordPress display name na tulad ng “Jo.” Bumalik sa full name ng account (o sa local-part ng email) kapag masyadong maikli ang display name.
401 Unauthorized. Hindi nagloload ang API key constant, o na-regenerate ito pagkatapos ma-set ang constant. Ipinapakita lang minsan ang keys pag na-create at hindi na maretrieve ulit — kung nawala mo na ang bakas kung aling key ang live, i-delete na lang ang stale na isa at mag-issue ng bago sa halip na manghula.
Na-issue ang badge, pero sa maling badge design. Halos palaging ito ay stale na badges_ninja_badge_id post-meta value na naiwan mula sa testing. Dahil nabubuhay ang mapping sa course post, madaling makalimutan na binago mo ito matapos i-duplicate ang course para sa bagong cohort — sulit ang mabilisang check tuwing nagcoclone ka ng course.
Duplicate awards para sa parehong tao. Nasakop na ito sa itaas gamit ang user-meta guard, pero sulit itong ulitin: hindi guaranteed na magfifire nang eksaktong isang beses ang mga LMS completion hooks. Ituring ang “already awarded” bilang normal na case na dapat i-check, hindi edge case na dapat i-ignore.
Mga madalas itanong
Gumagana ba ito sa WooCommerce course bundles? Oo — kung dapat mag-trigger ng badge ang isang bundle purchase nang independent sa course completion (halimbawa isang “certified member” badge para sa kahit sinong bumili ng specific na bundle), i-hook ang woocommerce_order_status_completed sa halip na isang LMS completion action, at hanapin ang badge ID mula sa product meta sa halip na sa course.
Puwede bang makuha ng recipients ang badge nang walang WordPress account? Oo, at iyan mismo ang point. Naka-tie ang award sa email address nila sa Badges Ninja, hindi sa isang WordPress user record. Kung pinapayagan ng site mo ang guest checkout o anonymous quiz completion, siguraduhin lang na nakaka-capture ka ng tunay na email address na ipapasa sa badges_ninja_issue_award().
Paano kung gusto kong i-review ang awards bago ito ipalabas? Laktawan ang direktang pagfire ng call mula sa completion hook. Sa halip, isulat ang pending award (user, course, timestamp) sa isang custom table o post type, at i-issue ito mula sa isang scheduled task o isang admin na “Approve & Award” button na tumatawag sa parehong helper function on demand.
Kailangan ko ba ng hiwalay na badge bawat course, o puwedeng saklawin ng isang badge ang ilan? Pareho itong gumagana. May mga issuer na gumagawa ng isang badge bawat course para sa granularity; may iba naman na gumagawa ng iisang “program completion” badge at ina-award lang ito kapag natapos na ang bawat required course, chine-check ang prerequisite completion sa loob ng hook bago tawagin ang API.
Handa ka na bang mag-issue ng first verifiable credential mo? Mag-start nang libre sa badges.ninja — visual designer, public verification page, PDF certificate, Open Badge v2.0 output. Walang kailangang credit card.
Paano ginawa ang artikulong ito
Ang ilang artikulo sa blog na ito ay ginagawa gamit ang tulong ng AI assistant, pagkatapos ay sinusuri, tinitiyak ang katumpakan, at ine-edit ng Badges Ninja team bago ilathala. Bawat code sample at presyo ay beripikado laban sa live na produkto. Alamin pa ang tungkol sa aming editorial at AI na proseso sa aming pahina ng editorial process .

Tungkol sa may-akda
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.
Higit pa mula kay Nacho Coll
- Salesforce Open Badges: Mag-issue ng Verifiable Credentials mula sa CRM TriggersOkt 1, 2026 · 10min basahin
- Pag-issue ng Open Badges gamit ang Badges Ninja REST API: QuickstartSet 28, 2026 · 10min basahin
- I-embed ang Badge Verification sa Website Mo (Walang Iframe, Walang SDK)Set 24, 2026 · 10min basahin
