Node.js
No official Node.js backend SDK is published yet — call the REST API directly with fetch or your HTTP client of choice.
No @wajub/sdk package
There is no published @wajub/sdk npm package and no github.com/wajub/wajub-node
repository — npm install @wajub/sdk and import Wajub from '@wajub/sdk' do not work. Call
the REST API directly, as shown below.
Initialization
Store your keys in the environment and send them in the Authorization header — no client
object required:
const WAJUB_BASE_URL = 'https://api.wajub.com';
async function wajubRequest(method: string, path: string, body?: unknown, idempotencyKey?: string) {
const res = await fetch(`${WAJUB_BASE_URL}${path}`, {
method,
headers: {
Authorization: process.env.WAJUB_SECRET_KEY!, // no "Bearer" prefix
'Content-Type': 'application/json',
...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}),
},
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) {
const err = await res.json();
throw new Error(`${err.code}: ${err.message}`);
}
return res.json();
}Use cases
Collect a payment
const { transaction, authorization_url } = await wajubRequest('POST', '/payments', {
amount: 5000,
currency: 'XAF',
customer: { email: 'amina@example.com' },
callback: 'https://example.com/return',
});Pay out (Mobile Money)
const { transfer } = await wajubRequest(
'POST',
'/transfers',
{ amount: 100000, currency: 'XAF', beneficiary: { phone: '+237670000000', channel: 'cm.mtn', name: 'Amina' } },
crypto.randomUUID(), // Idempotency-Key
);Verify a webhook (Express)
Wajub signs webhooks with HMAC-SHA256 over "{timestamp}.{rawBody}", sent as
X-Wajub-Signature: v1={hex}. See Signature verification
for the full algorithm; a minimal check:
import express from 'express';
import crypto from 'crypto';
const app = express();
app.post('/webhooks/wajub', express.raw({ type: '*/*' }), (req, res) => {
const header = req.headers['x-wajub-signature'] as string; // "v1=<hex>"
const [, signature] = header.split('=');
const timestamp = req.headers['x-wajub-timestamp'] as string;
const expected = crypto
.createHmac('sha256', process.env.WAJUB_WEBHOOK_SECRET!)
.update(`${timestamp}.${req.body}`)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(400).json({ error: 'Invalid signature' });
}
const event = JSON.parse(req.body.toString());
if (event.type === 'payment.succeeded') fulfill(event.data);
res.sendStatus(200);
});Raw body required
To verify the signature you need the raw (unparsed) body. With Express, use
express.raw() on the webhook route, not express.json(). Check the
exact header names on Signature verification before
shipping this to production.
Local development
Use the real, published Wajub CLI (npm install -g @wajub/cli) to forward
webhooks to localhost and trigger test events while you build — no SDK required:
wajub listen --forward-to localhost:3000/webhooks/wajub
wajub trigger payment.complete