Easy PayFast integration for Django with full transaction tracking and real-time ITN (payment notification) logging for every payment.
dj-payfast - Django + Payfast Made Easy
PayFast Models for Django.
Introduction
dj-payfast implements all of the Payfast models intergration, for Django. Set up your webhook endpoint and start receiving model updates. You will then have a copy of all the payfast models available in Django models, as soon as they are updated!
The full documentation is available on Read the Docs.
Features
- Payfast Core
- Payfast Billing
- Payfast Cards (JS v2) and Sources (JS v3)
- Payment Methods and Payment Intents (SCA support)
- Support for multiple accounts and API keys
- Payfast Connect (partial support)
- Tested with Payfast API
2020-08-27(see API versions)
Requirements
- Django >=4.2
- Django Rest Framework (Portable)
- Python >=3.9
- PostgreSQL engine (recommended) >=12
- MySQL engine: MariaDB >=10.5 or MySQL >=8.0
- SQLite: Not recommended in production. Version >=3.26 required.
- Nginx, Gunicorn, Docker
- Celery is included
- Email setup
Installation
See installation instructions.
1. Install via pip
pip install dj-payfast
2. Add to INSTALLED_APPS
# settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third-party apps 'rest_framework', # Optional, for API support 'payfast', # Add this # Your apps 'myapp', ]
3. Configure URLs
# urls.py
from django.contrib import admin from django.urls import path, include
urlpatterns = [ path('admin/', admin.site.urls), path('payfast/', include('payfast.urls')), # Add this # Your other URLs ]
This creates the webhook endpoint at: /payfast/notify/
4. Run Migrations
python manage.py migrate
Configuration
Basic Configuration
Add your PayFast credentials to settings.py:
# settings.py
PayFast Configuration
PAYFASTMERCHANTID = 'yourmerchantid' # Your merchant ID
PAYFASTMERCHANTKEY = 'yourmerchantkey' # Your merchant key
PAYFASTPASSPHRASE = 'yourpassphrase' # Your passphrase (recommended)
PAYFASTTESTMODE = True # False for production
Environment Variables (Recommended)
Never commit credentials to version control! Use environment variables:
# settings.py
import os
PAYFASTMERCHANTID = os.environ.get('PAYFASTMERCHANTID') PAYFASTMERCHANTKEY = os.environ.get('PAYFASTMERCHANTKEY') PAYFASTPASSPHRASE = os.environ.get('PAYFASTPASSPHRASE') PAYFASTTESTMODE = os.environ.get('PAYFASTTESTMODE', 'True') == 'True'
Create a .env file:
# .env
PAYFASTMERCHANTID = 'yourmerchantid' # Your merchant ID
PAYFASTMERCHANTKEY = 'yourmerchantkey' # Your merchant key
PAYFASTPASSPHRASE = 'yourpassphrase' # Your passphrase (recommended)
PAYFASTTESTMODE = True # False for production
Getting PayFast Credentials
Sandbox (Testing):
- Sign up at sandbox.payfast.co.za
- Navigate to Home → Account Information
- Copy your Merchant ID and Merchant Key
- Generate a passphrase
- Sign up at www.payfast.co.za
- Complete merchant verification
- Navigate to Settings → Integration
- Copy your credentials
Usage Examples
Steps Taken When Using API Calls (To make it dynamic)
Create a payment (post) endpoint at: /payfast/payments/
// some fields are not required
// This is a post request
// Just changed it to this
{
"mpaymentid": "",
"user": null,
"amount": null,
"item_name": "",
"item_description": "",
"name_first": "",
"name_last": "",
"email_address": "",
"cell_number": "",
"custom_str1": "",
"custom_str2": "",
"custom_str3": "",
"custom_str4": "",
"custom_str5": "",
"custom_int1": null,
"custom_int2": null,
"custom_int3": null,
"custom_int4": null,
"custom_int5": null
}
This request returns something like this
{
"amount": "99.99",
"item_name": "Premium Subscription",
"item_description": "1 month premium access",
"name_first": "",
"name_last": "",
"email_address": "your.email@gmail.com",
"mpaymentid": "3a280ceb-344c-48d1-8e9c-7945f3f1194a",
"payfast_url": "http://127.0.0.1:2000/payments/checkout/2"
}
if you are using a frontend app like REACTJS just redirect to 'payfast_url'
After the completion of this payment payfast will redirect to complete endpoint or cancelled endpoint
Steps Taken Using Query Parameters (To make it dynamic)
Example 1: E-commerce Checkout
# views.py
from django.shortcuts import redirect, reverse
from urllib.parse import urlencode
from .models import Order
def processordercheckout(request, order_id): """ Process order and redirect to PayFast checkout """ order = Order.objects.get(id=order_id, user=request.user) # Calculate total total = order.calculate_total() # Build item description items = ', '.join([f"{item.quantity}x {item.product.name}" for item in order.items.all()]) params = urlencode({ 'amount': total, 'item_name': f'Order #{order.id}', 'item_description': items, 'customstr1': f'order{order.id}', 'custom_int1': order.items.count(), 'email_address': request.user.email, }) url = f"{reverse('payfast:checkout')}?{params}" return redirect(url)
Changelog
See release notes on Read the Docs.
Funding and Support
You can now become a sponsor to dj-payfast with GitHub Sponsors.
We've been bringing dj-payfast to the world for over 10 years and are excited to be able to start dedicating some real resources to the project.
Your sponsorship helps us keep a team of maintainers actively working to improve dj-payfast and ensure it stays up-to-date with the latest payfast changes. If you use dj-payfast commercially, we would encourage you to invest in its continued development by signing up for a paid plan. Corporate sponsors receive priority support and development time.
All contributions through GitHub sponsors flow into our Open Collective, which holds our funds and keeps an open ledger on how donations are spent.
Our Gold sponsors