How to integrate paystack to receive payment – implemented in PHP

How to integrate paystack in PHP is a tutorial by Firstclick Nigeria Limited to show developers how to integrate the paystack payment gateway into your application implemented in PHP.

This tutorial is simple to follow but If after going through the tutorial you still cannot figure out how to go about this or you just don’t want to be distracted from your core skills so as to deliver on project timeline, you can call or whatsApp us on +2348038983878 to integrate the paystack payment for you.

Create Paystack Account

First thing is to head over to paystack to create a free account. Once you’ve successfully created your account, login.

Copy Your API Test Key

Once logged in you arrive at the get started page. Scroll down and look to the right, you will find the section: Your Test Keys. Copy the test secret key; you will use this test key while in test mode or development mode. Note that you will have to replace this test key with the live key once you are ready to go live. You can only obtain the live key after you submit the required documents to paystack; the verification and approval process is very fast. I will talk about the requirements to go live later in this tutorial.

You can also find this key in Settings > API Keys & Webhooks

Our Paystack Class

I assume that you are familiar with curl if not you would want to go here http://www.hackingwithphp.com/15/10/2/your-first-curl-scripts first to familiarize yourself with it before continuing with this tutorial.

So this is the code for our class:

Class Paystack {
     Private $API_Test_Key = 'Your_API_Test_Key_Here';
     public static function Initialize_Transaction($Content_Type, $Ref_id, $Plan_amt, $email) {
        $Paystack = new Paystack();
        $request_headers = array();
        $request_headers[] = 'Authorization: Bearer ' . $Paystack->API_Test_Key;
        if (!empty($Content_Type)) {
            $request_headers[] = $Content_Type;
        }
        if (!empty($Ref_id) && !empty($Plan_amt) && !empty($email)) {
            $transacData = array("reference" => $Ref_id, "amount" => $Plan_amt, "email" => $email);
            $TransacPayload = json_encode($transacData);
        }

        $curl = curl_init("https://api.paystack.co/transaction/initialize"); //Initialiaze curl

        if (!empty($Ref_id) && !empty($Plan_amt) && !empty($email)) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, $TransacPayload);
        } else {
            curl_setopt($curl, CURLOPT_URL, "https://api.paystack.co/transaction/verify/" . $Ref_id);
        }
        curl_setopt($curl, CURLOPT_HTTPHEADER, $request_headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);

        return $curl;
    }

     public static function Execute_Transaction($curl) {
        $response = curl_exec($curl);
        return $response;
    }

     public static function Authorize_Payment($response) {
        $responseArry = json_decode($response);
        //echo "<pre>"; print_r($responseArry); echo "</pre>";
        $Auth_URL = $responseArry->data->authorization_url;
        $Status = $responseArry->status;
        $Staus_Msg = $responseArry->message;

        if ($Status === TRUE) {
            //REDIRECT to Authorization URL
            header('Location: ' . $Auth_URL);
        } else {
            echo 'An error occurred in the System while processing your payment, hence the transaction could not be completed. You may have to start all over again or contact an Admin.';
        }
    }
}

Initialize_Transaction() Method Explained

You need this paystack documentation page https://paystack.com/docs/api/ to understand what’s going on henceforth. It’s a long document containing all of paystack API Endpoints, so do a search for Initialize Transaction to arrive where i am right now.

Okay so according to the documentation: The Transactions API allows you create and manage payments on your integration. So to receive payment, you need to initialize the transaction from your backend.

Parameters needed to initialize transaction

Headers

In your code, you need to specify two headers parameters:

Authorization and Content-Type

In our code above, the line that sets the Authorization is:

$request_headers[] = 'Authorization: Bearer ' . $Paystack->API_Test_Key;

While

$Content_Type

passed in as the first parameter of the initialize_transaction method holds the Content-Type header parameter. The $Content_Type is assigned the value ‘Content-Type: application/json’ as you can also see in the paystack documentation.

Body Param
Amount and Email

