import { createHmac, timingSafeEqual } from 'crypto';
function sha512Sign(message, secret) {
return createHmac('sha512', secret).update(message).digest('hex');
}
export function sha512Verify(data: string, signature: string, key: string): boolean {
// Generate the expected HMAC
const expectedSignature = createHmac('sha512', key)
.update(data, 'utf8')
.digest('hex');
// Convert both signatures to buffers for timing-safe comparison
const expectedBuffer = Buffer.from(expectedSignature, 'hex');
const providedBuffer = Buffer.from(signature, 'hex');
// Ensure both buffers are the same length before comparison
if (expectedBuffer.length !== providedBuffer.length) {
return false;
}
// Use timing-safe comparison to prevent timing attacks
return timingSafeEqual(expectedBuffer, providedBuffer);
}
// Get the timestamp from 'Request-Timestamp' header
const requestTimestamp = "1704931925543";
const callbackUrl = "https://webhook.site/e1ae9397-bd8d-4327-ad92-da002ea2ef08";
const API_SECRET = "YOUR_API_SECRET"; // replace these with your actual API secret value
const requestSignature = "f17e737bf9d4a1f46f130126be4b2cdb3109a347565b5f824f9da0a45f14663db899812654d849d731cf825b884e1363a8364c5e622ec86f338a31fdeec7812d";
const event = {"event":"events.payout.succeeded","data":{"amount":10000,"callbackUrl":"https://webhook.site/e1ae9397-bd8d-4327-ad92-da002ea2ef08","confirmationState":"confirmed","currency":"NGN","destinationAccountNumber":"9845648577","destinationBankId":"bank_538ed2056326432ba8e6853b613997bb","emtl":0,"failureCode":null,"failureMessage":null,"fee":1500,"id":"po_dtb9z9jk4fs6vqelh3hb8dxcyscnldpx","liveMode":true,"metadata":{"category":"transfer"},"narration":"zapped","networkSessionId":"090286250606000850470781628636","reference":"trx_fww7b31pbs5mmT3k3qfb47","requiresConfirmation":false,"status":"succeeded","vat":0}}
const bodyHash = sha512Sign(JSON.stringify(event.data), API_SECRET);
const stringToSign = `${callbackUrl}${bodyHash}${timestamp}`;
// Generate the Request-Signature value for the header
const isValid = sha512Verify(stringToSign, requestSignature, API_SECRET);
console.log(isValid ? "Signature is valid" : "Signature is not valid");