Menerbitkan Open Badge dari WordPress (Tanpa Plugin yang Berat)

Terbitkan Open Badge dari plugin kursus/LMS WordPress apa pun (LearnDash, LifterLMS, Tutor) dengan memanggil API Badges Ninja saat kursus selesai — tanpa perlu menginstal plugin lencana terpisah.

Nacho Coll Oleh Diperbarui 11 menit baca
Terbitkan Open Badge dari plugin kursus/LMS WordPress apa pun (LearnDash, LifterLMS, Tutor) dengan memanggil API Badges Ninja saat kursus selesai — tanpa perlu menginstal plugin lencana terpisah.

Jika Anda menjalankan kursus di WordPress, Anda pasti sudah paham polanya: seseorang menyelesaikan modul di LearnDash, LifterLMS, atau Tutor LMS, LMS menandainya “complete”, lalu… tidak ada yang bisa diverifikasi. Mungkin Anda mengirim PDF lewat email. Mungkin Anda menginstal plugin lencana WordPress khusus yang menambahkan tabel database sendiri, pustaka gambar sendiri, dan definisinya sendiri tentang apa itu “lencana” — yang tidak bisa diverifikasi oleh siapa pun di luar situs Anda.

Ada cara yang lebih sederhana. Plugin kursus WordPress sudah memicu action hook begitu seseorang menyelesaikan kursus. Anda bisa menangkap hook itu dan membuat satu panggilan HTTP ke API Badges Ninja. Tanpa plugin tambahan, tanpa hosting tambahan, tanpa format lencana proprietary — hanya kredensial Open Badge v2.0 yang sesuai standar, yang bisa diverifikasi oleh penerima di mana saja, ditambahkan ke LinkedIn, dan diunduh sebagai PDF.

Postingan ini membahas pola tersebut satu kali, lalu menunjukkan hook spesifik untuk LearnDash, LifterLMS, dan Tutor LMS.

Kenapa tidak cukup pakai plugin lencana WordPress saja?

Plugin lencana WordPress khusus sebenarnya menyelesaikan masalah yang lebih sempit dari yang terlihat. Plugin ini bagus untuk menampilkan gambar di halaman “my achievements” di dalam situs Anda. Tapi biasanya jauh lebih lemah dalam hal-hal yang sebenarnya penting untuk sebuah kredensial:

  • Portabilitas. Lencana yang hanya ada sebagai shortcode di situs WordPress Anda bukanlah kredensial — itu hanya hiasan. Begitu penerima berganti pekerjaan, mengganti kotak masuk, atau situs Anda down, “buktinya” ikut hilang.
  • Verifikasi. Siapa pun seharusnya bisa memeriksa apakah sebuah kredensial itu asli tanpa perlu login ke admin WordPress Anda. Open Badge v2.0 secara desain memberi Anda URL verifikasi publik dan JSON-LD yang bisa dibaca mesin.
  • Beban pemeliharaan. Setiap plugin WordPress adalah satu hal lagi yang harus ditambal, satu tabel database lagi yang harus dicadangkan, satu titik kegagalan lagi saat pembaruan core.

Memanggil API eksternal saat kursus selesai menghindari ketiga masalah itu. WordPress tetap bertanggung jawab atas hal yang memang jadi keahliannya — pengiriman konten dan pelacakan progres — sementara kredensialnya sendiri berada di sistem yang dibangun khusus untuk menerbitkan, memverifikasi, dan membagikannya.

Polanya: satu hook, satu panggilan HTTP

Setiap plugin LMS WordPress utama memicu sebuah action saat pengguna menyelesaikan kursus. Integrasinya selalu tiga langkah yang sama:

  1. Sambungkan hook ke action penyelesaian untuk LMS spesifik Anda.
  2. Cari (atau buat) identitas penerima — biasanya cukup email dan nama tampilan akun WordPress mereka.
  3. Panggil POST /awards pada API Badges Ninja dengan wp_remote_post(), dengan menyertakan ID lencana dan detail penerima.

