File: /var/www/api_matriculas/app/Services/WebhookService.php
<?php
namespace App\Services;
use App\Http\Resources\WebhookResource;
use App\Repositories\WebhookRepository;
use App\Services\WebhookTokuService;
use App\Services\WebhookFirmaAkiService;
use App\Services\WebhookPlanbService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class WebhookService
{
protected $repository;
protected $tokuService;
protected $firmaAkiService;
public function __construct(
WebhookRepository $repository,
WebhookTokuService $tokuService,
WebhookFirmaAkiService $firmaAkiService
) {
$this->repository = $repository;
$this->tokuService = $tokuService;
$this->firmaAkiService = $firmaAkiService;
}
public function list()
{
$registers = $this->repository->getAll();
if ($registers->count() < 1) {
return [];
}
return $registers->map(fn($row) => new WebhookResource($row));
}
public function handleWebhook(Request $request): array
{
$payload = $request->all();
$headers = $request->headers->all();
Log::info('Valor crudo detectOrigin', ['X-Origin' => $request->header('X-Origin')]);
Log::info('Webhook handle recibido', [
'ip' => $request->ip(),
'headers' => $headers,
'payload' => $payload,
]);
// Detectar origen (TOKU_API, FIRMA_AKI, PLANB, etc.)
$origin = $this->detectOrigin($request);
Log::info("Origen detectado correctamente", ['origin' => $origin]);
// Registrar log en BD
$record = $this->repository->create([
'origin' => $origin,
'event_type' => data_get($payload, 'event_type'),
'payload' => $payload,
'headers' => $headers,
'reason' => data_get($payload, 'data.0.reason'),
]);
switch (strtoupper(trim($origin))) {
case 'TOKU_API':
$result = $this->tokuService->process($payload, $headers, $record);
break;
case 'FIRMAKI':
$result = $this->firmaAkiService->process($payload, $headers, $record);
break;
default:
Log::warning('Origen desconocido en Webhook', ['origin' => $origin]);
$result = ['handled' => false, 'origin' => $origin];
break;
}
return [
'handled' => $result['handled'] ?? false,
'origin' => $origin,
'event_type' => $payload['event_type'] ?? null,
'record_id' => $record->id ?? null,
];
}
/** Detecta origen de los headers o user-agent */
protected function detectOrigin(Request $request): ?string
{
// Intentar desde los headers primero
$candidates = [
'X-Origin-Api',
'X-Origin',
'x-origin-api',
'x-origin',
];
foreach ($candidates as $header) {
$val = $request->header($header);
if ($val) {
return strtoupper(trim(is_array($val) ? $val[0] : $val));
}
}
// Intentar desde metadata en el payload
$payload = $request->all();
$originFromMetadata = data_get($payload, 'document.metadata.X-Origin-APi')
?? data_get($payload, 'document.metadata.X-Origin-Api')
?? data_get($payload, 'metadata.X-Origin-APi')
?? data_get($payload, 'metadata.X-Origin-Api');
if ($originFromMetadata) {
return strtoupper(trim($originFromMetadata));
}
// Fallback por User-Agent
$ua = strtolower($request->header('User-Agent', ''));
if (str_contains($ua, 'toku-webhooks')) return 'TOKU_API';
if (str_contains($ua, 'firma')) return 'FIRMA_AKI';
if (str_contains($ua, 'planb')) return 'PLANB';
return 'UNKNOWN';
}
}