Pada tulisan sebelumnya saya sudah mencoba menghubungkan aplikasi Laravel ke MikroTik RouterOS melalui API.
Laravel sudah dapat melakukan test connection, membaca informasi router, dan mengambil daftar PPP session yang sedang aktif.
Tahap berikutnya adalah bagian yang lebih menarik.
Aplikasi tidak lagi hanya membaca data dari MikroTik, tetapi mulai melakukan perubahan konfigurasi pada router.
Dalam project billing ISP yang sedang saya kerjakan, salah satu kebutuhan utamanya adalah ketika pelanggan memiliki layanan internet, akun PPPoE pelanggan tersebut dapat dibuat dari aplikasi Laravel tanpa harus membuka WinBox dan membuat PPP Secret secara manual.
Proses seperti ini biasa disebut provisioning.
Pada tulisan ini saya akan mencatat bagaimana saya menyusun alur provisioning PPPoE dari Laravel ke MikroTik RouterOS.
Tulisan ini merupakan catatan dari proses saya membangun dan menguji aplikasi billing ISP menggunakan Laravel dan MikroTik CHR. Konfigurasi disederhanakan untuk kebutuhan lab, tetapi alur dan masalah yang dibahas berasal dari proses implementasi yang saya kerjakan.
Seri Laravel + MikroTik ISP Billing
Tulisan ini merupakan Part 4 dari seri Laravel + MikroTik yang sedang saya kerjakan.
- Cara Membuat PPPoE Server MikroTik CHR di VirtualBox
- Membangun Web App Billing MikroTik dengan Laravel
- Cara Menghubungkan Laravel ke MikroTik RouterOS API
- Provisioning PPPoE Otomatis dari Laravel ke MikroTik RouterOS
- Monitoring PPPoE Online / Offline dari Laravel
- Suspend dan Reactivate Pelanggan
- Monitoring Traffic PPPoE
- Invoice dan Pembayaran
- Notifikasi WhatsApp
- Persiapan Production
Pada Part 3 kita berhenti pada kondisi:
Laravel
│
│ RouterOS API
▼
MikroTik CHR
│
├── membaca /system resource
└── membaca /ppp active
Sekarang alurnya berkembang menjadi:
Database Laravel
│
│ data pelanggan
▼
PPPoE Provisioning Service
│
│ RouterOS API
▼
MikroTik CHR
│
▼
/ppp secret
Artinya aplikasi Laravel mulai menjadi bagian dari proses operasional jaringan.
Target Part 4
Target implementasi kali ini adalah:
- data pelanggan tetap disimpan di database Laravel
- paket internet memiliki mapping ke PPP Profile MikroTik
- Laravel dapat membuat PPP Secret melalui RouterOS API
- provisioning memiliki status yang jelas
- provisioning yang gagal tidak dianggap berhasil
- error dari router disimpan untuk debugging
- proses yang sama tidak membuat PPP Secret berulang kali
- aplikasi dapat menyimpan referensi akun yang sudah dibuat di router
Saya sengaja belum memasukkan suspend, reconnect, traffic monitoring, dan invoice pada tahap ini.
Masing-masing akan dibahas pada bagian berikutnya.
Topologi Lab
Environment yang saya gunakan masih melanjutkan lab sebelumnya.
┌──────────────────────────────┐
│ Laravel ISP Billing │
│ │
│ Customer │
│ Service Plan │
│ PPPoE Account │
└──────────────┬───────────────┘
│
│ RouterOS API
│ Port 8728
▼
┌──────────────────────────────┐
│ MikroTik CHR Server │
│ │
│ PPPoE Server │
│ PPP Profile │
│ PPP Secret │
└──────────────┬───────────────┘
│
│ PPPoE
▼
┌──────────────────────────────┐
│ MikroTik CHR Client │
│ │
│ PPPoE Client │
└──────────────────────────────┘
Untuk lab ini saya masih menggunakan RouterOS API pada port:
8728
Pada environment production tentu pendekatannya harus lebih ketat. API tidak seharusnya diekspos secara bebas ke internet. Akses sebaiknya dibatasi melalui private network, VPN, firewall, atau mekanisme lain yang sesuai dengan arsitektur jaringan.
Kenapa Provisioning Perlu Diotomatisasi?
Tanpa provisioning dari aplikasi, proses aktivasi pelanggan kira-kira seperti ini:
Admin membuat pelanggan
↓
Admin membuka WinBox
↓
Masuk menu PPP
↓
Membuat PPP Secret
↓
Memilih profile
↓
Mengisi password
↓
Kembali ke aplikasi billing
↓
Mengubah status pelanggan
Untuk beberapa pelanggan mungkin belum terasa merepotkan.
Tetapi jika jumlah pelanggan terus bertambah, proses manual seperti ini mulai memiliki beberapa risiko:
- username salah ketik
- profile salah dipilih
- password berbeda dengan database
- akun sudah dibuat tetapi status aplikasi belum berubah
- admin lupa membuat akun di router
- akun dibuat dua kali
- sulit mengetahui siapa yang melakukan provisioning
Karena itu saya ingin alurnya menjadi:
Admin membuat layanan pelanggan
↓
Klik Provision PPPoE
↓
Laravel melakukan validasi
↓
Laravel menghubungi RouterOS
↓
PPP Secret dibuat
↓
Laravel menyimpan hasil provisioning
Dengan demikian aplikasi menjadi pusat proses administrasi, sedangkan MikroTik menjadi sistem yang menjalankan konfigurasi jaringan.
Data Pelanggan dan Akun PPPoE Harus Dipisahkan
Salah satu keputusan struktur data yang saya gunakan adalah tidak menaruh semua informasi jaringan langsung pada tabel customers.
Pelanggan dan akun PPPoE merupakan dua hal yang berbeda.
Contohnya:
Customer
└── Ahmad Fauzi
├── Phone
├── Address
└── Status
PPPoE Account
└── ahmad-fauzi
├── Router
├── Service Plan
├── PPP Profile
├── Provision Status
└── Connection Status
Dengan struktur ini, satu pelanggan nantinya juga memungkinkan memiliki lebih dari satu layanan.
Contohnya:
Customer
└── Ahmad Fauzi
├── Rumah
│ └── ahmad-rumah
│
└── Toko
└── ahmad-toko
Struktur seperti ini lebih fleksibel dibanding menganggap satu customer selalu sama dengan satu PPPoE username.
Struktur Tabel PPPoE Account
Secara sederhana, tabel pppoe_accounts dapat memiliki informasi seperti berikut:
id
customer_id
service_plan_id
router_id
username
password
router_profile
routeros_secret_id
provision_status
connection_status
last_provisioned_at
last_error
created_at
updated_at
Contoh datanya:
Customer : Ahmad Fauzi
Username : ahmad-fauzi
Service Plan : Home 10 Mbps
Router : chr-lab-01
Router Profile : PAKET-10M
Provision Status : pending
Connection Status : offline
provision_status dan connection_status sengaja saya pisahkan.
Karena provision_status menjawab pertanyaan:
Apakah konfigurasi akun ini sudah berhasil dibuat di router?
Sedangkan connection_status menjawab:
Apakah pelanggan sedang terkoneksi ke PPPoE?
Keduanya tidak boleh dianggap sama.
Status Provisioning
Saya menggunakan alur status sederhana:
pending
↓
processing
↓
active
Jika terjadi error:
pending
↓
processing
↓
failed
Sehingga status yang mungkin adalah:
pending
processing
active
failed
Kenapa perlu processing?
Karena proses provisioning melibatkan sistem eksternal.
Laravel bisa saja sudah mengirim request tetapi RouterOS:
- timeout
- tidak dapat dijangkau
- menolak authentication
- username sudah ada
- profile tidak ditemukan
- mengalami error lainnya
Jadi kita tidak boleh langsung mengubah status menjadi active sebelum RouterOS benar-benar memberikan hasil yang sesuai.
Mapping Paket Internet ke PPP Profile
Pada aplikasi billing, paket internet biasanya memiliki informasi bisnis seperti:
Home 10 Mbps
Rp150.000 / bulan
10 Mbps download
10 Mbps upload
Sedangkan MikroTik bekerja menggunakan PPP Profile.
Contohnya:
PAKET-10M
Karena itu service plan perlu memiliki mapping ke profile router.
Contoh data pada service_plans:
name : Home 10 Mbps
price : 150000
download_mbps : 10
upload_mbps : 10
router_profile : PAKET-10M
Sehingga ketika pelanggan memilih:
Home 10 Mbps
Laravel mengetahui bahwa RouterOS harus menggunakan:
PAKET-10M
Pastikan PPP Profile Sudah Ada
Sebelum membuat secret, kita perlu memastikan profile tersedia di MikroTik.
Pada lab sebelumnya saya menggunakan profile:
PAKET-10M
Kita bisa mengeceknya menggunakan:
/ppp profile print
Contoh hasilnya:
0 name="default"
1 name="PAKET-10M"
local-address=10.10.10.1
remote-address=pppoe-pool
rate-limit=10M/10M
Jika profile belum ada, contoh konfigurasi lab:
/ppp profile add \
name=PAKET-10M \
local-address=10.10.10.1 \
remote-address=pppoe-pool \
rate-limit=10M/10M
Untuk project production, profile tentu sebaiknya dikelola lebih terstruktur.
Misalnya:
PAKET-10M
PAKET-20M
PAKET-30M
PAKET-50M
Jangan Membuat RouterOS Logic di Controller
Sama seperti Part 3, saya tidak ingin controller Laravel mengetahui detail command RouterOS.
Saya menggunakan struktur kurang lebih seperti:
app/
├── Http/
│ └── Controllers/
│ └── PppoeAccountController.php
│
├── Services/
│ └── MikroTik/
│ ├── RouterosClient.php
│ ├── PppoeProvisioningService.php
│ └── PppoeMonitoringService.php
│
└── Jobs/
└── ProvisionPppoeAccount.php
Controller bertanggung jawab menerima request.
Service menangani business logic.
Router client menangani komunikasi dengan MikroTik.
Job digunakan ketika proses ingin dijalankan melalui queue.
Secara sederhana:
Controller
↓
Provisioning Service
↓
RouterOS Client
↓
MikroTik
Dengan struktur ini, jika suatu saat cara berkomunikasi dengan RouterOS berubah, logic tersebut tidak perlu tersebar ke banyak controller.
Menambahkan Method PPP Secret pada RouterosClient
Pada Part 3 kita sudah memiliki konsep RouterosClient.
Sekarang kita tambahkan kemampuan untuk mengelola PPP Secret.
Contohnya:
class RouterosClient
{
public function testConnection(): bool
{
// Test RouterOS connection.
}
public function getSystemResource(): array
{
// /system/resource/print
}
public function getActivePppoeSessions(): array
{
// /ppp/active/print
}
public function findPppSecret(string $username): ?array
{
// /ppp/secret/print
}
public function createPppSecret(array $payload): array
{
// /ppp/secret/add
}
}
Dengan demikian PppoeProvisioningService tidak perlu mengetahui detail implementasi library RouterOS yang digunakan.
Service cukup mengatakan:
$router->findPppSecret($username);
atau:
$router->createPppSecret($payload);
Detail komunikasi dengan RouterOS tetap berada di satu tempat.
Payload PPP Secret
Data dasar yang kita perlukan untuk membuat akun PPPoE pada lab ini adalah:
name
password
service
profile
Contohnya:
$payload = [
'name' => 'ahmad-fauzi',
'password' => 'password-yang-dibuat-aplikasi',
'service' => 'pppoe',
'profile' => 'PAKET-10M',
];
Secara konsep, konfigurasi RouterOS yang ingin kita hasilkan setara dengan:
/ppp secret add \
name=ahmad-fauzi \
password=******** \
service=pppoe \
profile=PAKET-10M
Password sengaja tidak saya tampilkan.
Credential pelanggan maupun RouterOS tidak seharusnya muncul secara terbuka di screenshot, repository, log, maupun artikel.
Membuat PppoeProvisioningService
Business logic provisioning saya tempatkan pada service terpisah.
Contoh sederhananya:
namespace App\Services\MikroTik;
use App\Models\PppoeAccount;
use Throwable;
class PppoeProvisioningService
{
public function __construct(
protected RouterosClient $router
) {
}
public function provision(PppoeAccount $account): void
{
$account->update([
'provision_status' => 'processing',
'last_error' => null,
]);
try {
$existing = $this->router->findPppSecret(
$account->username
);
if ($existing) {
$account->update([
'routeros_secret_id' => $existing['.id'] ?? null,
'provision_status' => 'active',
'last_provisioned_at' => now(),
]);
return;
}
$result = $this->router->createPppSecret([
'name' => $account->username,
'password' => $account->password,
'service' => 'pppoe',
'profile' => $account->router_profile,
]);
$account->update([
'routeros_secret_id' => $result['.id'] ?? null,
'provision_status' => 'active',
'last_provisioned_at' => now(),
'last_error' => null,
]);
} catch (Throwable $e) {
report($e);
$account->update([
'provision_status' => 'failed',
'last_error' => $e->getMessage(),
]);
throw $e;
}
}
}
Contoh di atas masih disederhanakan.
Implementasi sebenarnya akan bergantung pada library RouterOS API yang digunakan pada project.
Yang paling penting di sini adalah alurnya:
account
↓
processing
↓
cek existing PPP Secret
↓
create jika belum ada
↓
simpan hasil
↓
active
Jika terjadi exception:
processing
↓
failed
Kenapa Harus Mengecek Username Sebelum Create?
Ini salah satu bagian yang menurut saya cukup penting ketika menghubungkan aplikasi dengan perangkat jaringan.
Misalnya admin menekan tombol:
Provision PPPoE
Laravel berhasil mengirim request dan RouterOS berhasil membuat:
ahmad-fauzi
Tetapi response dari aplikasi timeout sebelum browser menerima informasi bahwa proses berhasil.
Admin melihat proses seolah gagal kemudian menekan tombol Provision lagi.
Jika aplikasi langsung menjalankan:
/ppp secret add
tanpa melakukan pengecekan terlebih dahulu, aplikasi akan mencoba membuat resource yang sebenarnya sudah ada.
Karena itu sebelum create saya melakukan:
Find PPP Secret
│
▼
Username sudah ada?
┌──┴──┐
Ya Tidak
│ │
▼ ▼
Sync Create
│ │
└───┬───┘
▼
Active
Prinsip seperti ini membuat provisioning lebih idempotent.
Secara sederhana:
Menjalankan proses yang sama kembali sebisa mungkin tidak menghasilkan resource duplikat atau kondisi yang berbeda secara tidak sengaja.
Ini menjadi penting ketika nantinya provisioning dijalankan menggunakan queue dan memiliki mekanisme retry.
Jangan Hanya Percaya Status Database
Ada kasus sebaliknya.
Misalnya database Laravel menyimpan:
provision_status = active
Tetapi seseorang masuk ke WinBox dan menghapus PPP Secret secara manual.
Sekarang kondisi sistem menjadi:
Laravel Database
ahmad-fauzi
provision_status = active
≠
MikroTik RouterOS
ahmad-fauzi
tidak ditemukan
Artinya database dan router sudah tidak sinkron.
Karena itu aplikasi sebaiknya memiliki mekanisme untuk melakukan pengecekan atau reconciliation.
Contohnya:
Laravel
│
│ daftar account active
▼
RouterOS
│
│ cek PPP Secret
▼
Bandingkan
│
├── ditemukan → synchronized
│
└── tidak ditemukan → out_of_sync
Jika akun hilang dari router, administrator dapat diberi warning.
Contohnya:
Provision Status
Out of Sync
PPP Secret tidak ditemukan pada chr-lab-01.
Mekanisme seperti ini akan semakin penting ketika aplikasi menangani banyak pelanggan dan lebih dari satu router.
Menjalankan Provisioning Menggunakan Job
Provisioning sebenarnya dapat dilakukan langsung dari controller.
Tetapi saya lebih memilih memisahkannya melalui job.
Contoh:
namespace App\Jobs;
use App\Models\PppoeAccount;
use App\Services\MikroTik\PppoeProvisioningService;
class ProvisionPppoeAccount
{
public function __construct(
public int $accountId
) {
}
public function handle(
PppoeProvisioningService $service
): void {
$account = PppoeAccount::findOrFail(
$this->accountId
);
$service->provision($account);
}
}
Kemudian controller cukup melakukan:
ProvisionPppoeAccount::dispatch($account->id);
Keuntungannya:
- HTTP request tidak perlu menunggu router terlalu lama
- provisioning dapat di-retry
- failure lebih mudah dicatat
- proses dapat dipantau melalui queue
- controller tetap sederhana
- aplikasi lebih siap jika jumlah router bertambah
Alurnya menjadi:
Browser
│
▼
Laravel Controller
│
▼
Queue
│
▼
ProvisionPppoeAccount
│
▼
PppoeProvisioningService
│
▼
RouterosClient
│
▼
MikroTik
Flow Provisioning dari Dashboard
Dari sisi aplikasi, flow yang saya inginkan kurang lebih seperti ini:
Pelanggan
↓
Detail Pelanggan
↓
Layanan Internet
↓
PPPoE Account
↓
Provision PPPoE
Sebelum provisioning:
Customer
Ahmad Fauzi
Username
ahmad-fauzi
Package
Home 10 Mbps
Router
chr-lab-01
PPP Profile
PAKET-10M
Provision Status
Pending
Admin kemudian menekan:
Provision PPPoE
Status berubah:
Pending
↓
Processing
Laravel kemudian menghubungi RouterOS.
Jika berhasil:
Processing
↓
Active
Jika gagal:
Processing
↓
Failed
Dan aplikasi menampilkan informasi error yang aman untuk administrator.
Contoh Response Berhasil
Misalnya provisioning berhasil.
API aplikasi dapat mengembalikan response seperti:
{
"success": true,
"message": "PPPoE account provisioned successfully.",
"data": {
"username": "ahmad-fauzi",
"router": "chr-lab-01",
"profile": "PAKET-10M",
"provision_status": "active"
}
}
Password tidak perlu dikembalikan.
Apalagi ditampilkan pada log.
Verifikasi dari MikroTik
Setelah provisioning berhasil, saya tetap melakukan pengecekan dari RouterOS.
Gunakan:
/ppp secret print
Kita seharusnya melihat akun:
name="ahmad-fauzi"
service=pppoe
profile=PAKET-10M
Jika ingin mencari username tertentu:
/ppp secret print where name="ahmad-fauzi"
Dengan demikian kita memiliki dua bukti:
Laravel
provision_status = active
+
MikroTik
PPP Secret = tersedia
Ini jauh lebih aman dibanding hanya menganggap provisioning berhasil karena tombol di dashboard sudah ditekan.
Dari PPP Secret ke PPP Active
Ada satu perbedaan yang juga penting.
Setelah PPP Secret berhasil dibuat, belum tentu pelanggan langsung muncul pada:
/ppp active print
Karena PPP Secret adalah akun yang boleh melakukan authentication.
Sedangkan PPP Active adalah session pelanggan yang sedang terkoneksi.
Flow-nya:
PPP Secret dibuat
↓
Client PPPoE mencoba login
↓
RouterOS melakukan authentication
↓
Username + Password valid
↓
Session PPPoE terbentuk
↓
PPP Active
Jadi:
provision_status = active
tidak otomatis berarti:
connection_status = online
Inilah alasan saya memisahkan kedua status tersebut di database.
Contohnya pelanggan bisa saja:
Provision Status
Active
Connection Status
Offline
dan itu merupakan kondisi yang valid.
Akun tersedia di router, tetapi perangkat pelanggan sedang tidak terkoneksi.
Contoh Flow Lengkap
Setelah semua bagian digabungkan, flow provisioning menjadi:
Admin
│
▼
Laravel Dashboard
│
▼
PppoeAccountController
│
▼
ProvisionPppoeAccount Job
│
▼
PppoeProvisioningService
│
├── validasi account
├── validasi router
├── validasi profile
│
▼
RouterosClient
│
├── cari PPP Secret
│
├── jika ada → sync
│
└── jika belum ada → create
│
▼
MikroTik RouterOS
│
▼
PPP Secret
│
▼
Laravel menyimpan hasil
│
▼
Provision Status = Active
Dengan alur ini controller tetap tipis dan logic RouterOS tidak tersebar ke banyak bagian aplikasi.
Error yang Perlu Ditangani
Ketika mulai menulis konfigurasi ke router, error handling menjadi jauh lebih penting dibanding hanya membaca data.
Ada beberapa kondisi yang perlu diantisipasi.
Router Tidak Dapat Dijangkau
Contohnya:
Connection timed out
Status provisioning harus berubah menjadi:
failed
Database tidak boleh menganggap provisioning berhasil.
Authentication RouterOS Gagal
Misalnya credential pada .env salah.
Authentication failed
Aplikasi boleh menyimpan informasi error yang diperlukan untuk debugging, tetapi jangan menampilkan password RouterOS.
PPP Profile Tidak Ditemukan
Misalnya service plan mengarah ke:
PAKET-10M
tetapi profile tersebut belum tersedia pada router.
Aplikasi sebaiknya berhenti sebelum membuat secret dengan konfigurasi yang salah.
Flow-nya:
Provision
↓
Check Profile
↓
Tidak ditemukan
↓
Failed
Administrator kemudian dapat memperbaiki mapping service plan atau konfigurasi router.
Username Sudah Tersedia
Jangan langsung menganggap kondisi ini sebagai error fatal.
Kita perlu mengetahui apakah username tersebut memang merupakan resource yang sebelumnya dibuat untuk account yang sama.
Jika iya:
existing PPP Secret
↓
sync
↓
active
Jika username tersebut ternyata milik account lain:
username conflict
↓
failed
↓
administrator review
Dengan demikian aplikasi tidak mengambil alih resource yang bukan miliknya secara diam-diam.
Router Berhasil tetapi Database Gagal
Ini kasus yang lebih sulit.
Contohnya:
RouterOS
PPP Secret berhasil dibuat
↓
Laravel
gagal update database
Sekarang resource ada di router tetapi database menganggap proses belum berhasil.
Jika job kemudian melakukan retry dan langsung menjalankan:
/ppp secret add
kita akan mencoba membuat resource yang sudah ada.
Karena itu retry harus melakukan:
find first
bukan:
create first
Ini salah satu alasan idempotency sangat penting dalam provisioning.
Logging Provisioning
Saya juga ingin setiap aktivitas provisioning memiliki log.
Contoh informasi yang berguna:
timestamp
account_id
username
router_id
action
status
duration
error
Contoh:
2026-09-18 10:20:01
username : ahmad-fauzi
router : chr-lab-01
action : provision
status : success
duration : 420ms
Jika gagal:
2026-09-18 10:21:14
username : ahmad-fauzi
router : chr-lab-01
action : provision
status : failed
error : router connection timeout
Yang tidak boleh dicatat:
password pelanggan
password RouterOS
API credential
Logging bukan hanya berguna ketika mencari error.
Nantinya informasi ini juga dapat digunakan sebagai audit trail.
Misalnya kita ingin mengetahui:
Kapan account pelanggan diprovision?
Router mana yang digunakan?
Apakah pernah gagal?
Berapa kali retry dilakukan?
Jangan Mengirim Password ke Frontend Jika Tidak Diperlukan
Untuk dashboard admin, saya berusaha memperlakukan credential sebagai data sensitif.
Jika password tidak perlu ditampilkan, response API cukup mengembalikan:
{
"username": "ahmad-fauzi",
"profile": "PAKET-10M",
"provision_status": "active"
}
Tidak perlu mengembalikan password.
Semakin sedikit tempat credential berpindah, semakin kecil kemungkinan credential bocor melalui:
- browser
- network log
- screenshot
- error tracker
- console
- API response
- log aplikasi
Hal yang sama berlaku untuk credential RouterOS.
Credential koneksi router tetap disimpan pada konfigurasi server dan tidak dikirim ke browser.
Jangan Ekspos RouterOS API ke Internet Secara Bebas
Pada lab lokal saya menggunakan alamat private:
192.168.1.7:8728
Tetapi konfigurasi lab seperti ini tidak boleh diterjemahkan begitu saja menjadi:
PUBLIC_IP:8728
yang dapat diakses dari seluruh internet.
Untuk production, arsitektur yang lebih aman dapat berupa:
Internet
│
▼
Laravel Server
│
│ Private Network / VPN
▼
MikroTik Router
Kemudian akses API dibatasi hanya dari sumber yang memang membutuhkan.
Selain itu:
- gunakan account RouterOS khusus aplikasi
- gunakan hak akses minimum yang diperlukan
- batasi sumber koneksi menggunakan firewall
- jangan menggunakan credential administrator utama
- rotasi credential jika diperlukan
- jangan commit
.env - gunakan koneksi terenkripsi bila arsitektur memungkinkan
- catat dan monitor kegagalan authentication
Pada tahap lab saya memang lebih fokus memastikan flow aplikasi bekerja.
Tetapi ketika menuju production, bagian keamanan ini tidak boleh dilewati.
Provisioning Bukan Berarti Billing Sudah Selesai
Setelah Part 4 ini, aplikasi baru memiliki kemampuan:
Customer
↓
Service Plan
↓
PPPoE Account
↓
Provision
↓
PPP Secret
Tetapi sistem billing ISP masih membutuhkan banyak bagian lain.
Contohnya:
Apakah pelanggan sedang online?
Berapa lama pelanggan terkoneksi?
IP apa yang sedang digunakan?
Kapan terakhir kali pelanggan terlihat online?
Bagaimana jika pelanggan menunggak?
Bagaimana cara suspend?
Bagaimana mengaktifkan kembali setelah pembayaran?
Bagaimana monitoring traffic?
Bagaimana membuat invoice?
Bagaimana mengirim notifikasi?
Karena itu provisioning hanyalah salah satu bagian dari sistem.
Hasil Part 4
Sampai tahap ini kita sudah memiliki konsep:
✓ Laravel terhubung RouterOS
✓ membaca system resource
✓ membaca PPP Active
✓ customer dan PPPoE account terpisah
✓ service plan memiliki mapping PPP profile
✓ provisioning memiliki status
✓ pengecekan PPP Secret sebelum create
✓ PPP Secret dapat dibuat dari aplikasi
✓ error provisioning dicatat
✓ proses dapat dijalankan melalui queue
✓ hasil provisioning disimpan kembali ke database
Perubahan terbesarnya dibanding Part 3 adalah:
Part 3
Laravel ───── READ ─────> MikroTik
sekarang menjadi:
Part 4
Laravel ───── READ ─────> MikroTik
Laravel ───── WRITE ────> MikroTik
Aplikasi sudah mulai mengendalikan lifecycle konfigurasi pelanggan.
Selanjutnya: Monitoring PPPoE Online / Offline
Setelah PPP Secret berhasil dibuat, pertanyaan berikutnya adalah:
Bagaimana aplikasi Laravel mengetahui apakah pelanggan benar-benar sedang online?
Pada MikroTik kita sebenarnya sudah memiliki:
/ppp active print
Tetapi membaca command tersebut setiap kali dashboard dibuka bukan pendekatan yang ideal.
Pada Part 5 saya akan membahas bagaimana saya menyusun proses sinkronisasi PPP Active dari MikroTik ke database Laravel.
Targetnya:
MikroTik
│
│ /ppp active
▼
Laravel Scheduler / Queue
│
▼
Database
│
▼
Dashboard
Sehingga dashboard dapat menampilkan informasi seperti:
ahmad-fauzi
● Online
IP Address
10.10.10.10
Uptime
00:15:23
Last Seen
beberapa detik lalu
tanpa membuat browser harus terus-menerus melakukan query langsung ke router.
Catatan dari Implementasi
Dari proses ini saya mulai melihat bahwa integrasi Laravel dengan MikroTik bukan hanya persoalan:
bisa connect atau tidak
Ketika aplikasi mulai melakukan write ke RouterOS, kita harus mulai memikirkan kondisi-kondisi seperti:
request berhasil tetapi response timeout
router berhasil tetapi database gagal
database active tetapi resource router hilang
job dijalankan dua kali
username ternyata sudah digunakan
profile router berubah
router sedang offline
Hal-hal seperti ini mungkin tidak terlihat ketika pertama kali mencoba RouterOS API.
Tetapi justru bagian tersebut yang menjadi penting ketika integrasi mulai digunakan sebagai bagian dari aplikasi billing.
Penutup
Pada awal project, membuat PPPoE user melalui WinBox terasa cukup sederhana.
Tetapi ketika proses tersebut dipindahkan ke aplikasi billing, ternyata masalahnya bukan sekadar menjalankan:
/ppp secret add
Kita juga harus memikirkan:
status
retry
duplicate
timeout
synchronization
logging
security
konsistensi data
Di sinilah aplikasi billing mulai berubah dari sekadar dashboard CRUD menjadi sistem yang benar-benar berinteraksi dengan infrastruktur jaringan.
Pada Part berikutnya saya akan melanjutkan ke monitoring PPPoE online dan offline dari Laravel, menggunakan data /ppp active yang sebelumnya sudah berhasil kita baca dari RouterOS API.
Lanjut ke Part Berikutnya
Seri berikutnya:
Part 5 — Monitoring PPPoE Online / Offline dari Laravel
Pada bagian tersebut kita akan mulai menyinkronkan session PPPoE dari RouterOS ke database aplikasi sehingga status pelanggan dapat dipantau dari dashboard Laravel.
Wallahu a’lam.

