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/demo.sports-crowd.com/app/Http/Controllers/NmiController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Interfaces\PaymentGatewayControllerInterface;
use Exception;
use Illuminate\Http\Request;
use App\Http\Controllers\PaymentGatewayBridgeController;

class NmiController extends PaymentGatewayBridgeController implements PaymentGatewayControllerInterface
{

    public function index($order)
    {
        if ($order->gw_state == 'CONFIRMED') {
            return $this->webcheckoutDone($order);
        }
        $this->updatePendingStatus($order, false, false);
        return $this->generateWebcheckout($order->total_price, $order->gw_code_transaction, 'order');
    }

    public function ticketIndex($ticket)
    {
        if ($ticket->payment_state == 'CONFIRMED') {
            return $this->webcheckoutDone($ticket);
        }
        $this->updatePendingStatus($ticket, false, false);
        return $this->generateWebcheckout($ticket->total, $ticket->payment_reference, 'ticket');
    }

    public function genericIndex($paymentTransaction, $price, $origin, $clientId, $description)
    {
        if ($paymentTransaction->state == 'CONFIRMED') {
            return $this->webcheckoutDone(null, $paymentTransaction);
        }
        $this->updatePendingStatus($paymentTransaction, false, false);
        return $this->generateWebcheckout($price, $paymentTransaction->reference, $origin);
    }

    private function generateWebcheckout($price, $reference, $origin)
    {
        $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $domain = $protocol . $_SERVER['HTTP_HOST'];
        $redirectUrl = $domain . '/store/payment?origin=' . $origin . '&paymentGatewayId=' . $this->gatewayData->id;

        $xmlRequest = new \DOMDocument('1.0', 'utf-8');
        $xmlRequest->preserveWhiteSpace = false;
        $xmlRequest->formatOutput = true;
        $sales = $xmlRequest->createElement('sale');
        $apikey = $xmlRequest->createElement('api-key', $this->apiKey);
        $redirect = $xmlRequest->createElement('redirect-url', htmlspecialchars($redirectUrl));
        $amount = $xmlRequest->createElement('amount', $price);
        $address = $xmlRequest->createElement('ip-address', $_SERVER["REMOTE_ADDR"]);
        $currency = $xmlRequest->createElement('currency', $this->currency);
        $order_id = $xmlRequest->createElement('order-id', $reference);

        $sales->appendChild($apikey);
        $sales->appendChild($redirect);
        $sales->appendChild($amount);
        $sales->appendChild($address);
        $sales->appendChild($currency);
        $sales->appendChild($order_id);
        $xmlRequest->appendChild($sales);

        $data = $this->sendXMLviaCurl($xmlRequest, $this->urlApi);

        // Parse Step One's XML response
        $gwResponse = @new \SimpleXMLElement($data);
        if ((string)$gwResponse->result == 1) {
            // The form url for used in Step Two below
            $formURL = $gwResponse->{'form-url'};
        } else {
            throw new Exception(print " Error, received " . $data);
        }

        return view("nmi_payment_gateway.webcheckout")
            ->with('gatewayData', $this->gatewayData)
            ->with('team', $this->team)
            ->with('total_price', $this->fmt->formatCurrency($price, $this->currency, $this->minimumFractionDigits, $this->maximumFractionDigits))
            ->with('reference', $reference)
            ->with("order_id", $reference)
            ->with('formURL', $formURL);
    }

    public function sendXMLviaCurl($xmlRequest, $gatewayURL)
    {
        // helper function demonstrating how to send the xml with curl
        $ch = curl_init(); // Initialize curl handle
        curl_setopt($ch, CURLOPT_URL, $gatewayURL); // Set POST URL

        $headers = array();
        $headers[] = "Content-type: text/xml";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Add http headers to let it know we're sending XML
        $xmlString = $xmlRequest->saveXML();
        curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // Allow redirects
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Return into a variable
        curl_setopt($ch, CURLOPT_PORT, 443); // Set the port number
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Times out after 30s
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlString); // Add XML directly in POST
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

        // This should be unset in production use. With it on, it forces the ssl cert to be valid
        // before sending info.
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

