add the api of credit operation for the wallet to bank and cash to bank transaction
This commit is contained in:
parent
752ca31428
commit
aa18ffceeb
10
.env.example
10
.env.example
|
|
@ -50,12 +50,8 @@ SENTRY_LARAVEL_DSN=https://9d6f6b6a24514295910a3b0e5bdd1449@o1053292.ingest.sent
|
|||
SENTRY_TRACES_SAMPLE_RATE=1
|
||||
|
||||
# Configuration API GBS
|
||||
BANK_API_BASE_URL=http://192.168.1.173:8084/api/v1
|
||||
BANK_API_USERNAME=sa
|
||||
BANK_API_PASSWORD=Sa123456
|
||||
BANK_API_BASE_URL=http://192.168.1.173:2087/api/v1
|
||||
BANK_API_BRANCH_CODE=99001
|
||||
# Configuration API Bank Link
|
||||
BANK_LINK_API_BASE_URL=http://192.168.1.173:2087/api/v1
|
||||
BANK_LINK_API_LOGIN=admin
|
||||
BANK_LINK_API_PASSWORD=admin
|
||||
|
||||
BANK_API_LOGIN=admin
|
||||
BANK_API_PASSWORD=admin
|
||||
|
|
|
|||
|
|
@ -736,6 +736,8 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
->first();
|
||||
|
||||
if ($differentTypeAccount) {
|
||||
$user = User::find($request->id_user);
|
||||
if (!$user) return $this->errorResponse(trans('errors.user_not_found'));
|
||||
$customer_account_type = CustomerAccountType::find($request->account_type);
|
||||
if (!$customer_account_type) return $this->errorResponse(trans('errors.account_type_not_found'));
|
||||
|
||||
|
|
@ -771,6 +773,11 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
$newAccount->status = 'actived';
|
||||
$newAccount->save();
|
||||
|
||||
$user->update([
|
||||
'id_bank_country' => $newAccount->id_operator_country,
|
||||
'iban' => $result['accountNumber'] ?? null
|
||||
]);
|
||||
|
||||
try {
|
||||
Mail::to($user->email)->send(new BankAccountActivated($newAccount, $customer_account_type->name));
|
||||
} catch (\Exception $e) {
|
||||
|
|
@ -898,6 +905,7 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
'id_bank_country' => $bank_account->id_operator_country,
|
||||
'iban' => $result['accountNumber'] ?? null
|
||||
]);
|
||||
LOG::info('Numero du compte bancaire du User : ' . $user->id . ' : ' . ($user->iban ?? 'N/A'));
|
||||
|
||||
try {
|
||||
Mail::to($user->email)->send(new BankAccountActivated($bank_account, $name_of_account_type));
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use App\Models\Regulation;
|
|||
use App\Models\TypeIlinkTransaction;
|
||||
use App\Models\TypeOperator;
|
||||
use App\Models\User;
|
||||
use App\Models\UserBankAccount;
|
||||
use App\Models\Wallet;
|
||||
use App\Models\WalletAgent;
|
||||
use App\Models\WalletIlinkTransaction;
|
||||
|
|
@ -618,75 +619,114 @@ class iLinkTransactionController extends Controller
|
|||
* )
|
||||
* )
|
||||
*/
|
||||
case 4: //User - Envoi de wallet à banque
|
||||
|
||||
case 4: // User - Envoi de wallet à banque
|
||||
$this->validate($request, [
|
||||
'id_wallet_network' => 'required|integer|min:0|not_in:0',
|
||||
'montant' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$user = $walletUser->user;
|
||||
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
|
||||
|
||||
$this->checkUserIdentification($user->id);
|
||||
|
||||
if (!(isset($user->iban) && isset($user->id_bank_country)))
|
||||
$userBankAccount = UserBankAccount::where('id_user', $user->id)
|
||||
->where('id_operator_country', $user->id_bank_country)
|
||||
->where('status', 'actived')
|
||||
->first();
|
||||
|
||||
if (!$userBankAccount || !$userBankAccount->account_number) {
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
|
||||
}
|
||||
|
||||
|
||||
if ($request->montant > $walletUser->balance)
|
||||
if ($request->montant > $walletUser->balance) {
|
||||
throw new Exception(trans('errors.insufficient_balance'), 422);
|
||||
}
|
||||
|
||||
// Vérification de l'opérateur réseau
|
||||
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)
|
||||
->where('id_operator_country', $user->id_bank_country)
|
||||
->first();
|
||||
|
||||
//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)
|
||||
throw new Exception(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
|
||||
if (!$network_bank || $network_bank->operators_country->operator->type != 'bank') {
|
||||
throw new Exception(trans('errors.not_banking_operator'));
|
||||
}
|
||||
|
||||
if ($network_bank->operators_country->operator->type != 'bank')
|
||||
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:
|
||||
// throw new Exception(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
|
||||
// case 1:
|
||||
// throw new Exception(trans('errors.country_not_match_iban') . '. ' . trans('errors.update_banking_information'));
|
||||
// case 2:
|
||||
// throw new Exception(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
|
||||
// }
|
||||
|
||||
$transaction->frais = $frais = 0;
|
||||
$transaction->taxe = $taxe = 0;
|
||||
//$walletUser->balance -= $transaction->montant;
|
||||
//Emettre une trame SSL pour recharger le compte bancaire du montant de la transaction
|
||||
$transaction->commission_banque = 0;
|
||||
|
||||
$transaction->commission_hyp = 0;
|
||||
|
||||
$transaction->id_wallet_hyp = $walletHyperviseur->id;
|
||||
$transaction->frais = $frais;
|
||||
$transaction->bank = $user->bank->operators_country->operator->nom;
|
||||
$transaction->country = $user->bank->network->country->name;
|
||||
$transaction->id_bank = $user->id_bank_country;
|
||||
$transaction->iban = $user->iban;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
//$walletUser->save();
|
||||
// Préparation des données de transaction
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
//$transaction->save();
|
||||
$transaction->montant = $request->montant;
|
||||
$transaction->frais = 0;
|
||||
$transaction->taxe = 0;
|
||||
$transaction->nom_emetteur = $user->lastname;
|
||||
$transaction->prenom_emetteur = $user->firstname;
|
||||
$transaction->email_emetteur = $user->email;
|
||||
$transaction->network_emetteur = $network_bank->id_network;
|
||||
$transaction->bank = $network_bank->operators_country->operator->nom;
|
||||
$transaction->country = $network_bank->operators_country->country->name;
|
||||
$transaction->iban = $userBankAccount->account_number;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
|
||||
Log::info('-------------------------- User - Envoi de wallet à banque ------------------------------------');
|
||||
Log::info(json_encode($transaction));
|
||||
Log::info('------------------------------------------------------------------------------------------------');
|
||||
// --- DÉBUT DE LA TRANSACTION DB ---
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Débit provisoire du Wallet
|
||||
$walletUser->balance -= $transaction->montant;
|
||||
$walletUser->save();
|
||||
|
||||
$message = trans('messages.successful_user_send_to_bank',
|
||||
['id_transaction' => $transaction->id_transaction, 'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'net' => $this->toMoney($transaction->montant, $init_country), 'iban' => $request->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);
|
||||
$response_message = ($message . trans('messages.sent_by_mail'));
|
||||
$baseUrl = env('BANK_API_BASE_URL');
|
||||
$client = new Client(['connect_timeout' => 60]);
|
||||
|
||||
// Authentification (Bearer Token)
|
||||
$authResponse = $client->post($baseUrl . '/auth/authenticate', [
|
||||
'json' => ['login' => env('BANK_API_LOGIN'), 'password' => env('BANK_API_PASSWORD')]
|
||||
]);
|
||||
$token = json_decode($authResponse->getBody(), true)['data']['token'] ?? null;
|
||||
|
||||
if (!$token) throw new Exception(trans('errors.token_not_found'));
|
||||
|
||||
// Disbursement Payload
|
||||
$payload = [
|
||||
"clientMatricule" => $userBankAccount->customer_number,
|
||||
"crAccountId" => $userBankAccount->account_number,
|
||||
"description" => "Credit wallet sunEx vers compte bancaire",
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => "MOMODE",
|
||||
"traceNo" => $transaction->id_transaction,
|
||||
"transactionAmt" => (float)$transaction->montant
|
||||
];
|
||||
|
||||
$apiResponse = $client->post($baseUrl . '/account/disbursement', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'json' => $payload
|
||||
]);
|
||||
|
||||
$result = json_decode($apiResponse->getBody(), true);
|
||||
|
||||
if ($apiResponse->getStatusCode() <= 301 && ($result['success'] ?? true) != false) {
|
||||
$transaction->canceled = 0;
|
||||
$transaction->save();
|
||||
DB::commit();
|
||||
|
||||
// Envoi Mail
|
||||
$message = trans('messages.successful_user_send_to_bank', [
|
||||
'id_transaction' => $transaction->id_transaction,
|
||||
'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'account_Number' => $userBankAccount->account_number
|
||||
]);
|
||||
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
|
||||
|
||||
Log::info("SUCCESS: Wallet to Bank - Trx: " . $transaction->id_transaction);
|
||||
} else {
|
||||
throw new Exception("API Bank Refused: " . $apiResponse->getBody());
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error("FAILED: Wallet to Bank - Error: " . $e->getMessage());
|
||||
throw new Exception(trans('errors.bank_api_exception'), 500);
|
||||
}
|
||||
break;
|
||||
// case 5: //User - Envoi de carte à wallet
|
||||
// $frais =$montant * $config->taux_com_user_carte_wallet / 100;
|
||||
|
|
@ -1543,6 +1583,7 @@ class iLinkTransactionController extends Controller
|
|||
case 18: // Agent - Envoi de cash vers banque
|
||||
$this->validate($request, [
|
||||
'iban' => 'required',
|
||||
'montant' => 'required|numeric|min:1',
|
||||
'id_wallet_network' => 'required|integer|min:0|not_in:0',
|
||||
'id_bank' => 'required|integer|min:0|not_in:0',
|
||||
'nom_emetteur' => 'required',
|
||||
|
|
@ -1553,38 +1594,29 @@ class iLinkTransactionController extends Controller
|
|||
'nom_destinataire' => 'required',
|
||||
'prenom_destinataire' => 'required',
|
||||
]);
|
||||
|
||||
$agent = AgentPlus::findOrFail($network_agent->agent_id);
|
||||
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
|
||||
|
||||
if ($request->montant > $walletAgent->balance_princ)
|
||||
// Vérifications de solde et réseau
|
||||
if ($request->montant > $walletAgent->balance_princ) {
|
||||
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)
|
||||
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)
|
||||
->where('id_operator_country', $request->id_bank)
|
||||
->first();
|
||||
|
||||
if (!$network_bank || $network_bank->operators_country->operator->type != 'bank') {
|
||||
throw new Exception(trans('errors.bank_not_associated_with_network'));
|
||||
}
|
||||
|
||||
if ($network_bank->operators_country->operator->type != 'bank')
|
||||
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:
|
||||
// throw new Exception(trans('errors.invalid_iban'));
|
||||
// case 1:
|
||||
// throw new Exception(trans('errors.country_not_match_iban'));
|
||||
// case 2:
|
||||
// throw new Exception(trans('errors.bank_not_match_iban'));
|
||||
// }
|
||||
|
||||
$transaction->frais = $frais = 0;
|
||||
$transaction->taxe = $taxe = 0;
|
||||
//$walletUser->balance -= $transaction->montant;
|
||||
//Emettre une trame SSL pour recharger le compte bancaire du montant de la transaction
|
||||
// Préparation des données de la transaction
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
$transaction->montant = $request->montant;
|
||||
$transaction->frais = 0;
|
||||
$transaction->taxe = 0;
|
||||
$transaction->commission_banque = 0;
|
||||
|
||||
$transaction->commission_hyp = 0;
|
||||
$transaction->commission_sup = 0;
|
||||
$transaction->commission_ag = 0;
|
||||
|
|
@ -1592,26 +1624,92 @@ class iLinkTransactionController extends Controller
|
|||
$transaction->id_wallet_hyp = $walletHyperviseur->id;
|
||||
$transaction->id_wallet_ag = $walletAgent->id;
|
||||
$transaction->id_wallet_sup = $walletSuperviseur->id;
|
||||
$transaction->frais = $frais;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
|
||||
$transaction->nom_emetteur = $request->nom_emetteur;
|
||||
$transaction->prenom_emetteur = $request->prenom_emetteur;
|
||||
$transaction->email_emetteur = $request->email_emetteur;
|
||||
$transaction->nom_destinataire = $request->nom_destinataire;
|
||||
$transaction->prenom_destinataire = $request->prenom_destinataire;
|
||||
|
||||
$transaction->bank = $network_bank->operators_country->operator->nom;
|
||||
$transaction->country = $network_bank->network->country->name;
|
||||
$transaction->id_bank = $request->id_bank;
|
||||
$transaction->iban = $request->iban;
|
||||
//$walletUser->save();
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
//$transaction->save();
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
$receiver_client_matricule = UserBankAccount::where('iban', $request->iban)->first()->customer_number ?? null;
|
||||
|
||||
Log::info('-------------------------- Agent - Envoi de cash vers banque ------------------------------------');
|
||||
Log::info(json_encode($transaction));
|
||||
Log::info('------------------------------------------------------------------------------------------------');
|
||||
// --- DÉBUT DE LA TRANSACTION DB ---
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Débit du compte Agent (balance_princ car c'est une opération Cash)
|
||||
$walletAgent->balance_princ -= $transaction->montant;
|
||||
$walletAgent->save();
|
||||
|
||||
$message = trans('messages.successful_agent_send_from_cash_to_bank',
|
||||
['id_transaction' => $transaction->id_transaction, 'amount' => $this->toMoney($transaction->montant, $init_country), 'receiver_name' => $request->prenom_destinataire . ' ' . $request->nom_destinataire,
|
||||
'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);
|
||||
$response_message = ($message . trans('messages.sent_by_mail'));
|
||||
$baseUrl = env('BANK_API_BASE_URL');
|
||||
$client = new Client(['connect_timeout' => 60]);
|
||||
|
||||
// Authentification Bearer
|
||||
$authResponse = $client->post($baseUrl . '/auth/authenticate', [
|
||||
'json' => ['login' => env('BANK_API_LOGIN'), 'password' => env('BANK_API_PASSWORD')]
|
||||
]);
|
||||
$token = json_decode($authResponse->getBody(), true)['data']['token'] ?? null;
|
||||
|
||||
if (!$token) throw new Exception(trans('errors.token_not_found'));
|
||||
|
||||
// Payload de décaissement (Disbursement)
|
||||
// Note: Ici le clientMatricule est souvent un matricule système ou celui de l'agent
|
||||
// s'il possède un compte banque rattaché.
|
||||
$payload = [
|
||||
"clientMatricule" => $receiver_client_matricule, // Matricule receveur
|
||||
"crAccountId" => $request->iban, //Numero de compte bancaire receveur
|
||||
"description" => "Transfert Cash vers Banque - Emetteur: " . $request->prenom_emetteur . ' ' . $request->nom_emetteur,
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => "MOMODE",
|
||||
"traceNo" => $transaction->id_transaction,
|
||||
"transactionAmt" => (float)$transaction->montant
|
||||
];
|
||||
|
||||
$apiResponse = $client->post($baseUrl . '/account/disbursement', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'json' => $payload
|
||||
]);
|
||||
|
||||
$result = json_decode($apiResponse->getBody(), true);
|
||||
|
||||
if ($apiResponse->getStatusCode() <= 301 && ($result['success'] ?? true) != false) {
|
||||
$transaction->canceled = 0;
|
||||
$transaction->save();
|
||||
DB::commit();
|
||||
|
||||
// Logs et Envoi Mail
|
||||
Log::info('SUCCESS: Agent Cash to Bank - Trx: ' . $transaction->id_transaction);
|
||||
|
||||
$message = trans('messages.successful_agent_send_from_cash_to_bank', [
|
||||
'id_transaction' => $transaction->id_transaction,
|
||||
'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'receiver_name' => $request->prenom_destinataire . ' ' . $request->nom_destinataire,
|
||||
'iban' => $request->iban,
|
||||
'sender_name' => $request->prenom_emetteur . ' ' . $request->nom_emetteur,
|
||||
'bank' => $transaction->bank,
|
||||
'country' => $transaction->country
|
||||
]);
|
||||
|
||||
$this->sendMail($request->email_emetteur, trans('messages.successful_transaction'), $message);
|
||||
$response_message = ($message . trans('messages.sent_by_mail'));
|
||||
|
||||
} else {
|
||||
throw new Exception("API Bank Refused: " . $apiResponse->getBody());
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
// D. Échec : Annulation du débit agent
|
||||
DB::rollBack();
|
||||
Log::error("FAILED: Agent Cash to Bank - Error: " . $e->getMessage());
|
||||
throw new Exception(trans('errors.bank_api_exception'), 500);
|
||||
}
|
||||
break;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -341,15 +341,26 @@ trait Helper
|
|||
return $randomString;
|
||||
}
|
||||
|
||||
public function generateTransactionCode($length = 12)
|
||||
// public function generateTransactionCode($length = 12)
|
||||
// {
|
||||
// $characters = '23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
|
||||
// $charactersLength = strlen($characters);
|
||||
// $randomString = '';
|
||||
// for ($i = 0; $i < $length; $i++) {
|
||||
// $randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||
// }
|
||||
// return $randomString;
|
||||
// }
|
||||
|
||||
public function generateTransactionCode()
|
||||
{
|
||||
$characters = '23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
|
||||
$charactersLength = strlen($characters);
|
||||
$randomString = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||
}
|
||||
return $randomString;
|
||||
$data = random_bytes(16);
|
||||
|
||||
// Manipulation binaire pour respecter la norme UUID v4
|
||||
$data = chr(ord($data) & 0x0f | 0x40); // Version 4
|
||||
$data = chr(ord($data) & 0x3f | 0x80); // Variante RFC 4122
|
||||
|
||||
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||||
}
|
||||
|
||||
// Fonction de tri par date
|
||||
|
|
|
|||
Loading…
Reference in New Issue