Skip to content

Commit

Permalink
feat: non-payment webhook initial code
Browse files Browse the repository at this point in the history
  • Loading branch information
dcardos committed Aug 30, 2024
1 parent 6f98e05 commit 2d390b5
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 22 deletions.
24 changes: 2 additions & 22 deletions force-app/main/default/classes/AdyenPaymentHelper.cls
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public with sharing class AdyenPaymentHelper {

public static CommercePayments.GatewayNotificationResponse handleAsyncNotificationCallback(CommercePayments.PaymentGatewayNotificationContext gatewayNotificationContext) {
CommercePayments.PaymentGatewayNotificationRequest paymentGatewayNotificationRequest = Test.isRunningTest() ? null : gatewayNotificationContext.getPaymentGatewayNotificationRequest();
NotificationRequestItem notificationRequestItem = parseAdyenNotificationRequest(paymentGatewayNotificationRequest);
String adyenNotificationRequestPayload = Test.isRunningTest() ? TEST_NOTIFICATION_REQUEST_BODY : paymentGatewayNotificationRequest.getRequestBody().toString();
NotificationRequestItem notificationRequestItem = WebhookUtils.parseAdyenNotificationRequest(adyenNotificationRequestPayload);
Adyen_Adapter__mdt adyenAdapter = AdyenPaymentUtility.retrieveAdapterByMerchantAcct(notificationRequestItem.merchantAccountCode);
HMACValidator validator;
try {
Expand Down Expand Up @@ -63,27 +64,6 @@ public with sharing class AdyenPaymentHelper {
gatewayNotificationResponse.setStatusCode(AdyenConstants.HTTP_SUCCESS_CODE);
return gatewayNotificationResponse;
}

/**
* Take the http request from the async notification callback and deserializes it into AdyenNotificationResponse.
*
* @param notificationRequest The body of the Adyen notification request.
* @return AdyenNotificationRequest The deserialized version of the Adyen notification request.
*
*/
public static NotificationRequestItem parseAdyenNotificationRequest(CommercePayments.PaymentGatewayNotificationRequest notificationRequest) {
String adyenNotificationRequestPayload = Test.isRunningTest() ? TEST_NOTIFICATION_REQUEST_BODY : AdyenPaymentUtility.makeSalesforceCompatible(notificationRequest.getRequestBody().toString());
AdyenNotification adyenNotification = (AdyenNotification) JSON.deserialize(adyenNotificationRequestPayload, AdyenNotification.class);
NotificationRequestItem notificationRequestItem = new NotificationRequestItem();
if (adyenNotification != null) {
for (NotificationItems notificationItem : adyenNotification.notificationItems) {
if (notificationItem.NotificationRequestItem != null) {
notificationRequestItem = notificationItem.NotificationRequestItem;
}
}
}
return notificationRequestItem;
}

/**
* Creates and records (ie saves) the notification save result.
Expand Down
34 changes: 34 additions & 0 deletions force-app/main/default/classes/NonPaymentWebhookHandler.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@RestResource(UrlMapping='/nonPaymentWebhook/v1/*')
global with sharing class NonPaymentWebhookHandler {
@HttpPost
global static String doPost() {
NotificationRequestItem notificationRequestItem;
RestRequest req = RestContext.request;
String acceptedResponse = '[accepted]';
try {
notificationRequestItem = WebhookUtils.parseAdyenNotificationRequest(req.requestBody.toString());
Adyen_Adapter__mdt adyenAdapter = AdyenPaymentUtility.retrieveAdapterByMerchantAcct(notificationRequestItem.merchantAccountCode);
HMACValidator validator;
validator = new HMACValidator(notificationRequestItem, adyenAdapter.HMAC_Key__c);
if (!Test.isRunningTest() && !validator.validateHMAC()) {
return acceptedResponse + ', but not a valid notification request';
}
// TODO: CAPTURE/REFUND and its failed counterparts should not be valid here
if (!AdyenPaymentUtility.isValidNotification(notificationRequestItem)) {
return acceptedResponse + ', but no valid psp reference found or webhook type was ignored';
}
if (!AdyenPaymentUtility.relatedPaymentFound(notificationRequestItem.originalReference)) {
return acceptedResponse + ', but no related payment record found';
}
// TODO: create gateway log
return acceptedResponse;
} catch (Exception ex) {
System.debug(LoggingLevel.ERROR, ex.getMessage());
if (ex instanceof HMACValidator.HmacValidationException) {
return '[accepted] but not valid notification request';
} else {
return '[accepted] but an exception happened: ' + ex.getMessage();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<status>Active</status>
</ApexClass>
15 changes: 15 additions & 0 deletions force-app/main/default/classes/WebhookUtils.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
public with sharing class WebhookUtils {
public static NotificationRequestItem parseAdyenNotificationRequest(String notificationRequestBody) {
String notificationRequestCompatibleBody = AdyenPaymentUtility.makeSalesforceCompatible(notificationRequestBody);
AdyenNotification adyenNotification = (AdyenNotification) JSON.deserialize(notificationRequestCompatibleBody, AdyenNotification.class);
NotificationRequestItem notificationRequestItem = new NotificationRequestItem();
if (adyenNotification != null) {
for (NotificationItems notificationItem : adyenNotification.notificationItems) {
if (notificationItem.NotificationRequestItem != null) {
notificationRequestItem = notificationItem.NotificationRequestItem;
}
}
}
return notificationRequestItem;
}
}
5 changes: 5 additions & 0 deletions force-app/main/default/classes/WebhookUtils.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>61.0</apiVersion>
<status>Active</status>
</ApexClass>
2 changes: 2 additions & 0 deletions manifest/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
<members>TestDataFactory</members>
<members>AdyenGatewayAdapter</members>
<members>AdyenGatewayAdapterTest</members>
<members>NonPaymentWebhookHandler</members>
<members>WebhookUtils</members>
<name>ApexClass</name>
</types>
<types>
Expand Down

0 comments on commit 2d390b5

Please sign in to comment.