To simulate a card decline in Paystack test mode: use card 4084080000000409 to trigger "Do Not Honor", or 4084080000000005 to trigger "Insufficient Funds". These cards will fire a charge.failed webhook event. Verify that your webhook handler does not fulfill the order, your frontend shows a useful error message, and your retry flow works.
| Card Number | Decline Reason | gateway_response |
|---|---|---|
4084080000000409 |
Declined by issuer | Do Not Honor |
4084080000000005 |
Insufficient funds | Insufficient Funds |
4084080000000007 |
Card expired (simulate) | Expired Card |
4084080000000009 |
Incorrect PIN | Incorrect PIN |
All test decline cards use CVV 408 and any future expiry date.
// Webhook handler — handle both success and failure events
if (event.event === 'charge.success') {
await fulfillOrder(event.data.metadata.order_id);
}
if (event.event === 'charge.failed') {
var orderId = event.data.metadata?.order_id;
var reason = event.data.gateway_response; // "Do Not Honor", "Insufficient Funds", etc.
await db.orders.update({
id: orderId,
status: 'payment_failed',
failure_reason: reason,
});
// Notify the customer
await sendEmail(event.data.customer.email, {
subject: 'Payment failed',
body: 'Your payment of NGN ' + (event.data.amount / 100) + ' could not be processed. Reason: ' + reason + '. Please try a different card.',
});
}
Test this by sending the decline test card through your actual checkout flow in test mode, then verifying the webhook fires and your order status updates to payment_failed.
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