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/qas.sports-crowd.com/app/Core/Payment/Methods/PayU/PayUStrategy.php
<?php

declare(strict_types=1);

namespace App\Core\Payment\Methods\PayU;

use App\Core\Payment\Entities\Payment;
use App\Core\Payment\Entities\PaymentIntentResponse;
use App\Core\Payment\Entities\PaymentRetrieveResponse;
use App\Core\Payment\PaymentMethodInterface;
use App\Core\Payment\PaymentStatusEnum;
use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use Illuminate\Http\Request;

class PayUStrategy implements PaymentMethodInterface
{
    const PAYMENT_STATUS = [
        "APPROVED" => PaymentStatusEnum::CONFIRMED,
        "DECLINED" => PaymentStatusEnum::DECLINED,
        "PENDING" => PaymentStatusEnum::PENDING,
        "REJECTED" => PaymentStatusEnum::REJECTED
    ];

    private $parameters;
    private $placetopay;

    public function __construct(
        $parameters
    ) {
        $this->parameters = $parameters;
    }

    public function pay(Payment $payment): PaymentIntentResponse
    {
        $paymentIntentResponse = new PaymentIntentResponse(
            PaymentIntentResponse::ACTION_SHOW,
            null
        );

        $data = $this->createSessionRequest($payment);

        $paymentIntentResponse->setView('payu.webcheckout');
        $paymentIntentResponse->setData($data);

        return $paymentIntentResponse;
        $paymentIntentResponse->setRedirectUrl($paymentIntent->processUrl());
    }

    public function retrieve(Payment $payment): PaymentRetrieveResponse
    {
        try {
            $baseUrl = "https://sandbox.api.payulatam.com";
            if ($this->parameters->is_productive) {
                $baseUrl = "https://api.payulatam.com";
            }

            $baseUrl .= '/reports-api/4.0/service.cgi';

            $client = new Client();
            $response = $client->post(
                $baseUrl,
                [
                    'auth' => [
                        $this->parameters->client_id,
                        $this->parameters->api_key,
                    ],
                    'headers' => [
                        'Accept' => 'application/json'
                    ],
                    RequestOptions::JSON => [
                        "test" => $this->parameters->is_productive,
                        "language" => "es",
                        "command" => "ORDER_DETAIL_BY_REFERENCE_CODE",
                        "merchant" => [
                            "apiLogin" => $this->parameters->api_login,
                            "apiKey" => $this->parameters->api_key
                        ],
                        "details" => [
                            "referenceCode" => $payment->reference()
                        ]
                    ]
                ]
            );

            $body = $response->getBody()->getContents();
            $data = json_decode($body);

            if ($data->code == "SUCCESS") {
                $responseData = $data->result->payload[0];
                foreach ($responseData->transactions as $transaction) {
                    $status = self::PAYMENT_STATUS[$transaction->transactionResponse->state];
                    if ($transaction->transactionResponse->state == 'APPROVED') {
                        $payment->setPaymentGatewayTxId($transaction->id);
                        break;
                    }
                }
            }

            $retrieveResponse = new PaymentRetrieveResponse(
                $payment->paymentGatewayTxId(),
                $status,
                "Transacción procesada correctamente"
            );

            $retrieveResponse->setRawData($data);
            return $retrieveResponse;
        } catch (\Throwable $th) {
            return new PaymentRetrieveResponse(
                $payment->paymentGatewayTxId(),
                PaymentStatusEnum::PENDING,
                $th->getMessage()
            );
        }
    }

    public function retrievePlaceToPay(Payment $payment): PaymentRetrieveResponse
    {
        try {
            $paymentStatus = $this->placetopay->query((int) $payment->paymentGatewayTxId());
            $retrieveResponse = new PaymentRetrieveResponse(
                $paymentStatus->requestId(),
                self::PAYMENT_STATUS[$paymentStatus->status()->status()],
                $paymentStatus->status()->message()
            );

            $retrieveResponse->setRawData($paymentStatus->toArray());
            return $retrieveResponse;
        } catch (\Throwable $th) {
            return new PaymentRetrieveResponse(
                $payment->paymentGatewayTxId(),
                PaymentStatusEnum::PENDING,
                $th->getMessage()
            );
        }
    }

    private function createSessionRequest(Payment $payment)
    {
        return [
            'gateway_data' => [
                'url' => $this->parameters->is_productive ? $this->parameters->gw_url_prd : $this->parameters->gw_url_sandbox,
                'merchantId' => $this->parameters->merchant_id,
                'accountId' => $this->parameters->account_id,
                'isProductive' => (int) $this->parameters->is_productive
            ],
            'payment' => [
                'reference' => $payment->reference(),
                'description' => "PayU payment: {$payment->reference()}",
                'amount' => [
                    'currency' => $this->parameters->currency,
                    'total' => $payment->amount()->total()
                ],
            ],
            'buyer' => [
                'email' => $payment->customer()->email(),
            ],
            'signature' => $this->generateSignature($payment),
            'confirmationUrl' => $this->buildConfirmationUrl($payment),
            'responseUrl' => $this->buildReturnUrl($payment),
        ];
    }

    private function buildReturnUrl($payment)
    {
        $url = config('app.url') . '/store/payment';

        $queryString = [
            'paymentGatewayId' => $this->parameters->id,
            'reference' => $payment->reference()
        ];

        $queryString = array_merge($queryString, $this->parameters->extraConfirmUrlData);

        return Request::create($url)->fullUrlWithQuery($queryString);
    }

    private function buildConfirmationUrl($payment)
    {
        $url = config('app.url') . '/store/webhooksListener';

        $queryString = [
            'paymentGatewayId' => $this->parameters->id
        ];

        return Request::create($url)->fullUrlWithQuery($queryString);
    }

    private function generateSignature(Payment $payment)
    {
        return md5($this->parameters->api_key . '~' . $this->parameters->merchant_id . '~' . $payment->reference() . '~' . $payment->amount()->total() . '~' . $this->parameters->currency);
    }
}