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, signature, privateKeyPath) {
console.log('=== Debugging Signature Verification ===');
console.log('Payload length:', payload.length);
console.log('Payload snippet:', payload.substring(0, 100));
console.log('Signature:', signature.substring(0, 50) + '...');
try {
const privateKey = fs.readFileSync(privateKeyPath, 'utf8');
const publicKey = crypto.createPublicKey(privateKey);
const signatureBuffer = Buffer.from(signature, 'base64');
const verifier = crypto.createVerify('SHA256');
verifier.update(payload);
const isValid = verifier.verify({
key: publicKey,
padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
saltLength: crypto.constants.RSA_PSS_SALTLEN_AUTO
}, signatureBuffer);
return isValid;
} catch (error) {
console.error('Verification error:', error.message);
return false;
}
}Common Causes:
- Incorrect private key
- Payload altered before verification
- Signature encoding issues
Solutions:
- Use the correct private 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 about 15 hours ago