DEV Community

Cover image for How to Integrate Paystack payment system
Jeremy Ikwuje
Jeremy Ikwuje

Posted on • Updated on

How to Integrate Paystack payment system

In this guide, you'll learn how to integrate Paystack payment system on your website.

This guide is comprehensive, so you should go through every information for maximum output.

Paystack is a Modern online and offline payments for Africa.

Before you can start integrating Paystack, you will need a Paystack account. Create a free account now if you haven't already done so.

The Paystack API gives you access to pretty much all the features you can use on your account dashboard and lets you extend them for use in your application. It strives to be RESTful and is organized around the main resources you would be interacting with - with a few notable exceptions.

After creating an account, the next thing is to sign in to your new Paystack account. On your dashboard, you will find your public and secret key. We will make use of the public and secret key for this guide.

Spotlight: I built a better alternative to AbokiFX, you can check it out here.

Let Dive In

Paystack has three major approaches to integrate their API and collect payments on your websites. But this guide explains only two approaches. The third approach is with pure JavaScript, which I will discuss entirely on a separate post.

  1. Paystack Inline
  2. Paystack Standard

Using any one of the two depends on what you're trying to do. Each one comes with its own user and developer experience.

Paystack Inline

This approach offers a simple, secure and convenient payment flow for web. It can be integrated with a line of code thereby making it the easiest way to start accepting payments. It also makes it possible to start and end the payment flow on the same page, thus combating redirect fatigue.

Now, the code below displays a Paystack pay button.



<form>
  <script src="https://js.paystack.co/v1/inline.js"></script>
  <button type="button" onclick="payWithPaystack()"> Pay </button> 
</form>



Enter fullscreen mode Exit fullscreen mode

The pay button is yet to do what you expect. So if you click on it, nothing will happen. For it to work you need to add the payWithPaystack() Javascript function below the form.

Here is the payWithPaystack function provided by Paystack.



<!-- place below the html form -->
<script>
  function payWithPaystack(){
    var handler = PaystackPop.setup({
      key: 'paste your key here',
      email: 'customer@email.com',
      amount: 10000,
      ref: ''+Math.floor((Math.random() * 1000000000) + 1), // generates a pseudo-unique reference. Please replace with a reference you generated. Or remove the line entirely so our API will generate one for you
      metadata: {
         custom_fields: [
            {
                display_name: "Mobile Number",
                variable_name: "mobile_number",
                value: "+2348012345678"
            }
         ]
      },
      callback: function(response){
          alert('success. transaction ref is ' + response.reference);
      },
      onClose: function(){
          alert('window closed');
      }
    });
    handler.openIframe();
  }
</script>



Enter fullscreen mode Exit fullscreen mode

You need to replace the key: value 'paste your key here' with the public key on your Paystack account settings. If login, you can locate the key here.

Please note that the key to use with inline is the public key and not the secret key

If you did it correctly, on the click of the pay button, a nice looking Paystack payment UI will pop out. Since you're testing the payment API, you should use a test card.

To use a test card, you should use the test public key instead. And never forget to replace the test public key with the live public key on a live website.

paystack payment form

When the payment is successful, your browser will show an alert, indicating a successful transaction, with a reference key.

paystack payment form

With this Inline method, everything works on a single page. Also, notice the callback and onClose object key. The callback allows you to control the user experience within a callback function if the payment is successful. e.g Redirecting the user to a Thank You page.

Paystack Standard

This is the standard approach of collecting payments on your web app. The standard approach is a better and secure way to integrate within your php web app.

Now, for this approach to work on your server you need to confirm that your server can conclude a TLSv1.2 connection. Most up-to-date servers have this capability. If you're on a web server, you contact your service provider for guidance if you have any SSL errors.

For this approach, you'll need to create two new files.



   initialize.php
   callback.php


Enter fullscreen mode Exit fullscreen mode

Initialize a transaction

Paste the following code inside the initialize.php



<?php
$curl = curl_init();

$email = "your@email.com";
$amount = 30000;  //the amount in kobo. This value is actually NGN 300

// url to go to after payment
$callback_url = 'myapp.com/pay/callback.php';  

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.paystack.co/transaction/initialize",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => json_encode([
    'amount'=>$amount,
    'email'=>$email,
    'callback_url' => $callback_url
  ]),
  CURLOPT_HTTPHEADER => [
    "authorization: Bearer sk_test_36658e3260b1d1668b563e6d8268e46ad6da3273", //replace this with your own test key
    "content-type: application/json",
    "cache-control: no-cache"
  ],
));

$response = curl_exec($curl);
$err = curl_error($curl);

if($err){
  // there was an error contacting the Paystack API
  die('Curl returned error: ' . $err);
}

