Troubleshooting
Guide to resolving common webhook issues like signature verification, SSL certificate problems, rate limiting, and order retrieval.
Common Issues
1. Signature Verification Fails
Symptoms:
- 401 Unauthorized errors
- Signature verification fails
Debugging Steps:
function debugSignatureVerification(payload, signatureBase64, publicKeyPem) {
try {
console.log('=== Debugging Signature Verification ===');
console.log('Payload length:', payload.length);
console.log('Payload snippet:', payload.substring(0, 100));
console.log('Signature:', signatureBase64.substring(0, 50) + '...');
const sortedKeys = Object.keys(payload).sort();
const sortedObj = {};
sortedKeys.forEach(key => sortedObj[key] = payload[key]);
// Replicating your specific JSON formatting: {"a": 1, "b": 2} -> {"a": 1, "b": 2}
const jsonString = JSON.stringify(sortedObj, null, 0)
.replace(/:/g, ": ")
.replace(/,/g, ", ");
const dataBuffer = Buffer.from(jsonString, 'utf-8');
const signatureBuffer = Buffer.from(signatureBase64, 'base64');
// 2. Verify using Node's crypto module
const isValid = crypto.verify(
{
key: publicKeyPem,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: 222, // Match your specific salt length
},
dataBuffer,
signatureBuffer
);
console.log("Verification valid:");
return isValid;
} catch (err) {
console.error("Verification Error:", err.message);
return false;
}
}Common Causes:
- Incorrect public key
- Payload altered before verification
- Signature encoding issues
Solutions:
- Use the correct public key
- Verify with raw body buffer
- Ensure proper base64 decoding
2. Endpoint SSL Certificate Issues
Check SSL Certificate:
const https = require('https');
const url = require('url');
function checkSSLCertificate(webhookUrl) {
const parsedUrl = url.parse(webhookUrl);
const options = { hostname: parsedUrl.hostname, port: 443, method: 'GET' };
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
const cert = res.socket.getPeerCertificate();
const now = new Date();
const validTo = new Date(cert.valid_to);
if (validTo < now) {
console.log('❌ Certificate expired!');
} else {
console.log('✅ Certificate valid');
}
resolve(cert);
});
req.on('error', (error) => reject(error));
req.end();
});
}Test Webhook Endpoint:
async function testWebhookEndpoint(url) {
try {
const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ test: true }) });
if (response.ok || response.status === 405) {
console.log('✅ Endpoint accessible');
} else {
console.log('❌ Endpoint not accessible');
}
} catch (error) {
console.error('❌ Endpoint test failed:', error.message);
}
}3. Rate Limiting Issues
Symptoms:
- Delayed or failed webhooks
- HTTP 429 responses
Solutions:
- Optimize processing time
- Implement queuing
Monitor Rate Limits:
async function checkRateLimits() {
const response = await fetch('https://backend.sa.amwal.tech/api/webhook-endpoints/', { method: 'HEAD', headers: { 'X-API-Key': 'YOUR_API_KEY_FINGERPRINT' } });
console.log('Rate Limit Headers:', response.headers.get('X-RateLimit-Limit'), response.headers.get('X-RateLimit-Remaining'), response.headers.get('X-RateLimit-Reset'));
}4. Order Not Found
Debugging Steps:
async function debugOrderLookup(webhookPayload) {
const orderData = webhookPayload.data;
const lookupMethods = [
{ name: 'Amwal ID', url: `https://your-api.com/orders/search?amwal_id=${orderData.id}` },
{ name: 'Merchant Order ID', url: `https://your-api.com/orders/${orderData.merchant_order_id}` },
{ name: 'Ref ID', url: `https://your-api.com/orders/search?ref_id=${orderData.ref_id}` }
];
for (const method of lookupMethods) {
try {
const response = await fetch(method.url);
if (response.ok) {
console.log(`✅ Order found using ${method.name}`);
return await response.json();
}
} catch (error) {
console.error(`Error looking up by ${method.name}:`, error);
}
}
console.log('Order not found');
return null;
}Updated 3 days ago