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. Paystack with Strapi
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 22, 2026

Paystack with Strapi

In Strapi: create a custom route POST /api/payments/initialize that reads the product price from your Product content type, calls Paystack POST /transaction/initialize, and returns the authorization_url. Create POST /api/payments/webhook that validates HMAC and updates your Order content type to status "paid". Store PAYSTACK_SECRET_KEY in .env.

In this article

  1. 1. Strapi Custom Payment Routes
  2. 2. Strapi Payment Controller
  3. 3. Learn More

Strapi Custom Payment Routes

// src/api/payment/routes/payment.js (Strapi v4)
module.exports = {
  routes: [
    { method: 'POST', path: '/payments/initialize', handler: 'payment.initialize', config: { auth: false } },
    { method: 'POST', path: '/payments/webhook', handler: 'payment.webhook', config: { auth: false } },
  ],
};

Strapi Payment Controller

// src/api/payment/controllers/payment.js (Strapi v4)
const crypto = require('crypto');

module.exports = {
  async initialize(ctx) {
    var { productId, email } = ctx.request.body;

    // Fetch price from Strapi Product content type
    var product = await strapi.entityService.findOne('api::product.product', productId, { fields: ['name', 'price'] });
    if (!product) return ctx.notFound('Product not found');

    var reference = 'order_' + productId + '_' + Date.now();

    // Create order record in Strapi
    await strapi.entityService.create('api::order.order', {
      data: { reference, product: productId, customer_email: email, status: 'pending' },
    });

    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, amount: Math.round(product.price * 100), reference, currency: 'NGN' }),
    });
    var data = await res.json();
    ctx.body = { url: data.data.authorization_url };
  },

  async webhook(ctx) {
    var rawBody = ctx.request.rawBody; // requires Strapi raw body config
    var signature = ctx.request.headers['x-paystack-signature'];
    var expected = crypto.createHmac('sha512', process.env.PAYSTACK_WEBHOOK_SECRET).update(rawBody).digest('hex');
    if (expected !== signature) return ctx.unauthorized();

    var event = ctx.request.body;
    if (event.event === 'charge.success') {
      var orders = await strapi.entityService.findMany('api::order.order', {
        filters: { reference: event.data.reference },
      });
      if (orders.length > 0) {
        await strapi.entityService.update('api::order.order', orders[0].id, { data: { status: 'paid' } });
      }
    }
    ctx.status = 200;
  },
};

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 the Paystack with headless CMS checkout guide for the full architecture.

Sign up for the McTaba newsletter

Key Takeaways

  • ✓Create custom Strapi routes for Paystack initialize and webhook — Strapi handles routing, you write the controller.
  • ✓Fetch product price from Strapi's own Product content type — never trust frontend-supplied prices.
  • ✓Store orders in a Strapi Order collection type and update status on charge.success webhook.
  • ✓Keep PAYSTACK_SECRET_KEY and PAYSTACK_WEBHOOK_SECRET in Strapi's .env file.
  • ✓Strapi v4 and v5 use different controller/router patterns — check your Strapi version.

Frequently Asked Questions

How do I access the raw request body in Strapi for HMAC validation?
Strapi v4 parses JSON bodies before your controller sees them — ctx.request.rawBody may be undefined. To fix this, configure Strapi's body parser to preserve the raw body: in config/middlewares.js, set the body parser's enabled option to keep rawBody. Alternatively, use a custom Koa middleware before the body parser to capture the raw buffer.
Should I use Strapi v4 or v5 for a new Paystack project?
Use Strapi v5 (latest) for new projects. The routing and controller patterns are similar to v4 but with some differences in entityService and query engine. The payment integration code above is v4 — for v5, use strapi.documents() API instead of strapi.entityService where needed.
Can I use Strapi roles to protect the payment initialize route?
Yes. If your storefront has authenticated users, set config.auth to require authentication on the initialize route. If the frontend user is anonymous (e.g., a public checkout), keep auth: false but validate input rigorously server-side. Never trust the client-supplied price or product details.

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

Paystack Plugins and No-Code Integrations

A complete map of every official and community Paystack plugin, no-code connector, and automation tool. Covers e-commerce platforms, website builders, headless commerce, automation workflows, reporting integrations, and the decision framework for choosing plugins over custom code.

Read more

Paystack with OpenCart

A practical guide to integrating Paystack with OpenCart for African e-commerce stores. Covers extension installation, configuration, webhook setup, testing, and the most common setup problems.

Read more

Paystack with Zapier

Zapier connects Paystack to 6,000+ apps without writing code. This guide shows how to set up Paystack webhook triggers in Zapier and build the most common payment automation workflows for African businesses.

Read more

Paystack Storefront for a Small Business

Paystack Storefront gives small businesses a free online shop without needing a website or developer. List your products, set prices, and share a link. Customers browse, pick, and pay — you get notified and fulfill the order.

Read more

Accepting Payments with Paystack: Complete Guide

Everything you need to accept your first payment with Paystack: choosing between Initialize Transaction and the Charge API, handling amounts in kobo, attaching metadata, setting callback URLs, and designing transaction references that keep your system clean.

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.