To protect your server from unauthorised webhook events, we strongly recommend that you use Hash-based message authentication code (HMAC) signatures for our webhooks that support it. For the ones that support enabling HMAC signatures, each webhook event will include a signature calculated using a secret HMAC key and a payload from the webhook. By verifying this signature, you confirm that the webhook was sent by Adyen, and was not modified during transmission.
To verify HMAC signatures, you can either:
Enable HMAC signatures
The secret HMAC key is linked to a standard webhook endpoint. If you have multiple endpoints for receiving webhooks, generate an HMAC key for each of them.
You also need to generate a new HMAC key when you switch from test to live.
To start receiving HMAC signed webhooks, if the option is available:
- In your Customer Area, go to Developers > Webhooks.
- From the list of webhooks, select the one to configure.
- Select Edit webhook or the edit icon .
- Under Security, generate a new HMAC key or enter an existing HMAC key.
If you generate a new HMAC key, copy it and store it securely in your system. - Select Save configuration.
The HMAC key will now be used to sign webhook events that we send to your server. The signature is
included in the additionalData
field:
{
"live":"false",
"notificationItems":[
{
"NotificationRequestItem":{
"additionalData":{
"hmacSignature":"+JWKfq4ynALK+FFzGgHnp1jSMQJMBJeb87dlph24sXw="
},
...
}
}
]
}
If you generate a new HMAC key, make sure that you can still accept webhooks signed with your previous HMAC key for some time, because:
- It can take some time to propagate the new key in our infrastructure.
- HMAC signatures are calculated when the webhook payload is generated, so any webhook events queued before you saved the new key are signed using your previous key.
Verify using our libraries
You can verify signatures using our:
Verify using your own solution
To build your own solution for verifying HMAC signatures, follow these steps:
Step 1: Construct the payload
The values used below are from an example webhook. To test your solution, replace the values with actual values that you receive in a webhook event.
Concatenate the following values from the webhook event, in the given order:
Key | Value |
---|---|
pspReference |
7914073381342284 |
originalReference |
|
merchantAccountCode |
TestMerchant |
merchantReference |
TestPayment-1407325143704 |
value |
1130 |
currency |
EUR |
eventCode |
AUTHORISATION |
success |
true |
Assign an empty string to any fields that are empty, and use a colon (":") to delimit the values.
For the above values, with an empty originalReference
, you get:
7914073381342284::TestMerchant:TestPayment-1407325143704:1130:EUR:AUTHORISATION:true
Step 2: Calculate the HMAC signature
For hints about how to calculate the signature, have a look at the library code samples above.
-
Convert the payload that you constructed to a binary representation, given the UTF-8 charset.
-
Convert the hexadecimal HMAC key that you generated in your Customer Area from a hexadecimal string to a binary representation, given the UTF-8 charset.
-
Calculate an HMAC using:
- The SHA256 function.
- The binary representation of the payload.
- The binary representation of the HMAC key.
-
To get the final signature, Base64-encode the result.
Step 3: Compare signatures
If the signature that you calculated in Step 2 matches the hmacSignature
that you received, you'll know that the webhook event was sent by Adyen and was not modified during transmission.
Example
Sample HMAC key:
44782DEF547AAA06C910C43932B1EB0C71FC68D9D0C057550C48EC2ACF6BA056
Sample webhook event signed using the above HMAC key:
{
"live":"false",
"notificationItems":[
{
"NotificationRequestItem":{
"additionalData":{
"hmacSignature":"coqCmt/IZ4E3CzPvMY8zTjQVL5hYJUiBRg8UU+iCWo0="
},
"amount":{
"value":1130,
"currency":"EUR"
},
"pspReference":"7914073381342284",
"eventCode":"AUTHORISATION",
"eventDate":"2019-05-06T17:15:34.121+02:00",
"merchantAccountCode":"TestMerchant",
"operations":[
"CANCEL",
"CAPTURE",
"REFUND"
],
"merchantReference":"TestPayment-1407325143704",
"paymentMethod":"visa",
"success":"true"
}
}
]
}