Refactor ilink transaction controller, more secure

This commit is contained in:
Djery-Tom 2022-04-20 09:08:32 +01:00
parent 61b2c481c9
commit 0bc3eaf856
10 changed files with 854 additions and 658 deletions

View File

@ -3,6 +3,7 @@
namespace App\Exceptions;
use App\Traits\ApiResponser;
use ErrorException;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use Illuminate\Auth\Access\AuthorizationException;
@ -102,7 +103,7 @@ class Handler extends ExceptionHandler
return $this->errorResponse($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
if ($exception instanceof \ErrorException) {
if ($exception instanceof ErrorException) {
return $this->errorResponse($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}

View File

@ -20,11 +20,14 @@ use App\Models\WalletAgent;
use App\Models\WalletIlinkTransaction;
use App\Models\WalletsUser;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use DateTime;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Throwable;
class iLinkTransactionController extends Controller
{
@ -146,16 +149,19 @@ class iLinkTransactionController extends Controller
{
$transaction = new WalletIlinkTransaction();
$this->validate($request, [
'type' => 'required|integer|min:0|not_in:0',
'id_wallet_agent' => 'required_without:id_wallet_user|integer|min:0|not_in:0',
'id_wallet_user' => 'required_without:id_wallet_agent|integer|min:0|not_in:0',
'type' => 'required|integer|exists:type_ilink_transaction,id',
'id_wallet_agent' => 'required_without:id_wallet_user|integer|exists:wallets,id',
'id_wallet_user' => 'required_without:id_wallet_agent|integer|exists:wallets_users,id',
'password' => 'required',
'montant' => 'required|numeric|min:0|not_in:0',
]);
$type = TypeIlinkTransaction::findOrFail($request->type);
if (isset($request->id_wallet_agent)) {
$walletAgent = Wallet::findOrFail($request->get('id_wallet_agent'));
$id_wallet_agent = $request->input('id_wallet_agent');
$id_wallet_user = $request->input('id_wallet_user');
$type = TypeIlinkTransaction::findOrFail($request->input('type'));
if (isset($id_wallet_agent)) {
$walletAgent = Wallet::findOrFail($id_wallet_agent);
$network_agent = NetworksAgent::findOrFail($walletAgent->id_networkAgent);
$transaction->init_country = $init_country = $network_agent->network->country->id;
// Configuratrion du wallet
@ -170,8 +176,8 @@ class iLinkTransactionController extends Controller
$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);
} elseif (isset($request->id_wallet_user)) {
$walletUser = WalletsUser::findOrFail($request->id_wallet_user);
} elseif (isset($id_wallet_user)) {
$walletUser = WalletsUser::findOrFail($id_wallet_user);
$transaction->init_country = $init_country = $walletUser->user->network->country->id;
$result = ConfigWallet::join('networks', 'networks.id', '=', 'configWallet.id_network')
->where('networks.country_id', $init_country)->where('configWallet.type', 'ilink')
@ -196,18 +202,20 @@ class iLinkTransactionController extends Controller
return $tax->destination == 'international' && $tax->categorie == 'wallet';
}));
$paliers_config_wallets = $config->paliers_config_wallets->all();
$paliers_commission_wallets = $config->paliers_commissions_wallets->all();
$plr_user_wallet_wallet = $this->getPaliers($config->paliers_config_wallets->all(), "user_wallet_wallet_international");
$plr_user_wallet_cash = $this->getPaliers($config->paliers_config_wallets->all(), "user_wallet_cash_international");
$plr_agent_depot_wallet_ilink = $this->getPaliers($config->paliers_config_wallets->all(), "agent_depot_wallet_ilink_international");
$plr_agent_depot_autre_wallet = $this->getPaliers($config->paliers_config_wallets->all(), "agent_depot_autre_wallet_international");
$plr_agent_cash_cash = $this->getPaliers($config->paliers_config_wallets->all(), "agent_cash_cash_international");
$plr_user_wallet_wallet = $this->getPaliers($paliers_config_wallets, "user_wallet_wallet_international");
$plr_user_wallet_cash = $this->getPaliers($paliers_config_wallets, "user_wallet_cash_international");
$plr_agent_depot_wallet_ilink = $this->getPaliers($paliers_config_wallets, "agent_depot_wallet_ilink_international");
$plr_agent_depot_autre_wallet = $this->getPaliers($paliers_config_wallets, "agent_depot_autre_wallet_international");
$plr_agent_cash_cash = $this->getPaliers($paliers_config_wallets, "agent_cash_cash_international");
$plr_user_wallet_wallet_national = $this->getPaliers($config->paliers_config_wallets->all(), "user_wallet_wallet_national");
$plr_user_wallet_cash_national = $this->getPaliers($config->paliers_config_wallets->all(), "user_wallet_cash_national");
$plr_agent_depot_wallet_ilink_national = $this->getPaliers($config->paliers_config_wallets->all(), "agent_depot_wallet_ilink_national");
$plr_agent_depot_autre_wallet_national = $this->getPaliers($config->paliers_config_wallets->all(), "agent_depot_autre_wallet_national");
$plr_agent_cash_cash_national = $this->getPaliers($config->paliers_config_wallets->all(), "agent_cash_cash_national");
$plr_user_wallet_wallet_national = $this->getPaliers($paliers_config_wallets, "user_wallet_wallet_national");
$plr_user_wallet_cash_national = $this->getPaliers($paliers_config_wallets, "user_wallet_cash_national");
$plr_agent_depot_wallet_ilink_national = $this->getPaliers($paliers_config_wallets, "agent_depot_wallet_ilink_national");
$plr_agent_depot_autre_wallet_national = $this->getPaliers($paliers_config_wallets, "agent_depot_autre_wallet_national");
$plr_agent_cash_cash_national = $this->getPaliers($paliers_config_wallets, "agent_cash_cash_national");
$data = $request->all();
@ -221,25 +229,23 @@ class iLinkTransactionController extends Controller
'auth' => [env('VISA_API_USERNAME'), env('VISA_API_PASSWORD')]
]);
try {
DB::beginTransaction();
switch ($type->id) {
case 1: //User - Envoi wallet à wallet
$this->validate($request, $transaction->send_wallet_wallet_rules());
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if ($init_country != $request->final_country) {
$rep = $this->checkUserIdentification($user->id);
// dd($rep);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkUserIdentification($user->id);
}
if ($request->montant > $walletUser->balance) {
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 500);
} else {
//Verification des limites reglementaires
$rep = $this->checkReguationsLimits($walletUser->id, $init_country, $request->final_country, $transaction->montant);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkReguationsLimits($walletUser->id, $init_country, $request->final_country, $transaction->montant);
$transaction->frais = $frais = ($init_country != $request->final_country) ? $this->calculateFees($plr_user_wallet_wallet, $request->montant) : $this->calculateFees($plr_user_wallet_wallet_national, $request->montant);
$transaction->taxe = $taxe = ($init_country != $request->final_country) ? $this->calculateTax($taxesInternationales, $frais) : $this->calculateTax($taxesNationales, $frais);
@ -270,10 +276,10 @@ class iLinkTransactionController extends Controller
$walletDestinataire->save();
} else {
$country = Country::findOrFail($request->final_country);
return $this->errorResponse(trans('errors.wallet_country_not_match', ['country' => $country->name]));
throw new Exception(trans('errors.wallet_country_not_match', ['country' => $country->name]), 500);
}
} else {
return $this->errorResponse(trans('errors.wallet_not_defined'));
throw new Exception(trans('errors.wallet_not_defined'), 500);
}
//Mise a jour des comissions et compensation
@ -298,8 +304,9 @@ class iLinkTransactionController extends Controller
// La mise à jour des comissions de compensation se fera lors du traitement de la transaction
$transaction->status_reseau_payeur = 'EN_COURS';
$result = $this->sendFrame($this->PAYING_NETWORK_SIMULATOR_SEND_FRAME_URL, $transaction);
if ($result->getStatusCode() != 200)
return $this->errorResponse(trans('errors.unexpected_error'));
if ($result->getStatusCode() != 200) {
throw new Exception(trans('errors.unexpected_error'), 500);
}
}
$walletHyperviseur->balance_com += $transaction->part_reseau_emetteur;
$walletUser->balance -= $transaction->montant;
@ -317,21 +324,19 @@ class iLinkTransactionController extends Controller
'init_country' => $this->getCountryName($init_country), 'final_country' => $this->getCountryName($request->final_country),
'sender_code' => $user->user_code, 'receiver_code' => $transaction->id_destinataire, 'network' => $this->getNetworkName($transaction->network_destinataire)]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
$response_message = $message . trans('messages.sent_by_mail');
}
break;
case 2: //User - Envoi de wallet à carte
$this->validate($request, $transaction->user_card_rules());
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if ($request->montant > $walletUser->balance) {
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 500);
} else {
if (!(isset($user->numero_carte) && isset($user->expiration_date)))
return $this->errorResponse(trans('errors.no_bank_card_attached'));
if (!(isset($user->numero_carte) && isset($user->expiration_date))) {
throw new Exception(trans('errors.no_bank_card_attached'), 500);
}
$transaction->expiration_date = $user->expiration_date;
$transaction->numero_carte = $user->numero_carte;
@ -375,33 +380,26 @@ class iLinkTransactionController extends Controller
'net' => $this->toMoney($montantDepot, $init_country), 'fees' => $this->toMoney($frais, $init_country),
'sender_code' => $user->user_code, 'cart_number' => wordwrap($transaction->numero_carte, 4, ' ', true)]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = $message . trans('messages.sent_by_mail');
} else {
return $this->errorResponse(trans('errors.visa_api_failed'));
throw new Exception(trans('errors.visa_api_failed'), 500);
}
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
}
break;
case 3: //User - Envoi de wallet à cash
$this->validate($request, $transaction->send_wallet_cash_rules());
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if ($init_country != $request->final_country) {
$rep = $this->checkUserIdentification($user->id);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkUserIdentification($user->id);
}
if ($request->montant > $walletUser->balance) {
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 500);
} else {
//Verification des limites reglementaires
$rep = $this->checkReguationsLimits($walletUser->id, $init_country, $request->final_country, $transaction->montant);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkReguationsLimits($walletUser->id, $init_country, $request->final_country, $transaction->montant);
$transaction->frais = $frais = ($init_country != $request->final_country) ? $this->calculateFees($plr_user_wallet_cash, $request->montant) : $this->calculateFees($plr_user_wallet_cash_national, $request->montant);
$transaction->taxe = $taxe = ($init_country != $request->final_country) ? $this->calculateTax($taxesInternationales, $frais) : $this->calculateTax($taxesNationales, $frais);
@ -447,8 +445,9 @@ class iLinkTransactionController extends Controller
// La mise à jour des comissions de compensation se fera lors du traitement de la transaction
$transaction->status_reseau_payeur = 'EN_COURS';
$result = $this->sendFrame($this->PAYING_NETWORK_SIMULATOR_SEND_FRAME_URL, $transaction);
if ($result->getStatusCode() != 200)
return $this->errorResponse(trans('errors.unexpected_error'));
if ($result->getStatusCode() != 200) {
throw new Exception(trans('errors.unexpected_error'), 500);
}
}
$walletUser->balance -= $transaction->montant;
$walletHyperviseur->balance_com += $transaction->commission_hyp;
@ -473,10 +472,7 @@ class iLinkTransactionController extends Controller
'sender_code' => $user->user_code, 'receiver_code' => $transaction->id_destinataire, 'receiver_name' => $request->prenom_destinataire . ' ' . $request->nom_destinataire,
'sender_name' => $user->lastname . ' ' . $user->firstname, 'network' => $this->getNetworkName($transaction->network_destinataire)]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
$response_message = ($message . trans('messages.sent_by_mail'));
}
break;
/**
@ -517,39 +513,36 @@ class iLinkTransactionController extends Controller
]);
$user = $walletUser->user;
if (!$this->checkPassword($request->password, $user->encrypted_password, $user->salt))
return $this->errorResponse(trans('messages.incorrect_user_password'));
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
$rep = $this->checkUserIdentification($user->id);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkUserIdentification($user->id);
if (!(isset($user->iban) && isset($user->id_bank_country)))
return $this->errorResponse(trans('errors.wallet_not_linked_to_bank_account'));
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
if ($request->montant > $walletUser->balance)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 422);
//Reverifier si l'operateur est toujours associé au reseau
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)->where('id_operator_country', $user->id_bank_country)->first();
if (!$network_bank)
return $this->errorResponse(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
if ($network_bank->operators_country->operator->type != 'bank')
return $this->errorResponse(trans('errors.not_banking_operator') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.not_banking_operator') . '. ' . trans('errors.update_banking_information'));
//Reverifier le code IBAN correspond toujours
$country_code = $network_bank->network->country->code_country;
$bank_code = $network_bank->operators_country->code;
switch ($this->checkIBAN($user->iban, $country_code, $bank_code)) {
case 0:
return $this->errorResponse(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
case 1:
return $this->errorResponse(trans('errors.country_not_match_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.country_not_match_iban') . '. ' . trans('errors.update_banking_information'));
case 2:
return $this->errorResponse(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
}
$transaction->frais = $frais = 0;
@ -580,7 +573,7 @@ class iLinkTransactionController extends Controller
'net' => $this->toMoney($transaction->montant, $init_country), 'iban' => $request->iban, 'fees' => $this->toMoney($frais, $init_country),
'sender_code' => $user->user_code, 'bank' => $transaction->bank, 'country' => $transaction->country]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
break;
// case 5: //User - Envoi de carte à wallet
@ -593,13 +586,11 @@ class iLinkTransactionController extends Controller
// break;
case 9: // User - Retrait de wallet en cash
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if ($request->montant > $walletUser->balance) {
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'));
} else {
$rep = $this->checkUserIdentification($user->id);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkUserIdentification($user->id);
$transaction->final_country = $init_country;
$transaction->frais = $frais = $this->calculateFees($plr_user_wallet_cash_national, $request->montant);
@ -627,20 +618,15 @@ class iLinkTransactionController extends Controller
'fees' => $this->toMoney($frais + $taxe, $init_country), 'code' => wordwrap($code_retrait, 4, ' ', true),
'sender_code' => $user->user_code, 'init_country' => $this->getCountryName($init_country),]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
$response_message = ($message . trans('messages.sent_by_mail'));
}
break;
case 10: //User - Retrait de carte vers wallet
$this->validate($request, $transaction->user_card_rules());
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if (!(isset($user->numero_carte) && isset($user->expiration_date)))
return $this->errorResponse(trans('errors.no_bank_card_attached'));
throw new Exception(trans('errors.no_bank_card_attached'));
$transaction->expiration_date = $user->expiration_date;
$transaction->numero_carte = $user->numero_carte;
@ -685,26 +671,20 @@ class iLinkTransactionController extends Controller
'total' => $this->toMoney($montantRetrait, $init_country), 'fees' => $this->toMoney($frais, $init_country),
'sender_code' => $user->user_code, 'cart_number' => wordwrap($transaction->numero_carte, 4, ' ', true)]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
} else {
return $this->errorResponse(trans('errors.visa_api_failed'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
throw new Exception(trans('errors.visa_api_failed'));
}
break;
case 11: // User - Retrait de carte vers cash
$this->validate($request, $transaction->user_card_rules());
$user = $walletUser->user;
if ($this->checkPassword($request->password, $user->encrypted_password, $user->salt)) {
$rep = $this->checkUserIdentification($user->id);
if ($rep instanceof JsonResponse)
return $rep;
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
$this->checkUserIdentification($user->id);
if (!(isset($user->numero_carte) && isset($user->expiration_date)))
return $this->errorResponse(trans('errors.no_bank_card_attached'));
throw new Exception(trans('errors.no_bank_card_attached'));
$transaction->expiration_date = $user->expiration_date;
$transaction->numero_carte = $user->numero_carte;
@ -757,34 +737,30 @@ class iLinkTransactionController extends Controller
return $this->successResponse($message . trans('messages.sent_by_mail'));
} else {
return $this->errorResponse(trans('errors.visa_api_failed'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
throw new Exception(trans('errors.visa_api_failed'));
}
break;
case 12: // Agent - Retrait en cash
$this->validate($request, $transaction->remove_cash_rules());
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$this->validate($request->password, $agent->encrypted_password, $agent->salt);
$transaction = WalletIlinkTransaction::where('id_transaction', $request->id_transaction)->first();
if ($transaction) {
//Verifier si l'agent qui a effectué l'envoi de cash à cash ne puisse pas retirer l'argent
if ($transaction->type == 17)
if ($transaction->id_wallet_ag == $walletAgent->id)
return $this->errorResponse(trans('errors.agent_unauthorized'));
throw new Exception(trans('errors.agent_unauthorized'));
//Verifier que le reseau payeur est de type iLink
if (in_array($transaction->type, [3, 17])) {
$configPayeur = ConfigWallet::where('id_network', $transaction->network_destinataire)->firstOrFail();
if ($configPayeur->type != 'ilink')
return $this->errorResponse(trans('errors.withdrawal_network_unauthorized', ['network' => $this->getNetworkName($transaction->network_destinataire),
throw new Exception(trans('errors.withdrawal_network_unauthorized', ['network' => $this->getNetworkName($transaction->network_destinataire),
'country' => $this->getCountryName($transaction->final_country)]));
}
if ($transaction->status_retrait == 0) {
//Verifier que le pays de destinatation correspond au pays de retrait
if ($init_country != $transaction->final_country)
return $this->errorResponse(trans('errors.operation_cannot_performed_in_country'));
throw new Exception(trans('errors.operation_cannot_performed_in_country'));
if ($this->checkPassword($request->code_retrait, $transaction->encrypted_code_retrait, $transaction->code_retrait_salt)) {
$montantNet = $transaction->type == 11 ? $transaction->montant_net : $transaction->montant_net_final_country;
if (in_array($transaction->type, [3, 17])) {
@ -833,30 +809,27 @@ class iLinkTransactionController extends Controller
'code' => wordwrap($request->code_retrait, 4, ' ', true), 'final_country' => $this->getCountryName($transaction->final_country),
'sender_name' => $emetteur, 'receiver_name' => $destinataire, 'id_transaction_retrait' => $transaction->id_transaction]);
$this->sendMail($emailEmetteur, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
} else {
return $this->errorResponse(trans('errors.incorrect_withdrawal_amount'));
throw new Exception(trans('errors.incorrect_withdrawal_amount'));
}
} else {
return $this->errorResponse(trans('errors.invalid_withdrawal_code'));
throw new Exception(trans('errors.invalid_withdrawal_code'));
}
} else {
return $this->errorResponse(trans('errors.withdrawal_already_made'));
throw new Exception(trans('errors.withdrawal_already_made'));
}
} else {
return $this->errorResponse(trans('errors.transaction_not_exist'), Response::HTTP_NOT_FOUND);
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
throw new Exception(trans('errors.transaction_not_exist'), Response::HTTP_NOT_FOUND);
}
break;
case 13: // Agent - Retrait de la carte vers cash
$this->validate($request, $transaction->card_rules());
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$expiration_date = \DateTime::createFromFormat('m/y', $request->expiration_date);
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
$expiration_date = DateTime::createFromFormat('m/y', $request->expiration_date);
if (!$expiration_date)
$expiration_date = new \DateTime();
$expiration_date = new DateTime();
$transaction->expiration_date = $expiration_date;
$transaction->final_country = $init_country;
@ -910,34 +883,29 @@ class iLinkTransactionController extends Controller
$walletHyperviseur->save();
$transaction->id_transaction = $this->getTransactionID();
$transaction->save();
return $this->successResponse(trans('messages.successful_transaction'));
$response_message = (trans('messages.successful_transaction'));
} else {
return $this->errorResponse(trans('errors.visa_api_failed'));
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
throw new Exception(trans('errors.visa_api_failed'));
}
break;
case 14: // Agent - Envoi de cash vers wallet iLink
$this->validate($request, $transaction->cash_wallet_rules());
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
if ($request->montant > $walletAgent->balance_princ)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'));
$user = User::where('user_code', $request->user_code)->first();
if (!$user)
return $this->errorResponse(trans('errors.wallet_not_defined'));
throw new Exception(trans('errors.wallet_not_defined'));
$transaction->id_destinataire = $request->user_code;
$walletUser = WalletsUser::where('idUser', $user->id)->firstOrFail();
$transaction->final_country = $final_country = $user->network->country->id;
//Verification des limites reglementaires
$rep = $this->checkReguationsLimits($walletUser->id, $init_country, $final_country, $transaction->montant);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkReguationsLimits($walletUser->id, $init_country, $final_country, $transaction->montant);
$frais = ($init_country != $final_country) ? $this->calculateFees($plr_agent_depot_wallet_ilink, $request->montant) : $this->calculateFees($plr_agent_depot_wallet_ilink_national, $request->montant);
$taxe = ($init_country != $final_country) ? $this->calculateTax($taxesInternationales, $frais) : $this->calculateTax($taxesNationales, $frais);
@ -974,24 +942,19 @@ class iLinkTransactionController extends Controller
'net_final' => $this->toMoneyWithCurrency($montantDepot, $init_country, $final_country), 'fees' => $this->toMoney($frais + $taxe, $init_country), 'init_country' => $this->getCountryName($init_country),
'final_country' => $this->getCountryName($final_country), 'user_code' => $request->user_code]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail_to_recipient'));
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
}
$response_message = ($message . trans('messages.sent_by_mail_to_recipient'));
break;
case 15: // Agent - Envoi de cash vers autre wallet
$this->validate($request, array_merge($transaction->cash_cash_rules(), [
'id_destinataire' => 'required'
]));
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
if ($request->montant > $walletAgent->balance_princ)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 422);
//Verification des limites reglementaires
$rep = $this->checkReguationsLimits($request->id_document_emetteur, $init_country, $request->final_country, $transaction->montant, true);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkReguationsLimits($request->id_document_emetteur, $init_country, $request->final_country, $transaction->montant, true);
$frais = ($init_country != $request->final_country) ? $this->calculateFees($plr_agent_depot_autre_wallet, $request->montant) : $this->calculateFees($plr_agent_depot_autre_wallet_national, $request->montant);
$taxe = ($init_country != $request->final_country) ? $this->calculateTax($taxesInternationales, $frais) : $this->calculateTax($taxesNationales, $frais);
@ -1040,20 +1003,17 @@ class iLinkTransactionController extends Controller
'final_country' => $this->getCountryName($request->final_country), 'receiver_code' => $request->id_destinataire, 'network' => $this->getNetworkName($transaction->network_destinataire),
'sender_name' => $request->prenom_emetteur . ' ' . $request->nom_emetteur, 'receiver_name' => $request->prenom_destinataire . ' ' . $request->nom_destinataire,]);
$this->sendMail($request->email_emetteur, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
}
$response_message = ($message . trans('messages.sent_by_mail'));
break;
case 16: // Agent - Envoi de cash vers une carte visa
$this->validate($request, $transaction->card_rules());
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
if ($request->montant > $walletAgent->balance_princ)
return $this->errorResponse(trans('errors.insufficient_balance'));
$expiration_date = \DateTime::createFromFormat('m/y', $request->expiration_date);
throw new Exception(trans('errors.insufficient_balance'), 422);
$expiration_date = DateTime::createFromFormat('m/y', $request->expiration_date);
if (!$expiration_date)
$expiration_date = new \DateTime();
$expiration_date = new DateTime();
$transaction->expiration_date = $expiration_date;
$transaction->final_country = $init_country;
@ -1108,26 +1068,21 @@ class iLinkTransactionController extends Controller
$walletHyperviseur->save();
$transaction->id_transaction = $this->getTransactionID();
$transaction->save();
return $this->successResponse(trans('messages.successful_transaction'));
$response_message = (trans('messages.successful_transaction'));
} else {
return $this->errorResponse(trans('errors.visa_api_failed'), Response::HTTP_INTERNAL_SERVER_ERROR);
}
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
throw new Exception(trans('errors.visa_api_failed'), Response::HTTP_INTERNAL_SERVER_ERROR);
}
break;
case 17: // Agent - Envoi de cash vers cash
$this->validate($request, $transaction->cash_cash_rules());
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if ($this->checkPassword($request->password, $agent->encrypted_password, $agent->salt)) {
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
if ($request->montant > $walletAgent->balance_princ)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 422);
//Verification des limites reglementaires
$rep = $this->checkReguationsLimits($request->id_document_emetteur, $init_country, $request->final_country, $transaction->montant, true);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkReguationsLimits($request->id_document_emetteur, $init_country, $request->final_country, $transaction->montant, true);
$frais = ($init_country != $request->final_country) ? $this->calculateFees($plr_agent_cash_cash, $request->montant) : $this->calculateFees($plr_agent_cash_cash_national, $request->montant);
$taxe = ($init_country != $request->final_country) ? $this->calculateTax($taxesInternationales, $frais) : $this->calculateTax($taxesNationales, $frais);
@ -1177,7 +1132,7 @@ class iLinkTransactionController extends Controller
$transaction->status_reseau_payeur = 'EN_COURS';
$result = $this->sendFrame($this->PAYING_NETWORK_SIMULATOR_SEND_FRAME_URL, $transaction);
if ($result->getStatusCode() != 200)
return $this->errorResponse(trans('errors.unexpected_error'));
throw new Exception(trans('errors.unexpected_error'));
}
@ -1216,10 +1171,7 @@ class iLinkTransactionController extends Controller
'final_country' => $this->getCountryName($request->final_country), 'code' => wordwrap($code_retrait, 4, ' ', true),
'network' => $this->getNetworkName($transaction->network_destinataire)]);
$this->sendMail($request->email_emetteur, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
} else {
return $this->errorResponse(trans('messages.incorrect_user_password'));
}
$response_message = ($message . trans('messages.sent_by_mail'));
break;
/**
@ -1305,30 +1257,29 @@ class iLinkTransactionController extends Controller
'prenom_destinataire' => 'required',
]);
$agent = AgentPlus::findOrFail($network_agent->agent_id);
if (!$this->checkPassword($request->password, $agent->encrypted_password, $agent->salt))
return $this->errorResponse(trans('messages.incorrect_user_password'));
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
if ($request->montant > $walletAgent->balance_princ)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'), 422);
//Verifier si la banque est associée au reseau
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)->where('id_operator_country', $request->id_bank)->first();
if (!$network_bank)
return $this->errorResponse(trans('errors.bank_not_associated_with_network'));
throw new Exception(trans('errors.bank_not_associated_with_network'));
if ($network_bank->operators_country->operator->type != 'bank')
return $this->errorResponse(trans('errors.not_banking_operator'));
throw new Exception(trans('errors.not_banking_operator'));
//Verifier le code IBAN
$country_code = $network_bank->network->country->code_country;
$bank_code = $network_bank->operators_country->code;
switch ($this->checkIBAN($request->iban, $country_code, $bank_code)) {
case 0:
return $this->errorResponse(trans('errors.invalid_iban'));
throw new Exception(trans('errors.invalid_iban'));
case 1:
return $this->errorResponse(trans('errors.country_not_match_iban'));
throw new Exception(trans('errors.country_not_match_iban'));
case 2:
return $this->errorResponse(trans('errors.bank_not_match_iban'));
throw new Exception(trans('errors.bank_not_match_iban'));
}
$transaction->frais = $frais = 0;
@ -1363,7 +1314,8 @@ class iLinkTransactionController extends Controller
'net' => $this->toMoney($transaction->montant, $init_country), 'iban' => $request->iban, 'fees' => $this->toMoney($frais, $init_country), 'sender_name' => $request->prenom_emetteur . ' ' . $request->nom_emetteur,
'sender_code' => $codeGenerer->code_membre, 'bank' => $transaction->bank, 'country' => $transaction->country]);
$this->sendMail($request->email_emetteur, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
break;
/**
* @OA\Schema(
@ -1419,21 +1371,20 @@ class iLinkTransactionController extends Controller
'no_facture' => 'required',
]);
$user = $walletUser->user;
if (!$this->checkPassword($request->password, $user->encrypted_password, $user->salt))
return $this->errorResponse(trans('messages.incorrect_user_password'));
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
if ($request->montant > $walletUser->balance)
return $this->errorResponse(trans('errors.insufficient_balance'));
throw new Exception(trans('errors.insufficient_balance'));
//Verifier si l'operateur est associée au reseau
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)->where('id_operator_country', $request->id_operator)->first();
if (!$network_bank)
return $this->errorResponse(trans('errors.operator_not_associated_with_network'));
throw new Exception(trans('errors.operator_not_associated_with_network'));
if ($network_bank->operators_country->operator->type != $request->type_operator) {
$type_operator = TypeOperator::where('code', $request->type_operator)->firstOrFail();
$type = app()->isLocale('en') ? $type_operator->description_en : $type_operator->description_fr;
return $this->errorResponse(trans('errors.not_matching_operator', ['type_operator' => $type]));
throw new Exception(trans('errors.not_matching_operator', ['type_operator' => $type]));
}
@ -1466,7 +1417,8 @@ class iLinkTransactionController extends Controller
'net' => $this->toMoney($transaction->montant, $init_country), 'no_facture' => $request->no_facture, 'fees' => $this->toMoney($frais, $init_country),
'sender_code' => $user->user_code, 'operator' => $transaction->operator, 'type_operator' => $transaction->type_operator]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
break;
/**
* @OA\Schema(
@ -1501,34 +1453,31 @@ class iLinkTransactionController extends Controller
// ]);
$user = $walletUser->user;
if (!$this->checkPassword($request->password, $user->encrypted_password, $user->salt))
return $this->errorResponse(trans('messages.incorrect_user_password'));
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
$rep = $this->checkUserIdentification($user->id);
if ($rep instanceof JsonResponse)
return $rep;
$this->checkUserIdentification($user->id);
if (!(isset($user->iban) && isset($user->id_bank_country)))
return $this->errorResponse(trans('errors.wallet_not_linked_to_bank_account'));
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'));
//Reverifier si l'operateur est toujours associé au reseau
$network_bank = NetworksOperator::where('id_network', $transaction->network_emetteur)->where('id_operator_country', $user->id_bank_country)->first();
if (!$network_bank)
return $this->errorResponse(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
if ($network_bank->operators_country->operator->type != 'bank')
return $this->errorResponse(trans('errors.not_banking_operator') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.not_banking_operator') . '. ' . trans('errors.update_banking_information'));
//Reverifier le code IBAN correspond toujours
$country_code = $network_bank->network->country->code_country;
$bank_code = $network_bank->operators_country->code;
switch ($this->checkIBAN($user->iban, $country_code, $bank_code)) {
case 0:
return $this->errorResponse(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
case 1:
return $this->errorResponse(trans('errors.country_not_match_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.country_not_match_iban') . '. ' . trans('errors.update_banking_information'));
case 2:
return $this->errorResponse(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
throw new Exception(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
}
// Envoyer la trame vers banque pour debiter le compte client et recharger le compte bancaire de iLink
@ -1561,10 +1510,23 @@ class iLinkTransactionController extends Controller
'net' => $this->toMoney($transaction->montant, $init_country), 'iban' => $user->iban, 'fees' => $this->toMoney($frais, $init_country),
'sender_code' => $user->user_code, 'bank' => $transaction->bank, 'country' => $transaction->country]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
return $this->successResponse($message . trans('messages.sent_by_mail'));
$response_message = ($message . trans('messages.sent_by_mail'));
break;
default:
$response_message = "Default response message";
}
DB::commit();
return $this->successResponse($response_message);
} catch (Throwable $e) {
DB::rollBack();
if ($e instanceof ValidationException) {
throw $e;
}
Log::error($e->getMessage() . "\n" . $e->getTraceAsString());
return $this->errorResponse($e->getMessage(), $e->getCode());
}
}
public function lastUserTransactions($id_user)
@ -1980,6 +1942,10 @@ class iLinkTransactionController extends Controller
}
//Verfier les limites reglementaires
/**
* @throws Exception
*/
public function checkReguationsLimits($identifiant, $init_country, $final_country, $montant_transaction, $is_id_document_emetteur = false)
{
@ -1996,8 +1962,8 @@ class iLinkTransactionController extends Controller
$max_jour = ($init_country == $final_country) ? $regulation->montant_max_jour_national : $regulation->montant_max_jour_international;
$amount_admitted = $max_jour - $daily_sum;
if (($daily_sum + $montant_transaction) > $max_jour)
return $this->errorResponse(($init_country == $final_country) ? trans('errors.national_daily_regulations_limits_reached') : trans('errors.international_daily_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''));
throw new Exception(($init_country == $final_country) ? trans('errors.national_daily_regulations_limits_reached') : trans('errors.international_daily_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''), 500);
// Total montants hebdomadaire
if ($is_id_document_emetteur)
@ -2007,8 +1973,8 @@ class iLinkTransactionController extends Controller
$max_hebdo = ($init_country == $final_country) ? $regulation->montant_max_hebdo_national : $regulation->montant_max_hebdo_international;
$amount_admitted = $max_hebdo - $weekly_sum;
if (($weekly_sum + $montant_transaction) > $max_hebdo)
return $this->errorResponse(($init_country == $final_country) ? trans('errors.national_weekly_regulations_limits_reached') : trans('errors.international_weekly_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''));
throw new Exception(($init_country == $final_country) ? trans('errors.national_weekly_regulations_limits_reached') : trans('errors.international_weekly_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''), 500);
// Total montants mensuel
@ -2019,8 +1985,8 @@ class iLinkTransactionController extends Controller
$max_mensuel = ($init_country == $final_country) ? $regulation->montant_max_mensuel_national : $regulation->montant_max_mensuel_international;
$amount_admitted = $max_mensuel - $monthly_sum;
if (($monthly_sum + $montant_transaction) > $max_mensuel)
return $this->errorResponse(($init_country == $final_country) ? trans('errors.national_monthly_regulations_limits_reached') : trans('errors.international_monthly_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''));
throw new Exception(($init_country == $final_country) ? trans('errors.national_monthly_regulations_limits_reached') : trans('errors.international_monthly_regulations_limits_reached') . ' '
. ($amount_admitted > 0 ? trans('errors.regulations_limits_amount_transaction', ['amount' => $this->toMoney($amount_admitted, $init_country)]) : ''), 500);
}

View File

@ -164,6 +164,11 @@ class ConfigWallet extends Model
return $this->hasMany(PaliersConfigWallet::class, 'idConfig');
}
public function paliers_commissions_wallets()
{
return $this->hasMany(PaliersCommissionWallet::class, 'idConfig');
}
public function paliers_config_nano_credits()
{
return $this->hasMany(PaliersConfigNanoCredit::class, 'idConfig');

View File

@ -0,0 +1,11 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PaliersCommissionWallet extends Model
{
protected $table = 'paliers_commissions_wallet';
protected $guarded = ['id'];
}

View File

@ -217,8 +217,8 @@ class WalletIlinkTransaction extends Model
public function cash_cash_rules()
{
return [
'final_country' => 'required|integer|min:0|not_in:0',
'network_destinataire' => 'required|integer|min:0|not_in:0',
'final_country' => 'required|integer|exists:countries,id',
'network_destinataire' => 'required|integer|exists:networks,id',
'nom_emetteur' => 'required',
'prenom_emetteur' => 'required',
'type_document_emetteur' => 'required',
@ -240,23 +240,23 @@ class WalletIlinkTransaction extends Model
/// User Operation rules
public function send_wallet_wallet_rules(){
return [
'final_country' =>'required|integer|min:0|not_in:0',
'final_country' => 'required|integer|exists:countries,id',
'type_document_destinataire' => 'required',
// 'id_document_destinataire'=>'required',
'id_destinataire' => 'required_without:phone_destinataire',
'network_destinataire'=>'required|integer|min:0|not_in:0',
'network_destinataire' => 'required|integer|exists:networks,id',
];
}
public function send_wallet_cash_rules(){
return [
'final_country' =>'required|integer|min:0|not_in:0',
'final_country' => 'required|integer|exists:countries,id',
'nom_destinataire' => 'required',
'prenom_destinataire' => 'required',
'type_document_destinataire' => 'required',
// 'id_document_destinataire'=>'required',
'id_destinataire' => 'required_without:phone_destinataire',
'network_destinataire'=>'required|integer|min:0|not_in:0',
'network_destinataire' => 'required|integer|exists:networks,id',
];
}
}

View File

@ -34,6 +34,9 @@ trait ApiResponser
public function errorResponse($message, $code = Response::HTTP_BAD_REQUEST)
{
if ($code == 0) {
$code = Response::HTTP_BAD_REQUEST;
}
return response()->json($this->formatResponse($code, null, $message), $code);
}

View File

@ -29,6 +29,7 @@ use Brick\Money\ExchangeRateProvider\PDOProvider;
use Brick\Money\ExchangeRateProvider\PDOProviderConfiguration;
use Brick\Money\Money;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
@ -531,16 +532,20 @@ trait Helper
}
// Verifier l'identification d'un utilisateur à partir de son id
/**
* @throws Exception
*/
public function checkUserIdentification($id_user)
{
$identification = Identification::where('id_user', $id_user)->first();
if (isset($identification)) {
if ($identification->status == 0)
return $this->errorResponse(trans('errors.validation_user_identification_required'));
throw new Exception(trans('errors.validation_user_identification_required'), 422);
else
return $identification;
} else {
return $this->errorResponse(trans('errors.user_identification_required'));
throw new Exception(trans('errors.user_identification_required'), 422);
}
}
@ -568,4 +573,14 @@ trait Helper
return $pdf;
}
/**
* @throws Exception
*/
public function validatePassword($password, $encrypted_password, $salt)
{
if (!$this->checkPassword($password, $encrypted_password, $salt)) {
throw new Exception(trans('messages.incorrect_user_password'), 422);
}
}
}

View File

@ -109,7 +109,7 @@ $app->register(Illuminate\Mail\MailServiceProvider::class);
$app->register(\SwaggerLume\ServiceProvider::class);
$app->register(Maatwebsite\Excel\ExcelServiceProvider::class);
$app->register(\Barryvdh\DomPDF\ServiceProvider::class);
$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);
/*
|--------------------------------------------------------------------------
| Load The Application Routes

View File

@ -6,17 +6,18 @@
"type": "project",
"require": {
"php": "^7.3|^8.0",
"ext-json": "*",
"barryvdh/laravel-dompdf": "^0.9.0",
"brick/money": "^0.5.2",
"darkaonline/swagger-lume": "^8.0",
"flipbox/lumen-generator": "^9.1",
"guzzlehttp/guzzle": "^7.0.1",
"illuminate/mail": "^8.62",
"laravel/legacy-factories": "^1.1",
"laravel/lumen-framework": "^8.0",
"maatwebsite/excel": "^3.1",
"simplesoftwareio/simple-qrcode": "^4.2",
"twilio/sdk": "^6.28",
"ext-json": "*"
"twilio/sdk": "^6.28"
},
"require-dev": {
"fzaninotto/faker": "^1.9.1",

310
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "634654b92540c00e468be0b92031e6cd",
"content-hash": "04c333a4ed5959dbda293a3fdc8f6944",
"packages": [
{
"name": "bacon/bacon-qr-code",
@ -242,6 +242,73 @@
],
"time": "2021-04-03T20:56:48+00:00"
},
{
"name": "classpreloader/classpreloader",
"version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/ClassPreloader/ClassPreloader.git",
"reference": "af9284543aedb45ed58359374918141c0ac7ae34"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/af9284543aedb45ed58359374918141c0ac7ae34",
"reference": "af9284543aedb45ed58359374918141c0ac7ae34",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"nikic/php-parser": "^4.10.3",
"php": "^7.0.8 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"graham-campbell/analyzer": "^2.4.3 || ^3.0.4",
"phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19"
},
"type": "library",
"autoload": {
"psr-4": {
"ClassPreloader\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com"
},
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk"
}
],
"description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case",
"keywords": [
"autoload",
"class",
"preload",
"preloader"
],
"support": {
"issues": "https://github.com/ClassPreloader/ClassPreloader/issues",
"source": "https://github.com/ClassPreloader/ClassPreloader/tree/4.2.0"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/classpreloader/classpreloader",
"type": "tidelift"
}
],
"time": "2021-08-28T21:56:17+00:00"
},
{
"name": "darkaonline/swagger-lume",
"version": "8.0",
@ -930,6 +997,54 @@
},
"time": "2020-06-29T00:56:53+00:00"
},
{
"name": "flipbox/lumen-generator",
"version": "9.1.0",
"source": {
"type": "git",
"url": "https://github.com/flipboxstudio/lumen-generator.git",
"reference": "ee8e6a4feeb751369a3bbf998491143a68989be9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/flipboxstudio/lumen-generator/zipball/ee8e6a4feeb751369a3bbf998491143a68989be9",
"reference": "ee8e6a4feeb751369a3bbf998491143a68989be9",
"shasum": ""
},
"require": {
"classpreloader/classpreloader": "^3.0|^4.0|^4.2",
"illuminate/console": "^5.5|^6.0|^7.0|^8.0|^8.17|^9.0",
"illuminate/filesystem": "^5.5|^6.0|^7.0|^8.0|^8.17|^9.0",
"illuminate/support": "^5.5|^6.0|^7.0|^8.0|^8.17|^9.0",
"psy/psysh": "0.9.*|0.10.*|0.11.*",
"symfony/var-dumper": "^4.2|^4.3|^5.0|^5.1|^5.2|^6.0"
},
"suggest": {
"anik/form-request": "Required to use form request in Lumen."
},
"type": "library",
"autoload": {
"psr-4": {
"Flipbox\\LumenGenerator\\": "src/LumenGenerator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Krisan Alfa Timur",
"email": "krisan47@gmail.com"
}
],
"description": "A Lumen Generator You Are Missing",
"support": {
"issues": "https://github.com/flipboxstudio/lumen-generator/issues",
"source": "https://github.com/flipboxstudio/lumen-generator/tree/9.1.0"
},
"time": "2022-03-26T00:47:39+00:00"
},
{
"name": "graham-campbell/result-type",
"version": "v1.0.2",
@ -3898,6 +4013,62 @@
},
"time": "2018-02-13T20:26:39+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.13.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=7.0"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
},
"bin": [
"bin/php-parse"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.9-dev"
}
},
"autoload": {
"psr-4": {
"PhpParser\\": "lib/PhpParser"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0"
},
"time": "2021-09-20T12:20:58+00:00"
},
{
"name": "opis/closure",
"version": "3.6.2",
@ -4629,6 +4800,84 @@
},
"time": "2017-10-23T01:57:42+00:00"
},
{
"name": "psy/psysh",
"version": "v0.11.2",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "7f7da640d68b9c9fec819caae7c744a213df6514"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/7f7da640d68b9c9fec819caae7c744a213df6514",
"reference": "7f7da640d68b9c9fec819caae7c744a213df6514",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-tokenizer": "*",
"nikic/php-parser": "^4.0 || ^3.1",
"php": "^8.0 || ^7.0.8",
"symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4",
"symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4"
},
"conflict": {
"symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.2",
"hoa/console": "3.17.05.02"
},
"suggest": {
"ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
"ext-pdo-sqlite": "The doc command requires SQLite to work.",
"ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
"ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.",
"hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit."
},
"bin": [
"bin/psysh"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "0.11.x-dev"
}
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"Psy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Justin Hileman",
"email": "justin@justinhileman.info",
"homepage": "http://justinhileman.com"
}
],
"description": "An interactive shell for modern PHP.",
"homepage": "http://psysh.org",
"keywords": [
"REPL",
"console",
"interactive",
"shell"
],
"support": {
"issues": "https://github.com/bobthecow/psysh/issues",
"source": "https://github.com/bobthecow/psysh/tree/v0.11.2"
},
"time": "2022-02-28T15:28:54+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
@ -8039,62 +8288,6 @@
],
"time": "2020-11-13T09:40:50+00:00"
},
{
"name": "nikic/php-parser",
"version": "v4.13.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/50953a2691a922aa1769461637869a0a2faa3f53",
"reference": "50953a2691a922aa1769461637869a0a2faa3f53",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=7.0"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
},
"bin": [
"bin/php-parse"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.9-dev"
}
},
"autoload": {
"psr-4": {
"PhpParser\\": "lib/PhpParser"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.13.0"
},
"time": "2021-09-20T12:20:58+00:00"
},
{
"name": "phar-io/manifest",
"version": "2.0.3",
@ -9874,7 +10067,8 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^7.3|^8.0"
"php": "^7.3|^8.0",
"ext-json": "*"
},
"platform-dev": [],
"plugin-api-version": "2.1.0"