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/WorldPayController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\TokenCreditCard;
use App\GatewayPayment;
use App\Order;
use App\PaymentsHistory;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Crypt;

class WorldPayController extends Controller
{
    private $urlApiWorldPay;
    private $currency;
    private $apiVersion;
    private $clientKey;
    private $apiKey;


    public function __construct()
    {
        if(config('app.debug')){
            $gw = GatewayPayment::where('id', 2)->first();

            $this->urlApiWorldPay = $gw->gw_url_sandbox;
            $this->currency       = $gw->currency;
            $this->apiVersion     = 'v1';
            $this->clientKey      = $gw->api_login;
            $this->apiKey         = $gw->api_key;
        }else{
            $gw = GatewayPayment::where('id', 3)->first();

            $this->urlApiWorldPay = $gw->gw_url_sandbox;
            $this->currency       = $gw->currency;
            $this->apiVersion     = 'v1';
            $this->clientKey      = $gw->api_login;
            $this->apiKey         = $gw->api_key;
        }
    }

    /*
    Genera un token en base a los datos de la TC del cliente, para ser usado posteriormente en pagos.
    */
    public function generateTokenForCreditCard(Request $request){
        $validation = $this->validateFieldsForToken($request);
        if(!empty($validation)){
            return array('r' => false, 'm' => $validation);
        }

        // Datos peticion WorldPay
        $dataRequest = array(
            'reusable'      => true,
            'paymentMethod' => array('name' => $request->name,
                                     'expiryMonth' => $request->expiryMonth,
                                     'expiryYear'  => $request->expiryYear,
                                     'cardNumber'  => $request->cardNumber,
                                     'type'        => 'Card',
                                     'cvc'         => $request->cvc),
            'clientKey' => $this->clientKey
                                    );

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->post($this->apiVersion . '/tokens', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                                        'headers' => [
                'Accept' => 'application/json',
            ],
        ]);

        $body = (string) $responseGuzzle->getBody();

