The official Node.js and TypeScript client library for the AfconWave Payments API.
- ✅ Full TypeScript support — typed request payloads and response objects
- ⚡ Promise-based async/await API — clean and readable
- 🔒 Secure by default — API key injected at transport level
- 🌍 Payments + Payouts — single SDK for all money movement
- 🔔 Webhook support — built-in HMAC-SHA256 signature verification
- 🧪 Sandbox-ready — flip between test and live with one config change
npm install @afconwave/sdk
# or
yarn add @afconwave/sdk
# or
pnpm add @afconwave/sdkimport { AfconWave } from '@afconwave/sdk';
const afw = new AfconWave({
secretKey: 'sk_test_your_key_here',
// baseUrl: 'https://api.afconwave.com/v1' // optional
});const payment = await afw.payments.create({
amount: 5000, // Amount in minor units (e.g., 5000 = 50 XAF)
currency: 'XAF', // ISO 4217: XAF, XOF, NGN, GHS, KES, etc.
description: 'Order #1234',
callback_url: 'https://yoursite.com/payment/callback',
customer: {
name: 'Jean Dupont',
email: 'jean@example.com',
phone: '+237600000000',
},
metadata: {
order_id: 'ORD-1234',
},
});
console.log(payment.checkout_url); // Redirect user here
console.log(payment.id); // e.g., pay_507f191e8180fconst payment = await afw.payments.retrieve('pay_507f191e8180f');
console.log(payment.status); // "pending" | "success" | "failed"
console.log(payment.amount);
console.log(payment.paid_at);const payout = await afw.payouts.create({
amount: 10000,
currency: 'XAF',
recipient: {
phone: '+237600000001',
network: 'MTN', // "MTN" | "ORANGE" | "MOOV" | "WAVE"
name: 'Marie Kamga',
},
reference: 'PAYOUT-REF-001',
});
console.log(payout.status); // "pending" | "success" | "failed"const result = await afw.payments.list({
limit: 20,
status: 'success',
from: '2024-01-01',
to: '2024-12-31',
});
console.log(result.data); // Array of payments
console.log(result.total);Always verify that incoming webhooks are from AfconWave by checking the signature:
import { verifyWebhookSignature } from '@afconwave/sdk';
app.post('/webhooks/afconwave', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-afconwave-signature'] as string;
const webhookSecret = process.env.AFCONWAVE_WEBHOOK_SECRET!;
const isValid = verifyWebhookSignature({
payload: req.body.toString(),
signature,
secret: webhookSecret,
});
if (!isValid) {
return res.status(400).send('Invalid signature');
}
const event = JSON.parse(req.body.toString());
switch (event.event) {
case 'payment.success':
// Fulfill the order
console.log('Payment received:', event.data.id);
break;
case 'payment.failed':
// Notify the customer
break;
case 'payout.success':
// Update your records
break;
}
res.status(200).send('OK');
});The SDK throws typed errors you can handle by type:
import { AfconWave, AfconWaveError, AuthError, PaymentError } from '@afconwave/sdk';
try {
const payment = await afw.payments.create({ ... });
} catch (err) {
if (err instanceof AuthError) {
console.error('Invalid API Key');
} else if (err instanceof PaymentError) {
console.error('Payment failed:', err.message, err.code);
} else if (err instanceof AfconWaveError) {
console.error('API Error:', err.status, err.message);
}
}| Option | Type | Default | Description |
|---|---|---|---|
secretKey |
string |
required | Your AfconWave secret API key |
baseUrl |
string |
https://api.afconwave.com/v1 |
API base URL (override for sandbox) |
timeout |
number |
30000 |
Request timeout in milliseconds |
Use test keys prefixed with sk_test_ to run in sandbox mode. No real money moves.
const afw = new AfconWave({ secretKey: 'sk_test_...' });Sandbox test cards and phone numbers are listed at docs.afconwave.com/testing.
This SDK ships with full TypeScript type definitions. All methods are fully typed, including request payloads and response objects:
import type { Payment, Payout, CreatePaymentPayload } from '@afconwave/sdk';Full API documentation is available at docs.afconwave.com/api-reference.
- Fork the repository on GitHub
- Create your feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'feat: add new feature' - Push and open a Pull Request
MIT © AfconWave