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