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);
if (isset($user->iban) && isset($user->id_bank_country))
return $this->errorResponse(trans('errors.wallet_already_linked_to_bank_account'));
//Verifier si l'utilisateur est identifié
// 1. Vérifier si l'utilisateur est identifié
$this->checkUserIdentification($user->id);
//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)
// 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();
if (!$network_bank) {
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'));
}
//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'));
// case 1:
// return $this->errorResponse(trans('errors.country_not_match_iban'));
// case 2:
// return $this->errorResponse(trans('errors.bank_not_match_iban'));
// }
// Récupérer toutes les demandes pour cet utilisateur et cet opérateur
$existingRequests = UsersBankingAccountVerification::where('id_user', $user->id)
->where('id_bank_country', $request->id_bank)
->get();
$existingLinkingAccount = UsersBankingAccountVerification::where('iban', $request->iban)
->where('is_verified', 1)
->first();
if ($existingRequests->isNotEmpty()) {
if ($existingLinkingAccount)
if ($existingLinkingAccount->is_verified == 1 && $existingLinkingAccount->was_treated == 0){
return $this->errorResponse(trans('errors.you_already_have_request_in_progress_for_this_account'));
}else if ($existingLinkingAccount->is_verified == 1 && $existingLinkingAccount->was_treated == 1){
// CAS 1 : Une demande est déjà validée (is_verified=1, was_treated=1) pour cet IBAN
$alreadyLinked = $existingRequests->where('is_verified', 1)
->where('was_treated', 1)
->where('iban', $request->iban)
->first();
if ($alreadyLinked) {
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->id_transaction = $this->getTransactionID();
$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->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->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()
@ -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,
'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());
@ -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));
} catch (\Exception $e) {
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);
@ -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);
if (($response->getStatusCode() == 200 || $response->getStatusCode() <= 301) && ($result['data']['accountID'] == $user_bank_account_verfication->iban)) {
if (($result['status'] == 200 || $result['message'] == 'Success') && ($result['data']['clientID'] == $user_bank_account_verfication->iban)) {
$user_bank_account_verfication->update([
'account_number' => $result['data']['accountID'] ?? null,
'is_verified' => 1,
'was_treated' => 1
]);
$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
]);

View File

@ -19,6 +19,7 @@ use App\Models\TypeIlinkTransaction;
use App\Models\TypeOperator;
use App\Models\User;
use App\Models\UserBankAccount;
use App\Models\UsersBankingAccountVerification;
use App\Models\Wallet;
use App\Models\WalletAgent;
use App\Models\WalletIlinkTransaction;
@ -629,13 +630,12 @@ class iLinkTransactionController extends Controller
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
$this->checkUserIdentification($user->id);
$userBankAccount = UserBankAccount::where('id_user', $user->id)
->where('id_operator_country', $user->id_bank_country)
->where('status', 'actived')
->first();
$userBankAccountVerification = UsersBankingAccountVerification::where('user_code', $user->user_code)
->first();
$accountNumber = $user->iban;
if (!$userBankAccount || !$userBankAccount->account_number) {
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
if ((!$accountNumber || !$user->id_bank_country) && !$userBankAccountVerification) {
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
}
if ($request->montant > $walletUser->balance) {
@ -662,7 +662,7 @@ class iLinkTransactionController extends Controller
$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->iban = $accountNumber;
$transaction->date = $this->getCurrentTime($init_country);
// --- DÉBUT DE LA TRANSACTION DB ---
@ -685,11 +685,11 @@ class iLinkTransactionController extends Controller
// Disbursement Payload
$payload = [
"clientMatricule" => $userBankAccount->customer_number,
"crAccountId" => $userBankAccount->account_number,
"clientMatricule" => $userBankAccountVerification->iban,
"crAccountId" => $accountNumber,
"description" => "Credit wallet sunEx vers compte bancaire",
"operationDate" => $transaction->date,
"operationTypeCode" => "MOMODE",
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE' ),
"traceNo" => $transaction->id_transaction,
"transactionAmt" => (float)$transaction->montant
];
@ -713,7 +713,11 @@ class iLinkTransactionController extends Controller
$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
'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);
@ -1664,7 +1668,7 @@ class iLinkTransactionController extends Controller
"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",
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE'),
"traceNo" => $transaction->id_transaction,
"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'));
//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'));
}
// $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'));
// }
// Envoyer la trame vers banque pour debiter le compte client et recharger le compte bancaire de iLink
// ----->
$transaction->frais = $frais = 0;
$transaction->taxe = $taxe = 0;

View File

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

View File

@ -354,13 +354,19 @@ trait Helper
public function generateTransactionCode()
{
$data = random_bytes(16);
try {
$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
// On modifie l'octet à la position 6 et 8 uniquement
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Version 4
$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

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_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',
'bank_account_not_found' => 'Bank account not found',
];

View File

@ -335,8 +335,9 @@ Transaction information :
- Destination account: :sender_code
- Amount: :net_final",
'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',
'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_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',
'bank_account_not_found' => 'Compte bancaire non trouvé',
];

View File

@ -336,7 +336,8 @@ Informations de la transaction :
- Compte destinataire : :sender_code
- Montant : :net_final",
'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',
'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',
];