Yes, you can integrate Paystack with Django to handle payments securely and
efficiently! Here's a step-by-step guide to help you learn how to set up a Paystack
payment system using Django. This method will include:
1. Initializing the transaction on the Django backend.
2. Using the Paystack payment modal on the frontend.
3. Verifying the transaction via a webhook or API.
### Prerequisites
- You should have basic knowledge of Django (models, views, templates).
- You'll need an account with Paystack to get your **public key** and **secret key**.
### Steps to Integrate Paystack in Django
#### 1. **Install Required Packages**
Install the required packages for making HTTP requests from Django:
```bash
pip install requests
```
#### 2. **Set Up Paystack Keys in Django Settings**
In your `settings.py`, store your Paystack **public** and **secret** keys as
environment variables or directly in the settings file (for simplicity here):
```python
# settings.py
PAYSTACK_PUBLIC_KEY = 'your-paystack-public-key'
PAYSTACK_SECRET_KEY = 'your-paystack-secret-key'
```
#### 3. **Create a Payment Model (Optional)**
You might want to store the details of each payment in your database. For example:
```python
# models.py
from django.db import models
class Payment(models.Model):
reference = models.CharField(max_length=100, unique=True)
email = models.EmailField()
amount = models.IntegerField() # Amount in kobo (1 NGN = 100 kobo)
verified = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'Payment {self.reference}'
```
#### 4. **Django View to Initialize Payment**
Next, create a Django view that initializes the Paystack transaction on the backend
using their API. Paystack’s [Transaction Initialize
API](https://paystack.com/docs/api/#transaction-initialize) will return a payment
reference and authorization URL.
```python
# views.py
import requests
from django.conf import settings
from django.shortcuts import render, redirect
from django.http import JsonResponse
from .models import Payment
import random
def initialize_payment(request):
if request.method == "POST":
email = request.POST.get('email')
amount = int(request.POST.get('amount')) * 100 # Amount in kobo (1 NGN =
100 kobo)
# Generate a unique reference for the transaction
reference = f'PS_{random.randint(100000, 999999)}'
# Save the payment details in the database (optional)
payment = Payment.objects.create(
reference=reference,
email=email,
amount=amount
)
# Paystack transaction initialization request
headers = {
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
'Content-Type': 'application/json',
}
data = {
'email': email,
'amount': amount,
'reference': reference
}
url = 'https://api.paystack.co/transaction/initialize'
try:
response = requests.post(url, json=data, headers=headers)
response_data = response.json()
if response_data['status']:
# Redirect user to the Paystack payment page
return JsonResponse({'payment_url': response_data['data']
['authorization_url']})
else:
return JsonResponse({'error': 'Payment initialization failed'}, status=400)
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
else:
return render(request, 'payment_form.html')
```
### 5. **Frontend Form to Trigger Payment**
In your Django template, create a form to collect the email and amount for the
payment. The form will send data to the `initialize_payment` view when submitted.
```html
<!-- payment_form.html -->
<form id="paymentForm" method="POST">
{% csrf_token %}
<input type="email" name="email" placeholder="Enter your email" required>
<input type="number" name="amount" placeholder="Amount" required>
<button type="submit">Pay Now</button>
</form>
<script>
document.getElementById('paymentForm').addEventListener('submit', function
(e) {
e.preventDefault();
// Fetch the form data
const formData = new FormData(this);
fetch("{% url 'initialize_payment' %}", {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}'
}
})
.then(response => response.json())
.then(data => {
if (data.payment_url) {
// Redirect user to Paystack payment page
window.location.href = data.payment_url;
} else {
alert('Payment initialization failed');
}
})
.catch(error => console.log('Error:', error));
});
</script>
```
### 6. **Verify the Payment (Server-side)**
Once the user completes the payment, you should verify the transaction on the
server to confirm that it was successful. Paystack provides a **Transaction Verify
API** for this.
You can add this to your views:
```python
# views.py
def verify_payment(reference):
headers = {
'Authorization': f'Bearer {settings.PAYSTACK_SECRET_KEY}',
}
url = f'https://api.paystack.co/transaction/verify/{reference}'
try:
response = requests.get(url, headers=headers)
response_data = response.json()
if response_data['status'] and response_data['data']['status'] == 'success':
# Mark the payment as verified in your database
Payment.objects.filter(reference=reference).update(verified=True)
return True
return False
except Exception as e:
return False
```
In your **callback function** after the user pays, you can call this function to verify
the transaction using the `reference` returned from Paystack.
### 7. **Optional: Handle Webhooks**
You can also configure Paystack webhooks to automatically notify your server when
a transaction is completed. Set up an endpoint in Django to handle these
notifications.
```python
# views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
@csrf_exempt
def paystack_webhook(request):
if request.method == 'POST':
event = request.POST
# Check for the event type you're interested in
if event['event'] == 'charge.success':
reference = event['data']['reference']
# Verify the payment and update your database
verify_payment(reference)
return HttpResponse(status=200)
return HttpResponse(status=400)
```
### 8. **Urls Configuration**
Add the necessary URLs for initializing payments and handling webhooks in
`urls.py`:
```python
# urls.py
from django.urls import path
from .views import initialize_payment, paystack_webhook
urlpatterns = [
path('initialize-payment/', initialize_payment, name='initialize_payment'),
path('webhook/', paystack_webhook, name='paystack_webhook'),
]
```
---
### Summary of Steps:
1. **Backend Payment Initialization**: Django handles initializing the transaction via
Paystack’s API.
2. **Frontend Payment Modal**: The user is redirected to the Paystack payment
page via a generated authorization URL.
3. **Payment Verification**: After payment, you verify the transaction using
Paystack’s verification endpoint or by handling a webhook.
### Resources:
- Paystack Documentation: [https://paystack.com/docs/](https://paystack.com/docs/)
- Django Documentation:
[https://docs.djangoproject.com/](https://docs.djangoproject.com/)
This integration provides a secure and Django-friendly way to accept payments
using Paystack.