@@ -31,9 +31,13 @@ public function validateHMAC(string $hmacKey, string $hmacSign, string $webhook)
3131 }
3232
3333 /**
34+ * Validate the HMAC Signature of the webhook payload
35+ * Used for BankingWebhooks and ManagementWebhooks (where HMAC signature is provided in the HTTP header)
36+ * Note: HMAC signature is calculated considering the entire payload
37+ *
3438 * @param string $hmacKey Can be found in Customer Area
3539 * @param string $hmacSign Can be found in the Webhook headers
36- * @param string $webhook The response from Adyen
40+ * @param string $webhook The webhook payload
3741 * @return bool
3842 * @throws AdyenException
3943 */
@@ -42,17 +46,13 @@ public function validateHMACSignature(string $hmacKey, string $hmacSign, string
4246 if (!ctype_xdigit ($ hmacKey )) {
4347 throw new AdyenException ("Invalid HMAC key: $ hmacKey " );
4448 }
45- $ expectedSign = base64_encode (hash_hmac (
46- 'sha256 ' ,
47- $ webhook ,
48- pack ("H* " , $ hmacKey ),
49- true
50- ));
49+ $ expectedSign = self ::calculateHmacSignature ($ hmacKey , $ webhook );
5150 return hash_equals ($ expectedSign , $ hmacSign );
5251 }
5352 /**
53+ * Calculate HMAC Signature for Payments webhooks
5454 * @param string $hmacKey Can be found in Customer Area
55- * @param array $params The response from Adyen
55+ * @param array $params NotificationRequestItem object inside the webhook payload
5656 * @return string
5757 * @throws AdyenException
5858 */
@@ -76,7 +76,7 @@ public function calculateNotificationHMAC($hmacKey, $params)
7676
7777
7878 // base64-encode the binary result of the HMAC computation
79- $ merchantSig = base64_encode ( hash_hmac ( ' sha256 ' , $ dataToSign , pack ( " H* " , $ hmacKey), true ) );
79+ $ merchantSig = self :: calculateHmacSignature ( $ hmacKey, $ dataToSign );
8080 return $ merchantSig ;
8181 }
8282
@@ -111,6 +111,10 @@ private function getNotificationDataToSign($params)
111111 }
112112
113113 /**
114+ * Validate the HMAC Signature of the requestItem object included in the webhook payload
115+ * Used for Payment Webhooks (where HMAC signature is provided in the `additionalData` field)
116+ * Note: HMAC signature is calculated considering a subset of the fields (see `calculateNotificationHMAC` function)
117+ *
114118 * @param string $hmacKey
115119 * @param array $params
116120 * @return bool
@@ -180,4 +184,25 @@ public function isHmacSupportedEventCode($response)
180184 );
181185 return array_key_exists (self ::EVENT_CODE , $ response ) && in_array ($ response [self ::EVENT_CODE ], $ eventCodes );
182186 }
187+
188+ /**
189+ * Calculate HMAC signature
190+ *
191+ * @param string $hmacKey Can be found in Customer Area
192+ * @param string $payload The response from Adyen
193+ * @return string
194+ * @throws AdyenException
195+ */
196+ public function calculateHmacSignature (string $ hmacKey , string $ payload ): string
197+ {
198+ if (empty ($ hmacKey )) {
199+ throw new AdyenException ("You did not provide a HMAC key " );
200+ }
201+
202+ if (!ctype_xdigit ($ hmacKey )) {
203+ throw new AdyenException ("Invalid HMAC key: $ hmacKey " );
204+ }
205+
206+ return base64_encode (hash_hmac ('sha256 ' , $ payload , pack ("H* " , $ hmacKey ), true ));
207+ }
183208}
0 commit comments