Bonaventure OgetoBy Bonaventure Ogeto|

Build a Tutoring Marketplace with Split Payments

Build a tutoring marketplace with split payments by onboarding tutors with Paystack subaccounts (each tutor gets a subaccount tied to their bank account), then initializing each session payment with the tutor's subaccount code. Paystack routes 80% to the tutor at settlement and 20% stays in your platform account. The student pays one amount; Paystack handles the split.

Tutor Onboarding with Subaccounts

Tables: tutors (name, email, subject, hourly_rate, paystack_subaccount_code, status), sessions (tutor_id, student_id, subject, duration_mins, total_amount, scheduled_at, status, paystack_ref), students (name, email).

async function onboardTutor(tutorData) {
  // Create Paystack subaccount with tutor's bank details
  var res = await fetch('https://api.paystack.co/subaccount', {
    method: 'POST',
    headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      business_name: tutorData.name + ' - Tutoring',
      bank_code: tutorData.bank_code,
      account_number: tutorData.account_number,
      percentage_charge: 80, // Tutor gets 80%, platform keeps 20%
    }),
  });
  var data = await res.json();

  await db.tutors.update(tutorData.id, {
    paystack_subaccount_code: data.data.subaccount_code,
    status: 'active',
  });
  return data.data.subaccount_code;
}

The subaccount is created once per tutor. After that, every session payment automatically routes the tutor's share to their bank account at settlement — no manual payout work needed.

Session Booking and Payment

async function bookSession(studentId, studentEmail, tutorId, scheduledAt, durationMins) {
  var tutor = await db.tutors.findById(tutorId);
  var totalAmount = Math.ceil((tutor.hourly_rate / 60) * durationMins);

  var reference = 'SES-' + Date.now();
  var session = await db.sessions.create({
    tutor_id: tutorId, student_id: studentId,
    duration_mins: durationMins, total_amount: totalAmount,
    scheduled_at: scheduledAt, status: 'pending',
    paystack_ref: reference,
  });

  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: studentEmail,
      amount: totalAmount,
      currency: 'NGN',
      reference,
      subaccount: tutor.paystack_subaccount_code,
      bearer: 'account', // platform bears Paystack fees
      metadata: { session_id: session.id, tutor_id: tutorId, duration_mins: durationMins },
    }),
  });
  return (await res.json()).data.authorization_url;
}

// Webhook: confirm booking
if (event.event === 'charge.success') {
  var sessionId = event.data.metadata.session_id;
  await db.sessions.update(sessionId, { status: 'confirmed' });
  await notifyTutor(event.data.metadata.tutor_id, sessionId);
  await notifyStudent(studentId, sessionId);
}

At settlement time, Paystack sends 80% to the tutor's bank account and 20% stays in your platform Paystack account. You do not need to manually calculate or transfer the split — it is automatic.

Learn More

See build a home services booking marketplace for the same subaccount split pattern applied to service providers.

Sign up for the McTaba newsletter

Key Takeaways

  • Create a Paystack subaccount per tutor — they receive their share automatically at settlement.
  • The platform keeps commission without manually transferring money to tutors.
  • Set the split percentage based on your commission model (80/20 or 70/30).
  • Tutors need to complete KYC (bank account verified by Paystack) before they can receive payouts.
  • Handle session reschedules by updating the booking without creating a new payment transaction.

Frequently Asked Questions

When does the tutor receive their payment?
Paystack settles subaccount funds on the same T+1 or T+2 schedule as your main account (depending on the currency and market). The tutor does not receive money instantly — they receive it the next business day or within 2 business days. Communicate this clearly to tutors during onboarding so they understand settlement timing.
What if a student wants a refund after the session has already happened?
Establish a refund policy before launch. Common approach: refund if the tutor did not show up, no refund if the session was completed. Partial refunds for sessions where the tutor logged off early. If you issue a refund after the subaccount has already settled, Paystack debits the refund from your next settlement — meaning you may need to reclaim the funds from the tutor separately.
How do I handle group tutoring sessions where multiple students pay?
Each student pays separately for the same session. Create one session record and multiple payment records (one per student). The tutor's subaccount receives their percentage of each student's payment. Track attendance per student to handle partial refunds if a student misses a group session they already paid for.

Ready to build real-world apps?

Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.

Apply to the McTaba Marathon