add new fields account_number and bank_code on users_banking_account_verification table

This commit is contained in:
root 2026-02-20 17:16:41 +01:00
parent e5f5998d97
commit dd4836e49f
9 changed files with 151 additions and 66 deletions

View File

@ -541,53 +541,68 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
$user = User::findOrFail($request->id_user); $user = User::findOrFail($request->id_user);
if (isset($user->iban) && isset($user->id_bank_country)) // 1. Vérifier si l'utilisateur est identifié
return $this->errorResponse(trans('errors.wallet_already_linked_to_bank_account'));
//Verifier si l'utilisateur est identifié
$this->checkUserIdentification($user->id); $this->checkUserIdentification($user->id);
//Verifier si la banque est associée au reseau // 2. Vérifier si la banque est associée au réseau
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)->where('id_operator_country', $request->id_bank)->first(); $network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)
if (!$network_bank) ->where('id_operator_country', $request->id_bank)
->first();
if (!$network_bank) {
return $this->errorResponse(trans('errors.bank_not_associated_with_network')); return $this->errorResponse(trans('errors.bank_not_associated_with_network'));
}
if ($network_bank->operators_country->operator->type != 'bank') if ($network_bank->operators_country->operator->type != 'bank') {
return $this->errorResponse(trans('errors.not_banking_operator')); return $this->errorResponse(trans('errors.not_banking_operator'));
}
//Verifier le code IBAN // Récupérer toutes les demandes pour cet utilisateur et cet opérateur
// $country_code = $network_bank->network->country->code_country; $existingRequests = UsersBankingAccountVerification::where('id_user', $user->id)
// $bank_code = $network_bank->operators_country->code; ->where('id_bank_country', $request->id_bank)
// switch ($this->checkIBAN($request->iban, $country_code, $bank_code)) { ->get();
// case 0:
// return $this->errorResponse(trans('errors.invalid_iban'));
// case 1:
// return $this->errorResponse(trans('errors.country_not_match_iban'));
// case 2:
// return $this->errorResponse(trans('errors.bank_not_match_iban'));
// }
$existingLinkingAccount = UsersBankingAccountVerification::where('iban', $request->iban) if ($existingRequests->isNotEmpty()) {
->where('is_verified', 1)
->first();
if ($existingLinkingAccount) // CAS 1 : Une demande est déjà validée (is_verified=1, was_treated=1) pour cet IBAN
if ($existingLinkingAccount->is_verified == 1 && $existingLinkingAccount->was_treated == 0){ $alreadyLinked = $existingRequests->where('is_verified', 1)
return $this->errorResponse(trans('errors.you_already_have_request_in_progress_for_this_account')); ->where('was_treated', 1)
}else if ($existingLinkingAccount->is_verified == 1 && $existingLinkingAccount->was_treated == 1){ ->where('iban', $request->iban)
->first();
if ($alreadyLinked) {
return $this->errorResponse(trans('errors.wallet_already_linked_to_bank_account')); return $this->errorResponse(trans('errors.wallet_already_linked_to_bank_account'));
} }
// CAS 2 : Une demande est déjà en cours de traitement (was_treated=0)
// On ne permet pas une nouvelle demande si une précédente n'est pas encore traitée
$inProgress = $existingRequests->where('was_treated', 0)
->orWhere('is_verified', 0)
->first();
if ($inProgress) {
return $this->errorResponse(trans('errors.you_already_have_request_in_progress_for_this_account'));
}
// Note : Si une demande a été traitée (was_treated=1) mais concerne un autre IBAN, le code continuera et permettra une nouvelle demande.
}
// 3. Création de la nouvelle demande de liaison
$user_banking_account_verif = new UsersBankingAccountVerification(); $user_banking_account_verif = new UsersBankingAccountVerification();
$user_banking_account_verif->id_transaction = $this->getTransactionID(); $user_banking_account_verif->id_transaction = $this->getTransactionID();
$user_banking_account_verif->iban = $request->iban; $user_banking_account_verif->iban = $request->iban;
$user_banking_account_verif->id_user = $user->id; // Ajouté pour la cohérence
$user_banking_account_verif->user_code = $user->user_code; $user_banking_account_verif->user_code = $user->user_code;
$user_banking_account_verif->id_bank_country = $request->id_bank; $user_banking_account_verif->id_bank_country = $request->id_bank;
$user_banking_account_verif->is_verified = $user_banking_account_verif->was_treated = 0; $user_banking_account_verif->is_verified = 0;
$user_banking_account_verif->was_treated = 0;
$user_banking_account_verif->id_network = $request->id_wallet_network; $user_banking_account_verif->id_network = $request->id_wallet_network;
$user_banking_account_verif->save();
return $this->successResponse(trans('messages.successful_bank_account_attachment_taken')); if ($user_banking_account_verif->save()) {
return $this->successResponse(trans('messages.successful_bank_account_attachment_taken'));
}
return $this->errorResponse(trans('errors.error_occurred'));
} }
private function getTransactionID() private function getTransactionID()
@ -776,9 +791,26 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
'id_bank_country' => $newAccount->id_operator_country, 'id_bank_country' => $newAccount->id_operator_country,
'iban' => $result['accountNumber'] ?? null 'iban' => $result['accountNumber'] ?? null
]); ]);
LOG::info('Autre compte bancaire activé pour user: ' . $request->id_user . ' numero de compte: ' . $newAccount->account_number); $message = trans('messages.user_bank_account_activated_successfully', [
'bank' => $network_bank->operators_country->operator->nom ?? 'votre banque',
'account_number' => $newAccount->account_number
]);
return $this->successResponse(trans('messages.user_bank_account_activated_successfully'), 200); // Envoi du Mail
try {
$this->sendMail($user->email, trans('messages.creation_bank_account'), $message);
} catch (\Exception $e) {
Log::error("Erreur envoi mail compte rattaché: " . $e->getMessage());
return $this->successResponse(trans('messages.user_bank_account_activated_successfully',[
'bank' => $network_bank->operators_country->operator->nom ?? 'votre banque',
'account_number' => $newAccount->account_number
]), 200);
}
return $this->successResponse(trans('messages.user_bank_account_activated_successfully',[
'bank' => $network_bank->operators_country->operator->nom ?? 'votre banque',
'account_number' => $newAccount->account_number
]), 200);
} }
Log::error('Échec API Banque User: ' . $request->id_user . ' Response: ' . $response->getBody()); Log::error('Échec API Banque User: ' . $request->id_user . ' Response: ' . $response->getBody());
@ -915,9 +947,10 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
// Mail::to($user->email)->send(new BankAccountActivated($bank_account, $name_of_account_type)); // Mail::to($user->email)->send(new BankAccountActivated($bank_account, $name_of_account_type));
} catch (\Exception $e) { } catch (\Exception $e) {
Log::error("Mail error lors de l'activation: " . $e->getMessage()); Log::error("Mail error lors de l'activation: " . $e->getMessage());
return $this->successResponse(trans('messages.user_bank_account_activated_successfully', ['bank' => 'SunEx','account_number' => $bank_account->account_number]), 200);
} }
return $this->successResponse(trans('messages.user_bank_account_activated_successfully'), 200); return $this->successResponse(trans('messages.user_bank_account_activated_successfully', ['bank' => 'SunEx','account_number' => $bank_account->account_number]), 200);
} }
return $this->errorResponse('Erreur lors de l\'activation API', 500); return $this->errorResponse('Erreur lors de l\'activation API', 500);
@ -997,16 +1030,16 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
]); ]);
$result = json_decode($response->getBody(), true); $result = json_decode($response->getBody(), true);
if (($result['status'] == 200 || $result['message'] == 'Success') && ($result['data']['clientID'] == $user_bank_account_verfication->iban)) {
if (($response->getStatusCode() == 200 || $response->getStatusCode() <= 301) && ($result['data']['accountID'] == $user_bank_account_verfication->iban)) {
$user_bank_account_verfication->update([ $user_bank_account_verfication->update([
'account_number' => $result['data']['accountID'] ?? null,
'is_verified' => 1, 'is_verified' => 1,
'was_treated' => 1 'was_treated' => 1
]); ]);
$user->update([ $user->update([
'iban' => $user_bank_account_verfication->iban, 'iban' => $user_bank_account_verfication->account_number,
'id_bank_country' => $user_bank_account_verfication->id_bank_country 'id_bank_country' => $user_bank_account_verfication->id_bank_country
]); ]);

View File

@ -19,6 +19,7 @@ use App\Models\TypeIlinkTransaction;
use App\Models\TypeOperator; use App\Models\TypeOperator;
use App\Models\User; use App\Models\User;
use App\Models\UserBankAccount; use App\Models\UserBankAccount;
use App\Models\UsersBankingAccountVerification;
use App\Models\Wallet; use App\Models\Wallet;
use App\Models\WalletAgent; use App\Models\WalletAgent;
use App\Models\WalletIlinkTransaction; use App\Models\WalletIlinkTransaction;
@ -629,13 +630,12 @@ class iLinkTransactionController extends Controller
$this->validatePassword($request->password, $user->encrypted_password, $user->salt); $this->validatePassword($request->password, $user->encrypted_password, $user->salt);
$this->checkUserIdentification($user->id); $this->checkUserIdentification($user->id);
$userBankAccount = UserBankAccount::where('id_user', $user->id) $userBankAccountVerification = UsersBankingAccountVerification::where('user_code', $user->user_code)
->where('id_operator_country', $user->id_bank_country) ->first();
->where('status', 'actived') $accountNumber = $user->iban;
->first();
if (!$userBankAccount || !$userBankAccount->account_number) { if ((!$accountNumber || !$user->id_bank_country) && !$userBankAccountVerification) {
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422); throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
} }
if ($request->montant > $walletUser->balance) { if ($request->montant > $walletUser->balance) {
@ -662,7 +662,7 @@ class iLinkTransactionController extends Controller
$transaction->network_emetteur = $network_bank->id_network; $transaction->network_emetteur = $network_bank->id_network;
$transaction->bank = $network_bank->operators_country->operator->nom; $transaction->bank = $network_bank->operators_country->operator->nom;
$transaction->country = $network_bank->operators_country->country->name; $transaction->country = $network_bank->operators_country->country->name;
$transaction->iban = $userBankAccount->account_number; $transaction->iban = $accountNumber;
$transaction->date = $this->getCurrentTime($init_country); $transaction->date = $this->getCurrentTime($init_country);
// --- DÉBUT DE LA TRANSACTION DB --- // --- DÉBUT DE LA TRANSACTION DB ---
@ -685,11 +685,11 @@ class iLinkTransactionController extends Controller
// Disbursement Payload // Disbursement Payload
$payload = [ $payload = [
"clientMatricule" => $userBankAccount->customer_number, "clientMatricule" => $userBankAccountVerification->iban,
"crAccountId" => $userBankAccount->account_number, "crAccountId" => $accountNumber,
"description" => "Credit wallet sunEx vers compte bancaire", "description" => "Credit wallet sunEx vers compte bancaire",
"operationDate" => $transaction->date, "operationDate" => $transaction->date,
"operationTypeCode" => "MOMODE", "operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE' ),
"traceNo" => $transaction->id_transaction, "traceNo" => $transaction->id_transaction,
"transactionAmt" => (float)$transaction->montant "transactionAmt" => (float)$transaction->montant
]; ];
@ -713,7 +713,11 @@ class iLinkTransactionController extends Controller
$message = trans('messages.successful_user_send_to_bank', [ $message = trans('messages.successful_user_send_to_bank', [
'id_transaction' => $transaction->id_transaction, 'id_transaction' => $transaction->id_transaction,
'amount' => $this->toMoney($transaction->montant, $init_country), 'amount' => $this->toMoney($transaction->montant, $init_country),
'account_Number' => $userBankAccount->account_number 'iban' => $accountNumber,
'net' => $this->toMoney($transaction->montant, $init_country),
'sender_code' => $user->user_code,
'country' => $network_bank->operators_country->country->name,
'bank' => $network_bank->operators_country->operator->nom
]); ]);
$this->sendMail($user->email, trans('messages.successful_transaction'), $message); $this->sendMail($user->email, trans('messages.successful_transaction'), $message);
@ -1664,7 +1668,7 @@ class iLinkTransactionController extends Controller
"crAccountId" => $request->iban, //Numero de compte bancaire receveur "crAccountId" => $request->iban, //Numero de compte bancaire receveur
"description" => "Transfert Cash vers Banque - Emetteur: " . $request->prenom_emetteur . ' ' . $request->nom_emetteur, "description" => "Transfert Cash vers Banque - Emetteur: " . $request->prenom_emetteur . ' ' . $request->nom_emetteur,
"operationDate" => $transaction->date, "operationDate" => $transaction->date,
"operationTypeCode" => "MOMODE", "operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE'),
"traceNo" => $transaction->id_transaction, "traceNo" => $transaction->id_transaction,
"transactionAmt" => (float)$transaction->montant "transactionAmt" => (float)$transaction->montant
]; ];
@ -1864,19 +1868,17 @@ class iLinkTransactionController extends Controller
throw new Exception(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 //Reverifier le code IBAN correspond toujours
$country_code = $network_bank->network->country->code_country; // $country_code = $network_bank->network->country->code_country;
$bank_code = $network_bank->operators_country->code; // $bank_code = $network_bank->operators_country->code;
switch ($this->checkIBAN($user->iban, $country_code, $bank_code)) { // switch ($this->checkIBAN($user->iban, $country_code, $bank_code)) {
case 0: // case 0:
throw new Exception(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information')); // throw new Exception(trans('errors.invalid_iban') . '. ' . trans('errors.update_banking_information'));
case 1: // case 1:
throw new Exception(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: // case 2:
throw new Exception(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
// ----->
$transaction->frais = $frais = 0; $transaction->frais = $frais = 0;
$transaction->taxe = $taxe = 0; $transaction->taxe = $taxe = 0;

View File

@ -40,6 +40,8 @@ class UsersBankingAccountVerification extends Model
'id_transaction', 'id_transaction',
'user_code', 'user_code',
'iban', 'iban',
'account_number',
'bank_code',
'id_bank_country', 'id_bank_country',
'id_network', 'id_network',
'is_verified', 'is_verified',

View File

@ -354,13 +354,19 @@ trait Helper
public function generateTransactionCode() public function generateTransactionCode()
{ {
$data = random_bytes(16); try {
$data = random_bytes(16);
// Manipulation binaire pour respecter la norme UUID v4 // On modifie l'octet à la position 6 et 8 uniquement
$data = chr(ord($data) & 0x0f | 0x40); // Version 4 $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Version 4
$data = chr(ord($data) & 0x3f | 0x80); // Variante RFC 4122 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Variante RFC 4122
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); // Transformation en format UUID (8-4-4-4-12)
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
} catch (\Exception $e) {
// Fallback au cas où random_bytes échoue
return uniqid('TXN-', true);
}
} }
// Fonction de tri par date // Fonction de tri par date

View File

@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAccountNumberToUsersBankingAccountVerificationTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users_banking_account_verification', function (Blueprint $table) {
if (!Schema::hasColumn('users_banking_account_verification', 'account_number')) {
$table->string('account_number')->nullable()->after('iban');
$table->string('bank_code')->nullable()->after('account_number');
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users_banking_account_verification', function (Blueprint $table) {
if (Schema::hasColumn('users_banking_account_verification', 'account_number')) {
$table->dropColumn('account_number');
$table->dropColumn('bank_code');
}
});
}
}

View File

@ -104,5 +104,6 @@ Paying network : :network :country',
'your_previous_request_for_this_product_was_rejected' => 'Your previous request for this product was rejected', 'your_previous_request_for_this_product_was_rejected' => 'Your previous request for this product was rejected',
'your_previous_request_for_this_product_was_closed' => 'Your previous request for this product was closed', 'your_previous_request_for_this_product_was_closed' => 'Your previous request for this product was closed',
'you_already_have_request_in_progress_unvalidated' => 'You already have a request in progress that is not yet validated', 'you_already_have_request_in_progress_unvalidated' => 'You already have a request in progress that is not yet validated',
'bank_account_not_found' => 'Bank account not found',
]; ];