        if (!($data = curl_exec($ch))) {
            print  "curl error =>" . curl_error($ch) . "\n";
            throw new Exception(" CURL ERROR :" . curl_error($ch));
        }
        curl_close($ch);
        return $data;
    }

    public function payment(Request $request)
    {
        if (!empty($_GET['token-id'])) {
            $tokenId = $_GET['token-id'];

            $xmlRequest = new \DOMDocument('1.0', 'utf-8');
            $xmlRequest->preserveWhiteSpace = false;
            $xmlRequest->formatOutput = true;

            $xmlCompleteTransaction = $xmlRequest->createElement('complete-action');

            $apikey = $xmlRequest->createElement('api-key',  $this->apiKey);
            $tokenID = $xmlRequest->createElement('token-id', $tokenId);

            $xmlCompleteTransaction->appendChild($apikey);
            $xmlCompleteTransaction->appendChild($tokenID);
            $xmlRequest->appendChild($xmlCompleteTransaction);
            $data = $this->sendXMLviaCurl($xmlRequest, $this->urlApi);

            // Process Step Three
            $gwResponse = @new \SimpleXMLElement((string)$data);
            switch ((string)$gwResponse->result) {
                case '1':
                    $this->updatePayment(
                        (string)$gwResponse->{'order-id'},
                        'CONFIRMED',
                        2,
                        'Transacción confirmada por url',
                        (string)$gwResponse->{'transaction-id'}
                    );

                    $webcheckoutConfirmData = [
                        'state' => 'CONFIRMED',
                        'comment' => 'Transacción confirmada por url',
                        'origin' => $request['origin']
                    ];
                    break;
                case '3':
                    $this->updatePayment(
                        (string)$gwResponse->{'order-id'},
                        'REJECTED',
                        7,
                        (string)$gwResponse->{'result-text'},
                        (string)$gwResponse->{'transaction-id'}
                    );

                    $webcheckoutConfirmData = [
                        'state' => 'REJECTED',
                        'comment' => (string)$gwResponse->{'result-text'},
                        'origin' => $request['origin']
                    ];
                    break;
            }

            return $this->webcheckoutConfirm($webcheckoutConfirmData);
        }
    }

    public function webhooksListener(Request $request)
    {
        $utilController = new UtilController();
        $utilController->logFile($request);

        $requestContent = json_decode($request->getContent(), true);
        $data = $requestContent['event_body'];
        $paymentReference = $data['order_id'];
        $paymentTransactionId = $data['transaction_id'];

        switch ($requestContent['event_type']) {
            case 'transaction.sale.success':
                $this->updatePayment($paymentReference, 'CONFIRMED', 2, 'Venta exitosa', $paymentTransactionId);
                break;

            case 'transaction.sale.failure':
                $this->updatePayment($paymentReference, 'REJECTED', 7, 'Venta fallida', $paymentTransactionId);
                break;
        }
        return response(array('r' => true, 'm' => "Recibido", 'd' => null));
    }

    public function getTransactionByReference(Request $request)
    {
        return response()->json(array(
            'r' => true,
            'm' => 'Transacción obtenida con éxito',
            'd' => $this->getTransactionFromPaymentGateway($request["refTransaction_value"])
        ));
    }

    private function getTransactionFromPaymentGateway($reference)
    {
        $httpClient = new \GuzzleHttp\Client();
        $response = $httpClient->post(
            'https://secure.nmi.com/api/query.php?security_key=' . $this->gatewayData->api_key . '&order_id=' . $reference,
            ['headers' => ['Accept' => 'application/xml'],]
        )->getBody()->getContents();

        return json_decode(json_encode(simplexml_load_string($response)));
    }

    public function validatePayment($transactionId, $reference)
    {
        $payment = $this->getTransactionFromPaymentGateway($reference);
        if (!isset($payment->transaction)) {
            return;
        }

        $transaction = $payment->transaction;
        if (is_array($transaction)) {
            $transaction = end($transaction);
        }

        $action = $transaction->action;
        $action = is_array($action) ? end($action) : $action;

        switch ($transaction->condition) {
            case 'complete':
                $this->updatePayment(
                    $transaction->order_id,
                    'CONFIRMED',
                    2,
                    'Transacción confirmada por validación',
                    $transaction->transaction_id
                );
                break;
            case 'abandoned':
                $this->updatePayment(
                    $transaction->order_id,
                    'ABANDONED',
                    7,
                    'Transacción abandonada',
                    $transaction->transaction_id
                );
                break;
            case 'failed':
                $this->updatePayment(
                    $transaction->order_id,
                    'FAILED',
                    7,
                    $action->response_text,
                    $transaction->transaction_id
                );
                break;

            case 'pendingsettlement':
            case 'in_progress':
                break;

            default:
                break;
        }
    }
    /**
     * @param Request $request
     * @return mixed
     */
    public function responseTransaction(Request $request) {}

    public function getAuthorizationCode($gatewayResponse)
    {
        return null;
    }

    public function getPaymentMethod($gatewayResponse)
    {
        return null;
    }
}