Anda perlu API key terlebih dahulu. Buat satu dari dasbor Anda di bagian API Keys — lihat panduan API keys untuk langkah lengkapnya. Key hanya ditampilkan sekali saat dibuat, jadi simpan sebagai konstanta di wp-config.php, bukan di database:

define( 'BADGES_NINJA_API_KEY', 'bws_your_32_hex_key_here' );
define( 'BADGES_NINJA_BADGE_ID', 'your-badge-id' );

Key yang baru dibuat ditampilkan sekali

Simpan key ini hanya di sisi server. Semua hal dalam panduan ini berjalan di PHP pada server WordPress Anda — wp_remote_post() adalah panggilan sisi server, dan wp-config.php tidak pernah dikirim ke browser. Itulah yang Anda inginkan: key berpindah dari server ke server lewat HTTPS, dan tidak ada pengunjung situs yang bisa membacanya. Jangan pernah memindahkan panggilan ini ke JavaScript sisi klien — fetch() dari browser dengan key yang ditulis langsung di dalamnya akan mengekspos key tersebut ke siapa pun lewat dev tools browser mereka. Ada dua kebiasaan yang perlu dijaga: pastikan hosting Anda menyajikan wp-config.php sebagai PHP yang dieksekusi (bukan sebagai plaintext, dan jangan tinggalkan salinan wp-config.php.bak di webroot), serta buat API key khusus untuk integrasi ini agar Anda bisa mencabutnya secara terpisah jika suatu saat bocor — tanpa merusak alat Anda yang lain.

Fungsi helper bersama membuat setiap hook LMS tetap ringkas:

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 );
}

Email penerima di-hash dengan SHA-256 di sisi server begitu sampai di Badges Ninja, dan payload respons menyertakan URL verifikasi award — berguna jika Anda ingin menampilkan tautan “view your credential” langsung di WordPress setelah panggilan berhasil.

LearnDash

LearnDash memicu learndash_course_completed dengan satu argumen array berisi user dan 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 );
} );

Menyimpan ID lencana sebagai meta kursus (alih-alih satu konstanta global BADGES_NINJA_BADGE_ID) adalah pilihan yang tepat begitu Anda punya lebih dari satu kursus — setiap kursus dipetakan ke desain lencananya sendiri.

LifterLMS

LifterLMS memicu lifterlms_course_completed dengan $user_id dan $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 memicu tutor_course_complete_after dengan ID kursus, dan Anda mengambil pengguna saat ini dari sesi:

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 );
} );

Jika setup Tutor LMS Anda memicu penyelesaian dari proses background (misalnya lewat auto-grade kuis), ganti get_current_user_id() dengan ID pengguna yang disediakan oleh hook spesifik Anda — periksa payload dengan error_log( print_r( func_get_args(), true ) ) sekali saat setup untuk memastikan argumennya.

Mendesain lencana sebelum menyambungkan hook

Sebelum semua ini terpicu, Anda butuh lencana untuk diberikan. Visual designer menangani ini tanpa perlu mempekerjakan desainer — 80+ template bentuk, warna kustom, pustaka ikon, dan unggah logo, semuanya snap-to-grid. Jika Anda baru mengenal designer-nya, Designing Your First Verifiable Digital Certificate memandu Anda memilih template dan menghasilkan sesuatu yang benar-benar ingin dibagikan oleh penerima.

Setelah lencana dibuat, ambil ID-nya dari dasbor (atau lewat GET /badges) dan masukkan ke custom field kursus Anda.

Apa yang sebenarnya didapat penerima

Inilah bagian yang tidak bisa ditiru oleh plugin lencana WordPress buatan sendiri. Saat POST /awards berhasil, penerima mendapatkan:

  • URL verifikasi unik yang bisa dibuka siapa saja — tanpa perlu login WordPress — yang menunjukkan bahwa kredensial itu asli, siapa yang menerbitkannya, dan kapan.
  • Kode QR dan sertifikat PDF A4, dibuat otomatis.
  • Tombol Add to LinkedIn Profile, jika penerbit Anda telah mengatur ID organisasi LinkedIn — lihat Add a LinkedIn “Add to Profile” Button untuk setup satu kali.
  • Akses ke portal penerima mereka sendiri di badges.ninja/me, lewat login magic-link — tanpa perlu mengingat kata sandi, tanpa akun terpisah yang harus dikelola di situs WordPress Anda.
  • Open Badge v2.0 JSON-LD yang sesuai standar, sehingga verifier mana pun yang mendukung OB (bukan hanya Badges Ninja) bisa memvalidasinya.

