HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux Bradford-Sitios 6.14.0-1017-azure #17~24.04.1-Ubuntu SMP Mon Dec 1 20:10:50 UTC 2025 x86_64
User: www-data (33)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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';
    }
}