Secure Flutterwave Webhooks
When handling payments, relying solely on frontend callbacks is extremely dangerous. Webhooks are the source of truth for payment statuses. In this guide, we'll build a secure Flutterwave webhook handler using Express and TypeScript.
The Webhook Endpoint
Flutterwave sends an HTTP POST request to your specified webhook URL whenever a transaction is completed.
1. Setting up Express
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json()); // Middleware to parse JSON bodies
app.post('/webhook/flutterwave', (req: Request, res: Response) => {
// Webhook logic will go here
});
2. Validating the Secret Hash
Flutterwave allows you to specify a secret_hash in your dashboard. You must verify that the incoming request contains this hash in the verif-hash header.
app.post('/webhook/flutterwave', (req: Request, res: Response) => {
const secretHash = process.env.FLW_WEBHOOK_HASH;
const signature = req.headers['verif-hash'];
if (!signature || signature !== secretHash) {
// This request isn't from Flutterwave; discard
return res.status(401).send('Unauthorized');
}
// It's a valid request
const payload = req.body;
if (payload.event === 'charge.completed' && payload.data.status === 'successful') {
const transactionId = payload.data.id;
// Verify transaction via API before giving value
verifyTransaction(transactionId);
}
res.status(200).send('Success');
});
3. Final Verification
Even with the hash, best practice dictates you make a server-to-server call to Flutterwave to confirm the transaction amount and currency using the transactionId before giving value to the customer.
By following this pattern, your Flutterwave integrations will remain secure and reliable!
Ready to start building?
Explore the most comprehensive directory of APIs for Nigerian developers and find exactly what you need.
Browse the API Directory