Quick Start Guide
This guide will help you integrate PayFast into your Django application in under 10 minutes.
Prerequisites
Before you begin, make sure you have:
A Django project (3.2 or higher)
Python 3.8 or higher installed
A PayFast merchant account (sign up at payfast.co.za)
Your PayFast credentials (Merchant ID, Merchant Key, and Passphrase)
Step 1: Installation
Install dj-payfast using pip:
pip install dj-payfast
Or add it to your requirements.txt:
dj-payfast>=0.1.0
Step 2: Add to Django Settings
Add payfast to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps
'myapp',
# dj-payfast
'payfast',
]
Step 3: Configure PayFast Credentials
Add your PayFast credentials to settings.py:
For Testing (Sandbox)
# PayFast Configuration
PAYFAST_MERCHANT_ID = '10000100' # Sandbox merchant ID
PAYFAST_MERCHANT_KEY = '46f0cd694581a' # Sandbox merchant key
PAYFAST_PASSPHRASE = 'jt7NOE43FZPn' # Your passphrase (optional but recommended)
PAYFAST_TEST_MODE = True # Always True for sandbox
For Production
# PayFast Configuration
PAYFAST_MERCHANT_ID = 'your_live_merchant_id'
PAYFAST_MERCHANT_KEY = 'your_live_merchant_key'
PAYFAST_PASSPHRASE = 'your_secure_passphrase'
PAYFAST_TEST_MODE = False # False for live payments
Warning
Never commit your production credentials to version control! Use environment variables:
from dotzen import config
PAYFAST_MERCHANT_ID = config('PAYFAST_MERCHANT_ID')
PAYFAST_MERCHANT_KEY = config('PAYFAST_MERCHANT_KEY')
PAYFAST_PASSPHRASE = config('PAYFAST_PASSPHRASE')
PAYFAST_TEST_MODE = config('PAYFAST_TEST_MODE', 'True') == 'True'
Step 4: Configure URLs
Add PayFast URLs to your 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 line
# Your other URLs
]
This creates the webhook endpoint at /payfast/notify/ which PayFast will use to send payment notifications.
Step 5: Run Migrations
Create the necessary database tables:
python manage.py migrate
- This creates two tables:
payfast_payfastpayment- Stores payment recordspayfast_payfastnotification- Logs webhook notifications
Step 6: Create Your First Payment
Create a view to handle the checkout process:
# views.py
from django.shortcuts import redirect, reverse
from urllib.parse import urlencode
from .models import Product
def call_checkout_view(request):
# Create an order with details listed below
cart = Product(
price = 89.99,
name= "iPhone XS",
description="Latest iPhone For sale"
)
cart.save()
params = urlencode({
'amount': cart.price,
'item_name': f'{cart.name}',
'item_description': cart.description,
'custom_str1': f'cart_{cart.id}',
'custom_int1': 1,
})
url = f"{reverse('payfast:checkout')}?{params}"
return redirect(url)
Note: Payment Outcome Templates
The payment_cancel_view
and payment_success_view:
Are already defined with beautiful templates
Step 7: Override Templates
Create templates/payfast/checkout.html:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>Complete Your Payment</h1>
<div class="payment-details">
<h2>{{ payment.item_name }}</h2>
<p>{{ payment.item_description }}</p>
<h3>Amount: R{{ payment.amount }}</h3>
</div>
.. Add extra Information
<div class="payment-info">
<p>You will be redirected to PayFast to complete your payment securely.</p>
</div>
</div>
{% endblock %}
Step 8: Add URL Patterns
Add the views to your urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('checkout/', views.checkout_view, name='checkout'),
path('payment/success/', views.payment_success_view, name='payment_success'),
path('payment/cancel/', views.payment_cancel_view, name='payment_cancel'),
]
Step 9: Test Your Integration
Start your development server:
python manage.py runserver
Visit
http://localhost:8000/payfast/checkout/Fill in the payment form and click “Pay with PayFast”
You’ll be redirected to PayFast sandbox
Use test card details:
Card Number: 4242 4242 4242 4242
Expiry: Any future date
CVV: Any 3 digits
Complete the payment
Check the Django admin at
/admin/payfast/payfastpayment/to see your payment record
Note
In sandbox mode, payments are simulated. No real money is charged.
Step 10: Handle Webhooks (Important!)
PayFast sends ITN (Instant Transaction Notification) webhooks when payment status changes. dj-payfast handles these automatically, but you need to ensure your webhook URL is accessible.
For Local Development
Use a tool like ngrok to expose your local server:
ngrok http 8000
Then update your notify_url to use the ngrok URL:
notify_url = 'https://your-ngrok-url.ngrok.io/payfast/notify/'
For Production
Make sure your domain is accessible and HTTPS is enabled (required by PayFast).
Next Steps
You now have a working PayFast integration! Here’s what to explore next:
Usage Guide - Learn about advanced features
Webhooks Guide - Understand webhook processing in detail
Testing Guide - Learn how to test payments
serializers - Best way to use serializers
security - Best practices for secure payments
API Reference - Complete API reference
Common Next Features
Add Custom Fields
payment = PayFastPayment.objects.create(
# ... other fields ...
custom_str1='order_123', # Your order ID
custom_int1=request.user.id, # User ID for reference
)
Handle Payment Completion
Use Django signals to trigger actions when payments complete:
from django.db.models.signals import post_save
from django.dispatch import receiver
from payfast.models import PayFastPayment
@receiver(post_save, sender=PayFastPayment)
def payment_completed(sender, instance, **kwargs):
if instance.status == 'complete' and instance.payment_status == 'COMPLETE':
# Grant access, send email, etc.
activate_premium_membership(instance.user)
Query Payments
# Get all completed payments for a user
payments = PayFastPayment.objects.filter(
user=request.user,
status='complete'
)
# Get pending payments
pending = PayFastPayment.objects.filter(status='pending')
# Get total revenue
from django.db.models import Sum
total = PayFastPayment.objects.filter(
status='complete'
).aggregate(Sum('amount'))
Troubleshooting
Webhook not receiving notifications?
Check that your
notify_urlis publicly accessibleFor local development, use ngrok
Check PayFast ITN logs in the admin:
/admin/payfast/payfastnotification/
Signature validation failing?
Make sure your passphrase matches exactly
Check that
PAYFAST_TEST_MODEis set correctlyVerify your merchant credentials
Payment status not updating?
Check the
payfast_payfastnotificationtable for validation errorsEnsure your webhook endpoint is working: visit
/payfast/notify/(should show “Method Not Allowed”)
Getting Help
Check the Frequently Asked Questions (FAQ) for common questions
See Troubleshooting Guide for solutions to common issues
Open an issue on GitHub
Congratulations! 🎉
You’ve successfully integrated PayFast into your Django application. Your users can now make secure payments directly from your website.