$tranx = json_decode($response, true);

if(!$tranx['status']){
  // there was an error from the API
  print_r('API returned error: ' . $tranx['message']);
}

// comment out this line if you want to redirect the user to the payment page
print_r($tranx);
// redirect to page so User can pay
// uncomment this line to allow the user redirect to the payment page
header('Location: ' . $tranx['data']['authorization_url']);



Enter fullscreen mode Exit fullscreen mode

The initialize.php will initialize your customer transaction with the paystack API and redirect the user to a Paystack payment page.

On a live server, replace the test key with your own live secret key. Look for the line with comment 'replace this with your own test key' and remove the sk_test_xxxxxxxxx to your secret key.

Note that, the $email and $amount are the customer's email address and the amount they are to pay while the $callback_url is the URL the customer will be redirected to after payment.

Bringing the customers back to your site is an important part of the standard approach, so don't forget to change the $callback_url to that of your app.

The email and amount can be collected through forms or whatever way you intended.

The $amount is in Nigeria Kobo, so always add double zeros on any amount you are charging the customer. e.g 100000 for 1000

You can use this money tool for accuracy on the complicated amount.

When the customer enters their card details, Paystack will validate and charge the card. When successful, it will then redirect back to your callback_url set when initializing the transaction or on your dashboard at: https://dashboard.paystack.co/#/settings/developer .

If your callback_url is not set, your customers see a "Transaction was successful" message without any redirect.

Verify the Transaction

Now, since the callback is specified in your code, you need to set the callback.php.

Enter the code below inside the callback.php



<?php

$curl = curl_init();
$reference = isset($_GET['reference']) ? $_GET['reference'] : '';
if(!$reference){
  die('No reference supplied');
}

curl_setopt_array($curl, array(
  CURLOPT_URL => "https://api.paystack.co/transaction/verify/" . rawurlencode($reference),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "accept: application/json",
    "authorization: Bearer SECRET_KEY",
    "cache-control: no-cache"
  ],
));

$response = curl_exec($curl);
$err = curl_error($curl);

if($err){
    // there was an error contacting the Paystack API
  die('Curl returned error: ' . $err);
}

$tranx = json_decode($response);

if(!$tranx->status){
  // there was an error from the API
  die('API returned error: ' . $tranx->message);
}

if('success' == $tranx->data->status){
  // transaction was successful...
  // please check other things like whether you already gave value for this ref
  // if the email matches the customer who owns the product etc
  // Give value
  echo "<h2>Thank you for making a purchase. Your file has bee sent your email.</h2>";
}



Enter fullscreen mode Exit fullscreen mode

If you follow the steps correctly. You will get the following result.

'paystack standard demo'

If you run into the error below.



API returned error: Transaction reference not found


Enter fullscreen mode Exit fullscreen mode

Then make sure the SECRET_KEY in callback.php is the same as the one used in the initialize.php and the callback URL should be a live domain.

Congratulation, you just integrated paystack payment into your app.

Have any problem, you can comment. If it is urgent, you can message me on Twitter.

Hints

Go to dashboard > settings > webhook/keys to get your public and secret key for both the live and test.

The live keys are used for production purpose. While the public is for testing purpose.

To enable live mode on paystack, you'll need to submit your business details.

Top comments (88)

Collapse
 
knightsgram profile image
Knights Gram

I want to add paystack to my site. It got to a point where I don't know what's next.
I don't know where to add the files

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Did you follow the steps? Explain your situation.

Collapse
 
knightsgram profile image
Knights Gram

The problem is I don't even know how to start.
Can you give me a tutorial on how to start from scratch?. I already created a button to redirect to paystack but I don't know what to add and where to place the yabacon php files

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje

If you know how to set up a PHP project, then simply follow the tutorial from the beginning.

Ignore the yabacon PHP files for now, and follow the tutorial.

Thread Thread
 
Sloan, the sloth mascot
Comment deleted
 
knightsgram profile image
Knights Gram • Edited

How do I know my site callback url
I want the money to be added to the user wallet after successful payment. How do I add that?
In this case where I want user wallet to be updated, which method is best. Inline or standard. Or both

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje

Both are fine.

The inline method is great for user experience if you're comfortable with AJAX.

The callback_url is for the standard method. This is the PHP file paystack will redirect the user to after making a payment.

In this page, you confirm the user payment and update the user wallet.

Thread Thread
 
knightsgram profile image
Knights Gram

How do I update the wallet?
Is there a special code for that or I'll be the one to write it,
I think my site already has d callback but I don't know where it will be.

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje • Edited

You'll have to do that yourself, or if you need help, you can message me on telegram, I actually wrote a wallet example.

Thread Thread
 
knightsgram profile image
Knights Gram

