From a0e203d17e4ab24b6ed9c83ee1aa22ff4837c010 Mon Sep 17 00:00:00 2001 From: Shubham Kumar Date: Fri, 10 Jan 2025 16:04:41 +0530 Subject: [PATCH] Returning error response for failed HMAC validation (#77) --- .../main/default/classes/AdyenNotificationHandler.cls | 11 +++++++++-- force-app/main/default/classes/AdyenOMSConstants.cls | 1 + .../main/default/classes/NonPaymentWebhookHandler.cls | 10 +++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/force-app/main/default/classes/AdyenNotificationHandler.cls b/force-app/main/default/classes/AdyenNotificationHandler.cls index c5ec1d7..2edd716 100644 --- a/force-app/main/default/classes/AdyenNotificationHandler.cls +++ b/force-app/main/default/classes/AdyenNotificationHandler.cls @@ -11,10 +11,10 @@ public with sharing class AdyenNotificationHandler { try { validator = new HMACValidator(notificationRequestItem, adyenAdapter.HMAC_Key__c); if (!Test.isRunningTest() && !validator.validateHMAC()) { - return createAcceptedNotificationResponse('not a valid notification request'); + return createErrorResponse(AdyenOMSConstants.INVALID_NOTIFICATION, 403); } } catch (HMACValidator.HmacValidationException hmacValidationException) { - return createAcceptedNotificationResponse(hmacValidationException.getMessage()); + return createErrorResponse(hmacValidationException.getMessage(), 403); } if (!AdyenPaymentUtility.isValidNotification(notificationRequestItem)) { @@ -41,6 +41,13 @@ public with sharing class AdyenNotificationHandler { return gatewayNotificationResponse; } + private static CommercePayments.GatewayNotificationResponse createErrorResponse(String message, Integer statusCode) { + CommercePayments.GatewayNotificationResponse gatewayNotificationResponse = new CommercePayments.GatewayNotificationResponse(); + gatewayNotificationResponse.setResponseBody(Blob.valueOf(message)); + gatewayNotificationResponse.setStatusCode(statusCode); + return gatewayNotificationResponse; + } + /** * Creates and records (ie saves) the notification save result. * diff --git a/force-app/main/default/classes/AdyenOMSConstants.cls b/force-app/main/default/classes/AdyenOMSConstants.cls index d41607b..363b1a2 100644 --- a/force-app/main/default/classes/AdyenOMSConstants.cls +++ b/force-app/main/default/classes/AdyenOMSConstants.cls @@ -47,4 +47,5 @@ public with sharing class AdyenOMSConstants { public static final String PBL_ID_KEY = 'pblId'; public static final String GATEWAY_RESULT_SUCCESS = 'success'; public static final String GATEWAY_RESULT_SUCCESS_DESCRIPTION = 'Transaction Normal'; + public static final String INVALID_NOTIFICATION = 'Not a valid notification request'; } \ No newline at end of file diff --git a/force-app/main/default/classes/NonPaymentWebhookHandler.cls b/force-app/main/default/classes/NonPaymentWebhookHandler.cls index 8d02236..4aa6474 100644 --- a/force-app/main/default/classes/NonPaymentWebhookHandler.cls +++ b/force-app/main/default/classes/NonPaymentWebhookHandler.cls @@ -1,7 +1,6 @@ @RestResource(UrlMapping='/nonPaymentWebhook/v1/*') global without sharing class NonPaymentWebhookHandler { public static final String ACCEPTED_RESPONSE = '[accepted]'; - public static final String INVALID_NOTIFICATION = 'but not a valid notification request'; public static final String INVALID_WEBHOOK = 'but no valid psp reference found or webhook type was ignored'; public static final String NO_PAYMENT_FOUND = 'but no related payment record found'; public static final String EXCEPTION_OCCURRED = 'but an exception happened: '; @@ -13,7 +12,7 @@ global without sharing class NonPaymentWebhookHandler { NotificationRequestItem notificationRequestItem = WebhookUtils.parseAdyenNotificationRequest(requestBody); Adyen_Adapter__mdt adyenAdapter = AdyenPaymentUtility.retrieveAdapterByMerchantAcct(notificationRequestItem.merchantAccountCode); if (!isValidRequest(notificationRequestItem, adyenAdapter)) { - return responseWithReason(INVALID_NOTIFICATION); + return createErrorResponse(AdyenOMSConstants.INVALID_NOTIFICATION, 403); } if (!AdyenPaymentUtility.isValidNonPaymentWebhook(notificationRequestItem)) { return responseWithReason(INVALID_WEBHOOK); @@ -28,7 +27,7 @@ global without sharing class NonPaymentWebhookHandler { } return ACCEPTED_RESPONSE; } catch (HMACValidator.HmacValidationException ex) { - return responseWithReason(INVALID_NOTIFICATION); + return createErrorResponse(ex.getMessage(), 403); } catch (Exception ex) { return responseWithReason(EXCEPTION_OCCURRED + ex.getMessage()); } @@ -43,6 +42,11 @@ global without sharing class NonPaymentWebhookHandler { private static String responseWithReason(String reason) { return ACCEPTED_RESPONSE + ', ' + reason; } + + private static String createErrorResponse(String reason, Integer statusCode) { + RestContext.response.statusCode = statusCode; + return reason; + } private static void createGatewayLog(PaymentAuthorization paymentAuthorization, NotificationRequestItem notificationRequestItem, String requestBody) { String interactionStatus = notificationRequestItem.success == 'true' ? AdyenOMSConstants.PaymentGatewayLogStatus.SUCCESS.name() : AdyenOMSConstants.PaymentGatewayLogStatus.FAILED.name();