HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
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/vhost/disk-apps/comfama.sports-crowd.com/app/Core/Ticket/Application/TicketService.php
<?php

declare(strict_types=1);

namespace App\Core\Ticket\Application;

use App\Core\Payment\Entities\Amount;
use App\Core\Payment\Entities\Payment;
use App\Core\Payment\Entities\PaymentRetrieveResponse;
use App\Core\Payment\PaymentMethodContext;
use App\Core\Payment\PaymentStatusEnum;
use App\Core\Ticket\TicketStatusEnum;
use App\Core\User\Application\UserService;
use App\Http\Controllers\Api\TicketApiController;
use App\TicketMain;

class TicketService
{
    private $userService;

    public function __construct()
    {
        $this->userService = new UserService();
    }

    public function find(int $id)
    {
        return TicketMain::findOrFail($id);
    }

    public function getById(int $id)
    {
        return TicketMain::where("id", $id)->first();
    }

    public function getByReference(string $reference)
    {
        return TicketMain::where("payment_reference", $reference)->first();
    }

    public function getByPaymentGatewayTxId(string $txId)
    {
        return TicketMain::where('payment_transaction_id', $txId)->first();
    }

    public function setPaymentGatewayId($ticket, int $paymentGatewayId)
    {
        $ticket->gateway_payments_id = $paymentGatewayId;
        $ticket->update();
    }

    public function setPaymentGatewayTxId($ticket, $paymentGatewayTxId)
    {
        $ticket->payment_transaction_id = $paymentGatewayTxId;
        $ticket->update();
    }

    public function setTicketAsPending($ticket)
    {
        $ticket->pin ??= $this->generatePin();
        $ticket->payment_reference = strtoupper(hash("md5", (string) $ticket->id)) . '_' . $ticket->pin;
        $ticket->payment_state = TicketStatusEnum::PENDING;
        $ticket->update();
    }

    public function validatePayment($ticket): PaymentRetrieveResponse
    {
        $this->increasePaymentAttemps($ticket);

        if (!$this->hasPaymentProcessor($ticket)) {
            return PaymentRetrieveResponse::createPending();
        }

        $payment = $this->buildPayment($ticket);

        if ($payment->paymentGatewayStatus() == PaymentStatusEnum::CONFIRMED) {
            $retrieveResponse = new PaymentRetrieveResponse(
                (string) $payment->id(),
                $payment->paymentGatewayStatus(),
                $ticket->payment_comment
            );

            $retrieveResponse->setRawData(json_decode($ticket->gateway_response ?? ''));
            return $retrieveResponse;
        }

        $paymentContext = PaymentMethodContext::init($ticket->gateway_payments_id);
        $paymentMethodResponse = $paymentContext->retrieveTicketPayment($ticket);

        if ($paymentMethodResponse->status() == PaymentStatusEnum::CONFIRMED) {
            $this->confirmPayment($ticket, $paymentMethodResponse);
        } else {
            $this->voidPayment($ticket, $paymentMethodResponse);
        }

        $ticket->gateway_response = json_encode($paymentMethodResponse->rawData());
        $ticket->update();

        return $paymentMethodResponse;
    }

    public function buildPayment($ticket): Payment
    {
        $customer = $this->userService->buildCustomerFromUserId($ticket->user_id_log);
        $payment = new Payment(
            $ticket->id,
            $ticket->pin,
            $ticket->payment_reference,
            "",
            new Amount($ticket->total),
            $customer
        );
        $payment->setPaymentGatewayId($ticket->gateway_payments_id);
        $payment->setPaymentGatewayTxId($ticket->payment_transaction_id);
        $payment->setPaymentGatewayStatus($ticket->payment_state);

        return $payment;
    }

    private function confirmPayment($ticket, PaymentRetrieveResponse $paymentMethodResponse)
    {
        $this->updatePayment(
            $ticket->payment_reference,
            $paymentMethodResponse->status(),
            $paymentMethodResponse->message(),
            $paymentMethodResponse->id()
        );
    }

    private function voidPayment($ticket, PaymentRetrieveResponse $paymentMethodResponse)
    {
        $this->updatePayment(
            $ticket->payment_reference,
            $paymentMethodResponse->status(),
            $paymentMethodResponse->message(),
            $paymentMethodResponse->id()
        );
    }

    // TODO: check for refactor
    private function updatePayment(
        $paymentReference,
        $paymentState,
        $paymentComment,
        $paymentTransactionId
    ) {
        $ticketApiController = new TicketApiController();
        $ticketApiController->updateTicketMainByPaymentReference(
            $paymentReference,
            $paymentState,
            $paymentComment,
            $paymentTransactionId
        );
    }

    private function increasePaymentAttemps($ticket)
    {
        $ticket->payment_attempts = $ticket->payment_attempts + 1;
        $ticket->update();
    }

    private function hasPaymentProcessor($ticket)
    {
        return !is_null($ticket->gateway_payments_id);
    }

    private function generatePin($length = 10)
    {
        return substr(str_shuffle("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length);
    }
}