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/Order/Application/OrderService.php
<?php

declare(strict_types=1);

namespace App\Core\Order\Application;

use App\Core\Order\OrderStatusEnum;
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\User\Application\UserService;
use App\Events\Payment\PaymentConfirmed;
use App\Http\Controllers\OrderController;
use App\Order;

class OrderService
{
    private $userService;

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

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

    public function getByReference(string $reference)
    {
        return Order::where('gw_code_transaction', $reference)->first();
    }

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

    public function setOrderAsConfirmed($order)
    {
        $order->gw_state = OrderStatusEnum::CONFIRMED;
        $order->update();
    }

    public function setOrderAsPending($order)
    {
        $order->gw_code_transaction = strtoupper(hash("md5", (string) $order->id)) . '_' . $order->code;
        $order->gw_state = OrderStatusEnum::PENDING;
        $order->update();
    }

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

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

    public function buildPayment($order): Payment
    {
        $customer = $this->userService->buildCustomerFromUserId($order->client_id);
        $payment = new Payment(
            $order->id,
            $order->code,
            $order->gw_code_transaction,
            "",
            new Amount($order->total_price),
            $customer
        );
        $payment->setPaymentGatewayId($order->gateway_payments_id);
        $payment->setPaymentGatewayTxId($order->payment_transaction_id);
        $payment->setPaymentGatewayStatus($order->gw_state);

        return $payment;
    }

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

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

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

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

        $paymentContext = PaymentMethodContext::init($order->gateway_payments_id);
        $paymentMethodResponse = $paymentContext->retrieveOrderPayment($order);

        if ($paymentMethodResponse->status() == PaymentStatusEnum::CONFIRMED) {
            $this->confirmPayment($order, $paymentMethodResponse);
            event(new PaymentConfirmed($payment));
        } else {
            $this->voidPayment($order, $paymentMethodResponse);
        }

        $order->gateway_response = json_encode($paymentMethodResponse->rawData());
        $order->save();

        return $paymentMethodResponse;
    }

    public function isPaymentConfirmed($order)
    {
        return $order->gw_state == OrderStatusEnum::CONFIRMED;
    }

    private function confirmPayment($order, PaymentRetrieveResponse $paymentMethodResponse)
    {
        $this->updatePayment(
            $order->gw_code_transaction,
            $paymentMethodResponse->status(),
            2,
            $paymentMethodResponse->message(),
            $paymentMethodResponse->id()
        );
    }

    private function voidPayment($order, PaymentRetrieveResponse $paymentMethodResponse)
    {
        $this->updatePayment(
            $order->gw_code_transaction,
            $paymentMethodResponse->status(),
            7,
            $paymentMethodResponse->message(),
            $paymentMethodResponse->id()
        );
    }

    // TODO: check for refactor
    private function updatePayment(
        $paymentReference,
        $paymentState,
        $orderStateId,
        $paymentComment,
        $paymentTransactionId
    ) {
        $orderController = new OrderController();
        $orderController->updateOrderByPaymentReference(
            $paymentReference,
            $paymentState,
            $orderStateId,
            $paymentComment,
            $paymentTransactionId
        );
    }

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