How Do I Secure My Webhooks in Zoho Billing?
Securing your webhooks can help verify that the webhooks were actually sent from Zoho Billing.
To do this, you’d have to set up your server in such a way that it listens for webhooks from Zoho Billing. When your server receives a webhook from Zoho Billing, a hash value will have to be generated based on the payload and your secret token. Once done, check if it matches the hash value from Zoho Billing and thereby validate the source of the webhook. This can add a layer of security by enabling your server to disregard third-party webhooks pretending to originate from Zoho Billing.
To secure your webhooks:
- Go to Settings > Automation > Webhooks.
- Click + New Webhook.
- Mark the I want to secure this webhook box.
Enter a Secret Token of your choice. It must be alphanumeric and range between 12-50 characters.
Insight: This token will be used to compute a hash value and hence, you will have to ensure that the same token is available on your server to compute a similar hash value.
Click Save to set up the webhook.
Now, the webhook will be sent with a hash value in its header (X-Zoho-Webhook-Signature).
Validating the Webhook from Your Side
When your server receives the webhook, a hash value will have to be generated for the payload, in the same way that Zoho Billing generated it. This is necessary to produce the same hash value to validate the webhook.
The following parameters (if available) need to be used to generate the hash value:
- Query string parameters.
- Default payload/Customized raw JSON payload.
- x-www-form-urlencoded payload (key-value pairs).
Construct a string by sorting the payload’s key-value pairs in alphabetical order. The pairs must be sorted in an alphabetical order with respect to their keys.
Points to remember while constructing the string:
- If your webhook contains query string parameters, ensure that those key-value pairs are sorted along with the payload’s key-value pairs.
- There cannot be any spaces between the key-value pairs.
Once you’ve sorted the key-value pairs and constructed the string, append the raw JSON to the end of the string.
Warning: If your payload is in the x-www-form-urlencoded format, then the entire string must be decoded before generating the hash value.
For example, this is how you’d construct a string for a webhook with query string parameters and a default payload:
Query string parameters’ key-value pairs:
subscription_id=90343, name=basic
Default payload/raw JSON:
{"created_date":"2019-03-06","event_id":"5675"}
The constructed string would be:
namebasicsubscription_id90343{"created_date":"2019-03-06","event_id":"5675"}
Here’s another example for a webhook that contains query string parameters and an x-www-form-urlencoded payload:
Query string parameters’ key-value pairs:
customer_name=Bowman, status=active
x-www-form-urlencoded payload’s key-value pairs:
addon_description=Monthly addon, quantity=1
The constructed string would be:
addon_descriptionMonthly addoncustomer_nameBowmanquantity1statusactive
Warning: If one of the key value pairs contain spaces, the spaces must be inlcluded as well in the contructed string, as seen in the example above with the “Monthly addon” key-value pair.
The hash value can be computed by applying the HMAC-SHA256 algorithm on this string, along with the secret token that was used in Zoho Billing.
You can then proceed to validate the webhook by checking if the hash value computed form your side matches with the one in the header (X-Zoho-Webhook-Signature) of the webhook from Zoho Billing.