A comprehensive Django integration for Paystack Payment Gateway
Project description
paystack-django
A comprehensive Django integration for the Paystack Payment Gateway. This package provides a complete, production-ready solution for integrating Paystack payments into your Django applications.
Features
- Complete Paystack API Coverage — 26 API modules covering every Paystack endpoint
- Django Models — Pre-built models for transactions, customers, plans, subscriptions, transfers, and webhook events
- Webhook System — Signature-verified webhook handling with IP whitelisting and event deduplication
- Django Signals — Signals for payment success/failure, subscriptions, transfers, refunds, and disputes
- System Checks — Django startup checks validate your Paystack configuration
- Context Manager —
PaystackClientsupportswithstatements for clean session management - Retry & Backoff — Automatic retries with exponential back-off on transient failures
- Type Hints — Fully typed with
py.typedmarker for IDE and mypy support - Production Ready — Secure defaults, lazy logging, Decimal-safe currency conversion
Supported Services
| Category | API Modules |
|---|---|
| Payments | Transactions, Charge, Payment Requests, Pages |
| Customers | Customers, Direct Debit, Dedicated Accounts |
| Recurring | Plans, Subscriptions |
| Payouts | Transfers, Transfer Recipients, Transfer Control |
| Commerce | Products, Splits, Subaccounts |
| Operations | Refunds, Disputes, Settlements, Bulk Charges |
| Other | Verification, Terminal, Virtual Terminal, Apple Pay, Integration, Miscellaneous |
Installation
pip install paystack-django
Quick Start
1. Add to Django Settings
# settings.py
INSTALLED_APPS = [
# ...
'djpaystack',
]
PAYSTACK = {
'SECRET_KEY': 'sk_live_your_secret_key_here',
'PUBLIC_KEY': 'pk_live_your_public_key_here',
'WEBHOOK_SECRET': 'whsec_your_webhook_secret',
}
2. Run Migrations
python manage.py migrate djpaystack
3. Initialize a Transaction
from djpaystack import PaystackClient
client = PaystackClient()
response = client.transactions.initialize(
email='customer@example.com',
amount=50000, # Amount in kobo (500 NGN)
reference='order-001',
)
authorization_url = response['data']['authorization_url']
# Redirect user to authorization_url
The client can also be used as a context manager:
with PaystackClient() as client:
response = client.transactions.verify(reference='order-001')
4. Verify Transaction
response = client.transactions.verify(reference='order-001')
if response['data']['status'] == 'success':
print("Payment successful!")
5. Set Up Webhooks
# urls.py
from django.urls import path
from djpaystack.webhooks.views import handle_webhook
urlpatterns = [
path('webhooks/paystack/', handle_webhook, name='paystack_webhook'),
]
Configure the webhook URL in your Paystack Dashboard.
Usage Examples
Customers
client = PaystackClient()
# Create customer
response = client.customers.create(
email='customer@example.com',
first_name='John',
last_name='Doe',
phone='2348012345678',
)
# Fetch customer
response = client.customers.fetch(email_or_code='CUS_xxxxx')
Subscriptions
# Create a plan
response = client.plans.create(
name='Monthly Pro',
amount=500000, # 5,000 NGN
interval='monthly',
)
plan_code = response['data']['plan_code']
# Subscribe a customer
response = client.subscriptions.create(
customer='CUS_xxxxx',
plan=plan_code,
authorization='AUTH_xxxxx',
)
Transfers
# Create transfer recipient
response = client.transfer_recipients.create(
type='nuban',
name='John Doe',
account_number='0000000000',
bank_code='058',
)
recipient_code = response['data']['recipient_code']
# Initiate transfer
response = client.transfers.initiate(
source='balance',
amount=50000,
recipient=recipient_code,
reason='Payout',
)
Charge (Card, Bank Transfer, USSD, QR, EFT)
# Charge with bank transfer
response = client.charge.create(
email='customer@example.com',
amount=50000,
bank_transfer={'account_expires_at': '2025-12-31T23:59:59'},
)
# Charge with QR code (scan-to-pay)
response = client.charge.create(
email='customer@example.com',
amount=50000,
qr={'provider': 'visa'},
)
Refunds
# Create refund
response = client.refunds.create(transaction='123456')
# Retry a stuck refund
response = client.refunds.retry(id='123456')
Dedicated Virtual Accounts
# Single-step assignment
response = client.dedicated_accounts.assign(
email='customer@example.com',
first_name='John',
last_name='Doe',
phone='+2348012345678',
preferred_bank='wema-bank',
)
Dynamic Transaction Splits
response = client.transactions.initialize(
email='customer@example.com',
amount=100000,
split={
'type': 'percentage',
'bearer_type': 'account',
'subaccounts': [
{'subaccount': 'ACCT_xxx', 'share': 30},
{'subaccount': 'ACCT_yyy', 'share': 20},
],
},
)
Webhook Signals
Listen for payment events using Django signals:
from django.dispatch import receiver
from djpaystack.signals import paystack_payment_successful, paystack_payment_failed
@receiver(paystack_payment_successful)
def on_payment_success(sender, transaction_data, **kwargs):
reference = transaction_data['reference']
# Fulfil the order
@receiver(paystack_payment_failed)
def on_payment_failed(sender, transaction_data, **kwargs):
reference = transaction_data['reference']
# Notify the customer
Available signals: paystack_payment_successful, paystack_payment_failed, paystack_subscription_created, paystack_subscription_cancelled, paystack_transfer_successful, paystack_transfer_failed, paystack_refund_processed, paystack_dispute_created, paystack_dispute_resolved.
Configuration Reference
PAYSTACK = {
# Required
'SECRET_KEY': 'sk_...',
'PUBLIC_KEY': 'pk_...',
# Webhook
'WEBHOOK_SECRET': 'whsec_...',
'ALLOWED_WEBHOOK_IPS': [], # Empty = Paystack default IPs
# API behaviour
'BASE_URL': 'https://api.paystack.co',
'TIMEOUT': 30,
'MAX_RETRIES': 3,
'VERIFY_SSL': True,
'CURRENCY': 'NGN',
'ENVIRONMENT': 'production', # 'production' or 'test'
# Features
'AUTO_VERIFY_TRANSACTIONS': True,
'ENABLE_SIGNALS': True,
'ENABLE_MODELS': True,
'CACHE_TIMEOUT': 300,
'LOG_REQUESTS': False,
'LOG_RESPONSES': False,
'CALLBACK_URL': None,
}
Django Models
from djpaystack.models import (
PaystackTransaction,
PaystackCustomer,
PaystackPlan,
PaystackSubscription,
PaystackTransfer,
PaystackWebhookEvent,
)
Error Handling
from djpaystack.exceptions import (
PaystackError,
PaystackAPIError,
PaystackValidationError,
PaystackAuthenticationError,
PaystackNetworkError,
)
try:
response = client.transactions.verify(reference='ref-123')
except PaystackAuthenticationError:
print("Invalid API key")
except PaystackNetworkError:
print("Network error — will be retried automatically")
except PaystackAPIError as e:
print(f"API error: {e}")
Django Compatibility
| paystack-django | Django 3.2 | 4.0 | 4.1 | 4.2 | 5.0 | 5.2 | 6.0 |
|---|---|---|---|---|---|---|---|
| 1.1.x | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Python 3.8 – 3.14 supported.
Testing
pip install -e ".[dev]"
pytest --cov=djpaystack
Documentation
Full documentation is available at django-paystack.readthedocs.io.
Contributing
See CONTRIBUTING.md for guidelines.
License
MIT — see LICENSE.
Links
Made with ❤️ by Humming Byte
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paystack_django-1.1.0.tar.gz.
File metadata
- Download URL: paystack_django-1.1.0.tar.gz
- Upload date:
- Size: 55.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66d498154ad08e4dfacaf1b20bdb09a0a4bbe08b1c26c91289d2c320803b480b
|
|
| MD5 |
8f4aa23dd5e380160932ce7b3f03bbf2
|
|
| BLAKE2b-256 |
e8ef9f65f87bdc7c349e3a0e6fdc35f8ceb75806c804634cb740f56f28bbd9cd
|
Provenance
The following attestation bundles were made for paystack_django-1.1.0.tar.gz:
Publisher:
publish.yml on HummingByteDev/paystack-django
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
paystack_django-1.1.0.tar.gz -
Subject digest:
66d498154ad08e4dfacaf1b20bdb09a0a4bbe08b1c26c91289d2c320803b480b - Sigstore transparency entry: 971153319
- Sigstore integration time:
-
Permalink:
HummingByteDev/paystack-django@6a6bcec26546e720751992412122f43f00ecfd20 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/HummingByteDev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6a6bcec26546e720751992412122f43f00ecfd20 -
Trigger Event:
release
-
Statement type:
File details
Details for the file paystack_django-1.1.0-py3-none-any.whl.
File metadata
- Download URL: paystack_django-1.1.0-py3-none-any.whl
- Upload date:
- Size: 71.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6a7f5fa756819d4358eb4f8e9a601037d7cee8593f4229beec9706813ddcf0c
|
|
| MD5 |
b122d1f4828be6df4498a3787039052b
|
|
| BLAKE2b-256 |
59b6e12d0284d199096b568b2d5d543ebd05773cb1d1d20e64d930c64bb3a670
|
Provenance
The following attestation bundles were made for paystack_django-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on HummingByteDev/paystack-django
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
paystack_django-1.1.0-py3-none-any.whl -
Subject digest:
e6a7f5fa756819d4358eb4f8e9a601037d7cee8593f4229beec9706813ddcf0c - Sigstore transparency entry: 971153377
- Sigstore integration time:
-
Permalink:
HummingByteDev/paystack-django@6a6bcec26546e720751992412122f43f00ecfd20 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/HummingByteDev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6a6bcec26546e720751992412122f43f00ecfd20 -
Trigger Event:
release
-
Statement type: