From e9db02fcd3a213a21e328f429c2997bee0712697 Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Fri, 3 Nov 2023 00:53:37 +0100 Subject: [PATCH] feat: replace cinetpay payout by flutterwave --- .../Controllers/FlutterwaveController.php | 100 ++++++++++++++++-- app/Http/Controllers/PaymentController.php | 7 +- 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/FlutterwaveController.php b/app/Http/Controllers/FlutterwaveController.php index 60a32fe..c30481a 100644 --- a/app/Http/Controllers/FlutterwaveController.php +++ b/app/Http/Controllers/FlutterwaveController.php @@ -10,6 +10,7 @@ use App\Models\PaymentAggregator; use App\Models\PaymentTransaction; use DateTime; use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Lang; use Illuminate\Support\Facades\Log; @@ -248,7 +249,8 @@ class FlutterwaveController extends Controller 'customer_address' => 'nullable|string', 'customer_city' => 'nullable|string', 'customer_country' => 'required|string|size:2|in:CI,SN,ML,CM,TG,BF,CD,GN,BJ', - 'reason' => 'required|string' + 'reason' => 'required|string', + 'network_name' => 'required|string', ]); $aggregator = PaymentAggregator::where('name','like','%flutterwave%')->firstOrFail(); @@ -258,14 +260,14 @@ class FlutterwaveController extends Controller $customer_surname = $request->input('customer_surname'); $customer_name = $request->input('customer_name') ?? $customer_surname; $customer_email = $request->input('customer_email'); + $networkName = strtolower($request->input('network_name')); $country_code = $request->input('customer_country'); $phoneNumber = str_replace(' ','',$request->input('customer_phone_number')); $phone = new PhoneNumber($phoneNumber, $country_code); $phoneNumber = str_replace(' ','',$phone->formatInternational()); - $nationalPhone = str_replace(' ','',$phone->formatNational()); - $phonePrefix = substr($phoneNumber, 1, strlen($phoneNumber) - strlen($nationalPhone) - 1); + $accountNumber = substr($phoneNumber,1); $amount = $request->input('amount'); $payment_method = 'WALLET'; @@ -303,8 +305,9 @@ class FlutterwaveController extends Controller "Authorization" => 'Bearer '.config('variables.flw_secret_key') ], 'json' => [ - "account_bank" => 'orangemoney', - "account_number" => $nationalPhone, + "account_bank" => str_contains($networkName,'orange') ? 'orangemoney' : 'MTN', + "account_number" => $accountNumber, + 'beneficiary_name' => $customer_surname.' '.$customer_name, 'amount' => $amount, 'narration' => $request->input('reason'), 'currency' => $request->input('currency'), @@ -342,7 +345,7 @@ class FlutterwaveController extends Controller // $errorMessage = $responseData?->description ?? $responseData?->message; }catch (Throwable $e){ - Log::error("Error CinetPay transfert payment"); + Log::error("Error Flutterwave transfert payment"); $errorMessage = $e->getMessage(); Log::error("Response data :: ".json_encode($responseData ?? '')); Log::error($errorMessage); @@ -416,4 +419,89 @@ class FlutterwaveController extends Controller return response("OK"); // } } + + // Check Balance for payout or transfer + + /** + * @throws GuzzleException + */ + public function checkBalance(Request $request) + { + $this->validate($request, [ + 'country_id' => 'required|integer|exists:countries,id', + 'amount' => 'required|numeric', + 'type' => 'nullable|string' // mobilemoney,account + ]); + + + $amount = floatval($request->input('amount')); + $type = $request->input('type', 'mobilemoney'); + $countryId = $request->input('country_id'); + $country = Country::with('currency')->where('id', $countryId)->firstOrFail(); + $currencyCode = $country->currency->code; + + + // https://flutterwavedoc.readme.io/reference/get-all-wallet-balances + $balanceResponse = (new Client())->get('https://api.flutterwave.com/v3/balances/'.$currencyCode, [ + 'headers' => [ + "Authorization" => 'Bearer '.config('variables.flw_secret_key') + ], + 'timeout' => $this->timeout, + 'http_errors' => false + ]); + + $responseCode = $balanceResponse->getStatusCode(); + $responseData = json_decode($balanceResponse->getBody()->getContents()); + if ($responseCode == 200) { + $amountAvailable = $responseData?->data?->available_balance ?? 0; + + // https://flutterwavedoc.readme.io/reference/get-transfer-fee + $fees = 0; + $feesResponse = (new Client())->get('https://api.flutterwave.com/v3/transfers/fee', [ + 'headers' => [ + "Authorization" => 'Bearer '.config('variables.flw_secret_key') + ], + 'query' => [ + 'amount' => $amount, + 'currency' => $currencyCode, + 'type' => $type + ], + 'timeout' => $this->timeout, + 'http_errors' => false + ]); + + $responseCode = $feesResponse->getStatusCode(); + $responseData = json_decode($feesResponse->getBody()->getContents()); + if ($responseCode == 200) { + $data = $responseData?->data; + if(!empty($data)){ + $fee = $data[0]->fee; + $feeType = $data[0]->fee_type; + + if($feeType == 'value'){ + $fees = $fee; + } + + if($feeType == 'percentage'){ + $fees = $amount * $fee; + } + + $amount += $fees; + + if ($amountAvailable >= $amount){ + return $this->successResponse("Solde disponible"); + }else{ + + Log::error("Solde insuffisant :: ".$amountAvailable); + return $this->errorResponse(__('errors.service_unavailable_try_later')); + } + } + } + } + $errorMessage = $responseData?->description ?? $responseData?->message; + Log::error("Error CinetPay check balance"); + Log::error("Response data :: ".json_encode($responseData ?? '')); + return $this->errorResponse($errorMessage ?? __('errors.unexpected_error')); + + } } diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 95e2ca5..1d081d6 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -8,6 +8,7 @@ use App\Models\Country; use App\Models\PaymentAggregator; use App\Models\PaymentTransaction; use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Lang; use Illuminate\Support\Facades\Log; @@ -223,9 +224,13 @@ class PaymentController extends Controller } } + /** + * @throws GuzzleException + */ public function checkBalance(Request $request) { - return app(CinetpayController::class)->checkBalance($request); +// return app(CinetpayController::class)->checkBalance($request); + return app(FlutterwaveController::class)->checkBalance($request); }