africa-payments-utils
v1.0.1
Published
Free, tested utilities for African payment integrations: Kenyan phone number normalization and Paystack webhook signature verification.
Maintainers
Readme
africa-payments-utils
Free, tested utilities for African payment integrations — the two small pieces of logic that are easy to get subtly wrong and annoying to debug when they're wrong in production.
npm install africa-payments-utilsWhat's in here
normalizeKenyanPhone(phone: string): string
M-Pesa and most regional payment providers require phone numbers in strict
+254XXXXXXXXX format. Users type 0712..., 712..., 254712..., or the
full international format interchangeably, and a naive regex fails silently.
import { normalizeKenyanPhone } from 'africa-payments-utils';
normalizeKenyanPhone('0712345678'); // '+254712345678'
normalizeKenyanPhone('254712345678'); // '+254712345678'
normalizeKenyanPhone('+254712345678'); // '+254712345678'
normalizeKenyanPhone('712345678'); // '+254712345678'verifyPaystackSignature(rawBody, signature, secretKey): boolean
Verifies a Paystack webhook actually came from Paystack, via HMAC-SHA512 over the raw request body. Skipping this means anyone who finds your webhook URL can POST a fake "payment succeeded" event.
import { verifyPaystackSignature } from 'africa-payments-utils';
// Express: capture the raw body BEFORE it's parsed — this is the part
// most guides skip, and the signature will never match without it.
app.use(express.json({
verify: (req, res, buf) => { (req as any).rawBody = buf; }
}));
app.post('/webhooks/paystack', (req, res) => {
const isValid = verifyPaystackSignature(
(req as any).rawBody,
req.headers['x-paystack-signature'] as string,
process.env.PAYSTACK_SECRET_KEY!
);
if (!isValid) return res.status(401).send('Invalid signature');
// ... handle the verified event
});Why this exists as its own package
Both functions are extracted from a larger payment integration engine (handles M-Pesa STK Push, Paystack, Flutterwave, webhook reconciliation, and multi-tenant setups) that I sell separately. These two pieces are useful on their own regardless of what you're building, so they're free and MIT licensed rather than locked behind anything.
If you need the rest — STK Push initiation, dropped-transaction reconciliation, a multi-tenant Prisma schema — that's here: African Payment Gateway Engine
Testing
Every claim above is covered by a real test, including the failure cases (tampered body, wrong secret, empty inputs):
pnpm install
pnpm testLicense
MIT — see LICENSE.
