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 a Telemedicine Consultation Payment Flow
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

Build a Telemedicine Consultation Payment Flow

Build a telemedicine payment flow by requiring patients to pay the consultation fee via Paystack before the video call link is revealed, confirming payment via the charge.success webhook, and disbursing the doctor's share via Paystack Transfers after the consultation is completed and marked by the doctor. Use Paystack Subaccounts for automatic per-doctor settlement if you have many doctors.

In this article

  1. 1. Consultation Booking and Prepayment
  2. 2. Consultation Completion and Refund Handling
  3. 3. Learn More

Consultation Booking and Prepayment

Tables: doctors (name, specialty, consultation_fee, paystack_subaccount_code, paystack_recipient_code), consultations (patient_id, doctor_id, scheduled_at, duration_mins, status, video_link, paystack_ref, paid_at).

async function bookConsultation(patientEmail, patientId, doctorId, scheduledAt) {
  var doctor = await db.doctors.findById(doctorId);
  var reference = 'TELE-' + Date.now();

  var consultation = await db.consultations.create({
    patient_id: patientId,
    doctor_id: doctorId,
    scheduled_at: scheduledAt,
    status: 'pending_payment',
    paystack_ref: reference,
  });

  // Payment required before video link is revealed
  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: patientEmail,
      amount: doctor.consultation_fee,
      currency: 'NGN',
      reference,
      subaccount: doctor.paystack_subaccount_code, // doctor gets their share automatically
      bearer: 'subaccount', // platform fees deducted from doctor's share
      metadata: { consultation_id: consultation.id, patient_id: patientId, doctor_id: doctorId },
    }),
  });
  return { consultation, authorizationUrl: (await res.json()).data.authorization_url };
}

// Webhook: payment confirmed — generate and reveal video link
if (event.event === 'charge.success') {
  var meta = event.data.metadata;
  if (!meta.consultation_id) return res.sendStatus(200);

  var videoLink = await createVideoRoom(meta.consultation_id); // e.g., Daily.co or Jitsi
  await db.consultations.update(meta.consultation_id, {
    status: 'confirmed',
    video_link: videoLink,
    paid_at: new Date(),
  });
  await sendConsultationConfirmation(meta.patient_id, meta.doctor_id, videoLink);
}

Consultation Completion and Refund Handling

// Doctor marks consultation complete
async function completeConsultation(doctorId, consultationId, notes) {
  var consultation = await db.consultations.findById(consultationId);
  if (consultation.doctor_id !== doctorId) throw new Error('Not your consultation');
  if (consultation.status !== 'confirmed') throw new Error('Consultation not confirmed');

  await db.consultations.update(consultationId, {
    status: 'completed',
    doctor_notes: notes,
    completed_at: new Date(),
  });

  // If not using subaccounts, manually pay doctor via Transfer
  var doctor = await db.doctors.findById(doctorId);
  if (!doctor.paystack_subaccount_code && doctor.paystack_recipient_code) {
    var platformFee = Math.floor(consultation.fee * 0.15); // 15% platform fee
    var doctorPayout = consultation.fee - platformFee;
    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: doctorPayout, recipient: doctor.paystack_recipient_code, reason: 'Consultation payout' }),
    });
  }
}

// Doctor cancels — refund patient in full
async function cancelByDoctor(doctorId, consultationId) {
  var consultation = await db.consultations.findById(consultationId);
  if (consultation.doctor_id !== doctorId) throw new Error('Not your consultation');

  await fetch('https://api.paystack.co/refund', {
    method: 'POST',
    headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ transaction: consultation.paystack_ref }),
  });
  await db.consultations.update(consultationId, { status: 'cancelled_by_doctor' });
  await notifyPatient(consultation.patient_id, 'Your consultation was cancelled. Full refund issued.');
}

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 veterinary clinic booking and payment system for a related booking + deposit pattern applied to in-person appointments.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Require payment before the video call link is shown — this eliminates no-shows.
  • ✓Issue the consultation link only in the charge.success webhook, never before.
  • ✓Doctors on the platform can receive payouts via Paystack Transfers to their bank account.
  • ✓For multi-doctor platforms, Paystack Subaccounts automate per-doctor revenue splitting.
  • ✓Refund the patient in full if the doctor cancels — use the Paystack Refund API with the original reference.

Frequently Asked Questions

How do I handle patients who do not show up for the video call?
Patient no-shows should not result in a refund — the doctor's time was reserved. Define a no-show policy: if the patient does not join within 10 minutes of the start time, the consultation is marked "no_show" and no refund is issued. The doctor still receives their payout. Communicate this policy clearly at booking.
Should I use Paystack Subaccounts or manual Transfers for doctor payouts?
Subaccounts are cleaner at scale — the split happens automatically at payment time and you never need to manually transfer each doctor's earnings. Use Subaccounts if you have 5+ doctors. Use manual Transfers (charge to your account, pay doctors periodically) if you are a solo clinic or have a complex per-consultation fee structure that does not map to a fixed percentage.
What video platform should I integrate with?
Daily.co (REST API to create rooms, easy to embed), Twilio Video, or Whereby work well for telemedicine. For simpler implementations, generate a unique Jitsi Meet room URL (no API needed). Reveal the link only after payment. For privacy-sensitive consultations, choose a platform with end-to-end encryption and no recording by default.

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

KRA eTIMS and Payment Receipt Integration Considerations

A developer-focused guide to integrating KRA eTIMS with payment systems. Covers what eTIMS requires, how payment receipts from Paystack relate to tax invoices, integration approaches, third-party eTIMS tools, and the compliance timeline Kenyan developers need to plan for.

Read more

Commission Models on Paystack Splits

Paystack splits let your platform automatically collect commission on every transaction. This guide covers percentage commission, flat service fees, and tiered commission by vendor volume — with code for each model.

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.