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/matriculas_api_dev/app/Services/TokuService.php
<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class TokuService
{
    protected string $baseAuth = 'https://backoffice-public-api.trytoku.com';
    protected string $baseApi  = 'https://backoffice-api.trytoku.com';

    protected ?string $idToken = null;
    protected ?string $refreshToken = null;
    protected ?string $orgIdDefault = "org_qIJSr7I6x8k6zjmRkghbKg_BD3MNeLfe";
    protected ?string $orgId = null;

    /**
     * Login con credenciales de usuario
     */
    public function login(string $email, string $password): array
    {
        $response = Http::post("{$this->baseAuth}/log-in", [
            'user_email'    => $email,
            'user_password' => $password,
        ])->throw()->json();

        $this->idToken      = $response['idToken'] ?? null;
        $this->refreshToken = $response['refreshToken'] ?? null;

        return $response;
    }

    /**
     * Refrescar el token
     */
    public function refresh(): array
    {
        if (!$this->refreshToken) {
            throw new \Exception("No refreshToken disponible. Debes hacer login primero.");
        }

        $response = Http::post("{$this->baseAuth}/refresh", [
            'refresh_token' => $this->refreshToken,
        ])->throw()->json();

        $this->idToken      = $response['id_token'] ?? null;
        $this->refreshToken = $response['refresh_token'] ?? null;

        return $response;
    }

    /**
     * Obtener organizaciones del usuario
     */
    public function getUserOrganizations(): array
    {
        $response = Http::withHeaders([
            'Authorization' => "Bearer {$this->idToken}",
            'x-org-id'      => $this->orgIdDefault,
        ])->get("{$this->baseApi}/user/organizations")
            ->throw()
            ->json();

        // Si quieres quedarte con la primera organización
        if (!empty($response) && isset($response[0]['id'])) {
            $this->orgId = $response[0]['id'];
        }
        return $response;
    }


    /**
     * Obtener información de la organización
     */
    public function getOrganization(): array
    {
        $response = Http::withHeaders([
            'Authorization' => "Bearer {$this->idToken}",
            'x-org-id'      => $this->orgId, // se puede setear luego de 1ra llamada
        ])->get("{$this->baseApi}/organization")
            ->throw()
            ->json();

        // guardar org_id para futuras llamadas
        $this->orgId = $response['organization']['id'] ?? null;

        return $response;
    }

    /**
     * Listar customers con paginación
     */
    public function listCustomers(int $pageSize = 50, int $offset = 0): array
    {
        if (!$this->idToken || !$this->orgId) {
            throw new \Exception("Debes hacer login y obtener organización primero.");
        }

        return Http::withHeaders([
            'Authorization' => "Bearer {$this->idToken}",
            'x-org-id'      => $this->orgId,
        ])->get("{$this->baseApi}/organization/customers", [
            'page_size' => $pageSize,
            'offset'    => $offset,
        ])->throw()->json();
    }
}