Mock the Paystack API in Jest by using jest.mock() on your Paystack wrapper module, or by intercepting fetch calls with jest.spyOn(global, "fetch"). Return mock resolved values for success cases and rejected promises for error cases. This lets you test your handler logic for every scenario without network calls.
// lib/paystack.js — your wrapper
const fetch = require('node-fetch');
async function initializeTransaction({ email, amount, reference }) {
var res = await fetch('https://api.paystack.co/transaction/initialize', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY },
body: JSON.stringify({ email, amount, reference }),
});
return res.json();
}
async function verifyTransaction(reference) {
var res = await fetch('https://api.paystack.co/transaction/verify/' + reference, {
headers: { Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY },
});
return res.json();
}
module.exports = { initializeTransaction, verifyTransaction };
// --- payment.test.js ---
jest.mock('./lib/paystack', () => ({
initializeTransaction: jest.fn(),
verifyTransaction: jest.fn(),
}));
const paystack = require('./lib/paystack');
const { createCheckout } = require('./payment-service');
describe('createCheckout', () => {
beforeEach(() => jest.clearAllMocks());
it('returns authorization_url on success', async () => {
paystack.initializeTransaction.mockResolvedValue({
status: true,
data: {
authorization_url: 'https://checkout.paystack.com/abc',
reference: 'ref_001',
},
});
var result = await createCheckout({ email: 'user@test.com', amount: 100000 });
expect(result.authorization_url).toBe('https://checkout.paystack.com/abc');
});
it('throws on Paystack API failure', async () => {
paystack.initializeTransaction.mockRejectedValue(new Error('Network error'));
await expect(createCheckout({ email: 'user@test.com', amount: 100000 })).rejects.toThrow('Network error');
});
});
// If your code calls fetch directly without a wrapper
global.fetch = jest.fn();
describe('verifyPayment', () => {
it('returns success data when transaction is paid', async () => {
global.fetch.mockResolvedValueOnce({
json: () => Promise.resolve({
status: true,
data: { status: 'success', amount: 100000, reference: 'ref_001' },
}),
});
var result = await verifyPayment('ref_001');
expect(result.data.status).toBe('success');
});
it('handles 5xx server error from Paystack', async () => {
global.fetch.mockResolvedValueOnce({
ok: false,
status: 500,
json: () => Promise.resolve({ status: false, message: 'Server error' }),
});
await expect(verifyPayment('ref_bad')).rejects.toThrow();
});
afterEach(() => jest.resetAllMocks());
});
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
This guide is part of the Paystack testing guide.
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