Webhook Notification - How secret code work

Secret code is a secret value shared between the webhook sender and receiver. It is used to create x-signature - a value calculated by webhooks caller on the secret code given by receiver and the request JSON data . 

Secret code is included in the webhook registration that was sent to server during the registration.
More details on webhook registration.

When sending a webhook notification, Litium webhook sender uses secret code to create a SHA256 hasher, then the whole body will be serialized and then hashed using that hasher. This value will be set to x-signature key in the header before sending the webhook notification to receiver. 

To verify webhook notification is in fact called by Litium, the webhooks controller could implement the following methods to validate the received signature before processing the answer:

/// <summary>
        /// Verifies that the signature header matches that of the actual body.
        /// </summary>
        protected virtual async Task VerifySignature(string id, HttpRequestMessage request)
        {
            var secretKey = await GetReceiverConfig(request, Name, id, SecretMinLength, SecretMaxLength);

            // Get the expected hash from the signature header
            var header = GetRequestHeader(request, SignatureHeaderName);
            var values = header.SplitAndTrim('=');
            if (values.Length != 2 || !string.Equals(values[0], SignatureHeaderKey, StringComparison.OrdinalIgnoreCase))
            {
                var message = string.Format(CultureInfo.CurrentCulture, CustomReceiverResources.Receiver_BadHeaderValue, SignatureHeaderName, SignatureHeaderKey, "<value>");
                request.GetConfiguration().DependencyResolver.GetLogger().Error(message);
                var invalidHeader = request.CreateErrorResponse(HttpStatusCode.BadRequest, message);
                throw new HttpResponseException(invalidHeader);
            }

            byte[] expectedHash;
            try
            {
                expectedHash = EncodingUtilities.FromHex(values[1]);
            }
            catch (Exception ex)
            {
                var message = string.Format(CultureInfo.CurrentCulture, CustomReceiverResources.Receiver_BadHeaderEncoding, SignatureHeaderName);
                request.GetConfiguration().DependencyResolver.GetLogger().Error(message, ex);
                var invalidEncoding = request.CreateErrorResponse(HttpStatusCode.BadRequest, message);
                throw new HttpResponseException(invalidEncoding);
            }

            // Compute the actual hash of the request body
            byte[] actualHash;
            var secret = Encoding.UTF8.GetBytes(secretKey);
            using (var hasher = new HMACSHA256(secret))
            {
                var data = await request.Content.ReadAsByteArrayAsync();
                actualHash = hasher.ComputeHash(data);
            }

            // Now verify that the actual hash matches the expected hash.
            if (!WebHookReceiver.SecretEqual(expectedHash, actualHash))
            {
                var badSignature = CreateBadSignatureResponse(request, SignatureHeaderName);
                throw new HttpResponseException(badSignature);
            }
        }

In case of a passcode change, the webhook has to be unregistered and registered with new passcode.