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/comfama.sports-crowd.com/app/Http/Controllers/Api/LealPayController.php
<?php

namespace App\Http\Controllers\Api;

use stdClass;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\GatewayPayment;
use App\PaymentType;
use App\User;
use App\Parameter;
use App\Order;
use App\OrderProduct;
use App\LealCoin;
use App\LealCoinTransactionDetail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\OrderController;
use Illuminate\Support\Arr;

class LealPayController extends Controller
{
    private $urlApiLealPay;
    private $urlApiRegisterLealPay;
    private $userApiLealPay;
    private $passApiLealPay;
    private $timeout = 30; // Response timeout
    private $connect_timeout = 30; // Connection timeout

    public function __construct()
    {
        if (config('app.debug')) {
            $gw = GatewayPayment::where('name', 'Leal_sandbox')->first();
            $this->urlApiLealPay            = $gw->gw_url_prd;
            $this->urlApiRegisterLealPay    = $gw->gw_url_sandbox;
            $this->userApiLealPay           = $gw->user;
            $this->passApiLealPay           = $gw->pass;
        } else {
            $gw = GatewayPayment::where('name', 'Leal_PRD')->first();
            $this->urlApiLealPay            = $gw->gw_url_prd;
            $this->urlApiRegisterLealPay    = $gw->gw_url_sandbox;
            $this->userApiLealPay           = $gw->user;
            $this->passApiLealPay           = $gw->pass;
        }
    }

    /**
     * Generates token based on leal API user and pass data,
     * to be used later in leal queries (accumulation and redemption).
     */
    public function login($idUser = null)
    {
        // Datos peticion LealPay
        $dataRequest = new stdClass();
        $dataRequest->usuario = $this->userApiLealPay;
        $dataRequest->contrasena = $this->passApiLealPay;
        try {
            $clientGuzzle = new \GuzzleHttp\Client([
                'base_uri' => $this->urlApiLealPay,
                'defaults' => [
                    'exceptions' => false,
                ]
            ]);

            $responseGuzzle = $clientGuzzle->post('/apiexterno/api/comercios/login_cajero', [
                \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                'headers' => [
                    'Accept' => 'application/json',
                ],
                'timeout' => $this->timeout,
                'connect_timeout' => $this->connect_timeout
            ]);

            $body = (string) $responseGuzzle->getBody();
            if ($responseGuzzle->getStatusCode() == 200) {
                $body = json_decode($body);
                if ($body->code == 100) {
                    $user = User::find($idUser ? $idUser : Auth::user()->id);
                    $user->coin_token = $body->token;
                    $user->coin_refresh_token = $body->refresh_token;
                    $user->save();
                    return array('r' => true, 'm' => trans('messages.lealpay_successs_token'));
                } else {
                    return array('r' => false, 'm' => $body->message);
                }
            }
        } catch (\Exception $e) {
            return array('r' => false, 'm' => $e->getMessage());
        }
        return array('r' => false, 'm' => trans('messages.lealpay_error_token'));
    }

    public function getAllCoinStoreData()
    {
        $token = $this->getUserTokenData(Auth::user()->id);
        $client = new \GuzzleHttp\Client();
        $responseGuzzle = $client->get($this->urlApiLealPay . 'api/comercios/me', [
            'headers' => ['Authorization' => 'Bearer ' . $token]
        ]);
        $body = $responseGuzzle->getBody()->getContents();
        return json_decode($body);
    }

