McTaba Labs logo
Software EngineeringThe WhiteboardProjectsEventsMasterclassesWebinarsLearn
Book Call

500+ developers already in the community

Get answers, find accountability partners, and stay ahead

Join Discord →
McTaba Labs logo

Educating 1 million students in tech by 2030.

Programs

  • HighSchool Graduates Launchpad
  • AI & Business Automation
  • Corporate Training
  • McTaba Story & Mission
  • Full-Stack Curriculum
  • Course Pricing & Plans
  • Frequently Asked Questions

Resources

  • Join Discord Community
  • Tech Events in Nairobi
  • Masterclasses
  • Free Resources
  • Learn
  • Campus
  • Africa Tech Talent Report
  • Partner With Us
  • Start a Project
  • Our Work

Contact Us

  • 124 Manyani East Road, Lavington, Nairobi
  • +254727795603
  • Book a Discovery Call

Office Hours:

Mon-Fri: 9am - 2pm EAT

Sat: 10am - 12pm EAT

© 2027 McTaba Labs - A product of Edtech Industries. All rights reserved.

Privacy PolicyTerms of ServiceRefund Policy
  1. Learn
  2. Paystack for African Developers
  3. Build an Affiliate Commission Engine
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

Build an Affiliate Commission Engine

Build an affiliate commission engine by generating unique affiliate links with tracking codes, recording clicks and conversions, attributing commissions to the last-click affiliate when a Paystack webhook fires, maintaining a pending commission ledger, and paying out via Paystack Transfers on withdrawal request.

In this article

  1. 1. Click Tracking and Conversion Attribution
  2. 2. Commission Ledger and Payout
  3. 3. Learn More

Click Tracking and Conversion Attribution

Tables: affiliates (name, email, tracking_code, commission_rate, pending_balance, paid_balance, paystack_recipient_code), affiliate_clicks (affiliate_id, visitor_ip, visitor_session, clicked_at, converted), affiliate_conversions (affiliate_id, order_id, paystack_ref, order_amount, commission_amount, status, hold_until).

// When visitor clicks affiliate link: yoursite.com/ref?code=ABC123
async function trackClick(affiliateCode, visitorIp, visitorSession) {
  var affiliate = await db.affiliates.findByCode(affiliateCode);
  if (!affiliate) return;

  await db.affiliateClicks.create({
    affiliate_id: affiliate.id,
    visitor_ip: visitorIp,
    visitor_session: visitorSession,
    clicked_at: new Date(),
  });

  // Store attribution in session/cookie (30-day window)
  return affiliate.id; // save to cookie on the response
}

// When initializing Paystack checkout — read affiliate from session/cookie
async function initializeCheckoutWithAttribution(customerEmail, amount, orderId, affiliateId) {
  var reference = 'ORD-' + Date.now();
  var res = await fetch('https://api.paystack.co/transaction/initialize', {
    method: 'POST',
    headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      email: customerEmail, amount, currency: 'NGN', reference,
      metadata: {
        order_id: orderId,
        affiliate_id: affiliateId || null, // null if no affiliate
      },
    }),
  });
  return (await res.json()).data.authorization_url;
}

Commission Ledger and Payout

// Webhook: credit commission on successful payment
if (event.event === 'charge.success') {
  var meta = event.data.metadata;
  if (!meta.affiliate_id) return res.sendStatus(200);

  var affiliate = await db.affiliates.findById(meta.affiliate_id);
  var commissionAmount = Math.floor(event.data.amount * affiliate.commission_rate);

  var holdUntil = new Date();
  holdUntil.setDate(holdUntil.getDate() + 30); // 30-day hold for refund window

  await db.affiliateConversions.create({
    affiliate_id: affiliate.id,
    order_id: meta.order_id,
    paystack_ref: event.data.reference,
    order_amount: event.data.amount,
    commission_amount: commissionAmount,
    status: 'pending', // becomes 'available' after hold period
    hold_until: holdUntil,
  });

  // Mark the click as converted
  await db.affiliateClicks.markConverted(affiliate.id, meta.order_id);
}

// Cron: release commissions after hold period
async function releaseHeldCommissions() {
  var conversions = await db.affiliateConversions.findReadyToRelease(new Date());
  for (var conversion of conversions) {
    await db.affiliateConversions.update(conversion.id, { status: 'available' });
    await db.affiliates.increment(conversion.affiliate_id, 'pending_balance', conversion.commission_amount);
  }
}

