Documentation Index
Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Each Webhook request header includes X-SIGNATURE, which is signed using the Waffo private key. Merchants must use the Waffo public key to verify the signature.
Get the Waffo public key
Log in to Merchant Portal → Integration menu to view and copy the Waffo public key.
Dev or Admin role permissions are required to access this page.
Recommended approach: use the SDK
The SDK’s handleWebhook() method automatically performs signature verification, event parsing, routing, and response signing:
app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
const body = req.body.toString();
const signature = req.headers['x-signature'] as string;
const result = await waffo.webhook().handleWebhook(body, signature);
res.setHeader('X-SIGNATURE', result.responseSignature);
res.setHeader('Content-Type', 'application/json');
res.status(200).send(result.responseBody);
});
Manual verification
If you need to handle this manually (without the SDK), the verification steps are:
Get the signature
Get X-SIGNATURE from the request header.
Get the raw body
Get the raw request body string (do not JSON parse and then stringify).
Verify the signature
Use the Waffo public key + SHA256WithRSA to verify the signature.
Process the event
Process the event after the signature verification passes.
Sign the response
You must set the X-SIGNATURE header in the response (sign the response body with the merchant private key).
Manual examples
import { createVerify, createSign } from 'crypto';
function verifyWaffoSignature(body: string, signature: string): boolean {
const verify = createVerify('SHA256');
verify.update(body);
return verify.verify(process.env.WAFFO_PUBLIC_KEY!, signature, 'base64');
}
function signResponse(responseBody: string): string {
const sign = createSign('SHA256');
sign.update(responseBody);
return sign.sign(process.env.MERCHANT_PRIVATE_KEY!, 'base64');
}
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const body = req.body.toString();
const signature = req.headers['x-signature'] as string;
if (!verifyWaffoSignature(body, signature)) {
const failedBody = JSON.stringify({ message: 'failed' });
res.setHeader('X-SIGNATURE', signResponse(failedBody));
return res.status(200).send(failedBody);
}
// Process the event...
const successBody = JSON.stringify({ message: 'success' });
res.setHeader('X-SIGNATURE', signResponse(successBody));
res.status(200).send(successBody);
});
Notes
- You must verify the signature before processing the event. Do not respond first and then verify.
- The response must include the
X-SIGNATURE header, otherwise Waffo will treat the delivery as failed.
- Verify the signature using the raw request body; do not JSON parse and then stringify.
- The SDK provides a complete webhook handling pipeline. Using the SDK is recommended over manual handling.