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\WalletAgent;
use App\Models\WalletsUser;
use App\Models\Operator;
use App\Models\OperatorsCountry;
use App\Models\UserBankAccount;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
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);
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 Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\UserBankAccount;
/**
* Class User
@ -117,4 +119,8 @@ class User extends Model
{
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",
'payment_invalid' => "Invalid payment",
'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',
'identification_already_validated'=>'Identification already validated',
'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,
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",
'payment_invalid' => "Paiement invalide",
'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é',
'identification_already_validated' => 'Identification deja validé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,
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('banks_for_link/{id_wallet_network}', 'WalletController@getBanksInNetworkForLink');
$router->post('link_bank_account', 'WalletController@linkBankAccount');
//Creation d'un compte bancaire utilisateur (Agency Banking)
$router->post('create_user_bank_account', 'WalletController@createUserBankAccount');
});
});