View File

@ -335,8 +335,9 @@ Transaction information :
- Destination account: :sender_code - Destination account: :sender_code
- Amount: :net_final", - Amount: :net_final",
'create_bank_account_linked_successfully' => 'Bank account successfully linked to your user account', 'create_bank_account_linked_successfully' => 'Bank account successfully linked to your user account',
'user_bank_account_activated_successfully' => 'User bank account activated successfully', 'user_bank_account_activated_successfully' => 'Congratulations! Your new bank account at :bank has been successfully created. Your account number :account_number is automatically linked to your wallet.',
'wallet_already_linked_to_bank_account' => 'This wallet is already linked to a bank account', 'wallet_already_linked_to_bank_account' => 'This wallet is already linked to a bank account',
'request_bank_account_pending_validation_by_administrator' => 'Your bank account creation request is pending validation by an administrator', 'request_bank_account_pending_validation_by_administrator' => 'Your bank account creation request is pending validation by an administrator',
'creation_bank_account' => 'Bank account opening',
]; ];

View File

@ -104,4 +104,5 @@ Réseau payeur : :network :country',
'your_previous_request_for_this_product_was_rejected' => 'Votre précédente demande pour ce produit a été rejetée', 'your_previous_request_for_this_product_was_rejected' => 'Votre précédente demande pour ce produit a été rejetée',
'your_previous_request_for_this_product_was_closed' => 'Votre précédente demande pour ce produit a été clôturée', 'your_previous_request_for_this_product_was_closed' => 'Votre précédente demande pour ce produit a été clôturée',
'you_already_have_request_in_progress_unvalidated' => 'Vous avez déjà une demande en cours qui n\'est pas encore validée', 'you_already_have_request_in_progress_unvalidated' => 'Vous avez déjà une demande en cours qui n\'est pas encore validée',
'bank_account_not_found' => 'Compte bancaire non trouvé',
]; ];

View File

@ -336,7 +336,8 @@ Informations de la transaction :
- Compte destinataire : :sender_code - Compte destinataire : :sender_code
- Montant : :net_final", - Montant : :net_final",
'create_bank_account_linked_successfully' => 'Compte bancaire rattaché avec succès', 'create_bank_account_linked_successfully' => 'Compte bancaire rattaché avec succès',
'user_bank_account_activated_successfully' => 'Compte bancaire activé avec succès', 'user_bank_account_activated_successfully' => 'Félicitations ! Votre nouveau compte bancaire chez :bank a été créé avec succès. Votre numéro de compte :account_number est automatiquement rattaché à votre wallet/portefeuille.',
'wallet_already_linked_to_bank_account' => 'Votre wallet est deja rattaché à votre compte bancaire', 'wallet_already_linked_to_bank_account' => 'Votre wallet est deja rattaché à votre compte bancaire',
'request_bank_account_pending_validation_by_administrator' => 'Votre demande de création de compte bancaire est en attente de validation par un administrateur', 'request_bank_account_pending_validation_by_administrator' => 'Votre demande de création de compte bancaire est en attente de validation par un administrateur',
'creation_bank_account' => 'Ouverture de compte bancaire',
]; ];