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);
}
}