status !== PaymentStatus::PENDING) { return; } try { // Obtener el booking para acceder al restaurant_id $booking = $this->booking; if (!$booking) { return; } // Crear instancia del gateway Xendit if (!class_exists('\Alexr\Payments\GatewayXendit')) { return; } $gateway = new \Alexr\Payments\GatewayXendit($booking->restaurant_id); // Obtener el invoice_id desde settings o desde el campo específico $invoice_id = null; // Prioridad 1: Usar xendit_invoice_id si existe if ($this->xendit_invoice_id) { $invoice_id = $this->xendit_invoice_id; } // Prioridad 2: Buscar en settings['invoice']['id'] elseif (isset($this->settings['invoice']['id'])) { $invoice_id = $this->settings['invoice']['id']; } // Prioridad 3: Buscar en settings['callback']['invoice_data']['id'] elseif (isset($this->settings['callback']['invoice_data']['id'])) { $invoice_id = $this->settings['callback']['invoice_data']['id']; } if (!$invoice_id) { error_log("Xendit payment check: No invoice ID found for payment {$this->id}"); return; } // Consultar el estado actual en Xendit $invoice_data = $gateway->getInvoice($invoice_id); if ($invoice_data && strtoupper($invoice_data['status']) === 'PAID') { // El pago se ha completado, actualizar el estado error_log("Xendit payment status check: Payment {$this->id} is now PAID, updating status"); $this->status = PaymentStatus::SUCCEEDED; // Actualizar también el campo específico si existe if (property_exists($this, 'xendit_invoice_status')) { $this->xendit_invoice_status = 'PAID'; } // Actualizar el booking $booking->status = $booking->paymentStatus; $booking->save(); // Enviar notificaciones $booking->sendBookingEmail(); $booking->sendSmsNotification(); $booking->sendWhatsappNotification(); // Actualizar settings con la información actualizada $settings = $this->settings ?? []; $settings['status_check'] = [ 'checked_at' => date('Y-m-d H:i:s'), 'previous_status' => 'PENDING', 'new_status' => 'PAID', 'invoice_data' => $invoice_data, 'source' => 'manual_check' ]; $this->settings = $settings; $this->save(); error_log("Xendit payment successfully updated: booking {$booking->uuid}, status: PAID"); } elseif ($invoice_data && in_array(strtoupper($invoice_data['status']), ['EXPIRED', 'FAILED'])) { // El pago ha expirado o falló, actualizar el estado $new_status = strtoupper($invoice_data['status']) === 'EXPIRED' ? PaymentStatus::CANCELLED : PaymentStatus::FAILED; $this->status = $new_status; if (property_exists($this, 'xendit_invoice_status')) { $this->xendit_invoice_status = $invoice_data['status']; } $this->save(); error_log("Xendit payment status updated to {$invoice_data['status']} for payment {$this->id}"); } } catch (\Exception $e) { error_log('Xendit payment status check error: ' . $e->getMessage()); } } /** * Obtiene los datos de Xendit formateados para mostrar */ public function getXenditDataFormattedAttribute() { // Verificar estado del pago antes de mostrar los datos $this->checkXenditPaymentStatus(); $settings = $this->settings; if (empty($settings)) { return '
No Xendit data available
'; } $message = "
"; // Mostrar mensaje si se actualizó el estado if (isset($settings['status_check'])) { $statusCheck = $settings['status_check']; $message .= "
"; $message .= "Status Updated: Payment status was automatically updated on {$statusCheck['checked_at']} from {$statusCheck['previous_status']} to {$statusCheck['new_status']}"; $message .= "
"; } // Datos del callback si existen if (isset($settings['callback'])) { $callback = $settings['callback']; $message .= "

Callback Information

"; $message .= "
External ID: {$callback['external_id']}
"; $message .= "
Status: {$callback['status']}
"; $message .= "
Callback Time: {$callback['callback_time']}
"; $message .= "
Source: {$callback['source']}
"; // Datos de la factura del callback if (isset($callback['invoice_data'])) { $invoice = $callback['invoice_data']; $message .= "

Invoice Details

"; $message .= "
Invoice ID: {$invoice['id']}
"; $message .= "
Status: {$invoice['status']}
"; $message .= "
Amount: " . number_format($invoice['amount'] / 1, 2) . " {$invoice['currency']}
"; if (isset($invoice['paid_amount'])) { $message .= "
Paid Amount: " . number_format($invoice['paid_amount'] / 1, 2) . " {$invoice['currency']}
"; } if (isset($invoice['paid_at'])) { $message .= "
Paid At: " . date('Y-m-d H:i:s', strtotime($invoice['paid_at'])) . "
"; } $message .= "
Payment Method: {$invoice['payment_method']}
"; if (isset($invoice['payment_channel'])) { $message .= "
Payment Channel: {$invoice['payment_channel']}
"; } if (isset($invoice['credit_card_charge_id'])) { $message .= "
Credit Card Charge ID: {$invoice['credit_card_charge_id']}
"; } // Información del cliente if (isset($invoice['customer'])) { $customer = $invoice['customer']; $message .= "

Customer Information

"; $message .= "
Name: {$customer['given_names']} {$customer['surname']}
"; $message .= "
Email: {$customer['email']}
"; $message .= "
Mobile: {$customer['mobile_number']}
"; } // Enlace a la factura if (isset($invoice['invoice_url'])) { $message .= "
View Invoice >>
"; } } } // Datos de la factura inicial si no hay callback elseif (isset($settings['invoice'])) { $invoice = $settings['invoice']; $message .= "

Invoice Information

"; $message .= "
Invoice ID: {$invoice['id']}
"; $message .= "
External ID: {$invoice['external_id']}
"; $message .= "
Status: {$invoice['status']}
"; $message .= "
Amount: " . number_format($invoice['amount'] / 1, 2) . " {$invoice['currency']}
"; $message .= "
Description: {$invoice['description']}
"; $message .= "
Created: " . date('Y-m-d H:i:s', strtotime($invoice['created'])) . "
"; $message .= "
Expiry: " . date('Y-m-d H:i:s', strtotime($invoice['expiry_date'])) . "
"; // Información del cliente if (isset($invoice['customer'])) { $customer = $invoice['customer']; $message .= "

Customer Information

"; $message .= "
Name: {$customer['given_names']} {$customer['surname']}
"; $message .= "
Email: {$customer['email']}
"; $message .= "
Mobile: {$customer['mobile_number']}
"; } // Enlace a la factura if (isset($invoice['invoice_url'])) { $message .= "
View Invoice >>
"; } } // Datos del webhook si existen if (isset($settings['webhook'])) { $webhook = $settings['webhook']; $message .= "

Webhook Data

"; $message .= "
External ID: {$webhook['external_id']}
"; $message .= "
Status: {$webhook['status']}
"; if (isset($webhook['paid_amount'])) { $message .= "
Paid Amount: " . number_format($webhook['paid_amount'] / 1, 2) . "
"; } if (isset($webhook['paid_at'])) { $message .= "
Paid At: " . date('Y-m-d H:i:s', strtotime($webhook['paid_at'])) . "
"; } } // Información del modelo Payment $message .= "

Payment Model Information

"; $message .= "
Payment ID: {$this->id}
"; $message .= "
Current Status: " . strtoupper($this->status) . "
"; $message .= "
Amount: " . number_format($this->amount / 100, 2) . " " . strtoupper($this->currency) . "
"; if ($this->xendit_external_id) { $message .= "
External ID: {$this->xendit_external_id}
"; } if ($this->xendit_invoice_id) { $message .= "
Invoice ID: {$this->xendit_invoice_id}
"; } if ($this->xendit_invoice_status) { $message .= "
Invoice Status: " . strtoupper($this->xendit_invoice_status) . "
"; } // Mostrar datos en crudo en un área colapsable para debugging $message .= "

Raw Data

"; $message .= "
"; $message .= "Show Raw Settings"; $message .= "
"; $message .= "
" . htmlspecialchars(json_encode($settings, JSON_PRETTY_PRINT)) . "
"; $message .= "
"; $message .= "
"; $message .= "
"; return $message; } }