Flutterwave Payments (part 1)

Lincoln munene
4 min readMay 5, 2021

Hello there, Today I will be guiding you how to add Flutterwave gateway to process checkouts or mass disbursement of funds. I will implement this using Laravel (a php framework).

To begin, you will have to create an account at https://flutterwave.com then proceed to https://dashboard.flutterwave.com/dashboard/settings/apis.

apis page

Am hoping we are together up to here. Kindly do not toggle the Switch to Test Mode unless you are certain your application is error free. So lets say your client needs to deposit into his/her account , we need to provide a form where she/he inputs the amount she needs to pay. A simple implementation of the form is as below.

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Top Up</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<form method="POST" action="/flutterwave">
@csrf
<div class="modal-body">


<div class="form-group">
<label for="message-text" class="col-form-label">Amount to add</label>
<input type="number" name="amount" class="form-control" id="message-text" required>
</div>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Top-up Flutterwave</button>
</div>
</form>
</div>
</div>
</div>

Having created our form, Lets define our routes. We need a route called “/flutterwave” as defined on our form action. This route definitely accepts only post requests . We need also to define a GET route where Flutterwave will notify the user whether the payment was successful or did fail. From the root folder of your project, Navigate to >routes>web.php then add the following code .

//This will post the amount
Route::post('flutterwave', [accountController::class, 'flutter']);
//this will get response from flutterwave
Route::get('process', [accountController::class, 'process']);

You may have noticed the words “flutter” and “process”. Flutter is a function we will define on the accountController to make a post request to the flutterwave checkout page. Below is the code implementation.

public function flutter(Request $request)
{

$amount = $request->amount;

$email=auth()->user()->email;
$name=auth()->user()->name;

$request = [
'tx_ref' => time(),
'amount' => $amount,
'currency' => 'USD',
'payment_options' => 'card',
'redirect_url' => 'https://mydomain.com/process',
'customer' => [
'email' => $email,
'name' => $name
],
'meta' => [
'price' => $amount
],
'customizations' => [
'title' => 'Account Deposit',
'description' => 'Deposit'
]
];


$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.flutterwave.com/v3/payments',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($request),
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer FLWSECK-bac826ce1c1ae62afe8953152f09-X',
'Content-Type: application/json'
),
));

$response = curl_exec($curl);
curl_close($curl);

// print_r($response);

$res = json_decode($response);

if($res->status == 'success')
{
$link = $res->data->link;
return Redirect::to($link);
// header('Location: '.$link);
}
else
{
echo 'We can not process your payment';
}
}

From the request

tx_ref -Your transaction reference. This MUST be unique for every transaction

amount-Amount to charge the customer.

currency-currency to charge in. Which in our case is USD.

payment_options-This specifies the payment options to be displayed e.g — card, mobilemoney, ussd and so on.

redirect_url-URL to redirect to when a transaction is completed. This is useful for 3DSecure payments so we can redirect your customer back to a custom page you want to show them.

We used curl to post the data to https://api.flutterwave.com/v3/payments

CURL is a computer software project providing a library and command-line tool for transferring data using various network protocols.

we need to listen for the response from the api which will be channeled through https://mydomain.com/process as defined on web.php

public function process(Request $request)
{

$status = $request->input('status');
$email=auth()->user()->email;

$tx_ref = $request->input('tx_ref');

$transaction_id = $request->input('transaction_id');

if($status == 'cancelled')
{
// echo 'YOu cancel the payment';
return redirect()->to('https://mydomain.com')->with( 'error', "Canceled deposit" );
}elseif($status == 'successful')
{
$txid = $transaction_id;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.flutterwave.com/v3/transactions/{$txid}/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"Authorization: Bearer FLWSECK-bac826ce1c1ae62e852f09-X"
),
));
$response = curl_exec($curl);

curl_close($curl);

$res = json_decode($response);
if($res->status)
{
$amountPaid = $res->data->charged_amount;
$amountToPay = $res->data->meta->price;
if($amountPaid >= $amountToPay)
{

//update the user balance

$current_balance=auth()->user()->wallet;

$new_balance=$current_balance+$amountPaid;

$update= DB::table('users')
->where('email', $email)
->update(['wallet' => $new_balance]);

if($update){
return Redirect::to('https://mydomain.com/');
}

// echo 'Payment successful';
//* Continue to give item to the user
}
else
{
echo 'Fraud transaction detected';
}
}
else
{
echo 'Can not process payment';
}
}





}

If the payment is successful ,we verify that the transaction is actually legitimate or a fake request. If status is successful ,update the necessary rows and notify the user that the payment was received.

Below is a screenshot of a successful LIVE transaction i have done using Flutterwave stk push for mpesa.

This is very similar to transacting using a card because you only change the request parameters to

$request = [
'tx_ref' => time(),
'amount' => $amount,
'currency' => 'KES',
'payment_options' => 'mpesa',
'redirect_url' => 'https://mydomain.com/process',
'customer' => [
'email' => $email,
'name' => $name
],
'meta' => [
'price' => $amount
],
'customizations' => [
'title' => 'Account Deposit',
'description' => 'Deposit'
]
];

Let me know if you face any challenges in this tutorial.

contact me via whatsapp on +254704800563 for any further explanation.

--

--