Update Voucher , Tiket , Dashboard

membuat perubahan dan update
This commit is contained in:
YanDrs
2025-07-15 00:30:19 +07:00
parent 84c697516e
commit 0f32cf00ad
23 changed files with 2086 additions and 513 deletions
+21
View File
@@ -0,0 +1,21 @@
$api = new CrudRadiusServer();
// Tambah user
$api->request('add_user', 'POST', [
'username' => 'test123',
'password' => 'pass123'
]);
// Update user
$api->request('update_user', 'PUT', [
'username' => 'test123',
'password' => 'newpass'
]);
// Hapus user
$api->request('delete_user', 'DELETE', [
'username' => 'test123'
]);
// Ambil semua user
$api->request('get_all', 'GET');
+266
View File
@@ -0,0 +1,266 @@
<?php
// /interface l2tp-client
// add name=l2tp-out1 connect-to=tunnel.manjapro.net user=nta1cicukang password=nta1cicukang profile=default-encryption add-default-route=no disabled=no
// /ip firewall nat
// add chain=dstnat dst-address-list=IP-Public protocol=tcp dst-port=8229 action=dst-nat to-addresses=172.18.1.206 to-ports=8728 comment="NTA 1 Cicukang"
// add chain=dstnat dst-address-list=IP-Public protocol=tcp dst-port=144 action=dst-nat to-addresses=172.18.1.206 to-ports=144 comment="NTA 1 Cicukang"
// /
class CreateTunnel
{
public function addTunnel($Secret,$nasGroup)
{
// include "config/connect.php";
// include "config/routeros_api.class.php";
$mikrotik = new RouterosAPI();
$mikrotik->debug = false;
// Connect ke MikroTik
if ($mikrotik->connect2('manjapro.net', 'apiapkmanjapro', 'apiapkmanjapro123321', '2887')) {
// Ambil semua remote-address yang sudah dipakai
$secrets = $mikrotik->comm('/ppp/secret/print', [
"?local-address" => "172.18.1.100"
]);
$maxIp = 0;
foreach ($secrets as $secret) {
if (isset($secret['remote-address']) && filter_var($secret['remote-address'], FILTER_VALIDATE_IP)) {
$ipParts = explode('.', $secret['remote-address']);
if (count($ipParts) == 4 && $ipParts[0] == '172' && $ipParts[1] == '18' && $ipParts[2] == '1') {
$lastOctet = (int)$ipParts[3];
if ($lastOctet > $maxIp) {
$maxIp = $lastOctet;
}
}
}
}
// Hitung remote-address baru
$nextIp = $maxIp + 1;
$remoteAddress = "172.18.1." . $nextIp;
// Local address (bisa fix atau ambil dari pool)
$localAddress = "172.18.1.100";
// ==============================
// Ambil semua dst-port yang sudah digunakan
// ==============================
$natRules = $mikrotik->comm('/ip/firewall/nat/print');
$usedPorts = [];
foreach ($natRules as $rule) {
if (isset($rule['dst-port'])) {
$ports = explode(',', $rule['dst-port']);
foreach ($ports as $p) {
$usedPorts[] = (int)$p;
}
}
}
// Cari 2 port yang bebas mulai dari 2000
$startPort = 200;
$freePorts = [];
while (count($freePorts) < 2) {
if (!in_array($startPort, $usedPorts)) {
$freePorts[] = $startPort;
}
$startPort++;
if ($startPort > 9999) { // Batas port TCP
break; // Hindari infinite loop
}
}
if (count($freePorts) < 2) {
return [
'status' => false,
'message' => 'Tidak ada 2 port bebas yang tersedia'
];
}
$port1 = $freePorts[0];
$port2 = $freePorts[1];
// ==============================
// Generate user/pass
// ==============================
$secretUser = strtolower(preg_replace('/[^a-z0-9]/i', '', substr($Secret, 0, 12))) . "@manjapro.net";
$secretPass = strtolower(substr(md5($secretUser), 0, 12));
$nasSecret = substr(md5($secretUser), 0, 20);
// Tambahkan PPP secret
$add = $mikrotik->comm('/ppp/secret/add', [
"name" => $secretUser,
"password" => $secretPass,
"profile" => "default-encryption",
"local-address" => $localAddress,
"remote-address" => $remoteAddress,
"service" => "any",
"comment" => $Secret
]);
// Tambahkan 2 firewall NAT rules
$nat1 = $mikrotik->comm('/ip/firewall/nat/add', [
"chain" => "dstnat",
"dst-address-list" => "IP-Public",
"dst-port" => $port1,
"protocol" => "tcp",
"action" => "dst-nat",
"to-addresses" => $remoteAddress,
"to-ports" => $port1,
"comment" => $Secret
]);
$nat2 = $mikrotik->comm('/ip/firewall/nat/add', [
"chain" => "dstnat",
"dst-address-list" => "IP-Public",
"dst-port" => $port2,
"protocol" => "tcp",
"action" => "dst-nat",
"to-addresses" => $remoteAddress,
"to-ports" => $port2,
"comment" => $Secret
]);
$mikrotik->disconnect();
// Siapkan data response
$data = [
"name" => $secretUser,
"password" => $secretPass,
"profile" => "default-encryption",
"local-address" => $localAddress,
"remote-address" => $remoteAddress,
"service" => "any",
"nas_secret" => $nasSecret,
"nasgroupname" => $nasGroup,
"port-api" => $port1,
"port-remote" => $port2
];
return json_encode( [
'status' => true,
'message' => 'PPP secret dan NAT berhasil dibuat',
'data' => $data
] );
} else {
return json_encode ([
'status' => false,
'message' => 'Gagal terhubung ke MikroTik'
]);
}
}
public function deleteTunnel($Data)
{
$data = json_decode($Data);
// Validasi data yang diterima
if (!isset($data->data->{'name'}) || !isset($data->data->{'port-api'}) || !isset($data->data->{'port-remote'})) {
http_response_code(400);
echo json_encode([
'success' => false,
'message' => "Data tidak lengkap untuk menghapus tunnel"
]);
return;
}
$name = $data->data->{'name'};
$portApi = $data->data->{'port-api'};
$portRemote = $data->data->{'port-remote'};
$mikrotik = new RouterosAPI();
$mikrotik->debug = false;
// Connect ke MikroTik
if ($mikrotik->connect2('manjapro.net', 'apiapkmanjapro', 'apiapkmanjapro123321', 2887)) {
try {
// Hapus PPP Secret
$pppSecrets = $mikrotik->comm('/ppp/secret/print', [
"?name" => $name
]);
if (!empty($pppSecrets)) {
foreach ($pppSecrets as $secret) {
if (isset($secret['.id'])) {
$mikrotik->comm('/ppp/secret/remove', [
".id" => $secret['.id']
]);
}
}
}
// Hapus NAT untuk port-api
$natApi = $mikrotik->comm('/ip/firewall/nat/print', [
"?dst-port" => $portApi
]);
if (!empty($natApi)) {
foreach ($natApi as $rule) {
if (isset($rule['.id'])) {
$mikrotik->comm('/ip/firewall/nat/remove', [
".id" => $rule['.id']
]);
}
}
}
// Hapus NAT untuk port-remote
$natRemote = $mikrotik->comm('/ip/firewall/nat/print', [
"?dst-port" => $portRemote
]);
if (!empty($natRemote)) {
foreach ($natRemote as $rule) {
if (isset($rule['.id'])) {
$mikrotik->comm('/ip/firewall/nat/remove', [
".id" => $rule['.id']
]);
}
}
}
$mikrotik->disconnect();
// Kirim respon sukses
http_response_code(200);
echo json_encode([
'success' => true,
'message' => "Tunnel '$name' berhasil dihapus"
]);
} catch (Exception $e) {
$mikrotik->disconnect();
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Gagal menghapus tunnel: " . $e->getMessage()
]);
}
} else {
http_response_code(500);
echo json_encode([
'success' => false,
'message' => "Gagal koneksi ke MikroTik"
]);
}
}
}
// <===== CONTOH =====>
// $tunnel = new CreateTunnel();
// $result = $tunnel->addSecret('user123', 'pass123');
// if ($result['status']) {
// echo "✅ Berhasil: " . $result['remote-address'];
// } else {
// echo "❌ Gagal: " . $result['message'];
// }
+55
View File
@@ -0,0 +1,55 @@
<?php
class CrudRadiusServer
{
private $token = 'x4R7yP9@#gT1z!fL2wE8hQ%kM5vN0uS6aC';
private $baseUrl = "http://103.242.106.56:4408/api/";
public function request($action, $method = 'POST', $data = [])
{
$url = $this->baseUrl . "?action=" . urlencode($action);
$ch = curl_init($url);
$headers = [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->token
];
// Set CURL options
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Jika ada data, kirim sebagai JSON
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
// Eksekusi request
$response = curl_exec($ch);
if (curl_errno($ch)) {
// Return error sebagai array
return [
'success' => false,
'error' => curl_error($ch)
];
}
curl_close($ch);
// Decode JSON response
$decoded = json_decode($response, true);
// Jika JSON tidak valid
if (json_last_error() !== JSON_ERROR_NONE) {
return [
'success' => false,
'error' => 'Invalid JSON response from API'
];
}
return $decoded;
}
}
+110
View File
@@ -0,0 +1,110 @@
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
include __DIR__ . "/../config/connect.php"; // koneksi DB
try {
$potonganPersen = 10; // Potongan 10%
$potongan = $potonganPersen / 100; // Konversi ke desimal (0.1)
// Ambil parameter DataTables
$draw = intval($_GET['draw'] ?? 1);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$searchValue = $_GET['search']['value'] ?? '';
// Kolom yang bisa diurutkan
$columns = ['create_time', 'voucher', 'harga', 'status_cek', 'active_time', 'expaired_time'];
$orderColumnIndex = $_GET['order'][0]['column'] ?? 0;
$orderColumnDir = $_GET['order'][0]['dir'] ?? 'desc';
$orderColumn = $columns[$orderColumnIndex] ?? 'create_time';
// Kondisi dasar (statis)
$baseCondition = "id_agen_voucher IS NULL AND jenis IN ('sv-radius','sv-mikrotik','api-pw')";
// Hitung total data
$totalQuery = $pdo->query("SELECT COUNT(*) FROM ganerate_voucher WHERE $baseCondition");
$totalRecords = $totalQuery->fetchColumn();
// Query data + search
$sql = "SELECT create_time, voucher, harga, status_cek, active_time, expaired_time, jenis
FROM ganerate_voucher
WHERE $baseCondition";
$params = [];
if (!empty($searchValue)) {
$sql .= " AND (
create_time LIKE :search OR
voucher LIKE :search OR
status_cek LIKE :search OR
active_time LIKE :search OR
expaired_time LIKE :search
)";
$params[':search'] = "%$searchValue%";
}
// Hitung total setelah filter
$filteredSql = str_replace(
"SELECT create_time, voucher, harga, status_cek, active_time, expaired_time, jenis",
"SELECT COUNT(*)",
$sql
);
$stmtFiltered = $pdo->prepare($filteredSql);
$stmtFiltered->execute($params);
$filteredRecords = $stmtFiltered->fetchColumn();
// Tambahkan ORDER BY dan LIMIT
$sql .= " ORDER BY $orderColumn $orderColumnDir LIMIT :start, :length";
$stmt = $pdo->prepare($sql);
// Binding parameter
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
$stmt->bindValue(':length', $length, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Hitung biaya & saldo, lalu format angka
$data = [];
foreach ($rows as $row) {
$harga = floatval($row['harga']);
if ($row['jenis'] === 'api-pw') {
$biaya = $harga * $potongan;
} else {
$biaya = 0; // Tidak ada biaya jika bukan sv-radius
}
$saldo = $harga - $biaya;
$data[] = [
$row['create_time'],
$row['voucher'],
number_format($harga), // harga
number_format($biaya), // biaya
number_format($saldo), // saldo
$row['status_cek'],
$row['active_time'],
$row['expaired_time'],
];
}
// Kirim response JSON ke DataTables
$response = [
"draw" => $draw,
"recordsTotal" => $totalRecords,
"recordsFiltered" => $filteredRecords,
"data" => $data,
];
header('Content-Type: application/json');
echo json_encode($response);
} catch (Exception $e) {
// Tangani error
header('Content-Type: application/json');
echo json_encode([
"error" => $e->getMessage()
]);
}