Webhooks verification
Webhook Verification
To ensure the security and authenticity of webhook requests, you should verify that incoming webhook calls are genuinely from Gett. This verification process uses HMAC-SHA256 signatures with the secret_id
provided when you register your webhook subscription.
Always verify webhook signatures to prevent malicious actors from sending fake webhook events to your endpoint.
How Webhook Verification Works
To verify the authenticity of a webhook, you need to calculate a signature using the provided secret key and the request body (payload). This process is standard for HMAC-SHA256 signatures and can be reproduced in any programming language with a crypto library.
Step 1: Prepare the Data
You will need two components:
-
Secret Key: The
secret_id
returned when you registered your webhook subscription. This is a UUID string known only to you and Gett. For example:97cea50e-9358-4504-b612-d0179d029692
-
Payload: The exact, byte-for-byte request body received in the webhook. Any alteration, including extra whitespace, will result in an invalid signature. For example (see webhook events for more event types):
{"id":"01e829ee-5d79-467b-89e1-1cd1741ab177","event_type":"status_changed","env":"","message":"{\"order_id\":70692316,\"product_id\":\"ee5fd157-c16d-4fe8-838a-a6ca6fa08956\",\"status\":\"Cancelled\"}","timestamp":"2025-09-15T15:11:51.740212996Z"}
Step 2: Compute the HMAC Hash
Using your language's crypto library, generate an HMAC hash with the SHA256 algorithm.
Provide two arguments to the function:
- key: Your secret key (
secret_id
) - message: The payload string
The result of this step will be a raw sequence of bytes (a binary digest).
Step 3: Base64 Encode the Hash
Take the raw byte sequence from Step 2 and encode it into a string using standard Base64 encoding. This is necessary to represent the binary data in a text format.
Step 4: Format the Final Signature String
Prepend the prefix sha256=
to the Base64 encoded string from Step 3.
Expected Result
For the example data provided above, the final signature must be:
sha256=11psCFAijXoeXXloXhsjg1b5FgU+2nfJKERCd0PYT3A=
You can use this expected result to verify that your implementation is correct.
Implementation Example (Go)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
)
func main() {
secret := "97cea50e-9358-4504-b612-d0179d029692"
mac := hmac.New(sha256.New, []byte(secret))
payload := `{"id":"01e829ee-5d79-467b-89e1-1cd1741ab177","event_type":"status_changed","env":"","message":"{\"order_id\":70692316,\"product_id\":\"ee5fd157-c16d-4fe8-838a-a6ca6fa08956\",\"status\":\"Cancelled\"}","timestamp":"2025-09-15T15:11:51.740212996Z"}`
_, err := mac.Write([]byte(payload))
if err != nil {
fmt.Println(err)
return
}
result := "sha256=" + base64.StdEncoding.EncodeToString(mac.Sum(nil))
fmt.Println(result)
// Output: sha256=11psCFAijXoeXXloXhsjg1b5FgU+2nfJKERCd0PYT3A=
}
Best Practices
- Always verify signatures: Never trust webhook data without verification
- Use constant-time comparison: When comparing signatures, use a constant-time comparison function to prevent timing attacks
- Store secrets securely: Keep your
secret_id
in a secure configuration management system, not in your source code - Handle verification failures: Log and alert on signature verification failures, as they may indicate malicious activity
- Preserve the raw payload: Ensure you verify the signature against the exact bytes received, before any parsing or transformation
Next Steps
- Learn about webhook event types you can subscribe to
- Set up your webhook subscription to start receiving events
Updated 7 days ago