Verifying Webhook Signatures

Always verify the webhook signature to ensure the payload’s integrity and authenticity.

Fenan Pay signs the webhook payload using a private key. To ensure that the webhook you receive is from Fenan Pay and hasn’t been tampered with, verify the signature using the corresponding public key:

  • Test environment: on dashboard: settings > webhook settings > webhook_pubk_test
  • Production environment: on dashboard: settings > webhook settings > webhook_pubk_prod

How Webhook Signatures Work

Fenan Pay signs the body using private key speified in setting. The signature is sent in the webhook’s signature field. You should verify the integrity of the payload by comparing the provided signature with the one generated using your webhook’s public key.

Make sure to verify the body as a string (unmodified) because any changes could invalidate the signature.

The cryptographic algorithm and signing mechanism used is SHA256withRSA with a key length of 2048 bits.

Webhook Payload Structure

FieldTypeDescription
eventstringSpecifies the type of webhook notification.
bodystringContains either a PaymentIntent or WithdrawalIntent as a JSON string, depending on the event type.
eventstringSpecifies the type of webhook notification. which will be found inside the body object.

Key Points to Remember

  • Signature Field: The signature field contains the cryptographic signature to verify the authenticity of the webhook body.
  • body: Ensure you verify the body as a string, as any modifications can lead to a failed verification.

Example Implementations for Verifying Webhook Signatures

const crypto = require('crypto');

function verifySignature(payload, signature, publicKey) {
  const verify = crypto.createVerify('SHA256');
  
  // Convert the payload body into a string and update the verify object
  verify.update(payload.body);
  verify.end();
  
  // Verify the signature using the provided public key
  return verify.verify(publicKey, signature, 'base64');
}

// Example usage
const payload = { signature: 'example-signature', body: { event: 'payment_intent.succeeded', ...paymentIntentObject } };
const publicKey = '-----BEGIN PUBLIC KEY-----\nyour-public-key-here\n-----END PUBLIC KEY-----'; // should be the public key from the webhook settings including the Header and Footer
const isVerified = verifySignature(payload, signature, publicKey);

console.log('Signature verified:', isVerified);