File: /var/www/vhost/disk-apps/qas.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()
{
$gw = GatewayPayment::where('name', 'Leal_PRD')->first();
if (config('app.debug')) {
$gw = GatewayPayment::where('name', 'Leal_sandbox')->first();
}
if (!$gw) {
return;
}
$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);
}
}