finish with debit operation
This commit is contained in:
parent
313507835c
commit
f82fd804a2
|
|
@ -55,3 +55,5 @@ BANK_API_BRANCH_CODE=99001
|
|||
|
||||
BANK_API_LOGIN=admin
|
||||
BANK_API_PASSWORD=admin
|
||||
BANK_API_OPERATION_TYPE_CODE=MOMODE
|
||||
BANK_API_CUSTOMER_REL_CODE=399
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use Illuminate\Http\Request;
|
|||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Mail\BankAccountCreatedMail;
|
||||
use App\Mail\BankAccountLinked;
|
||||
use App\Mail\BankAccountActivated;
|
||||
use App\Models\CustomerAccountType;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
|
@ -898,7 +898,7 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
'identificationNumber' => $bank_account->identification_number,
|
||||
'paySlip' => $request->doc_front,
|
||||
'signatureCard' => $request->doc_back,
|
||||
'custRelCode' => '399'
|
||||
'custRelCode' => env('BANK_API_CUSTOMER_REL_CODE', '399')
|
||||
];
|
||||
|
||||
try {
|
||||
|
|
@ -944,7 +944,7 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
LOG::info(' Compte activé avec succès ! 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));
|
||||
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);
|
||||
|
|
@ -1045,24 +1045,27 @@ INNER JOIN countries c ON oc.id_country = c.id INNER JOIN type_operators top ON
|
|||
|
||||
Log::info('Compte bancaire rattaché avec succès pour transaction: ' . $request->id_transaction);
|
||||
try {
|
||||
// Mail::to($user->email)->send(new BankAccountLinked($user_bank_account_verfication));
|
||||
Mail::to($user->email)->send(new BankAccountLinked($user_bank_account_verfication));
|
||||
} catch (\Exception $e) {
|
||||
Log::error("Mail error: " . $e->getMessage());
|
||||
return $this->successResponse(trans('messages.create_bank_account_linked_successfully'), 200);
|
||||
}
|
||||
return $this->successResponse(trans('messages.create_bank_account_linked_successfully'), 200);
|
||||
}
|
||||
|
||||
} catch (RequestException $e) {
|
||||
$errorBody = $e->hasResponse() ? (string) $e->getResponse()->getBody() : $e->getMessage();
|
||||
$decodedBody = json_decode($errorBody, true);
|
||||
$extractedMessage = $decodedBody['message'] ?? $errorBody;
|
||||
|
||||
$user_bank_account_verfication->update([
|
||||
'is_verified' => 2,
|
||||
'was_traited' => 0,
|
||||
'was_treated' => 0,
|
||||
]);
|
||||
|
||||
Log::error('Erreur API Bank Link pour transaction ' . $request->id_transaction . ' : ' . $errorBody);
|
||||
Log::error('Erreur API Bank Link pour transaction ' . $request->id_transaction . ' : ' . $extractedMessage);
|
||||
|
||||
return $this->errorResponse(trans('errors.Error_occurred'));
|
||||
return $this->errorResponse('Account: '. $request->iban . ', ' . $extractedMessage ?? trans('errors.Error_occurred'), 500);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Erreur inattendue Bank Link : ' . $e->getMessage());
|
||||
return $this->errorResponse(trans('errors.Error_occurred'));
|
||||
|
|
|
|||
|
|
@ -625,24 +625,21 @@ class iLinkTransactionController extends Controller
|
|||
'id_wallet_network' => 'required|integer|min:0|not_in:0',
|
||||
'montant' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$response_message = '';
|
||||
$user = $walletUser->user;
|
||||
$this->validatePassword($request->password, $user->encrypted_password, $user->salt);
|
||||
$this->checkUserIdentification($user->id);
|
||||
|
||||
$userBankAccountVerification = UsersBankingAccountVerification::where('user_code', $user->user_code)
|
||||
->first();
|
||||
// Vérification des prérequis
|
||||
$accountNumber = $user->iban;
|
||||
|
||||
if ((!$accountNumber || !$user->id_bank_country) && !$userBankAccountVerification) {
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
|
||||
if (!$accountNumber || !$user->id_bank_country) {
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
|
||||
}
|
||||
|
||||
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();
|
||||
|
|
@ -651,7 +648,24 @@ class iLinkTransactionController extends Controller
|
|||
throw new Exception(trans('errors.not_banking_operator'));
|
||||
}
|
||||
|
||||
// Préparation des données de transaction
|
||||
// Récupération du matricule (Customer Code)
|
||||
$verification = UsersBankingAccountVerification::where('user_code', $user->user_code)
|
||||
->where('account_number', $accountNumber)->first();
|
||||
$accountInfo = UserBankAccount::where('id_user', $user->id)
|
||||
->where('account_number', $accountNumber)->first();
|
||||
|
||||
if ($verification) {
|
||||
$customer_code = $verification->iban;
|
||||
} elseif ($accountInfo) {
|
||||
$customer_code = $accountInfo->customer_number;
|
||||
} else {
|
||||
throw new Exception(trans('errors.bank_account_not_found'), 422);
|
||||
}
|
||||
|
||||
$bankName = $network_bank->operators_country->operator->nom;
|
||||
$countryName = $network_bank->operators_country->country->name;
|
||||
|
||||
// Préparation de la transaction
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
$transaction->montant = $request->montant;
|
||||
$transaction->frais = 0;
|
||||
|
|
@ -660,76 +674,106 @@ class iLinkTransactionController extends Controller
|
|||
$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 = $accountNumber;
|
||||
$transaction->init_country = 38;
|
||||
$transaction->final_country = 38;
|
||||
$transaction->bank_account_number = $accountNumber;
|
||||
$transaction->bank_name = $bankName;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
$transaction->status = 'PENDING';
|
||||
|
||||
// --- DÉBUT DE LA TRANSACTION DB ---
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Débit provisoire du Wallet
|
||||
$oldBalance = $walletUser->balance;
|
||||
$walletUser->balance -= $transaction->montant;
|
||||
$walletUser->save();
|
||||
$transaction->save();
|
||||
|
||||
$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;
|
||||
|
||||
$authData = json_decode($authResponse->getBody(), true);
|
||||
$token = $authData['data']['token'] ?? null;
|
||||
if (!$token) throw new Exception(trans('errors.token_not_found'));
|
||||
|
||||
// Disbursement Payload
|
||||
$payload = [
|
||||
"clientMatricule" => $userBankAccountVerification->iban,
|
||||
"crAccountId" => $accountNumber,
|
||||
"description" => "Credit wallet sunEx vers compte bancaire",
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE' ),
|
||||
"traceNo" => $transaction->id_transaction,
|
||||
"transactionAmt" => (float)$transaction->montant
|
||||
];
|
||||
|
||||
// Appel API Disbursement
|
||||
$apiResponse = $client->post($baseUrl . '/account/disbursement', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'json' => $payload
|
||||
'headers' => ['Authorization' => 'Bearer ' . $token, 'Accept' => 'application/json'],
|
||||
'json' => [
|
||||
"clientMatricule" => (string)$customer_code,
|
||||
"crAccountId" => (string)$accountNumber,
|
||||
"description" => "Credit wallet sunEx vers compte bancaire",
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE'),
|
||||
"traceNo" => $transaction->id_transaction,
|
||||
"transactionAmt" => (float)$transaction->montant
|
||||
]
|
||||
]);
|
||||
|
||||
$result = json_decode($apiResponse->getBody(), true);
|
||||
|
||||
if ($apiResponse->getStatusCode() <= 301 && ($result['success'] ?? true) != false) {
|
||||
$transaction->canceled = 0;
|
||||
// Analyse de la réponse
|
||||
if ($apiResponse->getStatusCode() <= 301 && isset($result['message']) && $result['message'] == 'Success') {
|
||||
|
||||
// Sécurisation des données de retour
|
||||
$apiData = $result['data'] ?? [];
|
||||
|
||||
$transaction->status = 'Success';
|
||||
$transaction->payment_transaction_id = $apiData['transactionId'] ?? null;
|
||||
$transaction->save();
|
||||
DB::commit();
|
||||
|
||||
if(isset($accountInfo)){
|
||||
$accountInfo->balance = $apiData['realBalance'] ?? $accountInfo->balance;
|
||||
$accountInfo->save();
|
||||
}
|
||||
|
||||
// Envoi Mail
|
||||
$message = trans('messages.successful_user_send_to_bank', [
|
||||
'id_transaction' => $transaction->id_transaction,
|
||||
'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'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
|
||||
'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'iban' => $accountNumber,
|
||||
'net' => $this->toMoney($transaction->montant, $init_country),
|
||||
'sender_code' => $user->user_code,
|
||||
'country' => $countryName,
|
||||
'bank' => $bankName
|
||||
]);
|
||||
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
|
||||
|
||||
Log::info("SUCCESS: Wallet to Bank - Trx: " . $transaction->id_transaction);
|
||||
// Log de succès
|
||||
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
|
||||
Log::info($result['data']['outMessage']. ' Transaction ID: ' . $result['data']['transactionId'].' Bank Account: ' . $result['data']['accountId'] . ' -Wallet New Balance: ' . $walletUser->balance.' -Old Wallet Balance: ' . $oldBalance);
|
||||
|
||||
$response_message =
|
||||
(($apiData['outMessage'] ?? 'Success') .
|
||||
' | ID: ' . ($apiData['transactionId'] ?? 'N/A') .
|
||||
' | Bank New Balance: ' . ($apiData['realBalance'] ?? 'N/A'));
|
||||
|
||||
} else {
|
||||
throw new Exception("API Bank Refused: " . $apiResponse->getBody());
|
||||
// La banque a refusé l'opération
|
||||
DB::rollBack();
|
||||
|
||||
// Optionnel : Enregistrer l'échec en base (nécessite une nouvelle instance car le rollback a tout annulé)
|
||||
Log::warning("BANK REFUSED: " . ($result['message'] ?? 'Unknown error'));
|
||||
return $this->errorResponse($result['message'] ?? trans('errors.Error_occurred'), 400);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
Log::error("FAILED: Wallet to Bank - Error: " . $e->getMessage());
|
||||
throw new Exception(trans('errors.bank_api_exception'), 500);
|
||||
$errorMessage = $e->getMessage();
|
||||
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$response = $e->getResponse();
|
||||
$body = (string) $response->getBody();
|
||||
$result = json_decode($body, true);
|
||||
if (isset($result['message'])) {
|
||||
$errorMessage = $result['message'];
|
||||
}
|
||||
}
|
||||
Log::error("CRITICAL ERROR Wallet2Bank: " . $errorMessage);
|
||||
return $this->errorResponse($errorMessage, 500);
|
||||
}
|
||||
break;
|
||||
// case 5: //User - Envoi de carte à wallet
|
||||
|
|
@ -1599,14 +1643,16 @@ class iLinkTransactionController extends Controller
|
|||
'prenom_destinataire' => 'required',
|
||||
]);
|
||||
|
||||
$response_message = '';
|
||||
$agent = AgentPlus::findOrFail($network_agent->agent_id);
|
||||
$this->validatePassword($request->password, $agent->encrypted_password, $agent->salt);
|
||||
|
||||
// Vérifications de solde et réseau
|
||||
// 1. Vérifications de solde
|
||||
if ($request->montant > $walletAgent->balance_princ) {
|
||||
throw new Exception(trans('errors.insufficient_balance'), 422);
|
||||
}
|
||||
|
||||
// 2. Vérification réseau et banque
|
||||
$network_bank = NetworksOperator::where('id_network', $request->id_wallet_network)
|
||||
->where('id_operator_country', $request->id_bank)
|
||||
->first();
|
||||
|
|
@ -1615,7 +1661,34 @@ class iLinkTransactionController extends Controller
|
|||
throw new Exception(trans('errors.bank_not_associated_with_network'));
|
||||
}
|
||||
|
||||
// Préparation des données de la transaction
|
||||
// Récupération du matricule (Customer Code)
|
||||
$accountInfo = UserBankAccount::where('account_number', $request->iban)->first();
|
||||
$verification = UsersBankingAccountVerification::where('account_number', $request->iban)->first();
|
||||
|
||||
if ($verification) {
|
||||
$client_matricule = $verification->iban;
|
||||
$beneficiary_user = User::where('user_code', $verification->user_code)->first();
|
||||
} elseif ($accountInfo) {
|
||||
$client_matricule = $accountInfo->customer_number;
|
||||
$beneficiary_user = User::where('id', $accountInfo->id_user)->first();
|
||||
} else {
|
||||
throw new Exception(trans('errors.bank_account_not_found'), 422);
|
||||
}
|
||||
|
||||
if (!$beneficiary_user) {
|
||||
throw new Exception(trans('errors.user_not_found'), 422);
|
||||
}
|
||||
|
||||
if (!$beneficiary_user->iban && !$beneficiary_user->id_bank_country) {
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
|
||||
}
|
||||
$accout_number = $beneficiary_user->iban;
|
||||
|
||||
// Préparation des variables de texte
|
||||
$bankName = $network_bank->operators_country->operator->nom;
|
||||
$countryName = $network_bank->network->country->name;
|
||||
|
||||
// 4. Préparation de la transaction
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
$transaction->montant = $request->montant;
|
||||
$transaction->frais = 0;
|
||||
|
|
@ -1635,37 +1708,39 @@ class iLinkTransactionController extends Controller
|
|||
$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;
|
||||
$transaction->bank_name = $bankName;
|
||||
$transaction->init_country = 38;
|
||||
$transaction->final_country = 38;
|
||||
$transaction->bank_account_number = $accout_number;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
$receiver_client_matricule = UserBankAccount::where('iban', $request->iban)->first()->customer_number ?? null;
|
||||
$transaction->status = 'PENDING';
|
||||
|
||||
// --- DÉBUT DE LA TRANSACTION DB ---
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
// Débit du compte Agent (balance_princ car c'est une opération Cash)
|
||||
// Débit provisoire du Wallet Agent
|
||||
$oldBalance = $walletAgent->balance_princ;
|
||||
$walletAgent->balance_princ -= $transaction->montant;
|
||||
$walletAgent->save();
|
||||
$transaction->save();
|
||||
|
||||
$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')]
|
||||
'json' => [
|
||||
'login' => env('BANK_API_LOGIN'),
|
||||
'password' => env('BANK_API_PASSWORD')
|
||||
]
|
||||
]);
|
||||
$token = json_decode($authResponse->getBody(), true)['data']['token'] ?? null;
|
||||
$authData = json_decode($authResponse->getBody(), true);
|
||||
$token = $authData['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 de décaissement
|
||||
$payload = [
|
||||
"clientMatricule" => $receiver_client_matricule, // Matricule receveur
|
||||
"crAccountId" => $request->iban, //Numero de compte bancaire receveur
|
||||
"clientMatricule" => (string)$client_matricule,
|
||||
"crAccountId" => (string)$accout_number,
|
||||
"description" => "Transfert Cash vers Banque - Emetteur: " . $request->prenom_emetteur . ' ' . $request->nom_emetteur,
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE'),
|
||||
|
|
@ -1683,36 +1758,53 @@ class iLinkTransactionController extends Controller
|
|||
|
||||
$result = json_decode($apiResponse->getBody(), true);
|
||||
|
||||
if ($apiResponse->getStatusCode() <= 301 && ($result['success'] ?? true) != false) {
|
||||
$transaction->canceled = 0;
|
||||
// Analyse de la réponse
|
||||
if ($apiResponse->getStatusCode() <= 301 && isset($result['message']) && $result['message'] == 'Success') {
|
||||
|
||||
// Sécurisation des données de retour
|
||||
$apiData = $result['data'] ?? [];
|
||||
|
||||
$transaction->status = 'Success';
|
||||
$transaction->payment_transaction_id = $apiData['transactionId'] ?? null;
|
||||
$transaction->save();
|
||||
DB::commit();
|
||||
|
||||
// Logs et Envoi Mail
|
||||
Log::info('SUCCESS: Agent Cash to Bank - Trx: ' . $transaction->id_transaction);
|
||||
if(isset($accountInfo)){
|
||||
$accountInfo->balance = $apiData['realBalance'] ?? $accountInfo->balance;
|
||||
$accountInfo->save();
|
||||
}
|
||||
|
||||
// Envoi Mail (Commenté comme demandé pour correspondre au Case 4)
|
||||
$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
|
||||
'bank' => $bankName,
|
||||
'country' => $countryName
|
||||
]);
|
||||
|
||||
$this->sendMail($request->email_emetteur, trans('messages.successful_transaction'), $message);
|
||||
$response_message = ($message . trans('messages.sent_by_mail'));
|
||||
|
||||
Log::info($result['data']['outMessage']. ' Transaction ID: ' . $result['data']['transactionId'].' Bank Account: ' . $result['data']['accountId'] . ' -Agent New Balance: ' . $walletAgent->balance_princ.' -Old Agent Balance: ' . $oldBalance);
|
||||
|
||||
$response_message =
|
||||
(($apiData['outMessage'] ?? 'Success') .
|
||||
' | ID: ' . ($apiData['transactionId'] ?? 'N/A') .
|
||||
' | Bank New Balance: ' . ($apiData['realBalance'] ?? 'N/A'));
|
||||
|
||||
} else {
|
||||
throw new Exception("API Bank Refused: " . $apiResponse->getBody());
|
||||
// La banque a refusé l'opération
|
||||
DB::rollBack();
|
||||
|
||||
Log::warning("BANK REFUSED Agent Cash to Bank: " . ($result['message'] ?? 'Unknown error'));
|
||||
return $this->errorResponse($result['message'] ?? trans('errors.Error_occurred'), 400);
|
||||
}
|
||||
|
||||
} 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);
|
||||
Log::error("CRITICAL ERROR AgentCash2Bank: " . $e->getMessage());
|
||||
throw new Exception(trans('errors.Error_occurred'), 500);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1845,29 +1937,49 @@ class iLinkTransactionController extends Controller
|
|||
* )
|
||||
* )
|
||||
*/
|
||||
case 20: //User - Retrait de la banque vers le wallet
|
||||
|
||||
//$this->validate($request, [
|
||||
//'code_retrait' => 'required',
|
||||
//]);
|
||||
case 20: // User - Retrait de la banque vers le wallet (Bank to Wallet)
|
||||
$this->validate($request, [
|
||||
'montant' => 'required|numeric|min:1',
|
||||
'password' => 'required'
|
||||
]);
|
||||
|
||||
$response_message = '';
|
||||
$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)))
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'));
|
||||
// Vérification des prérequis de liaison
|
||||
$accountNumber = $user->iban;
|
||||
if (!$accountNumber || !$user->id_bank_country) {
|
||||
throw new Exception(trans('errors.wallet_not_linked_to_bank_account'), 422);
|
||||
}
|
||||
|
||||
//Reverifier si l'operateur est toujours associé au reseau
|
||||
$network_bank = NetworksOperator::where('id_network', $transaction->network_emetteur)->where('id_operator_country', $user->id_bank_country)->first();
|
||||
if (!$network_bank)
|
||||
$verification = UsersBankingAccountVerification::where('user_code', $user->user_code)
|
||||
->where('account_number', $accountNumber)
|
||||
->first();
|
||||
|
||||
$accountInfo = UserBankAccount::where('id_user', $user->id)
|
||||
->where('account_number', $accountNumber)
|
||||
->first();
|
||||
|
||||
if ($verification) {
|
||||
$customer_code = $verification->iban;
|
||||
} elseif ($accountInfo) {
|
||||
$customer_code = $accountInfo->customer_number;
|
||||
} else {
|
||||
throw new Exception(trans('errors.bank_account_not_found'), 422);
|
||||
}
|
||||
|
||||
// Re-vérifier si l'opérateur est toujours associé au réseau
|
||||
$network_bank = NetworksOperator::where('id_network', $transaction->network_emetteur)
|
||||
->where('id_operator_country', $user->id_bank_country)
|
||||
->first();
|
||||
|
||||
if (!$network_bank || $network_bank->operators_country->operator->type != 'bank') {
|
||||
throw new Exception(trans('errors.operator_not_associated_with_network') . '. ' . trans('errors.update_banking_information'));
|
||||
}
|
||||
|
||||
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
|
||||
// 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)) {
|
||||
|
|
@ -1879,35 +1991,134 @@ class iLinkTransactionController extends Controller
|
|||
// throw new Exception(trans('errors.bank_not_match_iban') . '. ' . trans('errors.update_banking_information'));
|
||||
// }
|
||||
|
||||
|
||||
// 4. Préparation des données de transaction
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
$transaction->montant = $request->montant;
|
||||
$transaction->frais = $frais = 0;
|
||||
$transaction->taxe = $taxe = 0;
|
||||
//$walletUser->balance += $transaction->montant;
|
||||
$transaction->commission_banque = 0;
|
||||
|
||||
$transaction->commission_hyp = 0;
|
||||
|
||||
$transaction->id_wallet_hyp = $walletHyperviseur->id;
|
||||
$transaction->frais = $frais;
|
||||
|
||||
$bankName = $network_bank->operators_country->operator->nom;
|
||||
$countryName = $network_bank->network->country->name;
|
||||
|
||||
|
||||
$transaction->init_country = 38;
|
||||
$transaction->final_country = 38;
|
||||
$transaction->bank_account_number = $accountNumber;
|
||||
$transaction->bank_name = $bankName;
|
||||
$transaction->date = $this->getCurrentTime($init_country);
|
||||
$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;
|
||||
//$walletUser->save();
|
||||
$transaction->id_transaction = $this->getTransactionID();
|
||||
//$transaction->save();
|
||||
$transaction->status = 'PENDING';
|
||||
|
||||
Log::info('-------------------------- User - Retrait de la banque vers le wallet ------------------------------------');
|
||||
Log::info(json_encode($transaction));
|
||||
Log::info('------------------------------------------------------------------------------------------------');
|
||||
|
||||
$message = trans('messages.successful_user_remove_from_bank_to_wallet',
|
||||
['id_transaction' => $transaction->id_transaction, 'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'net' => $this->toMoney($transaction->montant, $init_country), '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'));
|
||||
try {
|
||||
// Sauvegarde initiale de la transaction
|
||||
$transaction->save();
|
||||
$oldBalance = $walletUser->balance;
|
||||
|
||||
$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')
|
||||
]
|
||||
]);
|
||||
$authData = json_decode($authResponse->getBody(), true);
|
||||
$token = $authData['data']['token'] ?? null;
|
||||
|
||||
if (!$token) throw new Exception(trans('errors.token_not_found'));
|
||||
|
||||
// Payload de débit
|
||||
$payload = [
|
||||
"clientMatricule" => (string)$customer_code,
|
||||
"crAccountId" => (string)$accountNumber,
|
||||
"drAccountId" => (string)$accountNumber,
|
||||
"description" => "Retrait Banque vers Wallet SunEx",
|
||||
"operationDate" => $transaction->date,
|
||||
"operationTypeCode" => env('BANK_API_OPERATION_TYPE_CODE'),
|
||||
"traceNo" => $transaction->id_transaction,
|
||||
"transactionAmt" => (float)$transaction->montant
|
||||
];
|
||||
|
||||
$apiResponse = $client->post($baseUrl . '/account/debit', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $token,
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'json' => $payload
|
||||
]);
|
||||
|
||||
$result = json_decode($apiResponse->getBody(), true);
|
||||
|
||||
// Analyse de la réponse
|
||||
if ($apiResponse->getStatusCode() <= 301 && isset($result['message']) && $result['message'] == 'Success') {
|
||||
|
||||
// Sécurisation des données de retour
|
||||
$apiData = $result['data'] ?? [];
|
||||
|
||||
// Crédit du Wallet du user dans notre système
|
||||
$walletUser->balance += $transaction->montant;
|
||||
$walletUser->save();
|
||||
|
||||
$transaction->status = $result['message'] ?? 'SUCCESS';
|
||||
$transaction->payment_transaction_id = $apiData['transactionId'] ?? null;
|
||||
$transaction->save();
|
||||
|
||||
if(isset($accountInfo)){
|
||||
$accountInfo->balance = $apiData['realBalance'] ?? $accountInfo->balance;
|
||||
$accountInfo->save();
|
||||
}
|
||||
|
||||
// Préparation du message
|
||||
$message = trans('messages.successful_user_remove_from_bank_to_wallet', [
|
||||
'id_transaction' => $transaction->id_transaction,
|
||||
'amount' => $this->toMoney($transaction->montant, $init_country),
|
||||
'net' => $this->toMoney($transaction->montant, $init_country),
|
||||
'iban' => $accountNumber,
|
||||
'fees' => $this->toMoney($frais, $init_country),
|
||||
'sender_code' => $user->user_code,
|
||||
'bank' => $bankName,
|
||||
'country' => $countryName
|
||||
]);
|
||||
|
||||
// Envoi Mail
|
||||
$this->sendMail($user->email, trans('messages.successful_transaction'), $message);
|
||||
|
||||
Log::info($apiData['outMessage']. ' Transaction ID: ' . ($apiData['transactionId'] ?? 'N/A') . ' Bank Account: ' . ($apiData['accountId'] ?? 'N/A') . ' -Wallet New Balance: ' . $walletUser->balance . ' -Old Wallet Balance: ' . $oldBalance);
|
||||
|
||||
$response_message = (($apiData['outMessage'] ?? 'Success') .
|
||||
' | ID: ' . ($apiData['transactionId'] ?? 'N/A') .
|
||||
' | Bank New Balance: ' . ($apiData['realBalance'] ?? 'N/A'));
|
||||
|
||||
} else {
|
||||
// La banque a refusé l'opération
|
||||
DB::rollBack();
|
||||
|
||||
Log::warning("BANK REFUSED Bank to Wallet: " . ($result['message'] ?? 'Unknown error'));
|
||||
return $this->errorResponse($result['message'] ?? trans('errors.Error_occurred'), 400);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
$errorMessage = $e->getMessage();
|
||||
|
||||
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
|
||||
$response = $e->getResponse();
|
||||
$body = (string) $response->getBody();
|
||||
$result = json_decode($body, true);
|
||||
if (isset($result['message'])) {
|
||||
$errorMessage = $result['message'];
|
||||
}
|
||||
}
|
||||
|
||||
Log::error("CRITICAL ERROR Bank2Wallet: " . $errorMessage);
|
||||
return $this->errorResponse($errorMessage, 400);
|
||||
}
|
||||
break;
|
||||
|
||||
case 21: //User - Retrait de carte vers autre wallet
|
||||
|
|
@ -2125,7 +2336,7 @@ class iLinkTransactionController extends Controller
|
|||
throw $e;
|
||||
}
|
||||
Log::error($e->getMessage() . "\n" . $e->getTraceAsString());
|
||||
return $this->errorResponse($e->getMessage(), $e->getCode());
|
||||
return $this->errorResponse(trans('errors.Error_occurred'), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,7 +159,10 @@ class WalletIlinkTransaction extends Model
|
|||
'pspReference',
|
||||
'from_network_emetteur',
|
||||
'id_transaction_network_emetteur',
|
||||
'montant_commission'
|
||||
'montant_commission',
|
||||
'status',
|
||||
'bank_account_number',
|
||||
'bank_name'
|
||||
];
|
||||
|
||||
public function country()
|
||||
|
|
|
|||
Loading…
Reference in New Issue