Skip to content

    Webhook verification

    This section walks you through the process of verifying incoming webhooks.

    Before you start

    At this point, we assume you have

    • sent the Notification Services CreateRequest to subscribe to the desired events
    • and received your notification_configuration_id with CreateResponse

    Of course you also should have received a webhook that you want to verify.

    Overview

    Before parsing the incoming webhook notification's payload, you need to verify the webhook. The following section describes how.

    How to verify our webhooks

    To make sure that the notification has been sent from Relay, and not from an unauthorized third party, you must check that the provided Relay signature is identical with a certain value (reference value).

    For this you need to get the Relay signature, calculate the reference value and in a final step compare these two values. If they are identical, your incoming webhook is verified.

    Get the Relay signature

    The Relay signature is one of the header parameters of your incoming webhook notification.

    Get the reference value

    You must calculate the reference value and compare it to the converted signature using the private key by following the steps described here.

    1. Create input string

    We need to create a hash out of the same data that has been used for Relay to create the Relay signature. Let's call that the creation of the input string.

    2. Get the public key

    We need to use our public key to run a function like publicKey.VerifyData (coding language dependent).

    3. Comparision

    Finally, we pass the input string, the algorithm and the converted signature as parameters to a VerifyData function. If successful, the function will return true.

    In the following section we describe each of these steps.

    The webhook is verified if the sent Relay signature is identical with the calculated reference value.

    Data needed for the verification

    Data needed for the verification

    Before we can calculate the input string and finally the reference value, let's make sure we've got the following data:

    1. Notification Configuration Id

    The notification_configuration_id is the unique id which you receive from the notifications service CreateResponse.

    2. Incoming webhook's header parameter

    Each webhook we send comes with the following header parameters:

    • Algorithm: for instance SHA256withRSA
    • EventId:
    • Time: the time of the request

    We need all of these three values to calculate the input string.

    An additional header parameter is the certificate url - the url where you get the public key from. We will need that public key later.

    The 5th header parameter is the signature we are testing against, as mentioned above.

    3. The incoming webhook's payload

    For now, the payload is just an encoded string. We need that string for creating the input string as well.

    You SHOULD NOT start to parse the payload before the verification was successful.

    Next, let's look at how an incoming webhook looks and where we find the required data mentioned above.

    Incoming webhook notification example

    Let's have a look at the components of a Relay webhook notification first.

    The notifications we send consist of the payload and the header parameters.

    Here is an example of a received webhook's header parameter.

    Example webhook header parameter

    Authorization : Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  
    
    Relay-Cert-Url : "https://ps.netsdev.eu/api/v1/notifications/certs/cert-78b66d512e1a49079a0c4878d50c1fac"  
    
    Relay-Auth-Algo : "SHA256withRSA" 
    
    Relay-Notification-Id : "b4668448aff74b28b74f670042158780” 
    
    Relay-Notification-Time :2022-05-21T07:20:04.0872758+00:00"

    As shown in the example above, the header contains:

    • the Authorization (RSA Signature)
    • the Relay-Cert-Url - the URL for the public certificate - from this url you'll receive the public certificate
    • the algorithm used for producing the signature, here it is `SHA256withRSA``
    • the Relay-Notification-Id - a value that is defined by us
    • the Relay-Notification-Time - the timestamp

    In addition to the header parameters the notification also contains the payload. We send the payload in the header as an Utf8 encoded string.

    Before parsing the webhook notification's payload, you should verify the webhook notification as described in the next section.

    Payload Example (decoded)

    Example webhook notification payload

    { 
        "Id": "b4668448aff74b28b74f670042158780", 
        "Source": "https://ps.nets.eu", 
        "SpecVersion": "1.0",

    1. Create input string

    The input string is a hash of a concatenated string.

    The concatenated string is composed as follows (the pipe symbol | is used as a delimiter):

    code

    ConfigurationId|EventId|formatedTime|crc32Value.ToString...

    Let's check, where each of these four components comes from:

    ConfigurationId

    This is the unique id from your webhook configuration request.

    eventId

    This comes with the webhooks header.

    formatedTime

    This is generated from the time value that comes with the webhook's header. Before concatenating it to the string, the value must be transformed into a culture neutral string like this (C# Example):

    code

    var formatedTime=Time.ToString(CulturInfo.InvarantCulture)
    crc32Value of the data

    The actual webhook's data comes with the payload as an Utf8 encoded string.

    For our purposes, we must transform that string with an CRC32 algorythm. The resulting value is what we add to the string.

    The CRC32 function converts a variable-length string into an 8-character string that is a text representation of the hexadecimal value of a 32 bit-binary sequence.

    Most of the coding languages have a build in function to convert the incoming string with CRC32.

    Uft8 encode the concatenated string

    Before we can use our input string as a parameter for a function, we need must Uft8 encode the string:

    Encoding.UFT8.GetBytes(concatenatedString)

    🎉

    With that, our income string is ready. We will now use it, to finally create the reference value.

    2. Get public key

    In order to calculate the Reference Value out of the income string you need the public key.

    You download your public key from the certificate url. The certificate url is transmitted to you as one of your webhook's header parameter (Relay-Cert-Url), as shown in the Incoming webhook notification example above.

    Usually your coding language provides a build in function that get's the RSAPublicKey according to the url (certificate url, in our case).

    In the next step you use your public key, the income string, and the signature to verify the webhook.

    3. Generate Reference value and compare with Relay Signature

    We are now ready to verify the incoming webhook.

    For this, we use the publicKey with a VerifyData function, and we convert the signature from the webhooks header parameter from the received string into the required ByteArray, like this (C# example):

    code

    convertedsignature = Convert.FromBase64String(signature)

    We pass the calculated income string (as described above), the converted signature, the algorithm from the header (eg Sha256) as parameters to that function, like this:

    code

    publicKey.VerifyData({income string},{converted signature},{Algorithm})

    Depending on the coding language you use, the name of the function might differ. Also there might be additional required parameters, .nets, in this case, for example expects a forth parameter: Pkc1Rsa.

    If the function returns true, your incoming webhook has been succesfully verified.

    🎉

    With your successful webhook verification, you can now start to parse the webhooks payload.

    Additional actions on webhooks

    Once you’ve created the webhook and received the corresponding notification_configuration_id you can perform various actions on that webhook, such as:

    • GetRequest

    • DeleteRequest

    • UpdateRequest