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