Implementation Example

A guide showing an example of how you can implement your Webhook Signature.

Webhook Security: Digest and Signature Verification

Our webhooks include two security layers to ensure both the integrity and authenticity of the payload:

Digest Header:

Provides a hash (e.g., using SHA-256) of the payload to confirm that the content hasn't been altered during transit.

Signature Header:

Typically provided as X-Signature, this header is an HMAC computed with your shared secret. It confirms that the webhook was sent by our server and that the payload is authentic.

How It Works:

  1. Receive the Webhook:
    Your endpoint will receive a POST request with both a Digest header and an X-Signature header along with the payload.
  2. Verify the Digest:
  • Compute the digest of the raw request body using the same hash algorithm (e.g., SHA-256).
  • Compare your computed digest with the value provided in the Digest header.
  • If they match, the payload's integrity is confirmed.
  1. Verify the Signature:
  • Using your secret key (YOUR_WEBHOOK_SECRET), compute the HMAC SHA256 of the raw request body.
  • Compare the computed signature with the value in the X-Signature header.
  • If they match, the request is confirmed to be from a trusted source.
  1. Handle the Request:
  • If both checks pass: Process the webhook payload as intended.
  • If either check fails: Reject the request (for example, by returning an HTTP 401 Unauthorized status) and log the incident for further review.

Example Implementation:

// Step 1: Retrieve the raw payload
rawPayload = getRawRequestBody()

// Step 2: Verify Digest
expectedDigest = SHA256(rawPayload)
if expectedDigest != requestHeader["Digest"]:
    // Integrity check failed
    return HTTP 400 Bad Request

// Step 3: Verify Signature
computedSignature = HMAC_SHA256(rawPayload, "YOUR_WEBHOOK_SECRET")
if computedSignature != requestHeader["X-Signature"]:
    // Authentication check failed
    return HTTP 401 Unauthorized

// Step 4: Process the webhook payload
processWebhookPayload(rawPayload)


Example Request:

POST /webhook-endpoint
Headers:
    Digest: "sha-256=your-computed-digest-value"
    X-Signature: "your-computed-signature-value"
    Content-Type: "application/json"
Body:
{
  "event": "transaction.completed",
  "data": {
    "transaction_id": "1234567890",
    "status": "completed"
  }
}

Important Security Note:

Keep your webhook secret (YOUR_WEBHOOK_SECRET) secure and never expose it publicly. Use this secret only on your server to compute and verify the webhook signature.