prepare(" SELECT a.id, a.id_tagihan, a.paid_at, a.status_check, a.gateway_type, b.akun, b.nama, b.verifikasi_tagihan, b.keterangan, b.nama_paket, b.jumlah_tagihan, b.ppn, b.kode_unik, b.id_data_server, b.id_setting_mikrotik, b.jenis_layanan, b.user_hotspot, b.id_pelanggan, b.nomor_whatsapp, b.id_marketing FROM payment_winpay a LEFT JOIN v_tagihan b ON a.id_tagihan = b.id WHERE a.status = 'PAID' AND (a.status_check IS NULL OR a.status_check IN (1,2,3)) AND (a.status_check_time IS NULL OR a.status_check_time < NOW()) LIMIT 5 "); $stmt->execute(); $tagihans = $stmt->fetchAll(PDO::FETCH_ASSOC); if ($tagihans) { foreach ($tagihans as $tagihan) { try { $user = $tagihan['akun']; $idtag = $tagihan['id_tagihan']; $nama = $tagihan['nama']; $nominal = $tagihan['verifikasi_tagihan']; $keterangan = 'Pembayaran ' . $tagihan['keterangan']; $invoice = 'kwitansi_' . date('Ymd') . $idtag . '.png'; $paketint = $tagihan['nama_paket']; $jumtagihan = 'Rp. ' . number_format($tagihan['jumlah_tagihan'], 0, ',', '.'); $ppn = 'Rp. ' . number_format($tagihan['ppn'], 0, ',', '.'); $subsidi = 'Rp. ' . number_format($tagihan['kode_unik'], 0, ',', '.'); $tanggal = $tagihan['paid_at']; $metode = "API Payment " . $tagihan['gateway_type']; // Ambil template kwitansi $stmt = $pdo->prepare(" SELECT backround_kwitansi, kabupaten FROM data_server WHERE id = :id "); $stmt->bindParam(':id', $tagihan['id_data_server'], PDO::PARAM_INT); $stmt->execute(); $result = $stmt->fetch(PDO::FETCH_ASSOC); if (!$result) { throw new Exception("Template kwitansi tidak ditemukan."); } $gambarKwitansi = '../img/' . $result['backround_kwitansi']; if (!file_exists($gambarKwitansi)) { throw new Exception("File kwitansi tidak ditemukan: $gambarKwitansi"); } // Membuat gambar $img = imagecreatefrompng($gambarKwitansi); $white = imagecolorallocate($img, 245, 245, 245); $black = imagecolorallocate($img, 0, 0, 0); $orange = imagecolorallocate($img, 0, 0, 128); $fontPath = '../dist/X_10x20_LE.gdf'; $font = imageloadfont($fontPath); $line = str_repeat('_', 100); imagestring($img, $font, 320, 30, 'KWITANSI PEMBAYARAN', $black); imagestring($img, 3, 580, 30, 'No Faktur', $black); imagestring($img, 3, 670, 30, ': ' . date('Ymd') . $idtag, $black); imagestring($img, 3, 580, 50, 'Tanggal', $black); imagestring($img, 3, 670, 50, ': ' . formatIndo(date('Y-m-d')), $black); imagestring($img, 3, 580, 70, 'No Pelanggan', $black); imagestring($img, 3, 670, 70, ': ' . $user, $black); imagestring($img, 5, 20, 81, $line, $orange); imagestring($img, 4, 30, 110, 'Telah Diterima Dari', $black); imagestring($img, 5, 200, 110, ': ' . $nama, $black); imagestring($img, 4, 30, 135, 'Sejumlah Uang', $black); imagestring($img, 4, 200, 135, ': ' . terbilang($nominal) . ' rupiah', $black); imagestring($img, 4, 30, 160, 'Untuk Pembayaran', $black); imagestring($img, 4, 200, 160, ': ' . $keterangan, $black); imagestring($img, 4, 30, 215, '1', $black); imagestring($img, 4, 70, 215, $paketint, $black); imagestring($img, 4, 620, 215, $jumtagihan, $black); if ($tagihan['ppn'] != 0) { imagestring($img, 4, 30, 235, '2', $black); imagestring($img, 4, 70, 235, 'PPN 11%', $black); imagestring($img, 4, 620, 235, $ppn, $black); } if ($tagihan['kode_unik'] != 0) { imagestring($img, 4, 30, 255, '3', $black); imagestring($img, 4, 70, 255, 'Subsidi', $black); imagestring($img, 4, 620, 255, $subsidi, $black); } imagestring($img, 5, 20, 265, $line, $orange); imagestring($img, 4, 550, 290, 'TOTAL', $black); imagestring($img, 4, 620, 290, 'Rp. '.number_format($nominal, 0, ',', '.'), $black); imagestring($img, 5, 550, 300, '__________________________ ', $orange); imagestring($img, 5, 50, 320, '______________________________', $orange); imagestring($img, $font, 70, 340, 'Terbilang : Rp. '.number_format($nominal, 0, ',', '.'), $black); imagestring($img, 5, 50, 350, '______________________________', $orange); $invoicePath = '../invoice/' . $invoice; $invoicePathMinio = 'invoice/' . $invoice; require '../controller/uploadMinioFiles.php'; ob_start(); imagepng($img); $imageData = ob_get_clean(); if (!imagepng($img, $invoicePath)) { throw new Exception("Gagal menyimpan kwitansi ke $invoicePath"); } // Upload file ke Minio uploadToMinioStorageRaw($imageData,$invoicePathMinio); imagedestroy($img); // Aktifkan user Mikrotik $API = new RouterosAPI(); $API->debug = false; $stmt = $pdo->prepare(" SELECT ip_address, port_api, username, password FROM setting_mikrotik WHERE id = :id "); $stmt->execute(['id' => $tagihan['id_setting_mikrotik']]); $mikrotik = $stmt->fetch(PDO::FETCH_ASSOC); if ($API->connect2($mikrotik['ip_address'], $mikrotik['username'], $mikrotik['password'], $mikrotik['port_api'])) { if ($tagihan['jenis_layanan'] == 'Hotspot') { $statuskas = "Pendapatan Hotspot"; $arrIDh = $API->comm("/ip/hotspot/user/getall", [ ".proplist" => ".id", "?name" => $tagihan['user_hotspot'], ]); if (!empty($arrIDh)) { $API->comm("/ip/hotspot/user/set", [ ".id" => $arrIDh[0][".id"], "disabled" => "false", ]); } } else { $statuskas = "Pendapatan PPPOE"; $arrID = $API->comm("/ppp/secret/getall", [ ".proplist" => ".id", "?name" => $user, ]); if (!empty($arrID)) { $API->comm("/ppp/secret/set", [ ".id" => $arrID[0][".id"], "disabled" => "false", ]); } } } // Update status pelanggan & tagihan $pdo->prepare("UPDATE pelanggan SET status = 'aktif' WHERE id = :id") ->execute(['id' => $tagihan['id_pelanggan']]); $pdo->prepare("UPDATE tagihan SET img_invoice = :inv, status = 'lunas', tanggal_bayar = NOW(), pelunas = '$metode' WHERE id = :id") ->execute(['inv' => $invoice, 'id' => $idtag]); $pdo->prepare("UPDATE payment_winpay SET status_check_time = NOW(), status_check = 27 WHERE id = :id") ->execute(['id' => $tagihan['id']]); // Kirim WhatsApp dengan kwitansi $nomor = explode(',', $tagihan['nomor_whatsapp']); $urlInvoice = 'https://manjapro.net/invoice/' . $invoice; // Cek transaksi dengan id tagihan $stmt = $pdo->prepare("SELECT id_tagihan FROM transaksi WHERE id_tagihan = :id"); $stmt->bindParam(':id', $idtag, PDO::PARAM_INT); $stmt->execute(); $tagid = $stmt->fetchColumn(); if ($tagid === false) { // Jika tidak ada, insert data transaksi baru $sql = "INSERT INTO transaksi (id_data_server, id_tagihan, id_user_akses, start_time, keterangan, pemasukan, metode_pembayaran, status) VALUES (:idds, :idtag, :idua, :start_time, :keterangan, :pemasukan, :metode, :status)"; $stmt = $pdo->prepare($sql); $stmt->bindParam(':idds', $tagihan['id_data_server'], PDO::PARAM_INT); $stmt->bindParam(':idtag', $idtag, PDO::PARAM_INT); $stmt->bindParam(':idua', $tagihan['id_marketing'], PDO::PARAM_INT); $stmt->bindParam(':start_time', $tanggal); $stmt->bindParam(':keterangan', $tagihan['keterangan']); $stmt->bindParam(':pemasukan', $tagihan['verifikasi_tagihan']); $stmt->bindParam(':metode', $metode); $stmt->bindParam(':status', $statuskas); $stmt->execute(); } $APIwa = new PesanWA(); $APIwa->Create_Pesan($tagihan['id_data_server'], $idtag, 'Pesan Melunasi Tagihan', 'tag'); $Pesan = $APIwa->Get_Pesan(); $APIwa->Send_Pesan($tagihan['id_data_server'], ['sendMediaFromUrl','Pesan Melunasi Tagihan'], $nomor, $Pesan, $urlInvoice); echo "[SUCCESS] Tagihan lunas: {$tagihan['nama']} ({$idtag})\n"; } catch (Exception $e) { error_log("[ERROR] {$e->getMessage()} untuk tagihan ID {$tagihan['id_tagihan']}"); echo "[ERROR] {$e->getMessage()} untuk tagihan ID {$tagihan['id_tagihan']}\n"; $count_check = $tagihan['status_check'] ?? 0 ; $check = $count_check + 1 ; $datetime = date('Y-m-d H:i:s', time() + 60); $stmt = $pdo->prepare("UPDATE payment_winpay SET status_check_time = :datetime, status_check = :check WHERE id = :id"); $stmt->execute([ 'datetime' => $datetime, 'check' => $check, 'id' => $tagihan['id'] ]); } } } else { echo "[INFO] Tidak ada tagihan WINPAY atau DOKU yang lunas.\n"; } } catch (PDOException $e) { error_log('[DB ERROR] ' . $e->getMessage()); echo "[DB ERROR] " . $e->getMessage() . "\n"; } catch (Exception $e) { error_log('[GENERAL ERROR] ' . $e->getMessage()); echo "[ERROR] " . $e->getMessage() . "\n"; }