Tidak satu pun dari itu adalah tugas WordPress untuk dibangun, dan tidak satu pun dari itu seharusnya hanya berada di dalam database WordPress Anda.

Menangani kegagalan dengan baik

Hook penyelesaian kursus terpicu selama permintaan halaman yang aktif, dan panggilan API yang lambat atau gagal seharusnya tidak menghalangi layar “congratulations” pembelajar. Dua penyesuaian praktis setelah Anda melewati tahap proof of concept:

Jangan biarkan award yang gagal menghalangi UI. Fungsi helper di atas sudah mencatat log dan mengembalikan false alih-alih melempar error — LearnDash, LifterLMS, dan Tutor semuanya tetap melanjutkan alur penyelesaian normal mereka terlepas dari apa yang dikembalikan badges_ninja_issue_award().

Antrekan alih-alih memanggil langsung, dalam skala besar. Jika Anda menjalankan kohort besar melalui satu kursus sekaligus (tanggal mulai kohort, pembukaan replay webinar), picu event terjadwal WP-Cron dari hook alih-alih memanggil API secara sinkron:

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 );

Ini menyebarkan beban dan mencegah satu permintaan lambat menjadi masalah pembelajar. Untuk batch yang benar-benar besar (seluruh kohort lama yang dimigrasikan sekaligus), lewati jalur hook WordPress sepenuhnya dan gunakan bulk awards via CSV — unggah sekali, dan platform akan mem-paginasi penerbitan di sisi server dengan pause/resume bawaan.

Catatan tentang idempotensi

Jika LMS Anda pernah memicu hook penyelesaiannya lebih dari sekali untuk pengguna yang sama (kasus umum LearnDash dengan pengulangan kuis, atau re-sync Tutor LMS), Anda tidak ingin memberikan lencana yang sama dua kali. Pengaman paling sederhana adalah flag user-meta WordPress yang Anda set tepat setelah panggilan berhasil:

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 );
}

Jika Anda menerbitkan dalam volume nyata dan ingin ini ditangani secara terpusat alih-alih per situs, lihat webhook-driven event handling atau API quickstart lengkap untuk bentuk request/response di setiap endpoint.

Saat pola ini berkembang melampaui satu kursus

Contoh di atas mengasumsikan satu lencana per kursus. Begitu Anda menjalankan kredensial yang bisa ditumpuk — lencana jalur yang terbuka setelah beberapa lencana kursus, atau capstone yang bergantung pada beberapa prasyarat — pindahkan pemetaan “lencana mana, untuk penyelesaian mana” dari post meta ke tabel lookup kecil, atau jalankan dari automasi berbasis spreadsheet (Airtable atau Google Sheets) yang memicu panggilan POST /awards yang sama. Panggilan API-nya sendiri tidak berubah; yang berubah hanya apa yang menentukan kapan panggilan itu dibuat.

Mengatasi masalah integrasi

Ada beberapa masalah yang menjadi penyebab sebagian besar kesulitan yang dialami orang saat menyambungkan ini untuk pertama kalinya:

Hook tidak pernah terpicu. Pastikan Anda menyambungkan action yang tepat untuk versi plugin Anda yang sebenarnya — LearnDash khususnya telah mengubah nama completion-hook di berbagai rilis utama (instalasi lama terkadang masih mengandalkan learndash_course_completed yang terpicu dari jalur kode berbeda dibanding yang lebih baru). Tambahkan error_log() sementara di bagian atas callback Anda dan pantau wp-content/debug.log saat Anda menyelesaikan kursus uji sebagai pengguna sekali pakai.

