add create bank account function

This commit is contained in:
root 2025-11-13 16:48:14 +01:00
parent 1340cc7011
commit 78ff205779
9 changed files with 360 additions and 3 deletions

View File

@ -8,6 +8,9 @@ use App\Models\User;
use App\Models\UsersBankingAccountVerification; use App\Models\UsersBankingAccountVerification;
use App\Models\WalletAgent; use App\Models\WalletAgent;
use App\Models\WalletsUser; use App\Models\WalletsUser;
use App\Models\Operator;
use App\Models\OperatorsCountry;
use App\Models\UserBankAccount;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
@ -585,4 +588,199 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
} while ($codeCorrect); } while ($codeCorrect);
return $code; return $code;
} }
/**
* @OA\Post(
* path="/wallets/users/create_bank_account",
* summary="Créer un compte bancaire pour un utilisateur simple",
* tags={"Créer un compte bancaire pour un utilisateur simple"},
* security={{"api_key":{}}},
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(property="id_user",
* type="integer",
* example=39,
* description="ID de l'utilisateur enregistré dans la base de données"
* ),
* @OA\Property(property="id_operator",
* type="integer",
* example=4,
* description="ID de la banque enregistré dans la base de données"
* ),
* @OA\Property(property="id_wallet_network",
* type="integer",
* example=243,
* description="ID du réseau auquel appartient le wallet exemple reseau Ilink World"
* ),
* @OA\Property(property="lastname",
* type="string",
* example = "Doe",
* description="Nom de famille de l'utilisateur"
* ),
* // ... Autres propriétés ici ...
* )
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : "Votre demande de création de compte bancaire a été prise en compte, vous recevrez un mail de confirmation dès lors que la banque aura validé votre demande",
* "error":null
* }
* )
* )
* )
*/
public function createUserBankAccount(Request $request)
{
$this->validate($request, [
'id_user' => 'required|integer|exists:users,id',
'id_operator' => 'required|integer|exists:operators,id',
'id_wallet_network' => 'required|integer|exists:networks,id',
'lastname' => 'required|string',
'firstname' => 'required|string',
'nationality' => 'required|string',
'birth_date' => 'required|date',
'birth_country' => 'required|string',
'birth_city' => 'required|string',
'father_firstname' => 'required|string',
'father_lastname' => 'required|string',
'mother_firstname' => 'required|string',
'mother_lastname' => 'required|string',
'marital_name' => 'nullable|string',
'marital_status' => 'nullable|string',
'profession' => 'required|string',
'sector_activity' => 'required|string',
'subsector_activity' => 'nullable|string',
'tax_number' => 'required|string',
'employee_number' => 'nullable|string',
'position' => 'nullable|string',
'employer_name' => 'nullable|string',
'employer_address' => 'nullable|string',
]);
// Vérifier que lutilisateur est identifié
$user = User::findOrFail($request->id_user);
$identification = $this->checkUserIdentification($user->id);
$operateur_country = OperatorsCountry::where('id_operator', $request->id_operator)->first();
if (!$operateur_country) {
return $this->errorResponse(trans('errors.bank_not_associated_with_network'));
}
// 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', $operateur_country->id)
->first();
if (!$network_bank) {
return $this->errorResponse(trans('errors.bank_not_associated_with_network'));
}
if ($network_bank->operators_country->operator->type != 'bank') {
return $this->errorResponse(trans('errors.not_banking_operator'));
}
$exist_user_request_create_account = UserBankAccount::where('id_user', $request->id_user)
->where('id_operator', $request->id_operator)
->first();
if (isset($exist_user_request_create_account)){
if ($exist_user_request_create_account->status == 'pending') {
return $this->errorResponse(trans('errors.request_create_account_already_sended'));
}
}
if(isset($exist_user_request_create_account)){
if ($exist_user_request_create_account->status == 'active') {
return $this->errorResponse(trans('messages.user_already_has_bank_account_with_this_operator', ['user_lastname' => $user->lastname]));
}
}
$bankAccount = new UserBankAccount();
$bankAccount->id_user = $user->id;
$bankAccount->id_operator = $request->id_operator;
$bankAccount->lastname = $request->lastname;
$bankAccount->firstname = $request->firstname;
$bankAccount->marital_name = $request->marital_name ?? 'null';
$bankAccount->nationality = $request->nationality;
$bankAccount->birth_date = $request->birth_date;
$bankAccount->birth_country = $request->birth_country;
$bankAccount->birth_city = $request->birth_city;
$bankAccount->father_firstname = $request->father_firstname;
$bankAccount->father_lastname = $request->father_lastname;
$bankAccount->mother_firstname = $request->mother_firstname;
$bankAccount->mother_lastname = $request->mother_lastname;
$bankAccount->marital_status = $request->marital_status ?? 'celibataire';
$bankAccount->profession = $request->profession;
$bankAccount->sector_activity = $request->sector_activity;
$bankAccount->subsector_activity = $request->subsector_activity ?? 'null';
$bankAccount->tax_number = $request->tax_number;
$bankAccount->employee_number = $request->employee_number;
$bankAccount->position = $request->position;
$bankAccount->employer_name = $request->employer_name ?? 'null';
$bankAccount->employer_address = $request->employer_address ?? 'null';
$bankAccount->balance = 0;
$bankAccount->status = 'pending';
$bankAccount->created_at = date('Y-m-d H:i:s');
$bankAccount->updated_at = date('Y-m-d H:i:s');
$bankAccount->save();
// Envoi des informations à la banque partenaire (via API)
// $payload = [
// 'account_number' => $bankAccount->account_number,
// 'iban' => $bankAccount->iban,
// 'swift_code' => $bankAccount->swift_code,
// 'lastname' => $bankAccount->lastname,
// 'firstname' => $bankAccount->firstname,
// 'birth_date' => $bankAccount->birth_date,
// 'nationality' => $bankAccount->nationality,
// 'birth_country' => $bankAccount->birth_country,
// 'network_code' => $network_bank->network->code ?? null,
// ];
Log::info('--- Envoi création compte bancaire à la banque partenaire ---');
// Log::info(json_encode($payload));
try {
// // Envoi à une API bancaire
// $response = Http::withHeaders([
// 'Accept' => 'application/json',
// 'Authorization' => 'Bearer ' . env('BANK_API_TOKEN'),
// ])->post(env('BANK_API_URL') . '/accounts/create', $payload);
// if ($response->failed()) {
// $bankAccount->status = 'rejected';
// $bankAccount->reason = $response->json('message') ?? 'Erreur API bancaire';
// $bankAccount->save();
// return $this->errorResponse(trans('errors.bank_api_failed'));
// }
// $bankAccount->status = 'active';
$bankAccount->reason = 'Demande de compte bancaire envoyée via API en attente de validation';
$bankAccount->save();
Log::info('Réponse API Banque: Compte bancaire créé avec succès');
} catch (\Exception $e) {
$bankAccount->status = 'rejected';
$bankAccount->reason = $e->getMessage();
$bankAccount->save();
Log::error('Erreur API Banque: ' . $e->getMessage());
return $this->errorResponse(trans('errors.bank_api_exception'));
}
return $this->successResponse([
'message' => trans('messages.successful_bank_account_creation')
]);
}
} }

