From cbb31f0b971f6d98b7de2a2f1491031e14df195a Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Fri, 5 Jun 2020 18:00:16 +0100 Subject: [PATCH] + Implementation of visa-api --- .env.example | 6 +- app/Exceptions/Handler.php | 19 +- app/Http/Controllers/CommissionController.php | 62 +++++- .../Controllers/TransactionController.php | 209 ++++++++++-------- app/Models/WalletTransaction.php | 8 +- app/Traits/ApiResponser.php | 2 +- resources/lang/en/errors.php | 3 +- resources/lang/fr/errors.php | 3 +- 8 files changed, 202 insertions(+), 110 deletions(-) diff --git a/.env.example b/.env.example index b5dbc04..b07c883 100755 --- a/.env.example +++ b/.env.example @@ -11,7 +11,7 @@ LOG_SLACK_WEBHOOK_URL= DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=iLink_test2 +DB_DATABASE=iLink_preprod DB_USERNAME=root DB_PASSWORD=vps@2017GA @@ -29,3 +29,7 @@ MAIL_USERNAME=noreply@ilink-app.com MAIL_PASSWORD=ilink2017GA MAIL_FROM_ADDRESS=noreply@ilink-app.com MAIL_FROM_NAME="iLink World" + +VISA_API_URL=localhost:8082 +VISA_API_USERNAME=admin +VISA_API_PASSWORD=PasswordHere! diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 68b5f11..b4ca2a6 100755 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -101,15 +101,26 @@ class Handler extends ExceptionHandler return $this->errorResponse($exception->getMessage(),Response::HTTP_INTERNAL_SERVER_ERROR); } + if ($exception instanceof \ErrorException) + { + return $this->errorResponse($exception->getMessage(),Response::HTTP_INTERNAL_SERVER_ERROR); + } + if ( $exception instanceof ClientException) { $message = $exception->getResponse()->getBody()->getContents(); - $error =json_decode($message) ; + $error =json_decode($message); $code = $exception->getCode(); - if($error) - return $this->errorResponse($error->error,$code); - else + if($error){ + if($error->message){ + $message = json_decode($error->message); + if(isset($message->errorMessage)) + return $this->errorResponse($message->errorMessage,$code); + return $this->errorResponse($message,$code); + } + return $this->errorResponse($error,$code); + } else return $this->errorResponse($message,$code); } diff --git a/app/Http/Controllers/CommissionController.php b/app/Http/Controllers/CommissionController.php index db17049..0d9d3ee 100755 --- a/app/Http/Controllers/CommissionController.php +++ b/app/Http/Controllers/CommissionController.php @@ -72,16 +72,68 @@ class CommissionController extends Controller $file_ext = end($original_filename_arr); $destination_path = './upload/user/'; $image = 'U-' . time() . '.' . $file_ext; +// File info +// $fileName = basename($_FILES["image"]["name"]); +// $imageUploadPath = $uploadPath . $fileName; +// $fileType = pathinfo($imageUploadPath, PATHINFO_EXTENSION); - if ($request->file('image')->move($destination_path, $image)) { - $user->image = '/upload/user/' . $image; - return $this->successResponse($user); - } else { - return $this->errorResponse('Cannot upload file'); + // Allow certain file formats + $allowTypes = array('jpg','png','jpeg','gif'); + if(in_array(strtolower($file_ext), $allowTypes)){ + // Image temp source +// $imageTemp = $_FILES["image"]["tmp_name"]; + + // Compress size and upload image + $compressedImage = $this->compressImage($request->file('image'), '/'. $image, 80); + if($compressedImage){ + return $this->successResponse("Image compressed successfully."); + }else{ + return $this->errorResponse( "Image compress failed!"); + } + }else{ + return $this->errorResponse('Sorry, only JPG, JPEG, PNG, & GIF files are allowed to upload.'); } + +// if ($request->file('image')->move($destination_path, $image)) { +// $user->image = '/upload/user/' . $image; +// return $this->successResponse($user); +// } else { +// return $this->errorResponse('Cannot upload file'); +// } } else { return $this->errorResponse('File not found'); } } + + /* + * Custom function to compress image size and + * upload to the server using PHP + */ + function compressImage($source, $destination, $quality) { + // Get image info + $imgInfo = getimagesize($source); + $mime = $imgInfo['mime']; + + // Create a new image from file + switch($mime){ + case 'image/jpeg': + $image = imagecreatefromjpeg($source); + break; + case 'image/png': + $image = imagecreatefrompng($source); + break; + case 'image/gif': + $image = imagecreatefromgif($source); + break; + default: + $image = imagecreatefromjpeg($source); + } + + // Save image + imagejpeg($image, $destination, $quality); + + // Return compressed image + return $destination; + } } diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 2c3e459..9fe707d 100755 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -17,6 +17,7 @@ use Illuminate\Support\Facades\DB; class TransactionController extends Controller { use ApiResponser; + /** * Create a new controller instance. * @@ -29,117 +30,134 @@ class TransactionController extends Controller public function add(Request $request) { - $transaction = new WalletTransaction ; - $this->validate($request,$transaction->rules()); + $transaction = new WalletTransaction; + $this->validate($request, $transaction->rules()); $walletAgent = Wallet::findOrFail($request->get('id_wallet')); - $network_agent = NetworksAgent::findOrFail( $walletAgent->id_networkAgent); + $network_agent = NetworksAgent::findOrFail($walletAgent->id_networkAgent); // Configuratrion du wallet - $config = ConfigWallet::where('id_network',$network_agent->network_id)->firstOrFail(); + $config = ConfigWallet::where('id_network', $network_agent->network_id)->firstOrFail(); // Recuperation des wallets hyperviseur et superviseur $codeGenerer = CodeGenerer::findOrFail($network_agent->codeGenerer_id); - $superviseur = AgentPlus::where('code_membre',$codeGenerer->code_parrain)->firstOrFail(); - $hyperviseur = AgentPlus::where('code_membre',$superviseur->code_parrain)->firstOrFail(); + $superviseur = AgentPlus::where('code_membre', $codeGenerer->code_parrain)->firstOrFail(); + $hyperviseur = AgentPlus::where('code_membre', $superviseur->code_parrain)->firstOrFail(); - $wallet_agent_sup = WalletAgent::where('agent_id', $superviseur->id)->firstOrFail(); - $wallet_agent_hyp = WalletAgent::where('agent_id', $hyperviseur->id)->firstOrFail(); + $wallet_agent_sup = WalletAgent::where('agent_id', $superviseur->id)->firstOrFail(); + $wallet_agent_hyp = WalletAgent::where('agent_id', $hyperviseur->id)->firstOrFail(); $walletSuperviseur = Wallet::findOrFail($wallet_agent_sup->wallet_id); $walletHyperviseur = Wallet::findOrFail($wallet_agent_hyp->wallet_id); $data = $request->all(); - $data['expiration_date'] = \DateTime::createFromFormat('m/y',$request->expiration_date); + if (isset($request->cvv) && !is_numeric($request->cvv)) + return $this->errorResponse('errors.invalid_cvv'); + + $data['expiration_date'] = \DateTime::createFromFormat('m/y', $request->expiration_date); + if(!$data['expiration_date']) + $data['expiration_date'] = new \DateTime(); $transaction->fill($data); - $client = new \GuzzleHttp\Client(); + $client = new \GuzzleHttp\Client([ + 'base_uri' => env('VISA_API_URL'), + 'auth'=>[env('VISA_API_USERNAME') , env('VISA_API_PASSWORD')] + ]); // Procedure de depot d'argent - if($transaction->type == 'credit') - { - $frais = $transaction->montant * $config->taux_com_client_depot / 100 ; + if ($transaction->type == 'credit') { + $frais = $transaction->montant * $config->taux_com_client_depot / 100; - // Verification faites au niveau du frontend + //Requete vers la banque + // 1 ---> Emmètre via API sécurisé SSL une requête de débit de notre + //compte marchand la valeur égale au $montantDepot( montant de la + //transaction – la frais calculé en % - frais minimum fixe du + //dépôt client) et créditer sa carte visa de cette valeur + $montantDepot = $transaction->montant - $frais - $config->frais_min_banque_depot; + + $body['amount'] = $montantDepot; + $body['card_number'] = $transaction->numCarte; + $body['cvv'] = $request->cvv; + $body['expiry_date'] = $data['expiration_date']->format('Y-m'); + // Verification faites au niveau du frontend // if($walletAgent->balance_princ >= ($transaction->montant + $frais + $config->frais_min_banque_depot)){ - $response = $client->post('https://ilink-app.com/mobilebackendtest/interacted/MembersAction.php'); - $code = $response->getStatusCode(); - if($code == 200){ - //Requete vers la banque - // 1 ---> Emmètre via API sécurisé SSL une requête de débit de notre - //compte marchand la valeur égale au $montantDepot( montant de la - //transaction – la frais calculé en % - frais minimum fixe du - //dépôt client) et créditer sa carte visa de cette valeur - $montantDepot = $transaction->montant - $frais - $config->frais_min_banque_depot; + $response = $client->post('fund-transfer-api/v1/transaction/push', ['json' => $body]); + $code = $response->getStatusCode(); + if ($code == 200) { - $banqueCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->part_banque_depot / 100); - $transaction->commission_banque = $banqueCommission; - // 2---> Emmètre via API sécurisé SSL une requête de débit de notre - //compte marchand du (Part de la banque partenaire en % - //pour le dépôtqui s’applique sur les frais minimum) et créditer - //le compte des opérations défini avec notre banque - //partenaire + $banqueCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->part_banque_depot / 100); + $transaction->commission_banque = $banqueCommission; + // 2---> Emmètre via API sécurisé SSL une requête de débit de notre + //compte marchand du (Part de la banque partenaire en % + //pour le dépôtqui s’applique sur les frais minimum) et créditer + //le compte des opérations défini avec notre banque + //partenaire - $walletAgent->balance_princ -= $transaction->montant; + $walletAgent->balance_princ -= $transaction->montant; - $agentCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->taux_com_ag_depot / 100); - $superviseurCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->taux_com_sup_depot / 100); - $hyperviseurCommission = $frais + $config->frais_min_banque_depot - $superviseurCommission - $agentCommission - $banqueCommission; + $agentCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->taux_com_ag_depot / 100); + $superviseurCommission = floatval(($frais + $config->frais_min_banque_depot) * $config->taux_com_sup_depot / 100); + $hyperviseurCommission = $frais + $config->frais_min_banque_depot - $superviseurCommission - $agentCommission - $banqueCommission; - $walletAgent->balance_com += $agentCommission; - $walletSuperviseur->balance_com += $superviseurCommission; - $walletHyperviseur->balance_com += $hyperviseurCommission; + $walletAgent->balance_com += $agentCommission; + $walletSuperviseur->balance_com += $superviseurCommission; + $walletHyperviseur->balance_com += $hyperviseurCommission; - $transaction->id_wallet_sup = $walletSuperviseur->id; - $transaction->commission_sup = $superviseurCommission; - $transaction->id_wallet_hyp = $walletHyperviseur->id; - $transaction->commission_hyp = $hyperviseurCommission; - $transaction->commission_ag = $agentCommission; - } + $transaction->id_wallet_sup = $walletSuperviseur->id; + $transaction->commission_sup = $superviseurCommission; + $transaction->id_wallet_hyp = $walletHyperviseur->id; + $transaction->commission_hyp = $hyperviseurCommission; + $transaction->commission_ag = $agentCommission; + } // }else{ // return $this->errorResponse('Solde agent inferieur au montant de depot + frais + frais minimun de depot de la banque', Response::HTTP_BAD_REQUEST); // } - // Procedure de retrait d'argent - }elseif ($transaction->type == 'debit') - { + // Procedure de retrait d'argent + } elseif ($transaction->type == 'debit') { // 12-05-20: Modif de Mr Manga : Le montant de la transaction c'est le montant de retrait sans les frais //Bloquer le retrait - return $this->errorResponse(trans('errors.service_unavailable'),Response::HTTP_BAD_REQUEST); -// $frais = $transaction->montant * $config->taux_com_client_retrait / 100; -// -// $response = $client->post('https://ilink-app.com/mobilebackendtest/interacted/MembersAction.php'); -// $code = $response->getStatusCode(); -// if($code == 200) { -// //Requete vers la banque -// // 1 ---> Emmètre via API sécurisé SSL une requête de retrait du -// //(montant de la transaction + frais de transaction) pour débiter -// //sa carte et créditer notre compte marchand -// $montantRetrait = $transaction->montant + $frais; -// -// $banqueCommission = floatval($transaction->montant * $config->part_banque_retrait / 100); -// $transaction->commission_banque = $banqueCommission; -// // 2---> Emmètre via API sécurisé SSL une requête de débit de notre -// //compte marchand du (montant de la transaction multiplié -// //par la Part de la banque partenaire en % ) et créditer le -// //compte des opérations défini avec notre banque partenaire -// -// $walletAgent->balance_princ += $transaction->montant; -// -// $agentCommission=floatval($transaction->montant*$config->taux_com_ag_retrait / 100); -// $superviseurCommission=floatval($transaction->montant*$config->taux_com_sup_retrait / 100); -// $hyperviseurCommission = $frais - $superviseurCommission - $agentCommission - $banqueCommission; -// -//// dd(array($hyperviseurCommission ,$superviseurCommission)); -// $walletAgent->balance_com += $agentCommission; -// $walletSuperviseur->balance_com += $superviseurCommission; -// $walletHyperviseur->balance_com += $hyperviseurCommission; -// -// $transaction->id_wallet_sup = $walletSuperviseur->id; -// $transaction->commission_sup = $superviseurCommission; -// $transaction->id_wallet_hyp = $walletHyperviseur->id; -// $transaction->commission_hyp = $hyperviseurCommission; -// $transaction->commission_ag = $agentCommission; -// } +// return $this->errorResponse(trans('errors.service_unavailable'), Response::HTTP_BAD_REQUEST); + $frais = $transaction->montant * $config->taux_com_client_retrait / 100; + + //Requete vers la banque + // 1 ---> Emmètre via API sécurisé SSL une requête de retrait du + //(montant de la transaction + frais de transaction) pour débiter + //sa carte et créditer notre compte marchand + $montantRetrait = $transaction->montant + $frais; + + $body['amount'] = $montantRetrait; + $body['card_number'] = $transaction->numCarte; + $body['cvv'] = $request->cvv; + $body['expiry_date'] = $data['expiration_date']->format('Y-m'); + + $response = $client->post('fund-transfer-api/v1/transaction/pull', ['json' => $body]); + $code = $response->getStatusCode(); + if($code == 200) { + + $banqueCommission = floatval($transaction->montant * $config->part_banque_retrait / 100); + $transaction->commission_banque = $banqueCommission; + // 2---> Emmètre via API sécurisé SSL une requête de débit de notre + //compte marchand du (montant de la transaction multiplié + //par la Part de la banque partenaire en % ) et créditer le + //compte des opérations défini avec notre banque partenaire + + $walletAgent->balance_princ += $transaction->montant; + + $agentCommission=floatval($transaction->montant*$config->taux_com_ag_retrait / 100); + $superviseurCommission=floatval($transaction->montant*$config->taux_com_sup_retrait / 100); + $hyperviseurCommission = $frais - $superviseurCommission - $agentCommission - $banqueCommission; + +// dd(array($hyperviseurCommission ,$superviseurCommission)); + $walletAgent->balance_com += $agentCommission; + $walletSuperviseur->balance_com += $superviseurCommission; + $walletHyperviseur->balance_com += $hyperviseurCommission; + + $transaction->id_wallet_sup = $walletSuperviseur->id; + $transaction->commission_sup = $superviseurCommission; + $transaction->id_wallet_hyp = $walletHyperviseur->id; + $transaction->commission_hyp = $hyperviseurCommission; + $transaction->commission_ag = $agentCommission; + } } @@ -152,9 +170,10 @@ class TransactionController extends Controller return $this->successResponse($walletAgent); } - public function lastTransactions($id_wallet){ - $transactions = WalletTransaction::where('id_wallet',$id_wallet)->orderBy('date','desc')->limit(10) - ->get(['type' ,DB::raw('\'wallet\' as source'), 'montant' ,'numCarte AS destinataire' , 'date', 'id']); + public function lastTransactions($id_wallet) + { + $transactions = WalletTransaction::where('id_wallet', $id_wallet)->orderBy('date', 'desc')->limit(10) + ->get(['type', DB::raw('\'wallet\' as source'), 'montant', 'numCarte AS destinataire', 'date', 'id']); return $this->successResponse($transactions); } @@ -162,28 +181,28 @@ class TransactionController extends Controller { $rules = [ 'id_wallet' => 'required|integer|min:1', - 'montant'=> 'required|numeric|min:0|not_in:0', - 'type' =>'required|in:credit,debit', + 'montant' => 'required|numeric|min:0|not_in:0', + 'type' => 'required|in:credit,debit', ]; - $this->validate($request,$rules); + $this->validate($request, $rules); $walletAgent = Wallet::findOrFail($request->get('id_wallet')); - $network_agent = NetworksAgent::findOrFail( $walletAgent->id_networkAgent); + $network_agent = NetworksAgent::findOrFail($walletAgent->id_networkAgent); // Configuratrion du wallet - $config = ConfigWallet::where('id_network',$network_agent->network_id)->firstOrFail(); + $config = ConfigWallet::where('id_network', $network_agent->network_id)->firstOrFail(); $commission = null; - if($request->type == 'credit') { + if ($request->type == 'credit') { //Depot - $commission = ( $request->montant * $config->taux_com_client_depot / 100 ) + $config->frais_min_banque_depot; + $commission = ($request->montant * $config->taux_com_client_depot / 100) + $config->frais_min_banque_depot; $data['montant_calcule'] = $request->montant - $commission; - }elseif ($request->type == 'debit'){ + } elseif ($request->type == 'debit') { // Retrait - $commission = $request->montant * $config->taux_com_client_retrait / 100 ; + $commission = $request->montant * $config->taux_com_client_retrait / 100; $data['montant_calcule'] = $request->montant + $commission; } - $data['commission'] = $commission ; + $data['commission'] = $commission; return $this->successResponse($data); } } diff --git a/app/Models/WalletTransaction.php b/app/Models/WalletTransaction.php index 04b8905..e87fa64 100755 --- a/app/Models/WalletTransaction.php +++ b/app/Models/WalletTransaction.php @@ -100,11 +100,15 @@ class WalletTransaction extends Model public function rules() { + //Verifier si ce sont les infos de la face avant ou arriere de la carte qui sont envoyés + // front -> Face avant : Numero de carte , cvv , etc... + // back -> Face arriere : Numero de serie return [ + 'facade'=>'required|in:front,back', 'montant'=> 'required|numeric|min:0|not_in:0', 'numCarte'=>'required', - 'cvv'=>'required|integer|min:100|max:9999', - 'expiration_date'=>'required|date_format:m/y|after_or_equal:today', + 'cvv'=>'required_if:facade,front|size:3', + 'expiration_date'=>'required_if:facade,front|date_format:m/y|after_or_equal:today', 'type' =>'required|in:credit,debit', 'id_wallet' => 'required|integer|min:0' ]; diff --git a/app/Traits/ApiResponser.php b/app/Traits/ApiResponser.php index 08c7557..a4cf8b7 100755 --- a/app/Traits/ApiResponser.php +++ b/app/Traits/ApiResponser.php @@ -11,7 +11,7 @@ trait ApiResponser return response($this->formatResponse($code,$data,null) , $code)->header('Content-Type', 'application/json'); } - public function errorResponse($message , $code) + public function errorResponse($message , $code = Response::HTTP_BAD_REQUEST) { return response()->json($this->formatResponse($code,null,$message), $code); } diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index ffd971e..ed6e509 100755 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -2,5 +2,6 @@ return [ 'model_not_found' => 'Does not exist any instance of :model with given id', 'unexpected_error'=> 'Unexpected error. Try later', - 'service_unavailable' => 'Service unavailable' + 'service_unavailable' => 'Service unavailable', + 'invalid_cvv' => 'Invalid CVV' ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index dd1d875..895af46 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -2,5 +2,6 @@ return [ 'model_not_found' => 'Il n\'existe aucune instance de :model avec l\'id donné', 'unexpected_error'=> 'Erreur inattendue. Essayer plus tard', - 'service_unavailable' => 'Service non disponible' + 'service_unavailable' => 'Service non disponible', + 'invalid_cvv' => 'CVV invalide' ];