Tul xxx Tul
User / IP
:
216.73.217.33
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
gimnasiofitnes
/
app
/
Controllers
/
Viewing: ApiController.php
<?php namespace App\Controllers; use MercadoPago\MercadoPagoConfig; use MercadoPago\Client\MerchantOrder\MerchantOrderClient; use MercadoPago\Client\Payment\PaymentClient; class ApiController extends BaseController { public function handleWebhook() { header('Content-Type: application/json'); http_response_code(200); $logFile = WRITEPATH . 'logs/mercadopago_webhook.log'; if (!file_exists(dirname($logFile))) { mkdir(dirname($logFile), 0777, true); } $raw = file_get_contents('php://input'); file_put_contents($logFile, "RAW: $raw\n", FILE_APPEND); $data = json_decode($raw, true); if (!$data) { file_put_contents($logFile, "ERROR: JSON inválido\n", FILE_APPEND); echo json_encode(['success' => false, 'message' => 'JSON inválido']); return; } // Detectar tipo de evento $type = $data['type'] ?? ($data['topic'] ?? null); $id = null; // Extraer ID dependiendo del tipo if ($type === 'payment') { $id = $data['data']['id'] ?? ($data['id'] ?? null); } elseif ($type === 'merchant_order') { if (!empty($data['resource'])) { $parts = explode('/', $data['resource']); $id = end($parts); } } if (!$type || !$id) { file_put_contents($logFile, "Evento inválido. Data:\n" . print_r($data, true) . "\n", FILE_APPEND); echo json_encode(['success' => false, 'message' => 'Parámetros inválidos']); return; } // Si es simulación (live_mode = false), ignoramos if (isset($data['live_mode']) && $data['live_mode'] === false) { file_put_contents($logFile, "Simulación recibida. Tipo: $type - ID: $id\n", FILE_APPEND); echo json_encode(['success' => true, 'message' => 'Simulación']); return; } MercadoPagoConfig::setAccessToken(env('MERCADOPAGO_ACCESS_TOKEN')); try { if ($type === 'payment') { $paymentClient = new PaymentClient(); $payment = $paymentClient->get($id); file_put_contents($logFile, "Payment Data:\n" . print_r($payment, true) . "\n====================\n", FILE_APPEND); if ($payment && $payment->status === 'approved') { if (!empty($payment->order->id)) { $merchantClient = new MerchantOrderClient(); $merchantOrder = $merchantClient->get($payment->order->id); $this->procesarMerchantOrder($merchantOrder, $payment); } } } elseif ($type === 'merchant_order') { $merchantClient = new MerchantOrderClient(); $merchantOrder = $merchantClient->get($id); $this->procesarMerchantOrder($merchantOrder); } } catch (\Exception $e) { file_put_contents($logFile, "ERROR: " . $e->getMessage() . "\n", FILE_APPEND); } echo json_encode(['success' => true]); } private function procesarMerchantOrder($merchantOrder, $payment = null) { $logFile = WRITEPATH . 'logs/mercadopago_webhook.log'; $user_id = $merchantOrder->external_reference ?? ($payment ? $payment->external_reference : null); if (!$user_id) { file_put_contents($logFile, "Referencia inválida en merchantOrder\n", FILE_APPEND); return; } if (empty($merchantOrder->items)) { file_put_contents($logFile, "Sin items en la orden para user_id: $user_id\n", FILE_APPEND); return; } $planId = $merchantOrder->items[0]->id; $planModel = new \App\Models\MembershipTypeModel(); $plan = $planModel->find($planId); if (!$plan) { file_put_contents($logFile, "Plan no encontrado: {$planId}\n", FILE_APPEND); return; } $membershipModel = new \App\Models\MembershipModel(); $paymentModel = new \App\Models\PaymentModel(); // ✅ Verificar si ya existe membresía para este mp_order_id $existingMembership = $membershipModel ->where('mp_order_id', $merchantOrder->id) ->first(); if ($existingMembership) { file_put_contents($logFile, "Orden {$merchantOrder->id} ya procesada. Ignorando.\n", FILE_APPEND); return; } // === Crear membresía === $startDate = date('Y-m-d'); $endDate = $startDate; // por defecto if (!empty($plan['duration'])) { switch (strtolower($plan['duration'])) { case 'semanal': $endDate = date('Y-m-d', strtotime($startDate . ' +7 days')); break; case 'quincenal': $endDate = date('Y-m-d', strtotime($startDate . ' +15 days')); break; case 'mensual': $endDate = date('Y-m-d', strtotime($startDate . ' +1 month')); break; case 'anual': $endDate = date('Y-m-d', strtotime($startDate . ' +1 year')); break; default: // Si no coincide, usa 30 días como fallback $endDate = date('Y-m-d', strtotime($startDate . ' +30 days')); break; } } $membershipData = [ 'mp_order_id' => $merchantOrder->id, 'user_id' => $user_id, 'membership_type_id' => $planId, 'start_date' => $startDate, 'end_date' => $endDate, 'status' => 'active' ]; try { $membershipId = $membershipModel->insert($membershipData); file_put_contents($logFile, "Membresía registrada para user_id: {$user_id}\n", FILE_APPEND); } catch (\Exception $e) { file_put_contents($logFile, "ERROR al registrar membresía: " . $e->getMessage() . "\n", FILE_APPEND); return; } // === Registrar pago === if ($payment) { $paymentData = [ 'membership_id' => $membershipId, 'amount' => $payment->transaction_amount, 'payment_date' => date('Y-m-d'), 'payment_name' => 'Mercado Pago', 'payment_method_id' => null, 'box_id' => null, 'mp_payment_id' => $payment->id // Opcional ]; try { $paymentModel->insert($paymentData); file_put_contents($logFile, "Pago registrado para membresía ID: {$membershipId}\n", FILE_APPEND); } catch (\Exception $e) { file_put_contents($logFile, "ERROR al registrar pago: " . $e->getMessage() . "\n", FILE_APPEND); } } } }
Coded With 💗 by
0x6ick