DEV Community

Cover image for I Got Tired of Rewriting Payment Code, So I Built a Unified SDK for Africa
Idorenyin Williams
Idorenyin Williams

Posted on

I Got Tired of Rewriting Payment Code, So I Built a Unified SDK for Africa

Last weekend, I hit a wall.

I was working on a project that needed payment integration. I started with Paystack. Halfway through, I realized for business reasons, I needed to switch to Flutterwave.

"Should be a quick 10-minute job," I thought.

I was wrong. It was a nightmare.

The Fragmentation Problem

Switching from Paystack to Flutterwave wasn't a simple swap. It was a complete refactor.

  • Inconsistent Data: Paystack expects the amount in kobo (50000). Flutterwave wants Naira (500).
  • Prop Name Hell: Was it publicKey or public_key? ref or tx_ref?
  • Different Response Objects: Success callbacks returned completely different data structures.

My clean codebase was suddenly littered with if (provider === 'paystack') statements. It was messy, hard to maintain, and felt incredibly inefficient. If I was struggling with this, thousands of other African developers probably were too.

A senior engineer's solution would be to write an Adapter pattern—a translation layer to normalize the data. But that’s dozens of lines of boilerplate code just to get started.

There had to be a better way. So I built one.

Introducing use-africa-pay

use-africa-pay is an open-source SDK that unifies Africa's top payment gateways (Paystack, Flutterwave, Monnify, and Remita) under one simple, consistent API.

It’s the Adapter pattern you don't have to write.

Before: The Manual, Messy Way

// Every provider needs its own config and logic
if (provider === 'paystack') {
// ...handle Paystack's props, amount in kobo, and response
}
if (provider === 'flutterwave') {
// ...handle Flutterwave's props, amount in Naira, and response
}``
Enter fullscreen mode Exit fullscreen mode

After: The Unified, Clean Way

With use-africa-pay, you write your logic once.

import { useAfricaPay } from '@use-africa-pay/core';

function PaymentButton({ provider, amount, email }) {
const { initializePayment } = useAfricaPay({
provider: provider, // 'paystack' | 'flutterwave' | 'monnify'
apiKey: '...',
amount: amount, // Always in the base currency (e.g., Naira)
email: email,
onSuccess: (response) => {
// Standardized response!
console.log('Success! Transaction ID:', response.transactionId);
},
onClose: () => console.log('Payment closed.'),
});

return <button onClick={initializePayment}>Pay Now</button>;
}
Enter fullscreen mode Exit fullscreen mode

That’s it. Now, switching from Paystack to Flutterwave is as simple as changing the provider prop. The SDK handles all the messy translation in the background.

We Need Your Help! This is an Open-Source Project

I built this over a weekend, but its potential is huge. The goal is to create the ultimate payment layer for African developers, built by the community.

This is a perfect opportunity if you're looking for your first open-source contribution. We have several issues labeled good first issue that are ready to be picked up.

How you can contribute:

  • Star the repo on GitHub to show your support.
  • 💻 Pick up an issue and submit a PR.
  • 💡 Suggest a new feature or request integration for another payment gateway.

Let's work together to solve this problem for everyone.

What other payment gateways should we add next? Let me know in the comments!

Top comments (0)