Webhook Security - Signature Key
Real-time event notifications for your application
To ensure authenticity and integrity of webhook requests, we include a digital signature using the HMAC-SHA256 algorithm. This signature is sent in the request header as x-signature.
This ensures:
1Sample Payload & Headers
Sample Webhook Payload:
json
{
"transactionId": "trx_123",
"externalId": "ext_456",
"payerDocument": "12345678900",
"payerFullName": "João da Silva",
"endToEnd": "E123456789123456789",
"status": "APPROVED",
"amount": 5000,
"type": "TRANSACTION"
}Request Headers:
x-signature: e1a95db39ef6a1a8f3f35f33e63b527a16f4f2c...
Content-Type: application/json2Signature Validation
You must validate that the x-signature received matches the HMAC signature generated locally using the raw JSON payload and your secretKey.
Important Notes:
signature field, remove it before verifying3Basic TypeScript Example
typescript
import * as crypto from 'crypto';
function sortObjectKeys(obj: any): any {
if (obj === null || typeof obj !== 'object' || obj instanceof Date) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => sortObjectKeys(item));
}
const sortedObj: any = {};
Object.keys(obj)
.sort()
.forEach((key) => {
sortedObj[key] = sortObjectKeys(obj[key]);
});
return sortedObj;
}
export function verifySignature(
payload: any,
receivedSignature: string,
secret: string
): boolean {
const sortedPayload = sortObjectKeys(payload);
const payloadString = JSON.stringify(sortedPayload);
const calculatedSignature = crypto
.createHmac("sha256", secret)
.update(payloadString)
.digest("hex");
return calculatedSignature === receivedSignature;
}4Full NestJS Example
typescript
import {
Controller,
Post,
Req,
Headers,
UnauthorizedException,
} from '@nestjs/common';
import { Request } from 'express';
import { verifySignature } from './utils/verifySignature';
@Controller()
export class WebhookController {
@Post('/webhook')
async handleWebhook(
@Req() req: Request,
@Headers('x-signature') signature: string,
) {
const secret = 'YOUR_SECRET_KEY_HERE';
const payload = req.body;
const isValid = verifySignature(payload, signature, secret);
if (!isValid) {
throw new UnauthorizedException('Invalid signature');
}
// ✅ Signature is valid. Process the webhook
console.log('Received valid webhook:', payload);
// Process your business logic here
return { status: 'success' };
}
}5Security Best Practices
Keep your secret key safe:
secretKey in client-side codeAlways verify the signature:
Handle webhooks securely:
Security First
Always validate webhook signatures to ensure authenticity and prevent security vulnerabilities.
Need more help?
Check our complete API reference or contact our support team for assistance.