A flexible, production-ready Django package for managing affiliate marketing programs with referral tracking, commissions, and payouts.
- đź”— Referral Link Management - Create and track custom referral links
- 📊 Detailed Analytics - Track clicks, conversions, and revenue
- đź’° Commission System - Flexible commission rules (percentage or flat rate)
- đź’ł Payout Management - Handle affiliate payouts with multiple methods
- 🏢 Optional Multi-Tenancy - Support multiple platforms with isolated data
- 🎯 Attribution Models - First-click, last-click, or custom attribution
- đź”’ Secure & Production-Ready - Built with Django best practices
pip install django-affiliate-system# settings.py
INSTALLED_APPS = [
# ... other apps
'django_affiliate_system',
]# settings.py
AFFILIATE_SYSTEM = {
# Required
'DOMAIN_PROTOCOL': 'https', # or 'http' for local dev
'DOMAIN': 'yourdomain.com',
# Optional - Defaults shown
'DEFAULT_COMMISSION_RATE': 10.0, # 10%
'COOKIE_DURATION_DAYS': 30,
'DEFAULT_REDIRECT_URL': '/',
'ENABLE_MULTI_TENANCY': False, # Set True for multi-tenant
'ENABLE_SESSIONS': False, # Set True for multi-touch attribution
'DEFAULT_ATTRIBUTION_MODEL': 'last_click',
'DEFAULT_PAYOUT_THRESHOLD': 50.0,
'AUTO_APPROVE_COMMISSIONS': False,
# CORS (if tracking from different domains)
'ALLOWED_CORS_ORIGINS': [
'https://yourdomain.com',
],
}# settings.py
MIDDLEWARE = [
# ... other middleware
'django_affiliate_system.middleware.AffiliateTrackingMiddleware',
# Optional: Only if using multi-tenancy
# 'django_affiliate_system.middleware.TenantMiddleware',
# Optional: Only if tracking from different domains
# 'django_affiliate_system.middleware.CORSMiddleware',
]# urls.py
from django.urls import path, include
urlpatterns = [
# ... other urls
path('affiliates/', include('django_affiliate_system.urls')),
# Referral link redirect handler
path('r/<slug:slug>/',
'django_affiliate_system.views.ReferralLinkRedirectView.as_view(),
name='referral-redirect'),
]python manage.py migratefrom django.contrib.auth import get_user_model
from django_affiliate_system.models import Affiliate
User = get_user_model()
user = User.objects.get(email='[email protected]')
# Create affiliate (code is auto-generated if not provided)
affiliate = Affiliate.objects.create(
user=user,
code='MYAFFILIATE', # Optional: auto-generated if omitted
is_active=True,
payout_threshold=50.0,
payout_method='paypal'
)from django_affiliate_system.models import ReferralLink
link = ReferralLink.objects.create(
affiliate=affiliate,
slug='summer-sale-2024', # Must be unique
destination_url='https://yourdomain.com/products',
campaign_name='Summer Sale 2024'
)
# Full referral URL: https://yourdomain.com/?ref=summer-sale-2024Use the public API endpoint to track clicks and conversions:
import requests
# Track a click
requests.post('https://yourdomain.com/affiliates/api/referral-actions/track/', json={
'referral_code': 'MYAFFILIATE', # or 'referral_slug': 'summer-sale-2024'
'event_type': 'click',
'metadata': {
'source': 'email_campaign',
'utm_source': 'newsletter'
}
})
# Track a conversion
requests.post('https://yourdomain.com/affiliates/api/referral-actions/track/', json={
'referral_code': 'MYAFFILIATE',
'event_type': 'purchase',
'is_conversion': True,
'conversion_value': 99.99,
'metadata': {
'order_id': '12345'
}
})from django_affiliate_system.models import CommissionRule
# Percentage-based commission
CommissionRule.objects.create(
name='Purchase Commission',
action_type='purchase',
is_percentage=True,
value=10.0, # 10%
min_value=5.0, # Minimum $5
max_value=100.0, # Maximum $100
is_active=True,
priority=1
)
# Flat rate commission
CommissionRule.objects.create(
name='Signup Bonus',
action_type='signup',
is_percentage=False,
value=25.0, # $25 flat
is_active=True,
priority=1
)All endpoints require authentication except tracking endpoints.
GET /affiliates/affiliates/- List affiliates (or get own profile)GET /affiliates/affiliates/stats/- Get affiliate statisticsPOST /affiliates/affiliates/- Create affiliate (admin only)
GET /affiliates/referral-links/- List referral linksPOST /affiliates/referral-links/- Create referral linkGET /affiliates/referral-links/{id}/- Get referral link details
POST /affiliates/api/referral-actions/track/- Track any event
GET /affiliates/commissions/- List commissionsPOST /affiliates/commissions/{id}/approve/- Approve commission (admin)POST /affiliates/commissions/{id}/reject/- Reject commission (admin)
GET /affiliates/payouts/- List payoutsPOST /affiliates/payouts/request/- Request payout (affiliate)
# Via API
GET /affiliates/affiliates/stats/?date_from=2024-01-01&date_to=2024-12-31
# Response includes:
# - total_clicks, total_conversions, conversion_rate
# - total_earnings, pending_earnings, paid_earnings
# - top_links, traffic_sources, etc.// Track clicks automatically
document.querySelectorAll("a[data-affiliate-link]").forEach((link) => {
link.addEventListener("click", async (e) => {
await fetch("/affiliates/api/referral-actions/track/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
referral_code: e.target.dataset.affiliateCode,
event_type: "click",
metadata: {
page_url: window.location.href,
referrer: document.referrer,
},
}),
});
});
});
// Track conversion after purchase
async function trackPurchase(affiliateCode, orderValue) {
await fetch("/affiliates/api/referral-actions/track/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
referral_code: affiliateCode,
event_type: "purchase",
is_conversion: true,
conversion_value: orderValue,
}),
});
}Enable multi-tenancy to support multiple platforms:
# settings.py
AFFILIATE_SYSTEM = {
'ENABLE_MULTI_TENANCY': True,
# ...
}
# Add middleware
MIDDLEWARE = [
'django_affiliate_system.middleware.TenantMiddleware',
# ...
]# Create tenants
from django_affiliate_system.models import Tenant
tenant = Tenant.objects.create(
name='Platform A',
slug='platform-a',
subdomain='platforma', # platforma.yourdomain.com
destination_url='https://platforma.com',
owner=admin_user
)Track user journeys across multiple touchpoints:
# settings.py
AFFILIATE_SYSTEM = {
'ENABLE_SESSIONS': True,
'DEFAULT_ATTRIBUTION_MODEL': 'first_click', # or 'last_click'
}
# Track with session ID
requests.post('/affiliates/api/referral-actions/track/', json={
'referral_code': 'MYAFFILIATE',
'event_type': 'click',
'session_id': 'user-session-123',
'use_sessions': True
})Override commission calculation:
# your_app/services.py
from django_affiliate_system.services.commision import create_commission
from django_affiliate_system.models import Commission
def create_custom_commission(action):
# Your custom logic here
commission = Commission.objects.create(
affiliate=action.referral_link.affiliate,
referral_action=action,
amount=calculate_custom_amount(action),
rate=0,
status='pending'
)
return commissionThe package automatically registers all models in Django admin with:
- List/filter/search functionality
- CSV export
- Inline editing where appropriate
Access at: /admin/django_affiliate_system/
# Run tests
python manage.py test django_affiliate_system
# With coverage
coverage run --source='django_affiliate_system' manage.py test
coverage report- Always use HTTPS in production
- Set secure cookie settings:
# settings.py SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
- Implement rate limiting on tracking endpoints
- Validate referral codes to prevent abuse
- Use environment variables for sensitive settings
-
Use database indexes (already included in models)
-
Cache affiliate lookups:
from django.core.cache import cache affiliate = cache.get(f'affiliate_{code}') if not affiliate: affiliate = Affiliate.objects.get(code=code) cache.set(f'affiliate_{code}', affiliate, 3600)
-
Use select_related/prefetch_related for queries
-
Consider async tasks for commission calculation:
# With Celery from celery import shared_task @shared_task def process_commission(action_id): action = ReferralAction.objects.get(id=action_id) create_commission(action)
Check that:
AffiliateTrackingMiddlewareis installed- Cookies are enabled in browser
- Domain matches cookie domain
Verify:
- Commission rules exist for the action type
- Rules are active (
is_active=True) - Check logs for errors
Ensure:
ENABLE_MULTI_TENANCYisTrueTenantMiddlewareis installed- Subdomain DNS is configured correctly
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
MIT License - see LICENSE file for details
- Documentation: [docs link]
- Issues: [GitHub issues]
- Email: [email protected]
- Initial release
- Core affiliate tracking
- Commission system
- Payout management
- Optional multi-tenancy
- Multi-touch attribution