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
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.
Example Implementations for Verifying Webhook Signatures
Copy
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 usageconst 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 Footerconst isVerified = verifySignature(payload, signature, publicKey);console.log('Signature verified:', isVerified);
Copy
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 usageconst 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 Footerconst isVerified = verifySignature(payload, signature, publicKey);console.log('Signature verified:', isVerified);
Copy
import base64from cryptography.hazmat.primitives import hashesfrom cryptography.hazmat.primitives.asymmetric import paddingfrom cryptography.hazmat.primitives.serialization import load_pem_public_keydef verify_signature(payload, signature, public_key): try: # Load the public key key = load_pem_public_key(public_key.encode()) # Verify the signature key.verify( base64.b64decode(signature), payload['body'].encode(), padding.PKCS1v15(), hashes.SHA256() ) return True except: return False# Example usagepayload = {'signature': 'example-signature', 'body': '{"event": "payment_intent.succeeded", ...}'}public_key = '-----BEGIN PUBLIC KEY-----\nyour-public-key-here\n-----END PUBLIC KEY-----'is_verified = verify_signature(payload, payload['signature'], public_key)print('Signature verified:', is_verified)