wp_remote_post() timeout. Lingkungan shared hosting terkadang memblokir HTTPS keluar ke host yang tidak dikenal, atau membatasi timeout permintaan di bawah 15 detik yang diset di atas. Jika panggilan terus-menerus timeout, tanyakan ke penyedia hosting Anda apakah koneksi keluar ke api.badges.ninja diizinkan, dan pastikan ekstensi PHP curl Anda memiliki sertifikat CA terkini — bundel sertifikat yang kedaluwarsa adalah kegagalan diam-diam yang umum pada stack shared-hosting lama.

400 Bad Request. Payload kehilangan field wajib atau bentuknya salah. POST /awards mengharapkan badgeId, objek recipient bersarang dengan name dan email, serta timestamp issuedOn — helper di atas mengirim persis itu. Kesalahan paling umum ada pada name penerima: harus minimal 5 karakter, sehingga nama tampilan WordPress seperti “Jo” akan ditolak. Gunakan nama lengkap akun (atau bagian lokal email) sebagai cadangan saat nama tampilan terlalu pendek.

401 Unauthorized. Konstanta API key tidak termuat, atau key sudah dibuat ulang setelah konstanta diset. Key hanya ditampilkan sekali saat dibuat dan tidak bisa diambil lagi — jika Anda kehilangan jejak key mana yang aktif, hapus yang lama dan terbitkan yang baru daripada menebak-nebak.

Lencana diberikan, tapi ke desain lencana yang salah. Ini hampir selalu adalah nilai post-meta badges_ninja_badge_id yang basi, sisa dari pengujian. Karena pemetaan ini berada di post kursus, mudah lupa bahwa Anda mengubahnya setelah menduplikasi kursus untuk kohort baru — layak dicek sekilas setiap kali Anda mengkloning kursus.

Award ganda untuk orang yang sama. Sudah dibahas di atas dengan pengaman user-meta, tapi perlu ditekankan lagi: hook penyelesaian LMS tidak dijamin terpicu tepat satu kali. Anggap “sudah diberikan” sebagai kondisi normal yang perlu dicek, bukan kasus khusus yang bisa diabaikan.

Pertanyaan yang sering diajukan

Apakah ini berfungsi dengan bundel kursus WooCommerce? Ya — jika pembelian bundel seharusnya memicu lencana secara independen dari penyelesaian kursus (misalnya lencana “certified member” untuk siapa pun yang membeli bundel tertentu), sambungkan hook woocommerce_order_status_completed alih-alih action penyelesaian LMS, dan ambil ID lencana dari meta produk, bukan dari kursus.

Bisakah penerima mendapatkan lencana tanpa akun WordPress? Bisa, dan memang itu intinya. Award terikat pada alamat email mereka di Badges Ninja, bukan pada catatan pengguna WordPress. Jika situs Anda mengizinkan checkout sebagai tamu atau penyelesaian kuis anonim, pastikan saja Anda menangkap alamat email yang asli untuk diteruskan ke badges_ninja_issue_award().

Bagaimana jika saya ingin meninjau award sebelum diterbitkan? Jangan picu panggilan langsung dari hook penyelesaian. Sebagai gantinya, tulis award yang tertunda (user, course, timestamp) ke tabel kustom atau post type, lalu terbitkan lewat tugas terjadwal atau tombol admin “Approve & Award” yang memanggil fungsi helper yang sama sesuai permintaan.

Apakah saya butuh lencana terpisah per kursus, atau satu lencana bisa mencakup beberapa kursus? Keduanya bisa. Sebagian penerbit membuat satu lencana per kursus demi granularitas; yang lain membuat satu lencana “program completion” dan hanya memberikannya setelah setiap kursus yang diwajibkan selesai, dengan memeriksa penyelesaian prasyarat di dalam hook sebelum memanggil API.


Siap menerbitkan kredensial terverifikasi pertama Anda? Mulai gratis di badges.ninja — visual designer, halaman verifikasi publik, sertifikat PDF, output Open Badge v2.0. Tanpa kartu kredit.

Nacho Coll

Tentang penulis

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.

Kembali ke Blog

Artikel Terkait