    /**
     * Obtains the user's currency information
     */
    public function getExternalCoins($userExternalId, $userId, $request)
    {
        $token = $this->getUserTokenData($userId);
        $idStore = $this->getIdStore();
        $uid = $userExternalId;
        $lealCoin = LealCoin::where('user_id', $userId)->first();
        try {
            $client = new \GuzzleHttp\Client();
            $responseGuzzle = $client->get($this->urlApiLealPay . '/comercios/consultar_saldo/' . $uid, [
                'headers' => ['Authorization' => 'Bearer ' . $token]
            ]);
            $bodyClient = $responseGuzzle->getBody()->getContents();
            $bodyClient = json_decode($bodyClient);

            $dataRequest = array(
                'uid'           => $uid != null ? $uid : '',
                'cedula'        => $uid != null ? '' : Auth::user()->document,
                'id_comercio'   => $idStore,
                'pagina'        => $request['pagina'] != null ? $request['pagina'] : 1
            );
            if ($request['fecha_inicio']) {
                $dataRequest['fecha_inicio'] = $request['fecha_inicio'];
            }
            if ($request['fecha_fin'] || $request['fecha_inicio']) {
                $dataRequest['fecha_fin'] = $request['fecha_fin'] != null ? $request['fecha_fin'] : Carbon::now()->addDays(1)->format('Y-m-d');
            }
            $clientGuzzle = new \GuzzleHttp\Client([
                'base_uri' => $this->urlApiLealPay,
                'defaults' => [
                    'exceptions' => false,
                ]
            ]);
            $responseGuzzle = $clientGuzzle->post('/apiexterno/api/comercios/historial_transacciones_comercio', [
                \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                'headers' => ['Authorization' => 'Bearer ' . $token],
                'timeout' => $this->timeout,
                'connect_timeout' => $this->connect_timeout
            ]);
            $body = (string) $responseGuzzle->getBody();
            // CONSOLE: return $body;
            $body = json_decode($body);

            $response = [];
            $response = Arr::add($response, 'all_coins', $bodyClient->code == 100 ? $bodyClient->data->saldoCoins : 0);
            $response = Arr::add($response, 'transactions', $body->code == 100 ? $body->data->data : 0);
            $response = Arr::add($response, 'locked', $lealCoin != null ? $lealCoin->locked : 0);
            return array($response);
        } catch (\Exception $e) {
            // return array($e->getMessage());
            if ($lealCoin) {
                $transactionsDetail = LealCoinTransactionDetail::where('leal_coins_id', $lealCoin->id)->orderBy('created_at', 'DESC')->skip(0)->take(20)->get();
                $lealCoin->transactions = $transactionsDetail;
                return array($lealCoin);
            }
        }
        return array();
    }

