API Documentation
  • 🏡Home
  • Overview
    • 💡What we do
    • ✨Our Features
  • General Guide
    • 🏷️Introduction
    • 📪Test and Go Live
    • 💁Configuration
      • Custormers
        • Create Customer
        • Fetch Loan Customers
        • Fetch Customers
      • Loan Types
        • Fetch Loan Types
        • Loan Reasons
      • Country
        • Get all countries
        • Get states by country Id
      • Branch
        • Create Branch
        • Branches
      • Sales Person
        • Create a Salesperson
        • Get Sales Persons
      • Team
        • Create a Team
        • Get Teams
      • Employers
      • Industries
      • Commission
  • Products Guide
    • 🏛️Loans
      • New Loan Application
      • Activate/De-Activate Auto approval
      • Loan Information
      • Active Loans
      • Repayment Schedule Calculation
      • Create payment entries
      • Spool Repayments Due
      • Repayment Activation File
      • Repayment Activation Information
      • Disburse
    • 🪝Webhooks
      • Webhooks Verification.
      • Verification Steps
Powered by GitBook
On this page
  • Constructing the signed content
  • Determining the expected signature
  • Verify timestamp

Was this helpful?

  1. Products Guide
  2. Webhooks

Verification Steps

Verifying signatures manually

PreviousWebhooks Verification.

Last updated 1 year ago

Was this helpful?

Each webhook call includes three headers with additional information that are used for verification:

  • svix-id: the unique message identifier for the webhook message. This identifier is unique across all messages, but will be the same when the same webhook is being resent (e.g. due to a previous failure)

  • svix-timestamp: timestamp in .

  • svix-signature: the encoded list of signatures (space delimited).

Constructing the signed content

The content to sign is composed by concatenating the id, timestamp and payload, separated by the full-stop character (.). In code, it will look something like:

signedContent = $"{svix_id}.{svix_timestamp}.{body}"

Where body is the raw body of the request. The signature is sensitive to any changes, so even a small change in the body will cause the signature to be completely different. This means that you should not change the body in any way before verifying.

Determining the expected signature

So to calculate the expected signature, you should HMAC the signed_content from above using the base64 portion of your signing secret (this is the part after the whsec_ prefix) as the key. For example, given the secret whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw you will want to use MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw.

For example, this is how you can calculate the signature in:

// Some code

const crypto = require('crypto');

signedContent = `${svix_id}.${svix_timestamp}.${body}`
const secret = "whsec_5WbX5kEWLlfzsGNjH64I8lOOqUB6e8FH";

// Need to base64 decode the secret
const secretBytes = new Buffer(secret.split('_')[1], "base64");
const signature = crypto
  .createHmac('sha256', secretBytes)
  .update(signedContent)
  .digest('base64');
console.log(signature);

Make sure to remove the version prefix and delimiter (e.g. v1,) before verifying the signature.

Please note that to compare the signatures it's recommended to use a constant-time string comparison method in order to prevent timing attacks.

Verify timestamp

As mentioned above, Lenda also sends the timestamp of the attempt in the svix-timestamp header. You should compare this timestamp against your system timestamp and make sure it's within your tolerance in order to prevent timestamp attacks.

Lenda uses an with to sign its webhooks.

🪝
HMAC
SHA-256
seconds since epoch
Base64
Lenda webhook capture