Amount should be in kobo if currency is NGN and equivalent for other currencies. So for example if you want to receive say NGN10,000.00 for whatever product you are selling, you should set the amount parameter to 1000000 (no punctuation).

The other parameter which must be provided is customers email address.

Optional Parameters

There are optional parameters for Initialize Transaction API endpoint that your application may need to process. You should click on it to see the whole list. Follow the diagram below for direction.

Notice that in my code above, i passed in all the parameters as function arguments for Initialize_Transaction() apart from the Authorization header parameter.

In my code, the variables: $Ref_id and $channels are optional parameters ‘reference’ and ‘channels’. You can see their meaning when you click on Show optional parameters.

Execute_Transaction() Method

This method simply executes the Initialize_Transaction method and either returns True on success or False on failure.

Authorize_Payment() Method Explained

Why i have this method is that i am using it to retrieve and redirect to the paystack checkout url which is called $Auth_URL in this method. The authorization_url is one of the parameters that paystack returns as part of its response from execution of the Initialize_Transaction method. You have to retrieve this parameter from the response you get from paystack which is under the data parameter as you can see below

So the way you retrieve this authorization_url will be:

$Auth_URL = $responseArry->data->authorization_url;

So for the Authorize_Payment() Method, first pass in the response from execution of Initialize_Transaction() as a function argument.

Note that the response is in JSON format and you have to decode it back to a PHP array

$responseArry = json_decode($response);

Retrieve the authorization_url, status and message parameters returned from paystack to your application

$Auth_URL = $responseArry->data->authorization_url;
$Status = $responseArry->status;
$Staus_Msg = $responseArry->message;

If everything is as expected, then redirect to the paystack checkout page, so that customers can make payment.

if ($Status === TRUE) {
            //REDIRECT to Authorization URL
            header('Location: ' . $Auth_URL);
} else {
            echo 'An error occurred in the System while processing your payment, hence the transaction could not be completed. You may have to start all over again or contact an Admin.';
            //Log_Errors::Log_error_msg('', $Staus_Msg . ' caused for the user' . $clean['username'], __FILE__, __LINE__);
}

Download cacert.pem

As you can see from this line of code

curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem');

you need to download cacert.pem and reference it appropriately in your code depending on which folder you place the downloaded file. All you need to do is modify the code above to point to the folder where you placed the file.

Download the file from here http://curl.haxx.se/ca/cacert.pem

What exactly is cacert.pem for?

cacert.pem is a bundle of CA certificates that you use to verify that the server is really the correct site you’re talking to (when it presents its certificate in the SSL handshake). Go here https://stackoverflow.com/questions/14987857/what-exactly-is-cacert-pem-for to see the full answer to this question.

The Mainline

This is where we are going to be calling and controlling the methods in our Paystack Class.

I would like you to first of all head over to paystack and enter the callback url where you want paystack to redirect to after processing the customers payment. It is on that page you will take further actions, depending on the success or failure of the payment processing.

Call Initialize_Transaction Method

So after initializing all variables, you call the Initialize_Transaction method and pass in all variables as the function parameter thus:

$clean['amt'] = $_GET['amount'];
$clean['email'] = $_GET['Cust_email'];
$reference_id = 'generated unique id'
$Content_Type = 'Content-Type: application/json';

$curl = Paystack::Initialize_Transaction($Content_Type, $reference_id, $amt, $clean['email']);
if ($curl === false) {
     //handle exception here
     exit();
}

Notice that the Initialize_Transaction function is a static method so we do not need to create a new object of the Paystack class before referencing it; you reference it by typing Paystack::

Call Execute_Transaction()

$response = Paystack::Execute_Transaction($curl); //Execute the transaction here
if ($response === false) {
    //handle exception here
    exit();
}

Close curl object

curl_close($curl); //close curl object here

Call Authorize_Payment()

Paystack::Authorize_Payment($response);

Put the mainline code together

