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/agile-selling-wpb/app/Http/Controllers/PayuController.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 PayuController extends Controller
{
    private $urlApi;
    private $currency;
    private $apiVersion;
    private $apiLogin;
    private $apiKey;
    private $merchantId;
    private $accountId;
    private $is_productive;


    public function __construct(){
        if(env('APP_DEBUG')){
            $gw = GatewayPayment::where('id', 1)->first();

            $this->urlApi         = $gw->gw_url_sandbox;
            $this->currency       = $gw->currency;
            $this->apiVersion     = 'v1';
            $this->apiLogin       = $gw->api_login;
            $this->apiKey         = $gw->api_key;
            $this->merchantId     = $gw->merchant_id;
            $this->accountId      = $gw->account_id;
            $this->is_productive  = $gw->is_productive;
        }else{
            $gw = GatewayPayment::where('id', 4)->first();

            $this->urlApi         = $gw->gw_url_prd;
            $this->currency       = $gw->currency;
            $this->apiVersion     = 'v1';
            $this->apiLogin       = $gw->api_login;
            $this->apiKey         = $gw->api_key;
            $this->merchantId     = $gw->merchant_id;
            $this->accountId      = $gw->account_id;
            $this->is_productive  = $gw->is_productive;
        }
    }

    /*
    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 PayU
        $dataRequest = array(
            'language'        => 'es',
            'command'         => 'CREATE_TOKEN',
            'merchant'        => array('apiLogin' => $this->apiLogin, 'apiKey' => $this->apiKey),
            'creditCardToken' => array('payerId' => Auth::user()->id,
                                     'name'                 => $request->name,
                                     'identificationNumber' => Auth::user()->document,
                                     'paymentMethod'        => $request->paymentMethod,
                                     'number'               => $request->cardNumber,
                                     'expirationDate'       => $request->expiryYear. '/' . $request->expiryMonth)
                                    );

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

        $responseGuzzle = $clientGuzzle->post('/payments-api/4.0/service.cgi', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                                        'headers' => [
                'Accept' => 'application/json',
            ],
        ]);

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

        if($responseGuzzle->getStatusCode() == 200 && $body->code == 'SUCCESS'){
            $userToken = new TokenCreditCard;

            $userToken->user_id           = Auth::user()->id;
            $userToken->token             = $body->creditCardToken->creditCardTokenId;
            $userToken->obfuscated_number = $body->creditCardToken->maskedNumber;
            $userToken->card_type         = $body->creditCardToken->paymentMethod;
            $userToken->gateway           = 'PayU';
            $userToken->name_cc           = $body->creditCardToken->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'), 'd' => $userToken->id);

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

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

    // se utiliza para generar el pago de una order al usuario
    public function applyChargeCreditCardUser(Request $request)
    {
      $user_id = Auth::user()->id;
      // TC actual para pagos.
      $cc                   = TokenCreditCard::where([['user_id', $user_id],['current',1]])->first();

      // Datos peticion PayU
      $dataRequest = array(
          'language' => 'es',
          'command'  => 'SUBMIT_TRANSACTION',
          'merchant' => array(
              'apiKey'   => $this->apiKey,
              'apiLogin' => $this->apiLogin),
          'transaction' => array(
              'order' => array(
                  'accountId'        => $this->accountId,
                  'referenceCode'    => 'Generate order payment:' . Auth::user()->id . '-' . $cc->id,
                  'description'      => 'Generate order payment:' . Auth::user()->id . '-' . $cc->id . '-' . $request["amount"],
                  'language'         => 'es',
                  'signature'        => $this->generateSignature('Generate order payment:' . Auth::user()->id . '-' . $cc->id, $request["amount"]),
                  'notifyUrl'        => '',
                  'additionalValues' =>
                      array('TX_VALUE' => array(
                          'value'    => $request["amount"],
                          'currency' => $this->currency
                          )
                      )
              ),
                      'creditCardTokenId' => $cc->token,
                      'extraParameters'   =>
                          array('INSTALLMENTS_NUMBER' => 1),
                      'type'           => 'AUTHORIZATION_AND_CAPTURE',
                      'paymentMethod'  => $cc->card_type,
                      'paymentCountry' => 'CO',
                  ),
                 'test' => $this->is_productive == true ? false : true );


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

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

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

      if($responseGuzzle->getStatusCode() == 200 && $body->code == 'SUCCESS'){
          // Store transaction.
          $p = new PaymentsHistory;

          $p->description       = 'Generate order payment user_id-tdc_id:' . Auth::user()->id . '-' . $cc->id;
          $p->reference_gw      = $body->transactionResponse->transactionId;
          $p->reference2_gw     = $body->transactionResponse->orderId;
          $p->obfuscated_number = $cc->obfuscated_number;
          $p->card_type         = $cc->card_type;
          $p->value             = $request["amount"];
          $p->save();

          return array('r' => true, 'm' => 'Se ha generado exitosamente el pago.', 'd' => $p->id);
      }else{
          return array('r' => false, 'm' => 'Ha ocurrido un error al generar cobro en la TC.');
      }
    }

    public function applyChargeToCreditCardUserOnOrder($orderObject, $type){
        $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.');
        }

        $referenceCode = 'COMPRA TC:' . Auth::user()->id . '-' . $cc->id . 't' . microtime(true);

        // Datos peticion WorldPay
        $dataRequest = array(
            'language' => 'es',
            'command'  => 'SUBMIT_TRANSACTION',
            'merchant' => array(
                'apiKey'   => $this->apiKey,
                'apiLogin' => $this->apiLogin),
            'transaction' => array(
                'order' => array(
                    'accountId'        => $this->accountId,
                    'referenceCode'    => $referenceCode,
                    'description'      => 'COMPRA TC:' . Auth::user()->id . '-' . $cc->id . 't' . microtime(true),
                    'language'         => 'es',
                    'signature'        => $this->generateSignature($referenceCode, $valueForVerification),
                    'notifyUrl'        => '',
                    'additionalValues' =>
                        array('TX_VALUE' => array(
                            'value'    => $valueForVerification,
                            'currency' => $this->currency
                            )
                        )
                ),
                        'creditCardTokenId' => $cc->token,
                        'extraParameters'   =>
                            array('INSTALLMENTS_NUMBER' => 1),
                        'type'           => 'AUTHORIZATION_AND_CAPTURE',
                        'paymentMethod'  => $cc->card_type,
                        'paymentCountry' => 'CO',
                    ),
                   'test' => $this->is_productive == true ? false : true );


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

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

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

        if($responseGuzzle->getStatusCode() == 200 && $body->code == 'SUCCESS'){
            // Store transaction.
            $p = new PaymentsHistory;

            $p->description       = 'Authorization TC user_id-tdc_id: ' . Auth::user()->id . '-' . $cc->id;
            $p->reference_gw      = $body->transactionResponse->transactionId;
            $p->reference2_gw     = $body->transactionResponse->orderId;
            $p->obfuscated_number = $cc->obfuscated_number;
            $p->card_type         = $cc->card_type;
            $p->value             = $valueForVerification;

            $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.');
        }
    }

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

    private function generateSignature($referenceCode, $txValue){
        return md5($this->apiKey . '~' . $this->merchantId . '~' . $referenceCode . '~' . $txValue . '~' . $this->currency);
    }
    /*
    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.');
        }

        // Datos peticion PayU
        $dataRequest = array(
            'language' => 'es',
            'command'  => 'SUBMIT_TRANSACTION',
            'merchant' => array(
                'apiKey'   => $this->apiKey,
                'apiLogin' => $this->apiLogin
              ),
            'transaction' => array(
                'order' => array(
                    'accountId'        => $this->accountId,
                    'referenceCode'    => 'Authorization TC:' . Auth::user()->id . '-' . $cc->id,
                    'description'      => 'Authorization TC:' . Auth::user()->id . '-' . $cc->id . '-' . $valueForVerification,
                    'language'         => 'es',
                    'signature'        => $this->generateSignature('Authorization TC:' . Auth::user()->id . '-' . $cc->id, $valueForVerification),
                    'notifyUrl'        => '',
                    // 'buyer'            => array(
                    //   'fullName'  => "APPROVED"
                    // ),
                    'additionalValues' =>
                        array('TX_VALUE' => array(
                            'value'    => $valueForVerification,
                            'currency' => $this->currency
                            )
                        )
                ),
                'creditCardTokenId' => $cc->token,
                'extraParameters'   =>
                    array('INSTALLMENTS_NUMBER' => 1),
                'type'           => 'AUTHORIZATION_AND_CAPTURE',
                'paymentMethod'  => $cc->card_type,
                'paymentCountry' => 'CO',
                // 'payer'          => array(
                //   'fullName' => 'APPROVED',
                // ),
            ),
            'test' => $this->is_productive == true ? false : true );


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

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

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

        if($responseGuzzle->getStatusCode() == 200 && $body->code == 'SUCCESS'){


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

            // Store transaction.
            $p = new PaymentsHistory;

            $p->description       = 'Authorization TC user_id-tdc_id: ' . Auth::user()->id . '-' . $cc->id;
            $p->reference_gw      = $body->transactionResponse->transactionId;
            $p->reference2_gw     = $body->transactionResponse->orderId;
            $p->obfuscated_number = $cc->obfuscated_number;
            $p->card_type         = $cc->card_type;
            $p->value             = $valueForVerification;

            $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.', 'b' => $body);
        }else{
            return array('r' => false, 'm' => 'Ha ocurrido un error al enviar la verificación de tu TC.', 'e' => $body);
        }
    }

    /*
    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){
            $dataCancel = $this->cancelVerificationAmount($cc);
            if($dataCancel["r"]){
                $cc->verified = true;
                $cc->update();

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

        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($cc){
        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApi,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

         $dataRequest = array(
             'language' => 'es',
             'command'  => 'SUBMIT_TRANSACTION',
             'merchant' => array(
                 'apiKey'   => $this->apiKey,
                 'apiLogin' => $this->apiLogin,
             ),
             'transaction' => array(
                 'order' => array(
                     'id' => $cc->order_code_verification
                 ),
                 'type'                => 'REFUND',
                 'reason'              => 'Reembolso de monto para verificación.',
                 'parentTransactionId' => $cc->transaction_code_verification
                ),
                'test' => $this->is_productive == true ? false : true );

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

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

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

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

            // Store transaction.
            try {
              $p = new PaymentsHistory;

              $p->description       = 'Refund Authorization TC user_id-tdc_id: ' . Auth::user()->id . '-' . $cc->id;
              $p->reference_gw      = $body->transactionResponse->transactionId;
              $p->reference_gw      = $body->transactionResponse->orderId;
              $p->obfuscated_number = $cc->obfuscated_number;
              $p->card_type         = $cc->card_type;
              $p->value             = ($cc->mount_verification * -1);

              $p->save();

              return array('r' => true);

            } catch (\Exception $e) {
              return array('r' => false, 'e' => $e, 'b' => $body);
            }
        }

        return array('r' => false);
    }

    /*
    Elimina una tarjeta de credito del usuario, tanto de la plataforma borrado lógico como de PayU 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->urlApi,
            'defaults' => [
                'exceptions' => false,
            ],
        ]);

         $dataRequest = array(
             'language' => 'es',
             'command'  => 'REMOVE_TOKEN',
             'merchant' => array(
                 'apiKey'   => $this->apiKey,
                 'apiLogin' => $this->apiLogin,
             ),
             'removeCreditCardToken' => array(
                 'payerId' => Auth::user()->id,
                 'creditCardTokenId' => $cc->token
             )
         );

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

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

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

        if($responseGuzzle->getStatusCode() == 200 && $body->code == 'SUCCESS'){

            // Store transaction.
            $p = new PaymentsHistory;

            $p->description       = 'Se elimina el registro de la TC user_id-tdc_id: ' . Auth::user()->id . '-' . $cc->id;
            $p->reference_gw      = null;
            $p->reference_gw      = null;
            $p->obfuscated_number = $body->maskedNumber;
            $p->card_type         = $body->paymentMethod;
            $p->value             = 0;

            $p->save();

            return true;
        }

        return false;
    }
}