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 Pharmacy Ordering and Delivery App
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

Build a Pharmacy Ordering and Delivery App

Build a pharmacy ordering app by separating OTC (over-the-counter) and prescription medicine flows: OTC medicines pay immediately via Paystack; prescription medicines require a prescription photo upload and pharmacist approval before payment is collected. Use webhooks to confirm payment and trigger order fulfillment.

In this article

  1. 1. OTC vs Prescription Order Flow
  2. 2. Webhook Confirmation and Delivery Scheduling
  3. 3. Learn More

OTC vs Prescription Order Flow

Tables: medicines (name, category, price, requires_prescription, stock), orders (customer_id, items[], total, prescription_url, pharmacist_id, status, paystack_ref), deliveries (order_id, address, scheduled_time, rider_id, status).

OTC flow (most orders): customer selects medicines → cart total calculated → pay via Paystack → webhook confirms → order goes to pharmacy for picking.

Prescription flow: customer uploads prescription photo → order status: "awaiting_review" → pharmacist reviews (approves/rejects/modifies) → Paystack payment initialized → customer pays → order fulfilled.

async function createOrder(customerId, cartItems, prescriptionUrl) {
  var hasPrescriptionItems = cartItems.some(item => item.requires_prescription);
  var total = cartItems.reduce((sum, item) => sum + (item.price * item.qty), 0);

  var order = await db.orders.create({
    customer_id: customerId,
    items: cartItems,
    total,
    prescription_url: prescriptionUrl || null,
    status: hasPrescriptionItems ? 'awaiting_review' : 'pending_payment',
  });

  if (!hasPrescriptionItems) {
    // OTC: go straight to payment
    return await initializePayment(order);
  }
  // Prescription: wait for pharmacist to call initiatePaymentAfterApproval(orderId)
  return { order, message: 'Prescription submitted for review. You will receive a payment link once approved.' };
}

async function approveAndCharge(orderId, pharmacistId, finalAmount) {
  await db.orders.update(orderId, { status: 'approved', pharmacist_id: pharmacistId, total: finalAmount });
  return await initializePayment(await db.orders.findById(orderId));
}

Webhook Confirmation and Delivery Scheduling

if (event.event === 'charge.success') {
  var order = await db.orders.findByPaystackRef(event.data.reference);
  await db.orders.update(order.id, { status: 'paid' });

  // Notify pharmacy to start picking
  await notifyPharmacy(order.id);

  // Schedule delivery
  await db.deliveries.create({
    order_id: order.id,
    address: order.delivery_address,
    status: 'pending',
  });
}

// Track delivery stages
async function updateDelivery(deliveryId, newStatus, riderId) {
  var delivery = await db.deliveries.findById(deliveryId);
  await db.deliveries.update(deliveryId, { status: newStatus, rider_id: riderId });

  var statusMessages = {
    'picked_up': 'Your order has been picked up by our rider',
    'en_route': 'Your medicines are on the way',
    'delivered': 'Your order has been delivered',
  };

  await sendSMS(delivery.customer_phone, statusMessages[newStatus]);
}

For controlled substances and high-value prescription medicines, require an OTP or digital signature from the customer at delivery. This creates an audit trail showing the customer received their medicine.

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 grocery delivery app with rider payouts for the delivery and rider payout side of this architecture.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Separate OTC and prescription flows — prescription orders require pharmacist verification before payment.
  • ✓For prescription orders, collect prescription photo at order time but only initialize Paystack payment after pharmacist approval.
  • ✓Include medicine names, quantities, and dosage in Paystack metadata for dispute and audit purposes.
  • ✓Support delivery scheduling: some customers want morning delivery, some prefer pickup.
  • ✓Handle substitutions: if a medicine is out of stock, the pharmacist suggests an alternative and updates the order amount before payment.

Frequently Asked Questions

Do I need special licensing to operate a pharmacy delivery service in Nigeria or Kenya?
In Nigeria, pharmacy operations are regulated by the Pharmacists Council of Nigeria (PCN). An online pharmacy must be run by a licensed pharmacist and registered with PCN. In Kenya, the Pharmacy and Poisons Board (PPB) governs pharmacy operations. Consult a healthcare regulatory lawyer before launching — this is not just a payment integration question.
How do I handle out-of-stock substitutions?
When the pharmacist finds an item out of stock, they can suggest a substitution in the order management panel. This triggers a notification to the customer (SMS or push notification) with the substitution details and new price. The customer accepts or rejects. If rejected, that item is removed and the order total is updated before the Paystack payment is initialized.
Can customers save their prescriptions for refills?
Yes. Store prescription photos in cloud storage (AWS S3, Cloudinary, or Supabase Storage) linked to the customer account. When they return for a refill, they can reference a past prescription instead of uploading a new one. Add an expiry date to prescriptions (most prescriptions are valid for 6 months) and prompt re-upload when expired.

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 SACCO Loan Repayment Collection System

A complete build guide for SACCO loan repayment collection using Paystack. Covers loan schedule management, recurring M-Pesa charge collection, handling partial payments, late payment tracking, interest calculation considerations, member management, reporting for SACCO officials, integration with existing SACCO software, and regulatory compliance.

Read more

Building an Events Ticketing Platform with Splits

An events ticketing platform collects ticket revenue and routes it to event organizers after the event. This guide covers using Paystack splits to route organizer revenue and platform booking fees, handling multi-ticket types, and managing pre-event holds and post-event payouts.

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.