try {
     $clean['amt'] = $_GET['amount'];
     $clean['email'] = $_GET['Cust_email'];
     $reference_id = 'generated unique id'
     $Content_Type = 'Content-Type: application/json';

     $curl = Paystack::Initialize_Transaction($Content_Type, $reference_id, $amt, $clean['email']);
     if ($curl === false) {
          //handle exception here
          exit();
     }

     $response = Paystack::Execute_Transaction($curl); //Execute the transaction here
     if ($response === false) {
         //handle exception here
         exit();
     }

     curl_close($curl); //close curl object here
     Paystack::Authorize_Payment($response);
} catch (Exception $e) {
     //handle exception here
     exit();
}

What’s Next

With the Authorized_Payment ($response) called in the mainline code, the user is redirected payment detail submitted by clients’ to the paystack authorization_url – which is paystack checkout page – where client chooses to pay either with card or through bank etc.

Once paystack is done with the payment processing, they send a response to our callback url.

Callback URL Processing

So this is the code for my callback URL

<body id="body">
        <div id="container">
            <div class="center_box" id="response">
                <?php
                $reference_id = $_SESSION['reference_id'];

                $curl = Paystack::Initialize_Transaction('', $reference_id, '', '', ''); //Initialize transaction here
                if ($curl === false) {
                   //handle error message here
                    exit();
                }

                $response = Paystack::Execute_Transaction($curl); //Execute the transaction here
                $responseArry = json_decode($response);
                $Status = $responseArry->status;
                $_SESSION['Payment_Status'] = $Status;
                $Status_Msg = $responseArry->message;
                if ($Status === false) {
                    //handle error message here
                    exit();
                }
                if ($response === false) {
                    //handle error message here
                    exit();
                }
                //redirect to the expected page
                ?>
                <div align="center" class="row">
                    <?php
                    echo "<label style='color: #C00000; font-family: cursive; font-size: 20px;'><b>" . "Your payment was successful. You are now being redirected..." . "</b></label> <br><h3>Please wait while you are being redirected.</h3>";
                    ?>
                    <meta http-equiv="refresh" content="5;url=https://yourdomain/page_to_redirect_to.php">
                </div>
                <?php
                exit();
                ?>
            </div>
        </div><!--container ends-->
    </body>

Callback URL Explained

So i first retrieve the reference id from a session variable $_SESSION[‘reference_id’] into a variable called $reference_id.

Next i call Initialize_Transaction all over again but this time all parameters except the reference_id are empty.

Why empty parameter values? Notice this block of if statement

if (!empty($Ref_id) && !empty($Plan_amt) && !empty($email)) {
    curl_setopt($curl, CURLOPT_POSTFIELDS, $TransacPayload);
} else {
    curl_setopt($curl, CURLOPT_URL, "https://api.paystack.co/transaction/verify/" . $Ref_id);
}

in the Initialize_Transaction method of our Paystack class. I am calling the verify transaction this time around that i called the Initialize_Transaction method. Notice the url in the else part of the if statement is different from the url that is assigned if all parameters were passed into the Initialize_Transaction function. I simply want to verify if payment processing went well or not; how do i know which transaction we are dealing with here? The reference_id passed in as a parameter solves that one. That is why i used it in this very code because i want to be able to tell whether payment was successful or not so that i know what message to print to customers.

Then i call the $Execute_Transaction again and get a response

$response = Paystack::Execute_Transaction($curl);

I convert the response from JSON format to PHP array

$responseArry = json_decode($response);

I retrieve paystack’s returned parameters

$Status = $responseArry->status;
$_SESSION['Payment_Status'] = $Status;
$Status_Msg = $responseArry->message;

If response is false, something went wrong, handle the exception

if ($response === false) {
     //handle the exception here
     exit();
}

Else payment was successful, redirect customer appropriately.

?>
<div align="center" class="row">
<?php
   echo "<label style='color: #C00000; font-family: cursive; font-size: 20px;'><b>" . "Your payment was successful. You are now being redirected..." . "</b></label> <br>";
?>
  <meta http-equiv="refresh" content="5;url=https://landing_page.com">
  </div>
<?php
  exit();
?>
Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

You May Also Like