// Affiliate requests withdrawal
async function withdrawCommission(affiliateId, amount) {
  var affiliate = await db.affiliates.findById(affiliateId);
  if (amount > affiliate.pending_balance) throw new Error('Insufficient available balance');
  await db.affiliates.decrement(affiliateId, 'pending_balance', amount);

  await fetch('https://api.paystack.co/transfer', {
    method: 'POST',
    headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ source: 'balance', amount, recipient: affiliate.paystack_recipient_code, reason: 'Affiliate commission payout' }),
  });
}

Get weekly developer tips

Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.

No spam. Unsubscribe anytime.

Learn More

See build a referral payout system for a simpler referral-only version of this commission architecture.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Use last-click attribution: the affiliate who drove the final click before conversion gets the commission.
  • ✓Store affiliate_id in the Paystack transaction metadata for clean commission attribution in webhooks.
  • ✓Credit commissions to a pending_balance only after the charge.success webhook — never on click.
  • ✓Implement a 30-day hold on commissions to allow for refunds before paying affiliates.
  • ✓Pay affiliates via Paystack Transfers (bank or M-Pesa) on explicit withdrawal request with minimum threshold.

Frequently Asked Questions

What is the difference between an affiliate system and a referral system?
Referral systems are user-to-user (your existing customers invite their friends). Affiliate systems involve external publishers, bloggers, or influencers who promote your product to their audience in exchange for commission. Referral commissions are typically small (NGN 500 or 5%). Affiliate commissions are typically percentage-based (10-30%) on sales. This engine supports both models — the architecture is the same.
How do I prevent affiliate fraud (fake conversions)?
The 30-day hold before commissions become available gives you time to identify and reverse fraudulent orders before paying out. Additionally: verify that conversions come from unique IPs/devices, not the affiliate's own device. Flag self-referrals (affiliate using their own code). Monitor for conversion velocity spikes. Require email verification before affiliate accounts can withdraw.
Can affiliates track their own performance?
Build a simple affiliate dashboard showing: total clicks, total conversions, conversion rate, pending commissions (in hold period), available commissions (ready to withdraw), and paid commissions (historical). This transparency keeps affiliates motivated and reduces support requests about their earnings.

Learn Paystack Integration

KES 2,999

The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.

Start Paystack Course

Not ready? Create Free Account

Keep reading

Things You Can Build with Paystack: Project Guides

A complete map of real-world projects you can build using the Paystack API. From online store checkouts and subscription platforms to savings apps and solar pay-as-you-go systems, each category links to step-by-step build guides with working code.

Read more

Build a Parking Payment App

A build guide for a parking payment app where drivers scan a QR code on entry, pay for their session via Paystack (card or M-Pesa), and the system validates payment before the barrier lifts for exit. Covers time-based pricing, session management, and overstay handling.

Read more

Build a Referral Payout System

A build guide for a referral payout system where users share referral links, earn commissions when referrals convert, and withdraw their balance via Paystack Transfers to their bank account or M-Pesa wallet.

Read more

Build a Farmers Market Ordering Platform

A build guide for a farmers market ordering platform where customers order fresh produce from multiple farmers in one cart, the platform collects the combined payment via Paystack, and each farmer receives their share via Paystack Split Payments or Transfers. Covers inventory management, order routing to individual farmers, and delivery coordination.

Read more

Building an Event Ticketing Platform for Kenyan Events

Kenya has a growing events scene, from tech meetups and concerts to weddings and corporate conferences. Most ticketing platforms built for Western markets treat card payments as default and mobile money as an afterthought. This guide walks you through building a ticketing system that puts M-Pesa first, generates QR code tickets, handles check-ins, and splits revenue between multiple organizers.

Read more

Paystack Split Payments and Marketplaces: Complete Guide

Everything you need to split payments on Paystack: creating subaccounts, choosing between percentage and flat splits, multi-split transactions, fee configuration, delayed settlement, escrow-style patterns, and building real marketplace products with working Node.js code.

Read more

Explore related topics

M-Pesa & African Stack

M-Pesa Daraja API tutorials, USSD development, and WhatsApp Business API guides. The African Stack that global bootcamps do not teach.

Learn to Code in Kenya

Everything a Kenyan needs to know before writing their first line of code. Career paths, real costs, hardware requirements, and honest answers about what it takes.

Learning to Code

Roadmaps, language guides, and practical advice for learning to code and launching a programming career.

Breaking Into Tech

Practical, no-nonsense guides for anyone looking to start or change their career in tech. From choosing your first language to acing interviews.

The African Stack: Skills for This Market

The skills that make Kenyan developers hard to replace: M-Pesa, USSD, WhatsApp, fintech, and building for the African market.

Bonaventure Ogeto

Bonaventure Ogeto

Founder, McTaba Labs

Bonaventure is the founder of McTaba Labs, a coding bootcamp in Nairobi, Kenya. He has spent years building products for the African market and mentoring the next generation of developers across the continent.