    /**
     * Register the user in leal API, to obtain the 'uid' used in later transactions,
     * this new data will be stored in the user table.
     */
    public function userRegistration()
    {
        $token = $this->getUserTokenData(Auth::user()->id);
        $cmsStore = $this->getCmsStore();
        $idStore = $this->getIdStore();
        $branchStore = $this->getBranchStore();
        $dataRequest = array(
            'apellido'          => Auth::user()->last_name,
            'cedula'            => Auth::user()->document,
            'celular'           => Auth::user()->phone,
            'cod_pais'          => 'CO',
            'id_ciudad'         => 2,
            'cumpleanos'        => Auth::user()->userInfo->dob,
            'email'             => Auth::user()->email,
            'genero'            => $this->getUserSex(Auth::user()->userInfo->sex),
            'id_tarjeta'        => '',
            'nombre'            => Auth::user()->first_name,
            'tipo_documento'    => Auth::user()->document_type_id,
            'uid_cms'           => $cmsStore,
            'plataforma_origen' => 'POS',
            'tipo_registro'     => 'completo',
            'id_comercio'       => $idStore,
            'id_sucursal'       => $branchStore,
            'id_externo'        => $branchStore
        );
        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiRegisterLealPay,
            'defaults' => [
                'exceptions' => false,
            ]
        ]);

        $responseGuzzle = $clientGuzzle->post('/api/usu_usuarios/registrar', [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
            'headers' => ['Authorization' => 'Bearer ' . $token]
        ]);

        $body = (string) $responseGuzzle->getBody();
        if ($responseGuzzle->getStatusCode() == 200) {
            $body = json_decode($body);
            if ($body->code == 100) {
                User::where('id', Auth::user()->id)->update(['coin_uid' => $body->uid]);
                return array('r' => true, 'm' => trans('messages.lealpay_successs_user'), 'uid' => $body->uid);
            } else {
                return array('r' => false, 'c' => $body->code, 'm' => $body->message);
            }
        } else {
            return array('r' => false, 'm' => trans('messages.lealpay_error_user'));
        }
    }

    public function userUpdate()
    {
        $token = $this->getUserTokenData(Auth::user()->id);
        $idStore = $this->getIdStore();

        $client = new \GuzzleHttp\Client();
        $responseGuzzle = $client->get($this->urlApiRegisterLealPay . '/usu_usuarios/buscar_usuario/' . $idStore . '/' . Auth::user()->document . '?soloCedula=s', [
            'headers' => ['Authorization' => 'Bearer ' . $token]
        ]);

        $body = (string) $responseGuzzle->getBody();
        if ($responseGuzzle->getStatusCode() == 200) {
            $body = json_decode($body);
            if ($body->code == 100) {
                User::where('id', Auth::user()->id)->update(['coin_uid' => $body->data[0]->uid]);
                return array('r' => true, 'm' => trans('messages.lealpay_successs_user'), 'uid' => $body->data[0]->uid);
            } else {
                return array('r' => false, 'c' => $body->code, 'm' => $body->message);
            }
        } else {
            return array('r' => false, 'm' => trans('messages.lealpay_error_user'));
        }
    }

    public function validateUserPointsAccumulation($buy)
    {
        $user = User::where('id', ($buy instanceof Order) ? $buy->client_id : $buy->user_id_log)->first();
        if ($user && $user->coin_uid) {
            $data = ($buy instanceof Order) ? $this->mapOrderDetail($buy) : $this->mapTicketDetail($buy);
            $data['document'] = $user->document;
            $data['coin_uid'] = $user->coin_uid;
            $data['userId'] = $user->id;
            $this->login($user->id);
            $this->accumulateCoins($data);
        }
    }

    public function mapOrderDetail($order)
    {
        $orderDetail = OrderProduct::where('order_id', $order->id)->with('product', 'orderProductAttributes')->get();
        $items = [];
        foreach ($orderDetail as $item) {
            $detail = array(
                'idLinea'               => $item->products->id,
                'codigoItem'            => $item->products->plu,
                'descripcion'           => $item->products->name . ($item->orderProductAttributes && count($item->orderProductAttributes) > 0 ? ', TALLA ' . $item->orderProductAttributes[0]->value : ''),
                'descripcionAdicional'  => $item->comments,
                'cantidad'              => $item->quantity,
                'precioTotal'           => $item->price * $item->quantity,
                'precioUnidad'          => $item->price,
                'impuestoUnidad'        => 0,
                'tipoImpuesto'          => "iva 19%",
                'idExternoCategoria'    => '',
                'nombreCategoria'       => ''
            );
            array_push($items, $detail);
        }
        $payment = PaymentType::find($order->payment_type_id);
        $data = array(
            'totalAcum'     => $order->subtotal,
            'note'          => $order->instructions ? $order->instructions : 'Compra en tienda',
            'invoice'       => $order->code,
            'formPayment'   => $payment->name,
            'codSeller'     => 0,
            'subTotal'      => $order->subtotal,
            'priceTotal'    => $order->total_price,
            'discountTotal' => $order->discount_price,
            'items'         => $items
        );
        return $data;
    }

    public function mapTicketDetail($ticket)
    {
        $ticketDetail = Ticket::where('ticket_main_id', $ticket->id)->with(['seat', 'match_event', 'ticket_type'])->get();
        $items = [];
        foreach ($ticketDetail as $item) {
            $detail = array(
                'idLinea'               => $item->id,
                'codigoItem'            => $item->code_ticket,
                'descripcion'           => 'Ticket ' . $item->code_ticket,
                'descripcionAdicional'  => 'Ticket de ' . $item->ticket_type->name,
                'cantidad'              => 1,
                'precioTotal'           => $item->price,
                'precioUnidad'          => $item->price,
                'impuestoUnidad'        => 0,
                'tipoImpuesto'          => "iva 19%",
                'idExternoCategoria'    => '',
                'nombreCategoria'       => ''
            );
            array_push($items, $detail);
        }
        $payment = PaymentType::where('active', 1)->first();
        $data = array(
            'totalAcum'     => $ticket->total,
            'note'          => $ticket->comment_purchase_log ? $ticket->comment_purchase_log : 'Compra boleteria',
            'invoice'       => $ticket->payment_reference,
            'formPayment'   => $payment->name,
            'codSeller'     => 0,
            'subTotal'      => $ticket->total,
            'priceTotal'    => $ticket->total,
            'discountTotal' => 0,
            'items'         => $items
        );
        return $data;
    }

    /**
     * Accumulate points in leal API, with the purchase in store and/or tickets.
     */
    public function accumulateCoins($data)
    {
        $token = $this->getUserTokenData($data['userId']);
        $idStore = $this->getIdStore();
        $branchStore = $this->getBranchStore();
        $dataRequest = array(
            'idExterno'     => $branchStore,
            'criterio'      => $data['document'],
            'totalAcum'     => $data['totalAcum'],
            'transaccion'   => array(
                'clave'             => $data['invoice'],
                'noFactura'         => $data['invoice'],
                'fecha'             => Carbon::now()->format('Y-m-d H:i:s'),
                'fechaApertura'     => Carbon::now()->format('Y-m-d H:i:s'),
                'fechaCierre'       => Carbon::now()->format('Y-m-d H:i:s'),
                'totalPersonas'     => 1,
                'formaPago'         => $data['formPayment'],
                'codVendedor'       => $data['codSeller'],
                'subTotal'          => $data['subTotal'],
                'propina'           => 0,
                'impuestoTotal'     => $data['priceTotal'],
                'descuentoTotal'    => $data['discountTotal'],
                'items'             => $data['items']
            )
        );
        $clientGuzzle = new \GuzzleHttp\Client([
            'base_uri' => $this->urlApiLealPay,
            'defaults' => [
                'exceptions' => false,
            ]
        ]);

        $responseGuzzle = $clientGuzzle->post('/apiexterno/api/comercios/cargar_factura/' . $idStore, [
            \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
            'headers' => ['Authorization' => 'Bearer ' . $token]
        ]);

        $body = (string) $responseGuzzle->getBody();
        if ($responseGuzzle->getStatusCode() == 200) {
            $body = json_decode($body);
            if ($body->code == 100) {
                $lealCoin = $this->validateLealUserCoins($data['userId'], $body->coins_acumulados);
                $parameters = Parameter::first();
                $this->recordTransaction($this->mapCreditCheckoutTransactionData($lealCoin, ROUND($data['totalAcum'] / $parameters->value_points_coin), $data['invoice'], $body->transaccion_id, 1, $body->message));
                return array('r' => true, 'm' => trans('messages.lealpay_successs_user'), 'd' => $body);
            } else {
                return array('r' => false, 'm' => $body->message);
            }
        } else {
            return array('r' => false, 'm' => trans('messages.lealpay_error_user'));
        }
    }

    public function generateOTPToken(Request $request)
    {
        try {
            if ($request['uid'] == null) {
                return response()->json(array('status' => 'El coin_uid no puede ser nulo'), 400);
            }

            $token = $this->getUserTokenData(Auth::user()->id);
            $idStore = $this->getIdStore();
            $branchStore = $this->getBranchStore();

            $dataRequest = array(
                'uid'               => $request['uid'],
                'valor'             => $request['valor'],
                'id_comercio'       => $idStore,
                'id_sucursal'       => $branchStore,
                'codigo_credibanco' => '',
                'tipo_redencion'    => 'factura'
            );

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

            $responseGuzzle = $clientGuzzle->post('/apiexterno/api/comercios/generar_codigo_leal_coins', [
                \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                'headers' => ['Authorization' => 'Bearer ' . $token]
            ]);

            $body = (string) $responseGuzzle->getBody();
            return $body;
        } catch (\Exception $e) {
            return response()->json(array('status' => $e->getMessage()), 500);
        }
    }

    public function generateOrderPaymentCoins(Request $request)
    {
        try {
            $coinUid = $request['userInfo']['coin_uid'];
            if ($coinUid == null) {
                return response()->json(array('status' => 'El coin_uid no puede ser nulo'), 400);
            }

            $token = $this->getUserTokenData(Auth::user()->id);
            $idStore = $this->getIdStore();
            $branchStore = $this->getBranchStore();

            $dataRequest = array(
                'id_comercio'       => $idStore,
                'id_sucursal'       => $branchStore,
                'codigo_credibanco' => '',
                'uid'               => $coinUid,
                'valor'             => $request['order']['data']['total'],
                'token'             => '',
                'requiere_otp'      => false,
                'usuario_sistema'   => ''
            );

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

            $responseGuzzle = $clientGuzzle->post('/apiexterno/api/comercios/pagar_factura_leal_coins', [
                \GuzzleHttp\RequestOptions::JSON      => $dataRequest,
                'headers' => ['Authorization' => 'Bearer ' . $token]
            ]);

            $response = $responseGuzzle->getBody();
            $body = json_decode($response, true);

            if ($body['code'] != 100) {
                return (string) $response;
            }
            $lealCoin = $this->validateLealUserCoins($request['userInfo']['id'], $body['data']['puntos_totales']);
            $parameters = Parameter::first();
            $this->recordTransaction($this->mapCreditCheckoutTransactionData($lealCoin, ROUND($body['data']['puntos_usados']), '', $body['data']['codigo_transaccion']['id'], -1, $body['data']['message']));

            $orderData = new Request($request['order']);
            $order = new OrderController();
            return $order->create($orderData);
        } catch (\Exception $e) {
            // return array($e->getMessage());
            return response()->json(array('status' => $e->getMessage()), 500);
        }
    }

    private function getUserTokenData($userId)
    {
        $user = User::find($userId);
        return $user->coin_token;
    }

    private function getIdStore()
    {
        $parameters = Parameter::first();
        return intval($parameters->coin_store_identifier);
    }

    private function getCmsStore()
    {
        $parameters = Parameter::first();
        return $parameters->coin_cms_identifier;
    }

    private function getBranchStore()
    {
        $parameters = Parameter::first();
        return $parameters->coin_branch_identifier;
    }

    private function getUserSex($sex)
    {
        $gender = 'other';
        switch ($sex) {
            case 'M':
                $gender = 'male';
                break;
            case 'F':
                $gender = 'female';
                break;
            case 'I':
                $gender = 'intersex';
                break;
        }
        return $gender;
    }

    private function validateLealUserCoins($userId, $coins = 0)
    {
        $lealCoin = LealCoin::where('user_id', $userId)->first();
        if (!$lealCoin) {
            $lealCoin = new LealCoin();
            $lealCoin->all_coins = $coins;
            $lealCoin->user_id = $userId;
            $lealCoin->save();
        } else {
            $lealCoin->all_coins = $coins;
            $lealCoin->update();
        }
        return $lealCoin;
    }

    private function mapCreditCheckoutTransactionData($lealCoin, $coins, $invoice, $reference, $sign, $detail)
    {
        $data = new stdClass();
        $data->invoice          = $invoice;
        $data->reference        = $reference;
        $data->coins            = abs($coins);
        $data->sign             = $sign;
        $data->detail           = $detail;
        $data->leal_coins_id    = $lealCoin->id;
        return array($data);
    }

    private function recordTransaction($data)
    {
        $transactionsDetail = new LealCoinTransactionDetail();
        $transactionsDetail->invoice        = $data[0]->invoice;
        $transactionsDetail->reference      = $data[0]->reference;
        $transactionsDetail->coins          = $data[0]->coins;
        $transactionsDetail->sign           = $data[0]->sign;
        $transactionsDetail->detail         = $data[0]->detail;
        $transactionsDetail->leal_coins_id  = $data[0]->leal_coins_id;
        $transactionsDetail->cancelled      = false;
        $transactionsDetail->save();
    }

    public function testOrden($id)
    {
        auth()->loginUsingId(8);
        $order = Order::where('id', $id)->first();
        return $this->validateUserPointsAccumulation($order);
    }
}