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