Affiliates Plugin
Affiliate and partnership management system
Affiliates Plugin
The Affiliates Plugin provides a complete affiliate and partnership management system with referral tracking, commission management, payouts, and performance analytics.
Installation
npm install @deessejs/plugin-affiliatesConfiguration
// deesse.config.ts
import { defineConfig } from '@deessejs/core'
import { affiliatesPlugin } from '@deessejs/plugin-affiliates'
export const config = defineConfig({
plugins: [
affiliatesPlugin({
// Commission settings
commission: {
defaultRate: 10, // Default commission percentage
defaultType: 'percentage', // 'percentage' or 'fixed'
minPayout: 50, // Minimum payout amount
payoutCurrency: 'USD',
},
// Cookie tracking
tracking: {
cookieDays: 30, // Cookie validity in days
cookieName: 'affiliate_referral',
allowSelfReferral: false, // Prevent self-referrals
},
// Approval workflow
approval: {
autoApprove: false, // Require manual approval
verificationRequired: true,
},
// Payouts
payouts: {
method: 'manual', // 'manual', 'stripe', 'paypal'
frequency: 'monthly', // 'weekly', 'monthly', 'quarterly'
processingDays: 7, // Days to process payouts
},
// Performance tiers
tiers: {
enabled: true,
tiers: [
{ level: 1, name: 'Bronze', minSales: 0, commission: 10 },
{ level: 2, name: 'Silver', minSales: 1000, commission: 15 },
{ level: 3, name: 'Gold', minSales: 5000, commission: 20 },
{ level: 4, name: 'Platinum', minSales: 10000, commission: 25 },
],
},
// Notifications
notifications: {
newReferral: true,
commissionEarned: true,
payoutSent: true,
tierUpgraded: true,
},
}),
],
})Collections
Affiliates
Affiliate accounts and profiles:
{
name: 'affiliates',
fields: [
{
name: 'user',
type: 'reference',
relation: 'users',
required: true,
unique: true,
},
{
name: 'affiliateCode',
type: 'string',
unique: true,
admin: {
description: 'Unique affiliate referral code',
},
},
{
name: 'status',
type: 'enum',
enum: ['pending', 'approved', 'suspended', 'rejected'],
defaultValue: 'pending',
},
{
name: 'commissionRate',
type: 'number',
defaultValue: 10,
admin: {
description: 'Custom commission rate (overrides default)',
},
},
{
name: 'tier',
type: 'enum',
enum: ['bronze', 'silver', 'gold', 'platinum'],
defaultValue: 'bronze',
},
{
name: 'totalEarnings',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'pendingEarnings',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'totalPaid',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'totalReferrals',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'totalSales',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'payoutMethod',
type: 'enum',
enum: ['bank', 'paypal', 'stripe', 'wise'],
},
{
name: 'payoutDetails',
type: 'json',
admin: {
description: 'Payment method details (encrypted)',
},
},
{
name: 'taxId',
type: 'string',
admin: {
description: 'Tax identification number',
},
},
{
name: 'website',
type: 'string',
},
{
name: 'promotionalMethods',
type: 'array',
admin: {
description: 'How they plan to promote',
},
},
{
name: 'reason',
type: 'richtext',
admin: {
description: 'Why they want to join',
},
},
{
name: 'approvedAt',
type: 'datetime',
},
{
name: 'notes',
type: 'richtext',
admin: {
description: 'Internal notes about this affiliate',
},
},
],
}Referrals
Referral tracking records:
{
name: 'referrals',
fields: [
{
name: 'affiliate',
type: 'reference',
relation: 'affiliates',
required: true,
},
{
name: 'referredUser',
type: 'reference',
relation: 'users',
},
{
name: 'referralCode',
type: 'string',
required: true,
},
{
name: 'status',
type: 'enum',
enum: ['clicked', 'signed_up', 'purchased', 'completed'],
defaultValue: 'clicked',
},
{
name: 'clickedAt',
type: 'datetime',
defaultValue: () => new Date(),
},
{
name: 'signedUpAt',
type: 'datetime',
},
{
name: 'purchasedAt',
type: 'datetime',
},
{
name: 'ipAddress',
type: 'string',
},
{
name: 'userAgent',
type: 'string',
},
{
name: 'landingPage',
type: 'string',
admin: {
description: 'First page visited',
},
},
{
name: 'conversionRate',
type: 'number',
admin: {
readOnly: true,
},
},
],
}Commissions
Commission records:
{
name: 'commissions',
fields: [
{
name: 'affiliate',
type: 'reference',
relation: 'affiliates',
required: true,
},
{
name: 'referral',
type: 'reference',
relation: 'referrals',
},
{
name: 'order',
type: 'string',
admin: {
description: 'Order ID or reference',
},
},
{
name: 'amount',
type: 'number',
required: true,
admin: {
description: 'Sale amount',
},
},
{
name: 'commissionRate',
type: 'number',
required: true,
admin: {
description: 'Commission percentage used',
},
},
{
name: 'commissionAmount',
type: 'number',
required: true,
admin: {
description: 'Earned commission',
},
},
{
name: 'status',
type: 'enum',
enum: ['pending', 'approved', 'paid', 'rejected'],
defaultValue: 'pending',
},
{
name: 'type',
type: 'enum',
enum: ['percentage', 'fixed'],
defaultValue: 'percentage',
},
{
name: 'earnedAt',
type: 'datetime',
defaultValue: () => new Date(),
},
{
name: 'approvedAt',
type: 'datetime',
},
{
name: 'paidAt',
type: 'datetime',
},
{
name: 'payout',
type: 'reference',
relation: 'payouts',
admin: {
description: 'Associated payout',
},
},
{
name: 'notes',
type: 'text',
},
],
}Payouts
Payout records:
{
name: 'payouts',
fields: [
{
name: 'affiliate',
type: 'reference',
relation: 'affiliates',
required: true,
},
{
name: 'amount',
type: 'number',
required: true,
},
{
name: 'status',
type: 'enum',
enum: ['pending', 'processing', 'completed', 'failed'],
defaultValue: 'pending',
},
{
name: 'method',
type: 'enum',
enum: ['bank', 'paypal', 'stripe', 'wise'],
},
{
name: 'transactionId',
type: 'string',
admin: {
description: 'External transaction ID',
},
},
{
name: 'periodStart',
type: 'date',
},
{
name: 'periodEnd',
type: 'date',
},
{
name: 'requestedAt',
type: 'datetime',
defaultValue: () => new Date(),
},
{
name: 'processedAt',
type: 'datetime',
},
{
name: 'completedAt',
type: 'datetime',
},
{
name: 'currency',
type: 'string',
defaultValue: 'USD',
},
{
name: 'fees',
type: 'number',
defaultValue: 0,
admin: {
description: 'Processing fees deducted',
},
},
{
name: 'netAmount',
type: 'number',
admin: {
description: 'Amount after fees',
},
},
{
name: 'receiptUrl',
type: 'string',
admin: {
description: 'PDF receipt URL',
},
},
{
name: 'notes',
type: 'richtext',
},
],
}Creative Assets
Promotional materials for affiliates:
{
name: 'affiliateCreatives',
fields: [
{
name: 'name',
type: 'string',
required: true,
},
{
name: 'type',
type: 'enum',
enum: ['banner', 'text', 'email', 'social', 'video'],
required: true,
},
{
name: 'description',
type: 'text',
},
{
name: 'image',
type: 'media',
},
{
name: 'htmlCode',
type: 'text',
admin: {
description: 'Embed HTML for banners',
},
},
{
name: 'text',
type: 'text',
admin: {
description: 'Text ad copy',
},
},
{
name: 'url',
type: 'string',
admin: {
description: 'Destination URL',
},
},
{
name: 'size',
type: 'string',
admin: {
description: 'Banner dimensions (e.g., 728x90)',
},
},
{
name: 'isActive',
type: 'boolean',
defaultValue: true,
},
{
name: 'clicks',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
{
name: 'conversions',
type: 'number',
defaultValue: 0,
admin: {
readOnly: true,
},
},
],
}Partnerships
Strategic partnership management:
{
name: 'partnerships',
fields: [
{
name: 'name',
type: 'string',
required: true,
},
{
name: 'slug',
type: 'string',
unique: true,
},
{
name: 'type',
type: 'enum',
enum: ['affiliate', 'reseller', 'strategic', 'integration'],
required: true,
},
{
name: 'status',
type: 'enum',
enum: ['pending', 'active', 'paused', 'ended'],
defaultValue: 'pending',
},
{
name: 'logo',
type: 'media',
},
{
name: 'website',
type: 'string',
},
{
name: 'description',
type: 'richtext',
},
{
name: 'commissionRate',
type: 'number',
defaultValue: 10,
},
{
name: 'contactPerson',
type: 'string',
},
{
name: 'contactEmail',
type: 'string',
},
{
name: 'startDate',
type: 'date',
},
{
name: 'endDate',
type: 'date',
},
{
name: 'terms',
type: 'richtext',
admin: {
description: 'Partnership terms and conditions',
},
},
],
}Admin Pages
Affiliates Dashboard
- Affiliate overview with metrics
- Pending approvals queue
- Performance leaderboard
- Quick actions
Affiliate Management
- Detailed affiliate profiles
- Commission rate adjustments
- Tier management
- Status changes
Referrals Tracker
- Real-time referral tracking
- Conversion funnel
- Source attribution
- Geographic distribution
Commissions Management
- Commission queue
- Approval workflow
- Rejection handling
- Bulk operations
Payouts Center
- Payout queue
- Processing status
- Payment methods
- Generate payouts
Creative Assets
- Upload/manage creatives
- Performance tracking
- Preview assets
- Generate embed codes
API Routes
# Affiliate operations
GET /api/affiliates
GET /api/affiliates/me
POST /api/affiliates/register
PUT /api/affiliates/me
GET /api/affiliates/me/stats
# Referral tracking
POST /api/affiliates/track
GET /api/affiliates/me/referrals
GET /api/referrals/:code
# Commissions
GET /api/affiliates/me/commissions
GET /api/commissions
PUT /api/commissions/:id/approve
PUT /api/commissions/:id/reject
# Payouts
GET /api/affiliates/me/payouts
POST /api/affiliates/me/payouts/request
GET /api/payouts
POST /api/payouts/process
PUT /api/payouts/:id/status
# Creative assets
GET /api/affiliates/creatives
GET /api/affiliates/creatives/:id/embed
# Tracking
GET /api/ref/:code # Redirect with trackingFrontend Components
AffiliateSignup Component
import { AffiliateSignup } from '@deessejs/plugin-affiliates/components'
export default function JoinPage() {
return (
<AffiliateSignup
showTerms
requireApproval
onSuccess={() => router.push('/affiliate/dashboard')}
/>
)
}ReferralLink Component
import { ReferralLink } from '@deessejs/plugin-affiliates/components'
export default function ShareLink() {
return (
<ReferralLink
variant="input"
showQrCode
showCopyButton
shareOptions={['twitter', 'facebook', 'linkedin', 'email']}
/>
)
}CreativeGallery Component
import { CreativeGallery } from '@deessejs/plugin-affiliates/components'
export default function MarketingPage() {
return (
<CreativeGallery
filterByType={['banner', 'text', 'social']}
showPreview
showEmbedCode
showPerformance
/>
)
}AffiliateStats Component
import { AffiliateStats } from '@deessejs/plugin-affiliates/components'
export default function Dashboard() {
return (
<AffiliateStats
period="month" // 'week', 'month', 'year', 'all'
showEarnings
showReferrals
showConversion
showCharts
/>
)
}CommissionTable Component
import { CommissionTable } from '@deessejs/plugin-affiliates/components'
export default function EarningsPage() {
return (
<CommissionTable
status="all" // 'pending', 'approved', 'paid', 'all'
pagination={25}
exportData
/>
)
}Hooks
useAffiliate
'use client'
import { useAffiliate } from '@deessejs/plugin-affiliates/hooks'
export default function ProfilePage() {
const { affiliate, loading, error } = useAffiliate()
if (loading) return <div>Loading...</div>
if (!affiliate) return <div>Not an affiliate</div>
return (
<div>
<h2>Affiliate Code: {affiliate.affiliateCode}</h2>
<p>Earnings: ${affiliate.totalEarnings}</p>
</div>
)
}useReferralTracking
'use client'
import { useReferralTracking } from '@deessejs/plugin-affiliates/hooks'
export default function LandingPage() {
const { trackReferral } = useReferralTracking()
useEffect(() => {
// Automatically track referral on page load
trackReferral()
}, [])
return <div>Landing page content</div>
}useAffiliateStats
'use client'
import { useAffiliateStats } from '@deessejs/plugin-affiliates/hooks'
export default function StatsPage() {
const { stats, loading } = useAffiliateStats({
period: 'month',
})
return (
<div>
<h3>Earnings: ${stats.totalEarnings}</h3>
<h3>Referrals: {stats.totalReferrals}</h3>
<h3>Conversion Rate: {stats.conversionRate}%</h3>
</div>
)
}Server Functions
trackReferral
import { trackReferral } from '@deessejs/plugin-affiliates/server'
// Track referral click
export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const code = searchParams.get('ref')
if (code) {
await trackReferral({
code,
userAgent: request.headers.get('user-agent'),
ipAddress: request.headers.get('x-forwarded-for'),
landingPage: request.headers.get('referer'),
})
// Set cookie
const response = NextResponse.redirect(new URL('/', request.url))
response.cookies.set('affiliate_referral', code, {
maxAge: 30 * 24 * 60 * 60, // 30 days
})
return response
}
}createCommission
import { createCommission } from '@deessejs/plugin-affiliates/server'
// Create commission on purchase
export async function afterCheckout(order: Order) {
const referralCookie = cookies().get('affiliate_referral')
if (referralCookie) {
await createCommission({
referralCode: referralCookie.value,
orderAmount: order.total,
orderId: order.id,
})
}
}Referral URL Structure
/ref/:code # Redirect URL
?ref=CODE # Query parameter format
/affiliate # Affiliate program page
/affiliate/join # Registration page
/affiliate/dashboard # Affiliate dashboard
/affiliate/creatives # Marketing materials
/affiliate/stats # Performance stats
/affiliate/earnings # Commission history
/affiliate/payouts # Payout history
/admin/affiliates # Admin management
/admin/affiliates/:id # Affiliate details
/admin/commissions # Commission management
/admin/payouts # Payout processing
/admin/creatives # Creative assets
/admin/partnerships # Partnership managementCommission Calculation
// Percentage-based commission
commission = saleAmount * (commissionRate / 100)
// Fixed commission
commission = fixedAmount
// Tier-based commission
if (totalSales >= 10000) rate = 25 // Platinum
else if (totalSales >= 5000) rate = 20 // Gold
else if (totalSales >= 1000) rate = 15 // Silver
else rate = 10 // Bronze
commission = saleAmount * (rate / 100)Payout Processing
// Process pending commissions
async function processPayouts() {
const affiliates = await db.affiliates.findMany({
where: {
status: 'approved',
pendingEarnings: { gte: minPayout },
},
})
for (const affiliate of affiliates) {
const payout = await createPayout(affiliate)
await sendPayoutEmail(affiliate, payout)
}
}Next Steps
- Explore the Students Plugin
- Learn about Analytics Plugin
- Return to Plugins Overview