Integrating Paystack payments in Django
Django and Paystack Integrating

My name is Isyaku Murtala Abdulhamid, and I am an aspiring programmer from Nigeria. I have a deep passion for coding, and since I envision it as my long-term career path, I have decided to share my journey and insights through teaching on Hashnode. Through this blog, I aim to offer valuable lessons in programming, software engineering, machine learning, and all things related to information technology. With a particular emphasis on Python and JavaScript, my blog is designed to equip you with free resources and tools that will help you learn to code effectively and embark on a successful career in software engineering and programming. My ultimate goal is to provide you with the highest quality programming and technology content available on the internet, ensuring that you have the knowledge and skills needed to thrive in the ever-evolving tech industry.
Introduction
Paystack is a payment gateway that helps individuals and businesses in Africa accept payments from anywhere in the world. In this guide, I will show you how to use Paystack as a third-party API to handle payments on your Django website.
Prerequisites
To follow this guide, you need:
A good understanding of Python
Basic knowledge of Django
Basic knowledge of HTML
Familiarity with the Python requests library
A Paystack account
Project Setup
CCreate a folder, start a virtual environment, and set up the basic project
Create a virtual environment using python -m venv env on Windows. Use virtualenv env on Mac/Linux.
Activate the virtual environment with .\env\Scripts\activate on Windows or source env/bin/activate on Mac/Linux.
Install Django using pip install django. This will install the latest version of Django, but you can use any version you prefer. It's best to use the latest version for all your projects.
Create a project and install apps
Start the project with django-admin startproject core .
core is the project name, and the dot means the project starts in the current folder.
The next step is to create two apps: one for user authentication and another for handling all payment-related code.
python manage.py startapp users
python manage.py startapp payments


Add the newly installed apps in settings.py

Also add paystack secret and public keys in settings.py

Where to find them on paystack

Navigate into both Apps folders created and add a new file called urls.py and add the following code
from django.urls import path
urlpatterns = [
]
Include these urls in main url file core.urls
Your file should look like this
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include("users.urls")),
path('payments/', include("payments.urls")),
]
Creating models
Next step is to create a wallet model to keep track of funds deposited by a user and a payment model to describe what a payment is.
In payments.model
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import secrets
from .paystack import Paystack
# Create your models here.
class UserWallet(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
created_at = models.DateTimeField(default=timezone.now, null=True)
def __str__(self):
return self.user.__str__()
class Payment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
amount = models.PositiveIntegerField()
ref = models.CharField(max_length=200)
email = models.EmailField()
verified = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-date_created',)
def __str__(self):
return f"Payment for {user}: {self.amount}"
def save(self, *args, **kwargs):
while not self.ref:
ref = secrets.token_urlsafe(50)
object_with_similar_ref = Payment.objects.filter(ref=ref)
if not object_with_similar_ref:
self.ref = ref
super().save(*args, **kwargs)
We will need another helper class to handle payment verification, so in the payments folder create a file called paystack.py
paste this block of code in the file
from django.conf import settings
import requests
class Paystack:
PAYSTACK_SK = settings.PAYSTACK_SECRET_KEY
base_url = "https://api.paystack.co/"
def verify_payment(self, ref, *args, **kwargs):
path = f'transaction/verify/{ref}'
headers = {
"Authorization": f"Bearer {self.PAYSTACK_SK}",
"Content-Type": "application/json",
}
url = self.base_url + path
response = requests.get(url, headers=headers)
if response.status_code == 200:
response_data = response.json()
return response_data['status'], response_data['data']
response_data = response.json()
return response_data['status'], response_data['message']
you will need to install requests for this so do a quick pip install requests
with that we can now add a verify payment property on our payment model
def amount_value(self):
return int(self.amount) * 100
def verify_payment(self):
paystack = Paystack()
status, result = paystack.verify_payment(self.ref, self.amount)
if status:
if result['amount'] / 100 == self.amount:
self.verified = True
self.save()
if self.verified:
return True
return False
Your model should look like this:
from django.db import models
# Create your models here.
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import secrets
from .paystack import Paystack
# Create your models here.
class UserWallet(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
currency = models.CharField(max_length=50, default='NGN')
created_at = models.DateTimeField(default=timezone.now, null=True)
def __str__(self):
return self.user.__str__()
class Payment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
amount = models.PositiveIntegerField()
ref = models.CharField(max_length=200)
email = models.EmailField()
verified = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-date_created',)
def __str__(self):
return f"Payment: {self.amount}"
def save(self, *args, **kwargs):
while not self.ref:
ref = secrets.token_urlsafe(50)
object_with_similar_ref = Payment.objects.filter(ref=ref)
if not object_with_similar_ref:
self.ref = ref
super().save(*args, **kwargs)
def amount_value(self):
return int(self.amount) * 100
def verify_payment(self):
paystack = Paystack()
status, result = paystack.verify_payment(self.ref, self.amount)
if status:
if result['amount'] / 100 == self.amount:
self.verified = True
self.save()
if self.verified:
return True
return False
To be continued.