all(); Log::info('Midtrans Notification Received:', $payload); $notification = new Notification(); $transactionStatus = $notification->transaction_status; $orderId = $notification->order_id; $fraudStatus = $notification->fraud_status; $serverKey = config('midtrans.server_key'); $orderIdNotif = $payload['order_id'] ?? ''; $statusCodeNotif = $payload['status_code'] ?? ''; $grossAmountNotif = $payload['gross_amount'] ?? ''; $signatureKey = $payload['signature_key'] ?? ''; $hashed = hash('sha512', $orderIdNotif . $statusCodeNotif . $grossAmountNotif . $serverKey); if (!hash_equals($hashed, $signatureKey)) { Log::warning('Midtrans Signature Mismatch'); return response()->json(['message' => 'Invalid signature'], 403); } $invoice = Invoice::where('midtrans_order_id', $orderId)->first(); if (!$invoice) { Log::warning('Invoice not found: ' . $orderId); return response()->json(['message' => 'Invoice not found'], 404); } if ($invoice->status != 'unpaid') { return response()->json(['message' => 'Already processed'], 200); } if ($transactionStatus == 'settlement' || $transactionStatus == 'capture') { if ($fraudStatus == 'accept') { $invoice->status = 'paid'; $invoice->paid_at = now(); $invoice->transaction_id = $notification->transaction_id; $payment_type = $notification->payment_type; $metode_bayar = $payment_type; if ($payment_type == 'bank_transfer') { if (isset($notification->va_numbers[0])) { $bank = strtoupper($notification->va_numbers[0]->bank); $metode_bayar = 'Transfer Bank ' . $bank; $invoice->payment_code = $notification->va_numbers[0]->va_number; } elseif (isset($notification->bca_va_number)) { $metode_bayar = 'Transfer Bank BCA'; $invoice->payment_code = $notification->bca_va_number; } elseif (isset($notification->permata_va_number)) { $metode_bayar = 'Transfer Bank PERMATA'; $invoice->payment_code = $notification->permata_va_number; } } elseif ($payment_type == 'echannel') { $metode_bayar = 'Transfer Bank MANDIRI'; $invoice->payment_code = $notification->bill_key ?? ''; } elseif ($payment_type == 'cstore') { $store = isset($notification->store) ? strtoupper($notification->store) : 'Minimarket'; $metode_bayar = $store; $invoice->payment_code = $notification->payment_code ?? ''; } elseif (in_array($payment_type, ['qris', 'gopay', 'shopeepay'])) { $metode_bayar = strtoupper($payment_type) == 'QRIS' ? 'QRIS' : ucfirst($payment_type); } else { $metode_bayar = ucwords(str_replace('_', ' ', $payment_type)); } $invoice->payment_method = $metode_bayar; $invoice->save(); // ✅ KIRIM WHATSAPP $this->sendPaymentWhatsApp($invoice); Log::info('Invoice paid: ' . $orderId); } } elseif ($transactionStatus == 'expire') { $invoice->status = 'expired'; $invoice->save(); } elseif (in_array($transactionStatus, ['cancel', 'deny'])) { $invoice->status = 'failed'; $invoice->save(); } return response()->json(['message' => 'Success'], 200); } catch (\Exception $e) { Log::error('Midtrans Error: ' . $e->getMessage()); return response()->json(['error' => 'Internal error'], 500); } } // ✅ METHOD BARU: KIRIM WHATSAPP private function sendPaymentWhatsApp($invoice) { try { $user = $invoice->user; $phone = $user->profile->phone_number ?? null; if (!$phone) return; $phone = str_starts_with($phone, '0') ? '62' . substr($phone, 1) : $phone; $pesan = "✅ *PEMBAYARAN BERHASIL*\n\n" . "Yth. *{$user->name}*,\n\n" . "Pembayaran tagihan Anda telah berhasil.\n\n" . "📋 *RINCIAN*\n" . "━━━━━━━━━━━━━━━\n" . "▪ No. Invoice: *{$invoice->invoice_number}*\n" . "▪ Total: *Rp " . number_format($invoice->total_amount, 0, ',', '.') . "*\n" . "▪ Pemakaian: *{$invoice->pemakaian} M³*\n" . "▪ Metode: *{$invoice->payment_method}*\n" . "━━━━━━━━━━━━━━━\n\n" . "Terima kasih telah membayar.\n" . "*Admin PAMSIMAS*"; $response = Http::withHeaders(['Authorization' => env('FONNTE_TOKEN')]) ->withoutVerifying() ->post('https://api.fonnte.com/send', [ 'target' => $phone, 'message' => $pesan, ]); if ($response->successful()) { Log::info('WA sent to: ' . $phone); } else { Log::warning('WA failed: ' . $response->body()); } } catch (\Exception $e) { Log::error('WA Error: ' . $e->getMessage()); } } }