tte-bsre-laravel maintained by seahorseeeee
Laravel BSrE TTE Plugin (seahorseeeee/tte-bsre-laravel)
Package integrasi resmi Tanda Tangan Elektronik (TTE) BSrE v2 dari BSSN (Badan Siber dan Sandi Negara) untuk framework Laravel 12.x / 13.x dan PHP 8.4 / 8.5.
Package ini dirancang bersifat Universal & Database-Agnostic (tidak terikat pada satu jenis tabel/database), sehingga dapat digunakan di berbagai modul pemerintahan daerah seperti PBB-P2 (Massal), BPHTB, Pajak Daerah (SIMPATDA), Retribusi, SKRD, E-Surat, dan Layanan Publik Lainnya.
🚀 Fitur Unggulan
- ✅ BSrE API v2 Batch Signing: Menandatangani banyak dokumen PDF sekaligus (15–20 file PDF dalam 1 request HTTP) via JSON Base64.
- ✅ Single & Realtime Signing: Menandatangani 1 dokumen secara langsung (on-the-fly).
- ✅ Invisible & Visible Signature: Mendukung TTE tersembunyi (invisible) maupun visual barcode/stempel BSrE (visible).
- ✅ Passphrase Cryptography: Enkripsi dan dekripsi Passphrase TTE yang aman (AES-256-CBC) untuk mode antrian massal.
- ✅ Passphrase Pre-validation: Menguji keabsahan Passphrase ke server BSrE sebelum transaksi massal diproses.
- ✅ Verifikasi Dokumen: Memeriksa keaslian tanda tangan digital pada file PDF.
- ✅ ZIP Bundler: Utilitas untuk mengemas ribuan PDF per kelurahan/kategori menjadi file
.zip. - ✅ Bypass / Simulation Mode: Fitur simulasi signing lokal saat server BSrE sedang maintenance.
- ✅ Event-Driven Architecture: Menembakkan event
DocumentSigneddanDocumentSignFaileduntuk integrasi audit trail. - ✅ Artisan Command CLI: Perintah
php artisan tte:testuntuk menguji konektivitas & passphrase dari terminal.
📋 Persyaratan Sistem
- PHP:
^8.4 || ^8.5 - Laravel Framework:
^12.0 || ^13.0 - Ekstensi PHP:
ext-openssl,ext-zip,ext-json
📦 Cara Instalasi
Pilih salah satu metode instalasi berikut sesuai kebutuhan lingkungan Anda:
Opsi A: Menggunakan GitLab Repository (Privat / VCS)
Di file composer.json proyek Laravel target Anda, tambahkan blok repositories:
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.com/SeaHorseeeee/tte-bsre-laravel.git"
}
]
Kemudian jalankan perintah:
composer require seahorseeeee/tte-bsre-laravel
Opsi B: Menggunakan Packagist.org (Jika Repo Publik)
Jika repository telah didaftarkan ke Packagist.org:
composer require seahorseeeee/tte-bsre-laravel
Opsi C: Menggunakan Path Lokal (Untuk Pengembangan di Komputer yang Sama)
Jika ingin mengembangkan dan menguji secara lokal:
"repositories": [
{
"type": "path",
"url": "../tte-bsre-plugin"
}
]
Kemudian jalankan:
composer require seahorseeeee/tte-bsre-laravel
Langkah Setelah Instalasi:
1. Publish File Konfigurasi
php artisan vendor:publish --tag=tte-bsre-config
2. Konfigurasi Environment (.env)
Tambahkan variabel environment berikut ke file .env aplikasi Anda:
# URL Server BSrE BSSN
URL_BSRE="http://103.103.147.206"
# Kredensial Basic Auth API BSrE
TTE_USER="username_bsre"
TTE_PASS="password_bsre"
# NIK Pejabat Penandatangan Default
TTE_NIK="360401xxxxxxxxxx"
# Secret Key untuk Enkripsi Passphrase di Database (AES-256)
TTE_PASS_ENKRIPSI="KunciRahasiaEnkripsiTTE2026!"
# Timeout HTTP Request (Detik)
TTE_TIMEOUT=120
# Mode Bypass (True untuk testing simulasi lokal tanpa konek ke BSrE fisik)
TTE_BYPASS=false
3. Uji Coba Koneksi & Passphrase via Terminal
php artisan tte:test
Atau dengan argumen langsung:
php artisan tte:test "PassphraseRahasiaPejabat" --nik=3604011410680009
💻 Panduan Penggunaan di Kode Aplikasi
1. Menguji Validitas Passphrase TTE
Digunakan saat form penetapan/permohonan disubmit untuk memastikan passphrase pejabat benar sebelum proses panjang dimulai:
use TteBsre\Facades\BsreTte;
// Uji coba passphrase
$test = BsreTte::testPassphrase($request->input('passphrase'));
if (!$test['status']) {
return response()->json([
'error' => true,
'message' => 'Passphrase TTE salah: ' . $test['message']
], 422);
}
// Jika valid, enkripsi passphrase untuk disimpan ke database antrian
$encryptedPass = BsreTte::encryptPassphrase($request->input('passphrase'));
2. Mode Massal / Background Worker (Contoh: SPPT PBB Massal)
use TteBsre\Facades\BsreTte;
use TteBsre\DTO\SignDocument;
// 1. Ambil 15 antrian data dari database
$antrianSppt = SPPT::where('STATUS_GENERATE_TTE', 0)
->whereNotNull('PARPHASE_TTE')
->limit(15)
->get();
if ($antrianSppt->isNotEmpty()) {
// 2. Dekripsi passphrase
$passphrase = BsreTte::decryptPassphrase($antrianSppt[0]->PARPHASE_TTE);
// 3. Susun daftar dokumen SignDocument
$documents = [];
foreach ($antrianSppt as $sppt) {
$tempPdfPath = storage_path("app/temp/SPPT-{$sppt->nop}_temp.pdf");
$finalPdfPath = storage_path("app/hasil-pdf/{$sppt->tahun}/{$sppt->nop}.pdf");
// (Generate file PDF sementara menggunakan MPDF / DomPDF di sini)
$documents[] = SignDocument::fromFile(
id: (string) $sppt->nop,
filePath: $tempPdfPath,
outputPath: $finalPdfPath,
tampilan: 'INVISIBLE'
);
}
// 4. Eksekusi Batch Signing ke BSrE v2
$result = BsreTte::signBatch($documents, $passphrase);
if ($result->isSuccess()) {
foreach ($result->savedPaths as $nop => $savedPath) {
// Update tabel database aplikasi Anda
SPPT::where('NOP', $nop)->update(['STATUS_GENERATE_TTE' => 1]);
}
}
}
3. Mode Realtime / Satuan (Contoh: Validasi BPHTB / Cetak Salinan)
use TteBsre\Facades\BsreTte;
use TteBsre\DTO\SignDocument;
public function signBphtb(Request $request, $idTransaksi)
{
$transaksi = BphtbTransaksi::findOrFail($idTransaksi);
// Generate PDF ke string / file
$pdfBinary = Pdf::loadView('cetak.bukti-bphtb', compact('transaksi'))->output();
$doc = new SignDocument(
id: (string) $transaksi->id,
pdfContent: $pdfBinary,
outputPath: storage_path("app/bphtb/BPHTB-{$transaksi->no_registrasi}.pdf"),
tampilan: 'INVISIBLE'
);
// Langsung sign seketika
$result = BsreTte::signSingle($doc, $request->input('passphrase'));
if ($result->isSuccess()) {
$transaksi->update(['is_signed' => 1]);
return response()->download($result->getFirstSavedPath());
}
return back()->withErrors(['tte' => $result->message]);
}
4. Kompresi Folder Hasil TTE ke File ZIP (Download Massal)
use TteBsre\Facades\BsreTte;
public function downloadZipKelurahan($kecamatan, $kelurahan, $tahun)
{
$folderSumber = storage_path("app/hasil-pdf/{$tahun}/{$kecamatan}/{$kelurahan}");
$tujuanZip = storage_path("app/hasil-zip/{$kecamatan}{$kelurahan}.zip");
// Bundling seluruh isi folder menjadi ZIP
$zipPath = BsreTte::zip()->zipDirectory($folderSumber, $tujuanZip);
// Download response langsung ke browser
return BsreTte::zip()->downloadResponse($zipPath, "SPPT-{$kecamatan}-{$kelurahan}.zip");
}
5. Verifikasi Keabsahan Tanda Tangan PDF
use TteBsre\Facades\BsreTte;
$verify = BsreTte::verify(storage_path('app/dokumen_tervalidasi.pdf'));
if ($verify->isValid()) {
echo "Dokumen Sah! Ditandatangani oleh: " . json_encode($verify->signers);
} else {
echo "Dokumen Tidak Valid: " . $verify->message;
}
🛡️ Keamanan & Enkripsi
- Passphrase yang disimpan di database dienkripsi menggunakan algoritma standar industri AES-256-CBC dengan Initialization Vector (IV) acak per enkripsi.
- Tidak ada password atau passphrase yang disimpan dalam bentuk plaintext.
📄 Lisensi
MIT License. Dibuat oleh SeaHorse / Mitra Prima Utama & Komunitas Open Source.