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 Barbershop Appointment and Payment App
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

Build a Barbershop Appointment and Payment App

Build a barbershop appointment app by managing time slots per barber, requiring a deposit (NGN 500-1,000) to confirm the booking via Paystack, and releasing the slot back to available if payment does not complete within 15 minutes. The deposit is applied toward the final bill; clients forfeit it if they no-show without 2 hours notice.

In this article

  1. 1. Slot Management and Booking
  2. 2. Confirmation and Appointment Reminders
  3. 3. Learn More

Slot Management and Booking

Tables: barbers (name, specialty, avatar_url), services (name, duration_mins, price), slots (barber_id, date, start_time, end_time, status, booking_id), bookings (client_name, client_phone, barber_id, service_id, slot_id, deposit_paid, status, paystack_ref).

async function getAvailableSlots(barberId, date, serviceDurationMins) {
  return db.slots.findAll({
    barber_id: barberId, date, status: 'available',
    duration_gte: serviceDurationMins, // only slots long enough for the service
  });
}

async function holdAndPay(clientData, barberId, serviceId, slotId) {
  var service = await db.services.findById(serviceId);
  var slot = await db.slots.findById(slotId);
  if (slot.status !== 'available') throw new Error('Slot already booked');

  var deposit = 50000; // NGN 500 in kobo
  var reference = 'BARBER-' + Date.now();

  // Hold the slot
  await db.slots.update(slotId, { status: 'held', held_until: new Date(Date.now() + 15 * 60000) });

  var booking = await db.bookings.create({
    ...clientData, barber_id: barberId, service_id: serviceId, slot_id: slotId,
    deposit_paid: deposit, 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: clientData.email, amount: deposit, currency: 'NGN', reference,
      metadata: { booking_id: booking.id, slot_id: slotId, service: service.name },
    }),
  });
  return (await res.json()).data.authorization_url;
}

// Cron: release held slots where payment did not complete
async function releaseExpiredHolds() {
  var expiredSlots = await db.slots.findAll({ status: 'held', held_until_lt: new Date() });
  for (var slot of expiredSlots) {
    await db.slots.update(slot.id, { status: 'available', held_until: null });
    await db.bookings.update({ slot_id: slot.id, status: 'pending' }, { status: 'expired' });
  }
}

Confirmation and Appointment Reminders

if (event.event === 'charge.success') {
  var bookingId = event.data.metadata.booking_id;
  var slotId = event.data.metadata.slot_id;

  await db.bookings.update(bookingId, { status: 'confirmed' });
  await db.slots.update(slotId, { status: 'booked', booking_id: bookingId, held_until: null });

  var booking = await db.bookings.findById(bookingId);
  var slot = await db.slots.findById(slotId);

  // Send confirmation SMS
  await sendSMS(booking.client_phone, 'Booking confirmed! ' + slot.date + ' at ' + slot.start_time + '. Deposit: NGN ' + (event.data.amount / 100) + '. See you soon!');

  // Schedule reminder SMS 2 hours before appointment
  await scheduleReminder(booking.client_phone, slot.date, slot.start_time);
}

For no-show handling: if the client does not arrive within 30 minutes of their slot, mark the booking as "no_show". The deposit is forfeited (it stays in your account). Offer the barber a small compensation from the forfeited deposit as an incentive for holding the slot.

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 photography booking and deposit flow for the deposit pattern applied to creative service bookings.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Require a small deposit (NGN 500-1,000) at booking to dramatically reduce no-shows.
  • ✓Slot management per barber: each barber has their own calendar of available slots.
  • ✓Auto-release booked slots after 15 minutes if payment does not complete.
  • ✓Apply the deposit toward the final bill — clients pay only the balance at the shop.
  • ✓For multi-branch barbershops, use Paystack subaccounts to route each branch's deposits to their account.

Frequently Asked Questions

Should the deposit be refundable if the client cancels in advance?
Offer free cancellation up to 2 hours before the appointment — full deposit refund via Paystack Refund API. Within 2 hours, the deposit is forfeited. This policy protects the barber's time while being fair to clients who have genuine reasons to cancel with enough notice.
How do I handle walk-in clients who do not book online?
Walk-in clients pay at the counter (cash or POS). Create a simple admin panel for barbers to manually mark slots as "walk-in" with cash payment noted. This keeps your slot calendar accurate for online bookings and lets you track revenue from both channels.
Can I build this for a multi-branch barbershop?
Yes. Add a branches table and link barbers and slots to branches. On the booking page, let clients select a branch first, then choose a barber at that branch. If you want each branch to receive their own payouts, create a Paystack subaccount per branch and route deposits accordingly.

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 an Affiliate Commission Engine

A build guide for an affiliate commission engine where affiliates share tracking links, earn commissions when their referrals convert (pay via Paystack), and withdraw their balance via bank transfer. Covers click tracking, last-click attribution, commission ledger, and Paystack Transfers payout.

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 a Hospital Bill Payment System in Kenya

A developer guide to building a hospital bill payment system for Kenyan healthcare facilities. Covers patient registration, bill generation, partial payments and deposits, insurance co-pay handling, M-Pesa and card collection via Paystack, inpatient vs outpatient flows, and data protection for medical payments.

Read more

Splitting Payments Between a School and Its Departments

When a student pays school fees, the money needs to be split across multiple departments — tuition to the main account, library fee to the library department, sports levy to sports. This guide covers routing a single student payment to multiple department subaccounts using Paystack Transaction Splits.

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.