Simple Payroll system for a single transfer using Flutterwave’s Rave PHP SDK

So today we will be focusing on how to integrate Rave’s PHP SDK into a payroll system. This concept can be applied to any application using the Rave’s PHP SDK but our focus would be a payroll system which performs a single transfer. The system can be found here. You should download the starter files for this project here.

single transfer using rave


The requirements needed are -:

  • OOP PHP Knowledge
  • Your Rave account needs to be funded for the application to complete a transfer. You can read about it here.
  • A Pusher Account
  • A webhook test website. To test the webhook that will be returned from rave


  • Learn how to use rave’s PHP SDK in your PHP project
  • Learn how to handle webhooks in your PHP project
  • Learn how to use Pusher to perform real-time app notifications
  • Learn how to transfer money using Rave.

So, first of all, we download the official PHP SDK from the Flutterwave Github. This repo contains a PHP wrapper for the Flutterwave APIs which we would use in this project.

How to download the repo — we can download the project in one of 3 ways as follows:

  1. By a git clone
git clone

2. By using composer

composer require flutterwave-php-sdk

3. By manually downloading the git project here

PHP-SDK Github repository

When our download is complete. Add the Flutterwave PHP SDK to our starter files like so

Project folder showing the project structure

Rename the .env.example file to .env . Add your public key, secret key, environment and secret_hash (we will use the secret hash to set up a webhook later), like so

ENV = "staging or live"

Next, we open the class.api.php file which is the file where we would be making our API calls and include the codes to pull the API files from our PHP SDK, like so

use Flutterwave\Transfer;
project folder showing the class.api.php

For this project, we will need only the transfer API file to make transfers on our application.

Setting up a single transfer

When we open our application, it pulls the available balance and ledger balance from the rave account that matches with the public key and secret key added in the (.env) file.

Our application dashboard

A single transfer involves sending money to an individual. We have set up an empty function (singleTransfer ) in the class.api.phpfile which will be used to make calls to the flutterwave transfer API. To initiate a single transfer we add the following code to the empty function which calls the (singleTransfer) function on the rave PHP SDK.

$single = new Transfer();
$result = $single->singleTransfer($array);
$trx = json_decode($result, true);
return $trx;
project folder showing the empty single function

The $array that we pass to the (singleTranfer )function is gotten from the form data which should contain the following:

$array = array(   
'account_bank' => $bankcode,
'account_number' => $accountno,
'amount' => $amount,
'seckey' => $secretKey,
'narration' => $narration,
'currency' => "NGN",
'reference' => "rave-".time()

Below is an image showing how we collect the user data to transfer to

How we collect data from users

Results from a single transfer

We have set up pusher to send alerts across our application and will take advantage of this feature in this section. You can sign up for your own pusher account here and set it up. We will log all our responses to the console using pusher but pusher is capable of so much more.

Setting up Pusher

The API returns the following results

"status": "success",
"message": "TRANSFER-CREATED",
"data": {
"id": 542,
"account_number": "0690000044",
"bank_code": "044",
"fullname": "Mercedes Daniel",
"date_created": "2018-06-06T10:56:12.000Z",
"currency": "NGN",
"amount": 500,
"fee": 45,
"status": "NEW",
"reference": "rave-transfer-1528159847480966",
"narration": "New transfer",
"complete_message": "",
"requires_approval": 0,
"is_approved": 1,
"bank_name": "ACCESS BANK NIGERIA"

We have logged the results from the API in a console. This is made possible by using pusher which we have already set up.

The first response from the rave API

The result returned doesn’t mean that the process is complete, there are further steps to complete the process which involve setting up a webhook and a callback function.

Implementing a webhook for the single transfer

The concept of a WebHook is simple. A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST.

A web application implementing WebHooks will POST a message to a URL when certain things happen. To implement a webhook to receive notifications on the progress on our transfer, we need to set up our rave account for webhooks. Login to your rave account and navigate to the webhook section on your settings page.

Setting up a webhook on rave dashboard

Add your secret hash and URL (a link to the callback script that will process the responses from your rave account). We will now set up our callback function.

We have added a script (webhook.php). This is where we will process the responses from our rave dashboard. The URL to a hosted version of this file will be the URL of our webhook. You can also use this website to test your webhooks by copying and pasting the URL in your rave dashboard.

Add the following function to the webhook file like so

require __DIR__.'/vendor/autoload.php'; // Uncomment this autoloader if you need it
$dotenv = new Dotenv\Dotenv(__DIR__.'/include/classes/Flutterwave');
$options = array(
'cluster' => 'eu',
'encrypted' => true

$pusher = new Pusher\Pusher(

// Retrieve the request's body
$body = @file_get_contents("php://input");
// retrieve the signature sent in the reques header's.
$signature = (isset($_SERVER['HTTP_VERIF_HASH']) ? $_SERVER['HTTP_VERIF_HASH'] : '');
/* It is a good idea to log all events received. Add code *
* here to log the signature and body to db or file */
if (!$signature) {
// only a post with rave signature header gets our attention
// Store the same signature on your server as an env variable and check against what was sent in the headers
$local_signature = $_ENV['SECRET_HASH'];
// confirm the event's signature
if( $signature !== $local_signature ){
// silently forget this ever happened
http_response_code(200); // PHP 5.4 or greater
// parse event (which is json string) as object
// Give value to your customer but don't give any output
// Remember that this is a call from rave's servers and
// Your customer is not seeing the response here at all
$response = json_decode($body);
if (isset($response)) {
$data['message'] = $response;
$pusher->trigger('my-channel', 'my-event', $data);

echo '<script src=""></script>';
Pusher.logToConsole = true;
var pusher = new Pusher("084259e4e356fb9a0622", {
cluster: "eu",
forceTLS: true
var channel = pusher.subscribe("my-channel");
channel.bind("my-event", function(data) {

$data['message'] = $response;
$pusher->trigger('my-channel', 'my-event',$data);
echo '<script src=""></script>';
Pusher.logToConsole = true;
var pusher = new Pusher("084259e4e356fb9a0622", {
cluster: "eu",
forceTLS: true
var channel = pusher.subscribe("my-channel");
channel.bind("my-event", function(data) {


The webhook returns the following response which can be logged to the console

"fullname":"Forrest Green",
"narration":"Goods delivery services",
"complete_message":"DISBURSE FAILED: You have exceeded your daily frequency for this product",
"is_approved":1,"bank_name":"ACCESS BANK NIGERIA"}

This is the response from the webhook logged in the console

The final response from the rave API

From the result, we can see that our transfer is unsuccessful because we have exceeded our daily limit.

Thanks for reading

Next Article will be on using the bulk transfer features