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();
?>