Update Banyak
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
// ====== SECURITY LAYER ======
|
||||
$apiToken = "xyz123"; // samakan dengan di JS
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(["status" => false, "message" => "Gunakan POST"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['HTTP_X_API_TOKEN'] !== $apiToken) {
|
||||
echo json_encode(["status" => false, "message" => "Unauthorized"]);
|
||||
exit;
|
||||
}
|
||||
// =============================
|
||||
|
||||
function cekRekeningFlip($bank_code, $account_number) {
|
||||
|
||||
$flipKey = "JDJ5JDEzJHlkOFNYckl1a3U3VXJkZERKVnNZL3VTN1BLWmE2U3NMeUJXZC9COFV4LmZlb2VUTmdQaEN5"; // ganti dengan key kamu
|
||||
$url = "https://bigflip.id/api/v2/disbursement/bank-account-inquiry";
|
||||
|
||||
$data = [
|
||||
"bank_code" => strtolower($bank_code),
|
||||
"account_number" => $account_number,
|
||||
"inquiry_key" => uniqid("inq_")
|
||||
];
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
"Accept: application/json; charset=UTF-8",
|
||||
"Authorization: Basic " . base64_encode($flipKey . ":")
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
$error_msg = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return ["status" => false, "message" => $error_msg];
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (!$result) {
|
||||
return ["status" => false, "message" => "Flip API tidak balas JSON", "raw" => $response];
|
||||
}
|
||||
|
||||
if (isset($result['account_number'])) {
|
||||
return [
|
||||
"status" => true,
|
||||
"account_number" => $result['account_number'],
|
||||
"account_holder" => $result['account_holder'],
|
||||
"bank_code" => $result['bank_code']
|
||||
];
|
||||
}
|
||||
|
||||
return ["status" => false, "message" => $result];
|
||||
}
|
||||
|
||||
// ==== Eksekusi request ====
|
||||
$bank_code = $_POST['bank_code'] ?? '';
|
||||
$account_number = $_POST['account_number'] ?? '';
|
||||
|
||||
if (empty($bank_code) || empty($account_number)) {
|
||||
echo json_encode(["status" => false, "message" => "Bank atau nomor rekening kosong"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(cekRekeningFlip($bank_code, $account_number));
|
||||
@@ -88,7 +88,9 @@ class CreateTunnel
|
||||
// ==============================
|
||||
// Generate user/pass
|
||||
// ==============================
|
||||
$secretUser = strtolower(preg_replace('/[^a-z0-9]/i', '', substr($Secret, 0, 12))) . "@manjapro.net";
|
||||
// $secretUser = strtolower(preg_replace('/[^a-z0-9]/i', '', substr($Secret, 0, 12))) . "@manjapro.net";
|
||||
$prefix = strtolower(preg_replace('/[^a-z0-9]/i', '', substr($Secret, 0, 10)));
|
||||
$secretUser = $prefix . rand(1000, 9999) . "@manjapro.net";
|
||||
$secretPass = strtolower(substr(md5($secretUser), 0, 12));
|
||||
$nasSecret = substr(md5($secretUser), 0, 20);
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
include '../config/connect.php';
|
||||
|
||||
// Ambil parameter DataTables
|
||||
$draw = isset($_POST['draw']) ? intval($_POST['draw']) : 0;
|
||||
$start = isset($_POST['start']) ? intval($_POST['start']) : 0;
|
||||
$length = isset($_POST['length']) ? intval($_POST['length']) : 10;
|
||||
$search = isset($_POST['search']['value']) ? $_POST['search']['value'] : '';
|
||||
$orderColumnIndex = $_POST['order'][0]['column'] ?? 1;
|
||||
$orderDir = $_POST['order'][0]['dir'] ?? 'desc';
|
||||
$status = isset($_GET['s']) ? $_GET['s'] : 'SUCCESS';
|
||||
// Mapping kolom sesuai urutan table DataTable
|
||||
$columns = [
|
||||
0 => 'order_id',
|
||||
1 => 'keterangan',
|
||||
2 => 'nama',
|
||||
3 => 'jumlah',
|
||||
4 => 'saldo',
|
||||
5 => 'biaya',
|
||||
6 => 'status',
|
||||
7 => 'jenis',
|
||||
8 => 'input_time',
|
||||
9 => 'update_time',
|
||||
];
|
||||
|
||||
$orderColumn = $columns[$orderColumnIndex] ?? 'update_time';
|
||||
|
||||
// Filter server ID
|
||||
$id_data_server = isset($_GET['i']) ? $_GET['i'] : 0; // bisa single atau multiple (1,2,3)
|
||||
$where = "WHERE 1=1 ";
|
||||
if ($id_data_server > 0) {
|
||||
if ($id_data_server == 1) {
|
||||
$where .= ""; // semua server
|
||||
} else {
|
||||
// pastikan hanya angka dan koma
|
||||
$safe_ids = implode(',', array_map('intval', explode(',', $id_data_server)));
|
||||
$where .= " AND id_data_server IN ($safe_ids) AND status = '$status'";
|
||||
}
|
||||
}
|
||||
|
||||
// Query untuk hitung total
|
||||
try {
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM client_payment $where");
|
||||
$recordsTotal = (int) $stmt->fetchColumn();
|
||||
} catch (Exception $e) {
|
||||
$recordsTotal = 0;
|
||||
}
|
||||
|
||||
// Query untuk filter pencarian
|
||||
$searchQuery = '';
|
||||
if (!empty($search)) {
|
||||
$searchQuery = " AND (update_time LIKE :search OR keterangan) ";
|
||||
}
|
||||
|
||||
// Hitung total setelah filter
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM client_payment $where $searchQuery");
|
||||
if (!empty($search)) $stmt->bindValue(':search', "%$search%", PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$recordsFiltered = (int) $stmt->fetchColumn();
|
||||
} catch (Exception $e) {
|
||||
$recordsFiltered = 0;
|
||||
}
|
||||
|
||||
// Ambil data sesuai filter + order + limit
|
||||
$data = [];
|
||||
try {
|
||||
$sql = "SELECT order_id, keterangan, nama, jumlah, saldo, biaya, status, jenis, input_time, update_time
|
||||
FROM client_payment
|
||||
$where $searchQuery
|
||||
ORDER BY $orderColumn $orderDir
|
||||
LIMIT :start, :length";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
if (!empty($search)) $stmt->bindValue(':search', "%$search%", PDO::PARAM_STR);
|
||||
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':length', $length, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
|
||||
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$data[] = [
|
||||
"#PGPDN" . $row['order_id'],
|
||||
$row['keterangan'],
|
||||
$row['nama'],
|
||||
number_format((float)$row['jumlah'], 0, ',', '.'),
|
||||
number_format((float)$row['saldo'], 0, ',', '.'),
|
||||
number_format((float)$row['biaya'], 0, ',', '.'),
|
||||
$row['status'],
|
||||
$row['jenis'],
|
||||
$row['input_time'],
|
||||
$row['update_time'],
|
||||
];
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
// Response ke DataTables
|
||||
echo json_encode([
|
||||
"draw" => $draw,
|
||||
"recordsTotal" => $recordsTotal,
|
||||
"recordsFiltered" => $recordsFiltered,
|
||||
"data" => $data
|
||||
]);
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
include '../config/connect.php';
|
||||
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
$s = isset($_GET['s']) ? intval($_GET['s']) : 0;
|
||||
|
||||
if($id > 0){
|
||||
if($s == 1 ){
|
||||
$colum = "v_akumulasi_client_payment";
|
||||
} else {
|
||||
$colum = "v_akumulasi_paygw";
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("SELECT tersedia AS saldo FROM $colum WHERE id_data_server = :id LIMIT 1");
|
||||
$stmt->execute([':id' => $id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
echo json_encode($row ?: ["saldo" => 0]);
|
||||
} else {
|
||||
echo json_encode(["saldo" => 0]);
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require __DIR__ . "/../config/connect.php"; // koneksi PDO
|
||||
require __DIR__ . "/../config/gpt_ai.php"; // koneksi PDO
|
||||
|
||||
$action = $_GET['action'] ?? 'list';
|
||||
$id_server = isset($_GET['i']) ? $_GET['i'] : 0;
|
||||
|
||||
if ($action === 'list') {
|
||||
$limit = isset($_POST['length']) ? intval($_POST['length']) : 20;
|
||||
$start = isset($_POST['start']) ? intval($_POST['start']) : 0;
|
||||
|
||||
// pecah id server jadi array aman
|
||||
$ids = array_filter(array_map('intval', explode(',', $id_server)));
|
||||
$placeholders = implode(',', array_fill(0, count($ids), '?'));
|
||||
|
||||
// hitung total data distinct topik
|
||||
$stmt = $pdo->prepare("SELECT COUNT(DISTINCT topik)
|
||||
FROM chat_topik
|
||||
WHERE id_data_server IN ($placeholders)");
|
||||
$stmt->execute($ids);
|
||||
$totalData = $stmt->fetchColumn();
|
||||
|
||||
// ambil data unik berdasarkan topik (ambil id terbesar per topik)
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT ct.id, ct.topik, ct.deskripsi
|
||||
FROM chat_topik ct
|
||||
INNER JOIN (
|
||||
SELECT topik, MAX(id) AS max_id
|
||||
FROM chat_topik
|
||||
WHERE id_data_server IN ($placeholders)
|
||||
GROUP BY topik
|
||||
) tmax ON ct.id = tmax.max_id
|
||||
ORDER BY ct.id DESC
|
||||
LIMIT ?, ?
|
||||
");
|
||||
|
||||
// binding ids dulu
|
||||
$i = 1;
|
||||
foreach ($ids as $id) {
|
||||
$stmt->bindValue($i++, $id, PDO::PARAM_INT);
|
||||
}
|
||||
// binding limit
|
||||
$stmt->bindValue($i++, $start, PDO::PARAM_INT);
|
||||
$stmt->bindValue($i++, $limit, PDO::PARAM_INT);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$data = [];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$data[] = [
|
||||
$row['topik'],
|
||||
$row['deskripsi'],
|
||||
["id" => $row['id']]
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"draw" => intval($_POST['draw'] ?? 1),
|
||||
"recordsTotal" => intval($totalData),
|
||||
"recordsFiltered" => intval($totalData),
|
||||
"data" => $data
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if ($action === 'detail') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$stmt = $pdo->prepare("SELECT id, deskripsi, topik FROM chat_topik WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
echo json_encode($row ?: []);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'save') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$deskripsi = trim($_POST['deskripsi'] ?? '');
|
||||
$ids = array_filter(array_map('intval', explode(',', $_GET['i'] ?? '0')));
|
||||
|
||||
if ($deskripsi === '' || empty($ids)) {
|
||||
echo json_encode(["status" => "error", "msg" => "Data tidak valid"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// buat metadata dari GPT
|
||||
$payload = [
|
||||
"model" => "gpt-3.5-turbo",
|
||||
"messages" => [
|
||||
["role" => "system", "content" => "Tolong rubah kalimat berikut menjadi metadata berbentuk JSON."],
|
||||
["role" => "user", "content" => $deskripsi]
|
||||
],
|
||||
"temperature" => 0.0
|
||||
];
|
||||
|
||||
$GPT = new Gpt_Ai_Api();
|
||||
$metadata = $GPT->call_openai($payload);
|
||||
|
||||
// pastikan metadata berbentuk string JSON
|
||||
if (is_array($metadata) || is_object($metadata)) {
|
||||
$metadata = json_encode($metadata, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
// pastikan metadata berbentuk string JSON
|
||||
if (is_array($metadata) || is_object($metadata)) {
|
||||
$metadata = json_encode($metadata, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
if ($id > 0) {
|
||||
// update data yang sudah ada
|
||||
$stmt = $pdo->prepare("SELECT topik FROM chat_topik WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($row) {
|
||||
$topik = $row['topik'];
|
||||
|
||||
if (count($ids) > 1) {
|
||||
// multi server → replace ke semua id_data_server
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO chat_topik (id_data_server, topik, deskripsi, metadata)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE deskripsi = VALUES(deskripsi),
|
||||
metadata = VALUES(metadata)
|
||||
");
|
||||
foreach ($ids as $sid) {
|
||||
$stmt->execute([$sid, $topik, $deskripsi, $metadata]);
|
||||
}
|
||||
$pdo->commit();
|
||||
echo json_encode(["status" => "ok"]);
|
||||
} catch (Exception $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode(["status" => "error", "msg" => $e->getMessage()]);
|
||||
}
|
||||
} else {
|
||||
// single server → update biasa
|
||||
$stmt = $pdo->prepare("UPDATE chat_topik SET deskripsi = ?, metadata = ? WHERE id = ?");
|
||||
$ok = $stmt->execute([$deskripsi, $metadata, $id]);
|
||||
echo json_encode(["status" => $ok ? "ok" : "error"]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(["status" => "error", "msg" => "Topik tidak ditemukan"]);
|
||||
}
|
||||
} else {
|
||||
// jika id = 0 → insert baru
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO chat_topik (id_data_server, topik, deskripsi, metadata)
|
||||
VALUES (?, ?, ?, ?)
|
||||
");
|
||||
foreach ($ids as $sid) {
|
||||
// topik bisa digenerate otomatis dari deskripsi (misalnya hash/md5)
|
||||
$topik = substr(md5($deskripsi . $sid), 0, 16);
|
||||
$stmt->execute([$sid, $topik, $deskripsi, $metadata]);
|
||||
}
|
||||
$pdo->commit();
|
||||
echo json_encode(["status" => "ok"]);
|
||||
} catch (Exception $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode(["status" => "error", "msg" => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(["status" => "error", "msg" => "Action tidak valid"]);
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
require __DIR__ . "/../config/connect.php";
|
||||
require __DIR__ . "/../config/encrypt.php";
|
||||
|
||||
$datadecrypt = decrypt_url($_GET['data']);
|
||||
$dataurl = json_decode($datadecrypt, true);
|
||||
|
||||
$SqlSvData = $dataurl[0];
|
||||
$SqlDataWHIdM = $dataurl[1];
|
||||
$hotspotAktif = !empty($dataurl[2]) && $dataurl[2] == 1;
|
||||
|
||||
// Definisi kolom sesuai thead (No dihitung otomatis)
|
||||
$columns = ['nama','nik','akun'];
|
||||
if($hotspotAktif) {
|
||||
$columns[] = 'user_hotspot';
|
||||
}
|
||||
$columns = array_merge($columns, [
|
||||
'alamat','latitude','nomor_whatsapp','nama_server','nama_mikrotik','nama_paket','status_koneksi','time_start'
|
||||
]);
|
||||
|
||||
// Paging
|
||||
$limit = intval($_POST['length']);
|
||||
$offset = intval($_POST['start']);
|
||||
|
||||
// Order
|
||||
$orderIndex = intval($_POST['order'][0]['column']) - 1; // kurangi 1 karena No di kolom pertama
|
||||
$orderCol = $columns[$orderIndex] ?? 'nama';
|
||||
$orderDir = $_POST['order'][0]['dir'] ?? 'asc';
|
||||
|
||||
// Search
|
||||
$search = $_POST['search']['value'] ?? '';
|
||||
$where = "WHERE $SqlSvData status = 'aktif'";
|
||||
if(!empty($search)) {
|
||||
$where .= " AND (nama LIKE :search OR nik LIKE :search OR akun LIKE :search OR status_koneksi LIKE :search OR nomor_whatsapp LIKE :search OR nama_paket LIKE :search OR nama_server LIKE :search OR alamat LIKE :search OR time_start LIKE :search)";
|
||||
}
|
||||
|
||||
// Hitung total
|
||||
$totalStmt = $pdo->query("SELECT COUNT(id) FROM v_pelanggan WHERE $SqlSvData status = 'aktif'");
|
||||
$recordsTotal = $totalStmt->fetchColumn();
|
||||
|
||||
// Query data
|
||||
$sql = "SELECT id,akun,user_hotspot,nama,alamat,latitude,longitude,nomor_whatsapp,email,nik,
|
||||
nama_server,nama_paket,time_start,status_koneksi,nama_mikrotik,id_setting_mikrotik,
|
||||
time_update,ip_address
|
||||
FROM v_pelanggan $where
|
||||
ORDER BY $orderCol $orderDir
|
||||
LIMIT :limit OFFSET :offset";
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
if(!empty($search)) $stmt->bindValue(':search', "%$search%");
|
||||
$stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Format data
|
||||
$no = $offset + 1;
|
||||
$dataArray = [];
|
||||
foreach($data as $row) {
|
||||
$latlong = (substr($row['latitude'],0,1) != '-')
|
||||
? "<a href='https://google.com/maps/?q={$row['latitude']}' target='_blank'>{$row['latitude']}</a>"
|
||||
: "<a href='https://google.com/maps/?q={$row['latitude']},{$row['longitude']}' target='_blank'>{$row['latitude']}, {$row['longitude']}</a>";
|
||||
|
||||
$wa = "{$row['nomor_whatsapp']} <a href='https://wa.me/{$row['nomor_whatsapp']}' target='_blank' class='btn btn-sm btn-success' style='border-radius:20px;'><i class='fab fa-whatsapp'></i></a><br>{$row['email']}";
|
||||
|
||||
$status = $row['status_koneksi'];
|
||||
if($status == 'On') {
|
||||
$status .= " <a href='?".encrypt_url("user_remote|{$row['id']}|{$row['id_setting_mikrotik']}")."' class='btn btn-sm btn-success ml-1' style='border-radius: 20px;'>Remote</a><br>{$row['ip_address']}";
|
||||
}
|
||||
$status .= "<br>{$row['time_update']}";
|
||||
|
||||
$aksi = "<a href='?".encrypt_url("user_detail|{$row['id']}")."' class='btn btn-sm btn-info m-1'>Detail</a>";
|
||||
|
||||
// Build row sesuai urutan thead
|
||||
$rowData = [
|
||||
$no++,
|
||||
$row['nama'],
|
||||
$row['nik'],
|
||||
$row['akun']
|
||||
];
|
||||
|
||||
if($hotspotAktif) {
|
||||
$rowData[] = $row['user_hotspot'];
|
||||
}
|
||||
|
||||
$rowData[] = $row['alamat'];
|
||||
$rowData[] = $latlong;
|
||||
$rowData[] = $wa;
|
||||
$rowData[] = $row['nama_server'];
|
||||
$rowData[] = $row['nama_mikrotik'];
|
||||
$rowData[] = $row['nama_paket'];
|
||||
$rowData[] = $status;
|
||||
$rowData[] = $row['time_start'];
|
||||
$rowData[] = $aksi;
|
||||
|
||||
$dataArray[] = $rowData;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"draw" => intval($_POST['draw']),
|
||||
"recordsTotal" => $recordsTotal,
|
||||
"recordsFiltered" => $recordsTotal,
|
||||
"data" => $dataArray
|
||||
]);
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
include '../config/connect.php';
|
||||
|
||||
// Ambil parameter DataTables
|
||||
$draw = isset($_POST['draw']) ? intval($_POST['draw']) : 0;
|
||||
$start = isset($_POST['start']) ? intval($_POST['start']) : 0;
|
||||
$length = isset($_POST['length']) ? intval($_POST['length']) : 10;
|
||||
$search = isset($_POST['search']['value']) ? $_POST['search']['value'] : '';
|
||||
$orderColumnIndex = $_POST['order'][0]['column'] ?? 1;
|
||||
$orderDir = $_POST['order'][0]['dir'] ?? 'desc';
|
||||
|
||||
// Mapping kolom sesuai urutan table DataTable
|
||||
$columns = [
|
||||
0 => 'nama_server',
|
||||
1 => 'start_time',
|
||||
2 => 'nominal',
|
||||
3 => 'user_create',
|
||||
4 => 'status',
|
||||
5 => 'update_time',
|
||||
6 => 'id'
|
||||
];
|
||||
|
||||
$orderColumn = $columns[$orderColumnIndex] ?? 'start_time';
|
||||
|
||||
// Filter server ID
|
||||
$id_data_server = isset($_GET['i']) ? $_GET['i'] : 0; // bisa single atau multiple (1,2,3)
|
||||
$jenis = isset($_GET['s']) ? $_GET['s'] : 0;
|
||||
|
||||
// echo $jenis;
|
||||
$where = "WHERE 1=1 AND jenis = '$jenis'";
|
||||
if ($id_data_server > 0) {
|
||||
if ($id_data_server == 1) {
|
||||
$where .= ""; // semua server
|
||||
} else {
|
||||
// pastikan hanya angka dan koma
|
||||
$safe_ids = implode(',', array_map('intval', explode(',', $id_data_server)));
|
||||
$where .= " AND id_data_server IN ($safe_ids) ";
|
||||
}
|
||||
}
|
||||
|
||||
// Query untuk hitung total
|
||||
try {
|
||||
$stmt = $pdo->query("SELECT COUNT(*) FROM v_transaksi_withdraw $where");
|
||||
$recordsTotal = (int) $stmt->fetchColumn();
|
||||
} catch (Exception $e) {
|
||||
$recordsTotal = 0;
|
||||
}
|
||||
|
||||
// Query untuk filter pencarian
|
||||
$searchQuery = '';
|
||||
if (!empty($search)) {
|
||||
$searchQuery = " AND (user_create LIKE :search OR status LIKE :search OR nominal LIKE :search) ";
|
||||
}
|
||||
|
||||
// Hitung total setelah filter
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM v_transaksi_withdraw $where $searchQuery");
|
||||
if (!empty($search)) $stmt->bindValue(':search', "%$search%", PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$recordsFiltered = (int) $stmt->fetchColumn();
|
||||
} catch (Exception $e) {
|
||||
$recordsFiltered = 0;
|
||||
}
|
||||
|
||||
// Ambil data sesuai filter + order + limit
|
||||
$data = [];
|
||||
try {
|
||||
$sql = "SELECT nama_server, start_time, nominal, user_create, status, update_time, id_data_server, id, bukti_success
|
||||
FROM v_transaksi_withdraw
|
||||
$where $searchQuery
|
||||
ORDER BY $orderColumn $orderDir
|
||||
LIMIT :start, :length";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
if (!empty($search)) $stmt->bindValue(':search', "%$search%", PDO::PARAM_STR);
|
||||
$stmt->bindValue(':start', $start, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':length', $length, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
|
||||
|
||||
// foreach ($rows as $row) {
|
||||
// // Format nominal ke number_format
|
||||
// $row['nominal'] = number_format((float)$row['nominal'], 0, ',', '.');
|
||||
// // $row['status'] = ($row['status'] == 'pending') ? '<span class="badge bg-primary p-2">' . strtoupper($row['status']) . '</span>' : '<span class="badge bg-success p-2">' . strtoupper($row['status']) . '</span>';
|
||||
// $row['id'] = ['id' => '']
|
||||
// $data[] = array_values($row); // ubah ke numerik index biar sesuai DataTables
|
||||
// }
|
||||
foreach ($rows as $row) {
|
||||
$data[] = [
|
||||
$row['nama_server'],
|
||||
$row['start_time'],
|
||||
number_format((float)$row['nominal'], 0, ',', '.'),
|
||||
$row['user_create'],
|
||||
$row['status'],
|
||||
$row['update_time'],
|
||||
[ // kolom 6 → objek
|
||||
"id" => $row['id'],
|
||||
"bukti_success" => $row['bukti_success']
|
||||
]
|
||||
];
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
// Response ke DataTables
|
||||
echo json_encode([
|
||||
"draw" => $draw,
|
||||
"recordsTotal" => $recordsTotal,
|
||||
"recordsFiltered" => $recordsFiltered,
|
||||
"data" => $data
|
||||
]);
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
/**
|
||||
* Generate form/page HTML berdasarkan data JSON
|
||||
*/
|
||||
function formPage(string $dataform): string {
|
||||
$data = json_decode($dataform, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE || !$data || !isset($data['page'])) {
|
||||
return '<p class="text-danger">Data tidak valid.</p>';
|
||||
}
|
||||
|
||||
$page = $data['page'];
|
||||
$endpoint = $data['endpoint'] ?? '';
|
||||
$apikey = $data['apikey'] ?? '';
|
||||
$tokenkey = $data['tokenkey'] ?? '';
|
||||
|
||||
if ($page === 'flip') {
|
||||
return '
|
||||
<div class="form-group">
|
||||
<label>ENDPOINT URL</label>
|
||||
<input class="form-control" type="text" name="endpoint" value="' . htmlspecialchars($endpoint) . '">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>API SECRET KEY</label>
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control password-input" id="password1" name="apikey" value="' . htmlspecialchars($apikey) . '">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text password-toggle" data-target="password1">
|
||||
<span class="fas fa-eye"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>TOKEN VALIDASI</label>
|
||||
<div class="input-group">
|
||||
<input type="password" class="form-control password-input" id="password2" name="tokenkey" value="' . htmlspecialchars($tokenkey) . '">
|
||||
<div class="input-group-append">
|
||||
<div class="input-group-text password-toggle" data-target="password2">
|
||||
<span class="fas fa-eye"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.querySelectorAll(".password-toggle").forEach(function(toggle) {
|
||||
toggle.addEventListener("click", function() {
|
||||
var targetId = this.getAttribute("data-target");
|
||||
var input = document.getElementById(targetId);
|
||||
var icon = this.querySelector("span");
|
||||
|
||||
if (!input) return;
|
||||
|
||||
if (input.type === "password") {
|
||||
input.type = "text";
|
||||
icon.classList.remove("fa-eye");
|
||||
icon.classList.add("fa-eye-slash");
|
||||
} else {
|
||||
input.type = "password";
|
||||
icon.classList.remove("fa-eye-slash");
|
||||
icon.classList.add("fa-eye");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
';
|
||||
}
|
||||
|
||||
if ($page === 'paydisini') {
|
||||
return '
|
||||
<div class="form-group d-none">
|
||||
<label>Admin Payment Gateway</label>
|
||||
<select class="form-control" name="adminpg">
|
||||
<option value="2">Beban Owner</option>
|
||||
<option value="1">Beban Customer</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="text-center mb-4">
|
||||
<a data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
|
||||
<h6><b>Aturan dan Kebijakan</b></h6>
|
||||
</a>
|
||||
</div>
|
||||
<div class="collapse" id="collapseExample">
|
||||
<div class="text-center">
|
||||
<h6>Setelah mengaktifkan Paymnent Gateway ini kami anggap sudah menyetujui ketentuan di bawah ini</h6>
|
||||
</div>
|
||||
<div class="card-body text-justify">
|
||||
<h6>Umum</h6>
|
||||
<ul>
|
||||
<li>ManjaPro didukung oleh Paydisini Payment Gateway Indonesia untuk proses pembayaran.</li>
|
||||
<li>Semua transaksi harus dilakukan melalui sistem resmi ManjaPro untuk keamanan dan validasi.</li>
|
||||
<li>Pelanggan bertanggung jawab atas keamanan akun dan informasi pembayaran masing-masing.</li>
|
||||
</ul>
|
||||
|
||||
<h6>Alur Kerja Pembayaran</h6>
|
||||
<ul>
|
||||
<li>Pelanggan akan diberikan <strong>link pembayaran unik</strong> untuk setiap transaksi (ONE LINK – ONE TRANSACTION).</li>
|
||||
<li>Pembayaran dapat dilakukan melalui metode yang tersedia: BRI VA, BNI VA, Mandiri VA, atau QRIS.</li>
|
||||
<li>Setelah pembayaran diterima, dana akan ditahan selama 1x24 jam di rekening ManjaPro untuk proses pengecekan dan penyesuaian (check & balance).</li>
|
||||
<li>Saldo dapat digunakan atau ditarik (withdraw) setelah status pembayaran berhasil diverifikasi.</li>
|
||||
<li>Pelanggan wajib memastikan data pembayaran dan nominal yang dikirim sesuai dengan instruksi.</li>
|
||||
</ul>
|
||||
|
||||
<h6>Biaya Admin</h6>
|
||||
<ul>
|
||||
<li>Untuk biaya admin Payment Gateway bisa di bebankan ke pelanggan atau ke pemilik</li>
|
||||
<li>BRI VA : Rp. 2.950</li>
|
||||
<li>BNI VA : Rp. 4.500</li>
|
||||
<li>Mandiri VA : Rp. 2.950</li>
|
||||
<li>QRIS : 1%</li>
|
||||
</ul>
|
||||
|
||||
<h6>Withdraw / Penarikan Saldo</h6>
|
||||
<ul>
|
||||
<li>Withdraw hanya dapat dilakukan pada hari kerja. Permintaan pada hari libur akan diproses pada hari kerja berikutnya.</li>
|
||||
<li>Withdraw hanya dapat dilakukan ke rekening yang telah diverifikasi oleh sistem ManjaPro.</li>
|
||||
<li>Verifikasi rekening dapat dilakukan melalui menu <strong>Profil</strong> di akun pelanggan.</li>
|
||||
<li>Minimal saldo untuk melakukan withdraw adalah sesuai ketentuan yang berlaku di akun pelanggan.</li>
|
||||
<li>ManjaPro berhak menunda atau menolak transaksi withdraw jika ditemukan indikasi penipuan atau kesalahan data.</li>
|
||||
</ul>
|
||||
|
||||
<h6>Pemecahan Masalah / Komplain</h6>
|
||||
<ul>
|
||||
<li>Jika terjadi kesalahan pada transaksi atau masalah lainnya, pelanggan wajib menghubungi layanan pelanggan ManjaPro untuk perundingan.</li>
|
||||
<li>Setiap komplain akan diproses sesuai dengan data transaksi yang tercatat di sistem.</li>
|
||||
<li>Keputusan akhir akan diambil oleh ManjaPro setelah proses pengecekan dan verifikasi.</li>
|
||||
</ul>
|
||||
|
||||
<h6>Ketentuan Tambahan</h6>
|
||||
<ul>
|
||||
<li>ManjaPro berhak mengubah aturan dan kebijakan ini sewaktu-waktu tanpa pemberitahuan terlebih dahulu.</li>
|
||||
<li>Pelanggan dianggap menyetujui aturan ini saat melakukan transaksi melalui ManjaPro.</li>
|
||||
<li>Segala tindakan yang melanggar ketentuan dapat menyebabkan akun diblokir atau transaksi dibatalkan.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
return '<p class="text-danger">Page tidak dikenali.</p>';
|
||||
}
|
||||
|
||||
// Terima JSON dari fetch()
|
||||
$inputJSON = file_get_contents('php://input');
|
||||
|
||||
if (!$inputJSON) {
|
||||
echo "<p class='text-danger'>Data tidak diterima.</p>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Tampilkan hasil formPage
|
||||
echo formPage($inputJSON);
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
include '../config/connect.php';
|
||||
require 'payment/client/jwtoken/url_paymnet_encrypt.php';
|
||||
|
||||
function createUrlpaydisini($id)
|
||||
{
|
||||
if (empty($id) || !is_numeric($id)) {
|
||||
return ["status" => false];
|
||||
}
|
||||
|
||||
global $pdo;
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT nama_server, nama FROM v_tagihan WHERE id = :id LIMIT 1");
|
||||
if (!$stmt->execute(['id' => $id])) {
|
||||
return ["status" => false];
|
||||
}
|
||||
|
||||
$pelanggan = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$pelanggan) {
|
||||
return ["status" => false];
|
||||
}
|
||||
|
||||
$namaServer = $pelanggan['nama_server'] ?? '';
|
||||
$namaPelanggan = $pelanggan['nama'] ?? '';
|
||||
|
||||
$server = mb_strtolower(preg_replace('/[^a-zA-Z0-9]+/', '', (string)$namaServer));
|
||||
$nama = mb_strtolower(preg_replace('/[^a-zA-Z0-9]+/', '', (string)$namaPelanggan));
|
||||
|
||||
if ($server === '' || $nama === '') {
|
||||
return ["status" => false];
|
||||
}
|
||||
|
||||
$encId = jwt_encrypt($id);
|
||||
if (empty($encId) || !is_string($encId)) {
|
||||
return ["status" => false];
|
||||
}
|
||||
|
||||
return [
|
||||
"status" => true,
|
||||
"url" => "pay.manjapro.net/{$server}/{$nama}/{$encId}"
|
||||
];
|
||||
} catch (Throwable $e) {
|
||||
// kalau mau log error: error_log($e->getMessage());
|
||||
return ["status" => false];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
/** remote_add() // ambil data mikrotik lalu cek address aplikasi, jika address adalah "tunnel.manjapr.net" maka buat port nya di 2 mikrotik dan jika bukan maka buatnya langsung ke mikrotik nya
|
||||
* buat range port untuk remote ONU.
|
||||
* buat schedule untuk ubah port ke kosong
|
||||
*/
|
||||
class RemoteModem
|
||||
{
|
||||
private $pdo;
|
||||
|
||||
public function __construct($pdo)
|
||||
{
|
||||
$this->pdo = $pdo; // Inject PDO
|
||||
}
|
||||
|
||||
public function remote_add($id_mikrotik, $ip_akses, $nama_user)
|
||||
{
|
||||
$mikrotik = new RouterosAPI();
|
||||
$mikrotik->debug = false;
|
||||
|
||||
try {
|
||||
// 🔥 Ambil data Mikrotik
|
||||
$stmt = $this->pdo->prepare("SELECT ip_address, username, password, port_api, radius_nas_data
|
||||
FROM setting_mikrotik
|
||||
WHERE id = :id");
|
||||
$stmt->execute([':id' => $id_mikrotik]);
|
||||
$mikrotikUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$mikrotikUser) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Mikrotik dengan ID $id_mikrotik tidak ditemukan."
|
||||
]);
|
||||
}
|
||||
|
||||
// 🔥 Ambil remote-address jika tunnel
|
||||
$dataIP = json_decode($mikrotikUser['radius_nas_data']);
|
||||
$iptunnel = $dataIP->data->{'remote-address'} ?? null;
|
||||
|
||||
do {
|
||||
$freePort = rand(10000, 19999);
|
||||
|
||||
$stmt = $this->pdo->prepare("SELECT COUNT(*) FROM log_remote WHERE remote_port = :port");
|
||||
$stmt->execute([':port' => $freePort]);
|
||||
$count = $stmt->fetchColumn();
|
||||
} while ($count > 0);
|
||||
|
||||
|
||||
$Secret = "Remote-User-" . $nama_user;
|
||||
|
||||
if ($mikrotikUser['ip_address'] === "tunnel.manjapro.net" && !empty($iptunnel)) {
|
||||
// 🔥 Koneksi ke Mikrotik pusat
|
||||
if (!$mikrotik->connect2('manjapro.net', 'apiapkmanjapro', 'apiapkmanjapro123321', 2887)) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Gagal koneksi ke Mikrotik pusat."
|
||||
]);
|
||||
}
|
||||
|
||||
// Tambah NAT di Mikrotik pusat
|
||||
$mikrotik->comm('/ip/firewall/nat/add', [
|
||||
"chain" => "dstnat",
|
||||
"dst-address-list" => "IP-Public",
|
||||
"dst-port" => $freePort,
|
||||
"protocol" => "tcp",
|
||||
"action" => "dst-nat",
|
||||
"to-addresses" => $iptunnel,
|
||||
"to-ports" => $freePort,
|
||||
"comment" => $Secret
|
||||
]);
|
||||
$mikrotik->disconnect();
|
||||
|
||||
// 🔥 Koneksi ke Mikrotik remote
|
||||
if (!$mikrotik->connect2($mikrotikUser['ip_address'], $mikrotikUser['username'], $mikrotikUser['password'], $mikrotikUser['port_api'])) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Gagal koneksi ke Mikrotik remote."
|
||||
]);
|
||||
}
|
||||
|
||||
// Tambah NAT di Mikrotik remote
|
||||
$mikrotik->comm('/ip/firewall/nat/add', [
|
||||
"chain" => "dstnat",
|
||||
"dst-address" => $iptunnel,
|
||||
"dst-port" => $freePort,
|
||||
"protocol" => "tcp",
|
||||
"action" => "dst-nat",
|
||||
"to-addresses" => $ip_akses,
|
||||
"to-ports" => 80,
|
||||
"comment" => $Secret
|
||||
]);
|
||||
$mikrotik->disconnect();
|
||||
|
||||
$jenis = "tunnel";
|
||||
|
||||
} else {
|
||||
// 🔥 Koneksi ke Mikrotik langsung
|
||||
if (!$mikrotik->connect2($mikrotikUser['ip_address'], $mikrotikUser['username'], $mikrotikUser['password'], $mikrotikUser['port_api'])) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Gagal koneksi ke Mikrotik."
|
||||
]);
|
||||
}
|
||||
|
||||
// Tambah NAT di Mikrotik
|
||||
$mikrotik->comm('/ip/firewall/nat/add', [
|
||||
"chain" => "dstnat",
|
||||
"dst-address" => $mikrotikUser['ip_address'],
|
||||
"dst-port" => $freePort,
|
||||
"protocol" => "tcp",
|
||||
"action" => "dst-nat",
|
||||
"to-addresses" => $ip_akses,
|
||||
"to-ports" => 80,
|
||||
"comment" => $Secret
|
||||
]);
|
||||
$mikrotik->disconnect();
|
||||
|
||||
$jenis = "public";
|
||||
}
|
||||
|
||||
// 🔥 Simpan log_remote
|
||||
$stmt = $this->pdo->prepare("INSERT INTO log_remote
|
||||
(id_setting_mikrotik, nama_user, remote_port, aktif_time, jenis)
|
||||
VALUES (:id_setting_mikrotik, :nama_user, :remote_port, :aktif_time, :jenis)");
|
||||
$stmt->execute([
|
||||
':id_setting_mikrotik' => $id_mikrotik,
|
||||
':nama_user' => $nama_user,
|
||||
':remote_port' => $freePort,
|
||||
':aktif_time' => date('Y-m-d H:i:s'),
|
||||
':jenis' => $jenis
|
||||
]);
|
||||
|
||||
return json_encode([
|
||||
"status" => "success",
|
||||
"message" => "Remote berhasil ditambahkan.",
|
||||
"remote_port" => $freePort,
|
||||
"link_remote" => $mikrotikUser['ip_address'] . ":" . $freePort,
|
||||
"jenis" => $jenis
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function remote_close($id_mikrotik, $port)
|
||||
{
|
||||
$mikrotik = new RouterosAPI();
|
||||
$mikrotik->debug = false;
|
||||
|
||||
try {
|
||||
// 🔥 Ambil data Mikrotik
|
||||
$stmt = $this->pdo->prepare("SELECT ip_address, username, password, port_api, radius_nas_data
|
||||
FROM setting_mikrotik
|
||||
WHERE id = :id");
|
||||
$stmt->execute([':id' => $id_mikrotik]);
|
||||
$mikrotikUser = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$mikrotikUser) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => "Mikrotik dengan ID $id_mikrotik tidak ditemukan."
|
||||
]);
|
||||
}
|
||||
|
||||
$dataIP = json_decode($mikrotikUser['radius_nas_data']);
|
||||
$iptunnel = $dataIP->data->{'remote-address'} ?? null;
|
||||
|
||||
if ($mikrotikUser['ip_address'] === "tunnel.manjapro.net" && !empty($iptunnel)) {
|
||||
// 🔥 Hapus di Mikrotik pusat
|
||||
if ($mikrotik->connect2('manjapro.net', 'apiapkmanjapro', 'apiapkmanjapro123321', 2887)) {
|
||||
$this->removeNatRule($mikrotik, $port);
|
||||
$mikrotik->disconnect();
|
||||
}
|
||||
|
||||
// 🔥 Hapus di Mikrotik remote
|
||||
if ($mikrotik->connect2($mikrotikUser['ip_address'], $mikrotikUser['username'], $mikrotikUser['password'], $mikrotikUser['port_api'])) {
|
||||
$this->removeNatRule($mikrotik, $port);
|
||||
$mikrotik->disconnect();
|
||||
}
|
||||
} else {
|
||||
// 🔥 Hapus di Mikrotik langsung
|
||||
if ($mikrotik->connect2($mikrotikUser['ip_address'], $mikrotikUser['username'], $mikrotikUser['password'], $mikrotikUser['port_api'])) {
|
||||
$this->removeNatRule($mikrotik, $port);
|
||||
$mikrotik->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// 🔥 Hapus log_remote
|
||||
$stmt = $this->pdo->prepare("DELETE FROM log_remote
|
||||
WHERE id_setting_mikrotik = :id AND remote_port = :port");
|
||||
$stmt->execute([
|
||||
':id' => $id_mikrotik,
|
||||
':port' => $port
|
||||
]);
|
||||
|
||||
return json_encode([
|
||||
"status" => "success",
|
||||
"message" => "Remote pada port $port berhasil ditutup."
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
return json_encode([
|
||||
"status" => "error",
|
||||
"message" => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function removeNatRule($mikrotik, $port)
|
||||
{
|
||||
// 🔥 Cari dan hapus NAT rule berdasarkan dst-port
|
||||
$natRules = $mikrotik->comm('/ip/firewall/nat/print');
|
||||
foreach ($natRules as $rule) {
|
||||
if (isset($rule['dst-port']) && $rule['dst-port'] == $port) {
|
||||
$mikrotik->comm('/ip/firewall/nat/remove', ['.id' => $rule['.id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
|
||||
$flipKey = "JDJ5JDEzJHlkOFNYckl1a3U3VXJkZERKVnNZL3VTN1BLWmE2U3NMeUJXZC9COFV4LmZlb2VUTmdQaEN5"; // ganti dengan key kamu
|
||||
$url = "https://bigflip.id/api/v2/disbursement/bank-account-inquiry";
|
||||
|
||||
$bank_code = "bri"; // contoh bank
|
||||
$account_number = "778001005210532"; // contoh no rek
|
||||
$inquiry_key = uniqid("inq_"); // harus unik setiap request
|
||||
|
||||
$data = http_build_query([
|
||||
"bank_code" => strtolower($bank_code),
|
||||
"account_number" => $account_number,
|
||||
"inquiry_key" => $inquiry_key
|
||||
]);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
"Accept: application/json; charset=UTF-8",
|
||||
"Authorization: Basic " . base64_encode($flipKey . ":")
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
echo json_encode([
|
||||
"status" => false,
|
||||
"message" => curl_error($ch)
|
||||
]);
|
||||
curl_close($ch);
|
||||
exit;
|
||||
}
|
||||
curl_close($ch);
|
||||
|
||||
// cek apakah balasan valid JSON
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
echo json_encode([
|
||||
"status" => false,
|
||||
"message" => "Respon bukan JSON",
|
||||
"http" => $httpCode,
|
||||
"raw" => $response
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
"status" => true,
|
||||
"http" => $httpCode,
|
||||
"response" => $result
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
include '../config/connect.php';
|
||||
|
||||
$response = ["success" => false, "message" => "Terjadi kesalahan"];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(["success" => false, "message" => "ID tidak valid"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_FILES['bukti_success']) || $_FILES['bukti_success']['error'] !== UPLOAD_ERR_OK) {
|
||||
echo json_encode(["success" => false, "message" => "File gambar tidak ditemukan"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$uploadDir = __DIR__ . "/../img/bukti_success/";
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0777, true);
|
||||
}
|
||||
|
||||
$ext = pathinfo($_FILES['bukti_success']['name'], PATHINFO_EXTENSION);
|
||||
$fileName = "bukti_" . $id . "_" . time() . "." . strtolower($ext);
|
||||
$filePath = $uploadDir . $fileName;
|
||||
|
||||
if (move_uploaded_file($_FILES['bukti_success']['tmp_name'], $filePath)) {
|
||||
// Update status transaksi withdraw
|
||||
$sql = "UPDATE transaksi_withdraw
|
||||
SET status = 'success', bukti_success = :bukti, update_time = :update_time
|
||||
WHERE id = :id";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute([
|
||||
":bukti" => "img/bukti_success/" . $fileName,
|
||||
":update_time" => date('Y-m-d H:i:s'),
|
||||
":id" => $id
|
||||
]);
|
||||
|
||||
// Ambil data transaksi_withdraw yang baru saja diupdate
|
||||
$stmt = $pdo->prepare("SELECT * FROM transaksi_withdraw WHERE id = :id");
|
||||
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC); // hanya satu baris
|
||||
|
||||
if ($row) {
|
||||
// Generate nomor unik 10 digit
|
||||
$numid = date('Y_md').$id;
|
||||
$keterangan = "Withdraw Pendapatan Voucher Auto Pilot reff_" . $numid;
|
||||
|
||||
// Cek apakah transaksi dengan keterangan tsb sudah ada
|
||||
$stmt = $pdo->prepare("SELECT keterangan FROM transaksi WHERE keterangan = :keterangan");
|
||||
$stmt->bindParam(':keterangan', $keterangan, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$tagid = $stmt->fetchColumn();
|
||||
|
||||
if ($tagid === false) {
|
||||
$sql = "INSERT INTO transaksi
|
||||
(id_data_server, keterangan, pemasukan, start_time, metode_pembayaran, status)
|
||||
VALUES (:idds, :keterangan, :pemasukan, :start_time, :metode, 'Pendapatan Hotspot')";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->bindParam(':idds', $row['id_data_server'], PDO::PARAM_INT);
|
||||
$stmt->bindParam(':keterangan', $keterangan, PDO::PARAM_STR);
|
||||
$stmt->bindParam(':pemasukan', $row['nominal'], PDO::PARAM_STR);
|
||||
$stmt->bindValue(':start_time', date('Y-m-d H:i:s'));
|
||||
$stmt->bindValue(':metode', 'API Payment');
|
||||
$stmt->execute();
|
||||
}
|
||||
}
|
||||
|
||||
$response = ["success" => true, "message" => "Update berhasil"];
|
||||
} else {
|
||||
$response = ["success" => false, "message" => "Gagal upload file"];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
+29
-12
@@ -14,6 +14,7 @@ try {
|
||||
$length = intval($_GET['length'] ?? 10);
|
||||
$searchValue = $_GET['search']['value'] ?? '';
|
||||
$svid = $_GET['i'] ?? '';
|
||||
$statusFilter = $_GET['s'] ?? '';
|
||||
|
||||
// Kolom yang bisa diurutkan
|
||||
$columns = ['nama_server', 'voucher', 'harga', 'status', 'create_time', 'active_time', 'expaired_time'];
|
||||
@@ -22,14 +23,14 @@ try {
|
||||
$orderColumn = $columns[$orderColumnIndex] ?? 'create_time';
|
||||
|
||||
// Kondisi dasar (statis)
|
||||
$baseCondition = "id_data_server IN (".$svid.")";
|
||||
$baseCondition = "id_data_server IN (".$svid.") AND status = '" . $statusFilter . "'";
|
||||
|
||||
// Hitung total data
|
||||
$totalQuery = $pdo->query("SELECT COUNT(*) FROM v_generate_voucher_manual WHERE $baseCondition");
|
||||
$totalRecords = $totalQuery->fetchColumn();
|
||||
|
||||
// Query data + search
|
||||
$sql = "SELECT nama_server, nama_mikrotik, create_time, voucher, harga, jenis, active_time, expaired_time
|
||||
$sql = "SELECT *
|
||||
FROM v_generate_voucher_manual
|
||||
WHERE $baseCondition";
|
||||
$params = [];
|
||||
@@ -49,7 +50,7 @@ try {
|
||||
|
||||
// Hitung total setelah filter
|
||||
$filteredSql = str_replace(
|
||||
"SELECT nama_server, nama_mikrotik, create_time, voucher, harga, jenis, active_time, expaired_time",
|
||||
"SELECT *",
|
||||
"SELECT COUNT(*)",
|
||||
$sql
|
||||
);
|
||||
@@ -75,23 +76,39 @@ try {
|
||||
$data = [];
|
||||
foreach ($rows as $row) {
|
||||
$harga = floatval($row['harga']);
|
||||
if ($row['jenis'] === 'api-pw') {
|
||||
if (($row['jenis'] === 'api-pw' || $row['jenis'] === 'rad-api-pw') && $row['status'] == 'LUNAS') {
|
||||
$biaya = $harga * $potongan;
|
||||
$active = $row['active_time'];
|
||||
$expired = $row['expaired_time'];
|
||||
$saldo = $harga - $biaya;
|
||||
} else {
|
||||
$biaya = 0; // Tidak ada biaya jika bukan sv-radius
|
||||
if (($row['jenis'] != 'api-pw' || $row['jenis'] != 'rad-api-pw') && $row['status'] == NULL) {
|
||||
$biaya = 0; // Tidak ada biaya jika bukan sv-radius
|
||||
$active = $row['active_time'];
|
||||
$expired = $row['expaired_time'];
|
||||
$saldo = 0;
|
||||
} else {
|
||||
$biaya = 0; // Tidak ada biaya jika bukan sv-radius
|
||||
$active = "";
|
||||
$expired = "";
|
||||
$saldo = 0;
|
||||
}
|
||||
}
|
||||
$saldo = $harga - $biaya;
|
||||
|
||||
|
||||
$data[] = [
|
||||
$row['nama_server'] . '<br>' . $row['nama_mikrotik'],
|
||||
$row['voucher'],
|
||||
number_format($harga), // harga
|
||||
number_format($biaya), // biaya
|
||||
number_format($saldo), // saldo
|
||||
$row['jenis'],
|
||||
number_format((float)$harga, 0, ',', '.'),
|
||||
number_format((float)$biaya, 0, ',', '.'),
|
||||
number_format((float)$saldo, 0, ',', '.'),
|
||||
// number_format($harga), // harga
|
||||
// number_format($biaya), // biaya
|
||||
// number_format($saldo), // saldo
|
||||
$row['jenis'] . '<br>' . $row['status'],
|
||||
$row['create_time'],
|
||||
$row['active_time'],
|
||||
$row['expaired_time'],
|
||||
$active,
|
||||
$expired,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user