status !== PaymentStatus::PENDING) {
return;
}
try {
// Obtener el booking para acceder al restaurant_id
$booking = $this->booking;
if (!$booking) {
return;
}
// Crear instancia del gateway PayPal
if (!class_exists('\Alexr\Payments\GatewayPaypal')) {
return;
}
$gateway = new \Alexr\Payments\GatewayPaypal($booking->restaurant_id);
// Obtener el order_id desde settings
$order_id = null;
// Prioridad 1: Buscar en settings['paypal']['order']['id']
if (isset($this->settings['paypal']['order']['id'])) {
$order_id = $this->settings['paypal']['order']['id'];
}
// Prioridad 2: Buscar en settings['paypal']['validate']['id']
elseif (isset($this->settings['paypal']['validate']['id'])) {
$order_id = $this->settings['paypal']['validate']['id'];
}
if (!$order_id) {
error_log("PayPal payment check: No order ID found for payment {$this->id}");
return;
}
// Consultar el estado actual en PayPal
$paypal_order = $gateway->validate($order_id);
if (!$paypal_order) {
error_log("PayPal payment check: Could not retrieve order {$order_id} from PayPal API");
return;
}
$previous_status = $this->status;
$payment_updated = false;
$new_status_text = '';
// Verificar el estado del pago
if (isset($paypal_order['status'])) {
switch (strtoupper($paypal_order['status'])) {
case 'COMPLETED':
error_log("PayPal payment status check: Payment {$this->id} is now COMPLETED, updating status");
$this->status = PaymentStatus::SUCCEEDED;
// Actualizar el booking
$booking->status = $booking->paymentStatus;
$booking->save();
// Enviar notificaciones
$booking->sendBookingEmail();
$booking->sendSmsNotification();
$booking->sendWhatsappNotification();
$payment_updated = true;
$new_status_text = 'COMPLETED';
break;
case 'APPROVED':
// Mantener como pending pero podría necesitar captura
$this->status = PaymentStatus::PENDING;
$payment_updated = true;
$new_status_text = 'APPROVED';
break;
case 'CANCELLED':
case 'CANCELED':
error_log("PayPal payment status check: Payment {$this->id} is CANCELLED, updating status");
$this->status = PaymentStatus::CANCELLED;
$payment_updated = true;
$new_status_text = 'CANCELLED';
break;
case 'FAILED':
error_log("PayPal payment status check: Payment {$this->id} is FAILED, updating status");
$this->status = PaymentStatus::FAILED;
$payment_updated = true;
$new_status_text = 'FAILED';
break;
case 'PENDING':
case 'CREATED':
// Mantener como pending
$new_status_text = $paypal_order['status'];
$payment_updated = true;
break;
}
}
if ($payment_updated) {
// Actualizar settings con la información actualizada
$settings = $this->settings ?? [];
// Actualizar los datos de validación
$settings['paypal']['validate'] = $paypal_order;
// Agregar información de la verificación
$settings['status_check'] = [
'checked_at' => date('Y-m-d H:i:s'),
'previous_status' => $previous_status,
'new_status' => $this->status,
'paypal_status' => $paypal_order['status'],
'source' => 'manual_check'
];
$this->settings = $settings;
$this->save();
error_log("PayPal payment successfully updated: booking {$booking->uuid}, status: {$new_status_text}");
}
} catch (\Exception $e) {
error_log('PayPal payment status check error: ' . $e->getMessage());
}
}
/**
* Obtiene los datos de PayPal formateados para mostrar
*/
public function getPaypalDataFormattedAttribute()
{
// Verificar estado del pago antes de mostrar los datos
$this->checkPaypalPaymentStatus();
$settings = $this->settings;
if (!isset($settings['paypal'])) {
return '
";
// 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']} (PayPal: {$statusCheck['paypal_status']})";
$message .= "
";
}
// Datos de validación si existen (más actualizados)
if (isset($settings['paypal']['validate'])) {
$validate = $settings['paypal']['validate'];
$message .= "
PayPal Order Information (Validated)
";
$message .= "
Order ID: {$validate['id']}
";
$message .= "
Status: " . strtoupper($validate['status']) . "
";
$message .= "
Intent: " . strtoupper($validate['intent']) . "
";
$message .= "
Created: " . date('Y-m-d H:i:s', strtotime($validate['create_time'])) . "
";
$message .= "
Updated: " . date('Y-m-d H:i:s', strtotime($validate['update_time'])) . "
";
// Información del monto y moneda
if (isset($validate['purchase_units'][0]['amount'])) {
$amount = $validate['purchase_units'][0]['amount'];
$message .= "
Amount: {$amount['value']} {$amount['currency_code']}
";
}
// Información del payer
if (isset($validate['payer'])) {
$payer = $validate['payer'];
$message .= "
Payer Information
";
$message .= "
Name: {$payer['name']['given_name']} {$payer['name']['surname']}
";
$message .= "
Email: {$payer['email_address']}
";
$message .= "
Payer ID: {$payer['payer_id']}
";
if (isset($payer['address']['country_code'])) {
$message .= "
Country: {$payer['address']['country_code']}
";
}
}
// Información del payee (merchant)
if (isset($validate['purchase_units'][0]['payee'])) {
$payee = $validate['purchase_units'][0]['payee'];
$message .= "
Payee Information
";
$message .= "
Email: {$payee['email_address']}
";
$message .= "
Merchant ID: {$payee['merchant_id']}
";
}
// Información de capturas (pagos completados)
if (isset($validate['purchase_units'][0]['payments']['captures'])) {
$captures = $validate['purchase_units'][0]['payments']['captures'];
if (!empty($captures)) {
$capture = $captures[0]; // Tomar la primera captura
$message .= "
Capture Details
";
$message .= "
Capture ID: {$capture['id']}
";
$message .= "
Capture Status: " . strtoupper($capture['status']) . "
";
$message .= "
Captured Amount: {$capture['amount']['value']} {$capture['amount']['currency_code']}
";
$message .= "
Final Capture: " . ($capture['final_capture'] ? 'Yes' : 'No') . "
";
if (isset($capture['create_time'])) {
$message .= "
Capture Time: " . date('Y-m-d H:i:s', strtotime($capture['create_time'])) . "
";
}
// Información de fees si está disponible
if (isset($capture['seller_receivable_breakdown'])) {
$breakdown = $capture['seller_receivable_breakdown'];
$message .= "
Fee Breakdown
";
$message .= "
Gross Amount: {$breakdown['gross_amount']['value']} {$breakdown['gross_amount']['currency_code']}
";
if (isset($breakdown['paypal_fee'])) {
$message .= "
PayPal Fee: {$breakdown['paypal_fee']['value']} {$breakdown['paypal_fee']['currency_code']}
";
}
if (isset($breakdown['net_amount'])) {
$message .= "
Net Amount: {$breakdown['net_amount']['value']} {$breakdown['net_amount']['currency_code']}
";
}
}
// Seller protection
if (isset($capture['seller_protection'])) {
$protection = $capture['seller_protection'];
$message .= "
Seller Protection: " . strtoupper($protection['status']) . "
";
if (isset($protection['dispute_categories'])) {
$message .= "
Protection Categories: " . implode(', ', $protection['dispute_categories']) . "
";
}
}
}
}
// Enlaces útiles
if (isset($validate['links'])) {
$links = $validate['links'];
$message .= "
Links
";
foreach ($links as $link) {
if ($link['rel'] === 'self') {
$message .= "
";
break;
}
}
}
}
// Datos iniciales de la orden si no hay validación
elseif (isset($settings['paypal']['order'])) {
$order = $settings['paypal']['order'];
$message .= "
PayPal Order Information
";
$message .= "
Order ID: {$order['id']}
";
$message .= "
Status: " . strtoupper($order['status']) . "
";
$message .= "
Intent: " . strtoupper($order['intent']) . "
";
if (isset($order['purchase_units'][0]['amount'])) {
$amount = $order['purchase_units'][0]['amount'];
$message .= "
Amount: {$amount['value']} {$amount['currency_code']}
";
}
if (isset($order['create_time'])) {
$message .= "
Created: " . date('Y-m-d H:i:s', strtotime($order['create_time'])) . "
";
}
if (isset($order['update_time'])) {
$message .= "
Updated: " . date('Y-m-d H:i:s', strtotime($order['update_time'])) . "
";
}
}
// Información del tipo de pago
if (isset($settings['payment_type'])) {
$message .= "
Payment Type
";
$message .= "
Type: " . strtoupper($settings['payment_type']) . "
";
}
// 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) . "
";
$message .= "
Payment Type: " . strtoupper($this->payment_type) . "
";
// 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;
}
}