        if($responseGuzzle->getStatusCode() == 200){
            $body = json_decode($body);

            $userToken = new TokenCreditCard;

            $userToken->user_id           = Auth::user()->id;
            $userToken->token             = $body->token;
            $userToken->obfuscated_number = $body->paymentMethod->maskedCardNumber;
            $userToken->card_type         = $body->paymentMethod->cardType;
            $userToken->gateway           = 'Worldpay';
            $userToken->name_cc           = $body->paymentMethod->name;
            $userToken->current           = true;
            

            $userToken->save();

            // Se actualiza la nueva TC como tarjeta por default.
            TokenCreditCard:: where('user_id', Auth::user()->id)->update(['current' => false]);
            TokenCreditCard:: where('user_id', Auth::user()->id)->where('id', $userToken->id)->update(['current' => true]);

            return array('r' => true, 'm' => trans('messages.worldpay_successs_token'));

        }else{
            return array('r' => false, 'm' => trans('messages.worldpay_error_token'));
        }
    }

    /*
    Obtiene el listado de las TC del usuario.
    */
    public function getAllMyTC(Request $request){
        $user_id = Auth::user()->id;

        return TokenCreditCard:: where('user_id', $user_id)->select('id', 'obfuscated_number', 'card_type', 'current', 'verified', 'name_cc')->get();
    }

    /*
    Obtiene los detalles de un token de TC de un usuario.
    */
    public function getTokenForDetailTC(Request $request){
        $user_id  = Auth::user()->id;
        $token_id = $request->id;
        $token    = TokenCreditCard::where('user_id', $user_id)->where('id', $token_id)->first();

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->get($this->apiVersion . '/tokens/' . $request->token, [
            'headers' => [
                'Accept' => 'application/json',
            ],
        ]);

        return json_decode($body);
    }

    private function revalidateCVCTC($idTC){
        $cc  = TokenCreditCard::where('user_id', Auth::user()->id)->where('id', $idTC)->where('current', true)->first();
        $cvc = $this->decrypt($cc->cc_verification);

        // DataRequest
        $dataRequest = array('cvc' => $cvc, 'clientKey' => $this->clientKey);

        // Petición para updatear el CVC
        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->put($this->apiVersion . '/tokens/'. $cc->token, [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                                        'headers' => [
                'Accept' => 'application/json'
            ],
        ]);

        $body = (string) $responseGuzzle->getBody();

        if($responseGuzzle->getStatusCode() == 200){
            return true;
        }

        return false;
    }

    private function encrypt($str){
        return Crypt::encrypt($str);

    }

    private function decrypt($encoded){
        return Crypt::decrypt($encoded);
    }

    /*
    Realiza la validacion de los campos requeridos para la generación de un token en WorldPay.
    */
    private function validateFieldsForToken($request){
        $arrayMessages = array();

        if(!$request->name){
            array_push($arrayMessages, trans('messages.worldpay_error_name'));
        }

        if(!$request->expiryMonth){
            array_push($arrayMessages, trans('messages.worldpay_error_month'));
        }

        if(!$request->expiryYear){
            array_push($arrayMessages, trans('messages.worldpay_error_year'));
        }

        if(!$request->cardNumber){
            array_push($arrayMessages, trans('messages.worldpay_error_number'));
        }

        if(!$request->type){
            array_push($arrayMessages, trans('messages.worldpay_error_type'));
        }

        if(!$request->cvc){
            array_push($arrayMessages, trans('messages.worldpay_error_cvc'));
        }

        return $arrayMessages;
    }

    public function applyChargeToCreditCardUserOnOrder($orderObject){
        // Buscar Order
        $order   = Order::find($orderObject->id);
        $user_id = Auth::user()->id;
        // TC actual para pagos.
        $cc = TokenCreditCard::where('current', true)->where('user_id', $user_id)->first();

        // Revalidate CVC
        if(!$this->revalidateCVCTC($cc->id)){
            return array('r' => false, 'm' => 'Error al revalidar el CVC de la TC.');
        }

        // Datos peticion WorldPay
        $dataRequest = array(
            'token'              => $cc->token,
            'orderType'          => 'ECOM',
            'amount'             => $order->cost_real,
            'currencyCode'       => $this->currency,
            'orderDescription'   => 'Pago Orden: #' . $order->code,
            'customerOrderCode'  => $user_id . '-' . $order->id . '-' . $order->code,
            'settlementCurrency' => $this->currency,
            'name'               => Auth::user()->first_name . ' ' . Auth::user()->last_name);

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $clientGuzzle->setDefaultOption('Authorization', $this->apiKey);

        $responseGuzzle = $clientGuzzle->post($this->apiVersion . '/orders/', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
            'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => $this->apiKey
            ],
        ]);

        if($responseGuzzle->getStatusCode() == 200){
            $body = json_decode($body);

            // Store transaction.
            $p               = new PaymentsHistory;
            $p->order_id     = $order->id;
            $p->description  = 'Pago Orden Code: ' . $order->code;
            $p->reference_gw = $body->orderCode;

            $p->save();

            return array('r' => true, 'm' => 'Pago exitoso.');
        }else{
            return array('r' => false, 'm' => 'Ha ocurrido un error con el pago de tu orden.');
        }
    }

    public function applyRefundToCreditCardUser(){

    }

    public function authorizeChargeUser($orderObject){
        // Buscar Order
        $order   = Order::find($orderObject->id);
        $user_id = Auth::user()->id;

        // TC actual para pagos.
        $cc = TokenCreditCard::where('current', true)->where('user_id', $user_id)->first();

        // Datos peticion WorldPay
        $dataRequest = array(
            'token'              => $cc->token,
            'orderType'          => 'ECOM',
            'amount'             => $order->total_price,
            'authorizeOnly'      => true,
            'currencyCode'       => $this->currency,
            'orderDescription'   => 'Pago Orden: #' . $order->code,
            'customerOrderCode'  => $user_id . '-' . $order->id . '-' . $order->code,
            'settlementCurrency' => $this->currency,
            'name'               => Auth::user()->first_name . ' ' . Auth::user()->last_name);

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->post($this->apiVersion . '/orders/', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
            'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => $this->apiKey,

            ],
        ]);

        if($responseGuzzle->getStatusCode() == 200){
            $body = json_decode($body);

            // Store transaction.
            $p               = new PaymentsHistory;
            $p->order_id     = $order->id;
            $p->description  = 'Autorización Code: ' . $order->code . ' by ' . $order->total_price;
            $p->reference_gw = $body->orderCode;

            $p->save();

            return array('r' => true, 'm' => 'Pago exitoso.');
        }else{
            return array('r' => false, 'm' => 'Ha ocurrido un error con el pago de tu orden.');
        }
    }

    public function captureOrder(Request $request){

    }

    public function refundingOrder(Request $request){

    }

    public function setCurrentTC(Request $request){
        $user_id       = Auth::user()->id;
        $token_card_id = $request->id;

        TokenCreditCard:: where('user_id', $user_id)->update(['current' => false]);
        TokenCreditCard:: where('user_id', $user_id)->where('id', $token_card_id)->update(['current' => true]);

        return array('r' => true, 'm' => 'Se ha actualiado correctamente tu TC para pagos.');
    }

    // Se genera un valor aleatorio para enviar a confirmación el usuario.
    private function randomValueVerification(){
        return rand(360, 500);
    }

    /*
    Aplica un monto aleatorio para verificación a la TC únicamente de autorización.
    */
    public function applyVerificationAmount(Request $request){
        $user_id = Auth::user()->id;
        // TC actual para pagos.
        $cc                   = TokenCreditCard::where('id', $request->id)->where('user_id', $user_id)->first();
        $valueForVerification = $this->randomValueVerification();

        // Validar que ya se haya hecho la operación.
        if($cc->mount_verification != 0){
            return array('r' => false, 'm' => 'Ya se ha enviado el cobro de verificación a la TC, por favor revisa tus SMS o extractos e ingresa el valor cobrado.');
        }

        // Revalidate CVC
        if(!$this->revalidateCVCTC($cc->id)){
            return array('r' => false, 'm' => 'Error al revalidar el CVC de la TC.');
        }

        // Datos peticion WorldPay
        $dataRequest = array(
            'token'              => $cc->token,
            'orderType'          => 'ECOM',
            'amount'             => $valueForVerification,
            'authorizeOnly'      => true,
            'currencyCode'       => $this->currency,
            'orderDescription'   => 'Autorización TC:' . $user_id . '-' . $cc->id,
            'customerOrderCode'  => $user_id . '-' . $cc->id,
            'settlementCurrency' => $this->currency,
            'name'               => Auth::user()->first_name . ' ' . Auth::user()->last_name);

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->post($this->apiVersion . '/orders/', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                                        'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => $this->apiKey
            ],
        ]);

        $body = (string) $responseGuzzle->getBody();

        if($responseGuzzle->getStatusCode() == 200){
            $body = json_decode($body);

            // Se almacen el valor para realizar verificación.
            $cc->mount_verification      = $valueForVerification;
            $cc->order_code_verification = $body->orderCode;
            $cc->update();

            // Store transaction.
            $p               = new PaymentsHistory;
            $p->order_id     = $order->id;
            $p->description  = 'Autorización Code: ' . $order->code . ' by ' . $order->total_price;
            $p->reference_gw = $body->orderCode;

            $p->save();

            return array('r' => true, 'm' => 'Se ha enviado un monto como cargo temporal a tu tarjeta por favor indica el valor para verificarla.');
        }else{
            return array('r' => false, 'm' => 'Ha ocurrido un error al enviar la verificación de tu TC.');
        }
    }

    /*
    Valida el monto cargado temporalmente con el monto ingresado manualmente por el usuario.
    */
    public function verifyMyTC(Request $request){
        $cc = TokenCreditCard::where('user_id', Auth::user()->id)->where('id', $request->id)->first();

        if($cc->mount_verification == $request->amount){
            if($this->cancelVerificationAmount($cc->order_code_verification)){
                $cc->verified = true;
                $cc->update();

                return array('r' => true, 'm' => 'Verificación exitosa.');
            }else{
                return array('r' => false, 'm' => 'Ha ocurrido un error al completar el proceso de verificación de la TC.');
            }
        }

        return array('r' => false, 'm' => 'Lo sentimos el valor ingresado no corresponde, no se ha verificado la TC.');
    }

    /*
    Anula el monto de verificación de la TC.
    */
    private function cancelVerificationAmount($orderCode){
        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->delete($this->apiVersion . '/orders/' . $orderCode, [
            'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => $this->apiKey,
            ],
        ]);

        if($responseGuzzle->getStatusCode() == 200){

            // Store transaction.
            $p               = new PaymentsHistory;
            $p->order_id     = $order->id;
            $p->description  = 'Cancelación saldo de verificación';
            $p->reference_gw = $orderCode;

            $p->save();

            return true;
        }

        return false;
    }

    /*
    Elimina una tarjeta de credito del usuario, tanto de la plataforma borrado lógico como de WorldPay para inactivar el token.
    */
    public function deleteCreditCardUser(Request $request){
        $cc = TokenCreditCard::where('user_id', Auth::user()->id)->where('id', $request->id)->first();

        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiWorldPay,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

        $responseGuzzle = $clientGuzzle->delete($this->apiVersion . '/tokens/' . $cc->token, [
            'headers' => [
                'Accept'        => 'application/json',
                'Authorization' => $this->apiKey,
            ],
        ]);

        if($responseGuzzle->getStatusCode() == 200){
            if($cc->current == true){
                $firstCard = TokenCreditCard::where([['user_id', Auth::user()->id], ['id', '!=', $cc->id]])->whereNull('deleted_at')->first();
                if($firstCard){
                    $firstCard->current = true;
                    $firstCard->update();
                }
            }
            $cc->delete();
            return array('r' => true, 'm' => 'Se ha eliminado tu TC correctamente.');
        }
    }
}