Username not found on telegram

Let's chat via Twitter then @knightsgram

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje

Oh, I made a typo, You can try it t.me/ijsucceed

Collapse
 
patabah profile image
PatAbah • Edited

You said $email is my customer's email. So I tried getting my user's email from $_POST but each time I refer to $_POST anywhere in initialize.php I get a redirection error from browser "Page isn't redirecting properly"

This also means I can't pass the amount user is willing to pay via post in initialize.php

This is super weird and annoying. I'll appreciate any help please. Thanks

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

"Page isn't redirecting properly"? Uncommon. Try clearing your cache and cookie(important).

Each time you refer to $_POST, what do you mean?

Try isseting if the $_POST request was sent to see where the problem is coming from.

if( isset( $_POST['submit'] ) { 

You can engage with me live on twitter, that will be faster.

Collapse
 
patabah profile image
PatAbah • Edited

Your prompt response already makes me feel better :)

BTW, I was using Firefox on Android, I switched to Chrome... It worked. Back to Firefox and it worked too!

I don't know how, but I think the issue is resolved. Thanks.

One more thing...
For production, after replacing test_key with my real secret key, would PayStack override my callback_url? Or is it compulsory to set the callback_url in the field provided the Developer Dashboard?

I passed a $_GET parameter to the callback url containing specific subscription plans I offer so I could update the my DB with the parameter (plan) on success.

Is there a better way to do this?

Thanks once again

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje • Edited

No, Pat, as long as you set the callback_url in your code, then you're fine.

Thread Thread
 
patabah profile image
PatAbah

Thanks man. You're za best!

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje

Pleasure, thanks.

Collapse
 
ezuruikechinedu profile image
Chinedu • Edited

same here..but the values for $email and $amount in stored in sessions.
I get undefined _session variables..
Do i have to session_start()in both initialize.php and callback.php?

Thread Thread
 
ezuruikechinedu profile image
Chinedu

Don't worry...i've DONE IT

Thread Thread
 
elouisramsey profile image
elouisramsey

yo, please how did you solve this
using JS and I keep getting undefined

Collapse
 
okewater_1 profile image
Nedu

I have successfully added paystack to my plugin but i cannot update the plugin with payment information.
How can i add this code to the paystack file to be able to increase cause with payment details?

Collapse
 
oyeh20 profile image
oyeh20

thanks very much jeremiah, you provide what i have been looking for. please i still have a little problem. the code work successfully, but know, i need php code to insert the figure to the user wallet or account. so that he can confirm the transaction he made. regards

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Which user wallet are you referring to? is it that of Paystack or your own platform. Please specify.

Collapse
 
oyeh20 profile image
oyeh20 • Edited

I'm talking about my platform. Take for example, a user login to his/her account in my platform, and deposit money, using the paystack payment gateway.. Now I'm looking for the php script to give the user value, (e.g. he/she deposits #500 using paystack, and it was successful,, when he/she come back to my platform, he/she has to see the #500 in her account, to confirm that the payment he/she made was successful)

Thread Thread
 
ijsucceed profile image
Jeremy Ikwuje • Edited

You're to write the script yourself. You do that in the callback file.

if('success' == $tranx->data->status){
// transaction was successful...
// send the value the user made to the database and redirect back to any
// file you want.
}

Hope you get it?

Thread Thread
 
oyeh20 profile image
oyeh20

that is my issue now. have write many php script code with the little knowledge i have, but nothing happen. please i need a sample of already working php code, to learn from. i will be glad if anyone can share with me. regards

Thread Thread
 
kodnificent profile image
Victor Mbamara 🇳🇬

you need to create a webhook url where paystack sends a charge.success event to, if the payment was made successfully. It's in that webhook file you can update the users wallet if a charge.success event was received. Visit paystack documentation page for a better understanding.

Collapse
 
holynation profile image
Alatise Oluwaseun • Edited

Good afternoon @ijsucceed .
I really love your code for it simplicity. However, i did love to make some corrections starting with the initialize.php.
// this part of the code is wrong since an array is returned, so it should not be
if(!$tranx->status){
// there was an error from the API
print_r('API returned error: ' . $tranx['message']);
}
// the corrected version
if(!$tranx['status']){
print_r('API returned error: ' . $tranx['message']);
}
Thank you.

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

You're right @holynation .

I just ran some few tests. The actual issue came from the Paystack documentation.

Though it will be hard for one to notice ( including Paystack developers) since the page gets redirected to the checkout form.

header('Location: ' . $tranx['data']['authorization_url']);

Thanks.

Collapse
 
holynation profile image
Alatise Oluwaseun

That is true. I have actually been looking for that too in their documentation.
Also i wanna ask again, how do i send phone number and fullname along side the initialize.php api

Collapse
 
ibukunsoremekun profile image
Ibukun Soremekun

For those that will like to test these on local host server
you should follow the steps below

  1. ADD CURLOPT_SSL_VERIFYPEER => false, code to your curl_setopt_array()
  2. then set your callback url to the full your callback.php eg: localhost/PaystackProject/callback.php
Collapse
 
chuma_nd_ok profile image
Chuma Ndubuisi Okeke

Wow, Love this detailed tutorials @ijsucceed . Please am faced with a challenge.
i want to make for recurring debit but i was not able to retrieve "authentication code and card last four digits" after the successful payment. Help me out sir.

please see developers.paystack.co/reference#c...
.....
"gateway_response": "Successful",
"authorization": {
"authorization_code": "AUTH_72btv547",
"card_type": "mastercard",
"last4": "1839",
........

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Sorry, bro. I have no experience working on the recurring payment API.

Collapse
 
chuma_nd_ok profile image
Chuma Ndubuisi Okeke

Thanks for your prompt reply sir.

Collapse
 
gottfried profile image
Gottfried

Hi IJ
I would like to know if there is a way of adding customer details to this specific way of integrating. I have tried several times but i cannot seem to get it right.

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Late reply, but you can pass customer details through the metadata:

  'callback_url' => $callback_url,
  'metadata' => [
      'custom_fields' => [
        "first_name" => "John",
        "last_name" => "Micheal",
        'cart_id' => 84920392,
        "custom" => "any thing here"
      ]
  ]

I hope you got it.

Collapse
 
naijanewsworld profile image
Nigeria News World

Is there a way to create a form to enable customers input their details instead of having a predefined details on the dashboard?

Collapse
 
1delcab profile image
1delcab

Nice and clear explanation.

My problem is that the call back function does not provide the payment details (I.e the customer email) so as to insert in it MySQLi data base.
Or I'm to use session to keep the record

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

The payment details are usually sent (as JSON) to your webhook url.

But, just like you said, you should use the user session, then make sure you verify the session with the user details in your database.

Collapse
 
kelvin070 profile image
kelvin070

Please I have an ecomerce site and I want a paystack pay button but I want the script that you will take any sum from the total cost on the cart and show to the customer as what to pay rather than me adding the price please

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

You'll have to do that yourself, or if you need help, you can message me on telegram.

Collapse
 
adejumosamson profile image
AdejumoSamson

Hi Jeremiah.

Thanks for the detailed instructions.
I've been able to implement Paystack gateway successfully and gets a redirect to the specified callback URL.

But I'm having issues transferring data from the payment page to the webook URL specified on the Paystack dashboard.

Any hint on how that can be achieved?

Thank you.

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Welcome! Have you taken a look at this?

Collapse
 
stevebrain_dev profile image
Godwin Stephen • Edited

Hi, @ijsucceed , Thanks for the tuts. It really helped a lot as it is simple and detailed.
I have been able to integrate and I can successfully pay. Thumbs Up to you!.

but I want to be able to add other specific information to the API endpoint and also retrieve it at callback.php for further details verification before giving value to the customer.

I'm giving multiple values to different tables in the DB. e.g after successful payment, a customer is getting point value, product value, and an additional bonus value.

All these will have to verify the transaction match with their tables respectively before I can give value to the customer...

I tried adding extra form data to the form that is sent to initialize.php. but I'm not able to get those values, and I can't retrieve them from the API as well since it wasn't sent in the first place.

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Okay, getting you clearly, you want to pass some extra but important data to the API. And you want to get this extra data during the verification.

If that's the case:

Kindly contact me on Telegram or WhatsApp so we do a live session.

Collapse
 
segzyboiy profile image
SEGUN ISREAL (codeAdept)

Thanks for this post, really helpful, but please do you have any idea on how to integrate Paystack into Django WebApps? I have been looking for a way around this for days now, any help will be appreciated. Thanks in anticipation.

Collapse
 
ijsucceed profile image
Jeremy Ikwuje

Not really. I never built anything with Django before. Thank you.

Collapse
 
mghq_yt profile image
MGHQ-MobileGamerzHQ[YT]

has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
please I keep getting this error, what can I do, I get it when it goes to the
header('Location: ' . $tranx['data']['authorization_url']);

Collapse
 
ezuruikechinedu profile image
Chinedu

got this error:
API returned error: Authorization URL createdArray ( [status] => 1 [message] => Authorization URL created [data] => Array ( [authorization_url] => checkout.paystack.com/...............

Whats the problem

Collapse
 
ijsucceed profile image
Jeremy Ikwuje • Edited

Be sure your secret key is used in both initialization and verification. And if you're on live mode, then you have to be on a live server too.