View File

@ -9,6 +9,8 @@ namespace App\Models;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\UserBankAccount;
/** /**
* Class User * Class User
@ -117,4 +119,8 @@ class User extends Model
{ {
return $this->belongsTo(NetworksOperator::class, 'id_bank_country', 'id_operator_country'); return $this->belongsTo(NetworksOperator::class, 'id_bank_country', 'id_operator_country');
} }
public function bankAccounts()
{
return $this->hasMany(UserBankAccount::class);
}
} }

60
app/Models/UserBankAccount.php Executable file
View File

@ -0,0 +1,60 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use App\Models\Operator;
class UserBankAccount extends Model
{
protected $table = 'user_bank_accounts';
public $timestamps = false;
protected $fillable = [
'id_user',
'id_operator',
'account_number',
'iban',
'swift_code',
'account_type',
'balance',
'status',
'reason',
'lastname',
'firstname',
'marital_name',
'nationality',
'birth_date',
'birth_country',
'birth_city',
'father_firstname',
'father_lastname',
'mother_firstname',
'mother_lastname',
'marital_status',
'profession',
'sector_activity',
'subsector_activity',
'tax_number',
'employee_number',
'position',
'employer_name',
'employer_address',
'created_at',
'updated_at'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function bank()
{
return $this->belongsTo(Operator::class);
}
}

View File

@ -0,0 +1,82 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class CreateUserBankAccountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_bank_accounts', function (Blueprint $table) {
$table->id();
// Référence utilisateur
$table->unsignedInteger('id_user');
$table->unsignedInteger('id_operator')
->comment('Identifiant de lopérateur (banque partenaire)');
// Informations bancaires principales
$table->string('account_number')->unique()
->nullable()
->comment('Numéro de compte bancaire attribué par la banque');
$table->string('iban')->nullable()->comment('Numéro IBAN du compte si disponible');
$table->string('swift_code')->nullable()->comment('Code SWIFT/BIC de la banque');
$table->string('account_type')->nullable()->comment('Type de compte : courant, épargne, etc.');
$table->decimal('balance', 20, 2)->default(0);
$table->string('status')->default('pending')->comment('Statut du compte : pending, active, rejected, closed');
$table->string('reason')->nullable()->comment('Raison ou message en cas de rejet ou erreur API');
// Informations personnelles
$table->string('lastname')->comment('Nom de famille');
$table->string('firstname')->comment('Prénom');
$table->string('marital_name')->nullable()->comment('Nom marital si applicable');
$table->string('nationality');
$table->date('birth_date');
$table->string('birth_country')->comment('Pays de naissance');
$table->string('birth_city')->nullable()->comment('Ville de naissance');
// Parents
$table->string('father_firstname')->nullable()->comment('Prénom du père');
$table->string('father_lastname')->nullable()->comment('Nom du père');
$table->string('mother_firstname')->nullable()->comment('Prénom de la mère');
$table->string('mother_lastname')->nullable()->comment('Nom de la mère');
// Situation sociale et professionnelle
$table->enum('marital_status', ['celibataire', 'marie', 'veuf', 'divorce'])
->default('celibataire');
$table->string('profession')->nullable();
$table->string('sector_activity')->nullable();
$table->string('subsector_activity')->nullable();
$table->string('tax_number')->nullable()->comment('Numéro fiscal');
$table->string('employee_number')->nullable()->comment('Matricule employé');
$table->string('position')->nullable()->comment('Fonction ou poste occupé');
$table->string('employer_name')->nullable()->comment('Nom de lemployeur');
$table->string('employer_address')->nullable()->comment('Adresse de lemployeur');
$table->timestamps();
});
Schema::table('user_bank_accounts', function (Blueprint $table) {
$table->foreign('id_user')->references('id')->on('users')->onDelete('cascade');
$table->foreign('id_operator')->references('id')->on('operators')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('user_bank_accounts');
}
}

View File

@ -91,6 +91,8 @@ Paying network : :network :country',
'transaction_not_supported' => "This transaction is not supported", 'transaction_not_supported' => "This transaction is not supported",
'payment_invalid' => "Invalid payment", 'payment_invalid' => "Invalid payment",
'service_unavailable_in_country' => 'Service not available in this country', 'service_unavailable_in_country' => 'Service not available in this country',
'recipient_not_found' => "This recipient does not exist" 'recipient_not_found' => "This recipient does not exist",
'bank_api_exception' => 'An error occurred while creating the bank account',
'request_create_account_already_sended' => "A request to create a bank account has already been sent for this bank",
'user_not_found' => "User not found",
]; ];

View File

@ -16,6 +16,8 @@ return [
'validated_identification'=>'Validated identification', 'validated_identification'=>'Validated identification',
'identification_already_validated'=>'Identification already validated', 'identification_already_validated'=>'Identification already validated',
'successful_card_attachment' => 'Attachment of your card made', 'successful_card_attachment' => 'Attachment of your card made',
'user_already_has_bank_account_with_this_operator' => ":user_lastname already has a active bank account with this operator",
'successful_bank_account_creation' => 'The bank account creation request has been successfully sent you will be notified by email once the account is created',
'successful_identification_message' => 'Hi :name, 'successful_identification_message' => 'Hi :name,
Your identification has been taken into account. Approach an iLink World agent with your ID to validate your identity. Your identification has been taken into account. Approach an iLink World agent with your ID to validate your identity.

View File

@ -91,5 +91,8 @@ Réseau payeur : :network :country',
'transaction_not_supported' => "Cette transaction n'est pas supportée", 'transaction_not_supported' => "Cette transaction n'est pas supportée",
'payment_invalid' => "Paiement invalide", 'payment_invalid' => "Paiement invalide",
'service_unavailable_in_country' => 'Service non disponible dans ce pays', 'service_unavailable_in_country' => 'Service non disponible dans ce pays',
'recipient_not_found' => "Ce destinataire n'existe pas" 'recipient_not_found' => "Ce destinataire n'existe pas",
'bank_api_exception' => 'Une erreur est survenue lors de la création du compte bancaire',
'request_create_account_already_sended' => "Une demande de création de compte bancaire a déjà été envoyée pour cette banque",
'user_not_found' => "Utilisateur non trouvé",
]; ];

View File

@ -16,6 +16,8 @@ return [
'user_not_identificated' => 'Utilisateur non identifié', 'user_not_identificated' => 'Utilisateur non identifié',
'identification_already_validated' => 'Identification deja validée', 'identification_already_validated' => 'Identification deja validée',
'successful_card_attachment' => 'Rattachement de votre carte effectuée', 'successful_card_attachment' => 'Rattachement de votre carte effectuée',
'user_already_has_bank_account_with_this_operator' => ":user_lastname possède déjà un compte bancaire actif avec cet opérateur",
'successful_bank_account_creation' => 'La demande de création de compte bancaire a été envoyée avec succès vous serez notifié par email une fois le compte créé',
'successful_identification_message' => 'Salut :name, 'successful_identification_message' => 'Salut :name,
Votre identification a été prise en compte . Rapprochez vous d\'un agent iLink World muni de votre pièce d\'identité pour valider votre identité. Votre identification a été prise en compte . Rapprochez vous d\'un agent iLink World muni de votre pièce d\'identité pour valider votre identité.

View File

@ -72,6 +72,8 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route
$router->get('operators/{type}/{id_wallet_network}', 'WalletController@getWalletOperators'); $router->get('operators/{type}/{id_wallet_network}', 'WalletController@getWalletOperators');
$router->get('banks_for_link/{id_wallet_network}', 'WalletController@getBanksInNetworkForLink'); $router->get('banks_for_link/{id_wallet_network}', 'WalletController@getBanksInNetworkForLink');
$router->post('link_bank_account', 'WalletController@linkBankAccount'); $router->post('link_bank_account', 'WalletController@linkBankAccount');
//Creation d'un compte bancaire utilisateur (Agency Banking)
$router->post('create_user_bank_account', 'WalletController@createUserBankAccount');
}); });
}); });