From dbe40d932e51eaf38f20259738a5281541da6fa5 Mon Sep 17 00:00:00 2001 From: Shubham Kumar Date: Fri, 6 Dec 2024 14:54:15 +0100 Subject: [PATCH] pbl notification improvements --- .../main/default/classes/AdyenPBLHelper.cls | 6 ---- .../classes/NonPaymentWebhookHandler.cls | 19 +++++++++++ .../classes/NonPaymentWebhookHandlerTest.cls | 32 +++++++++++++++++++ .../main/default/classes/TestDataFactory.cls | 5 +++ 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/force-app/main/default/classes/AdyenPBLHelper.cls b/force-app/main/default/classes/AdyenPBLHelper.cls index c25c362..5363496 100644 --- a/force-app/main/default/classes/AdyenPBLHelper.cls +++ b/force-app/main/default/classes/AdyenPBLHelper.cls @@ -48,12 +48,6 @@ public with sharing class AdyenPBLHelper { dateTimePart = dateTimePart.replace('T', ' '); Datetime dt = Datetime.valueOf(dateTimePart); - Integer offsetHours = Integer.valueOf(timeZoneOffset.substring(0, 2)); - Integer offsetMinutes = Integer.valueOf(timeZoneOffset.substring(3, 5)); - // Adjust DateTime by subtracting the offset to store it as UTC - dt = dt.addHours(-offsetHours); - dt = dt.addMinutes(-offsetMinutes); - return dt; } diff --git a/force-app/main/default/classes/NonPaymentWebhookHandler.cls b/force-app/main/default/classes/NonPaymentWebhookHandler.cls index 2817d94..8d02236 100644 --- a/force-app/main/default/classes/NonPaymentWebhookHandler.cls +++ b/force-app/main/default/classes/NonPaymentWebhookHandler.cls @@ -69,8 +69,16 @@ global without sharing class NonPaymentWebhookHandler { } private static void processNotification(PaymentAuthorization payAuth, NotificationRequestItem requestItem) { + String paymentLinkId = requestItem.additionalData?.get('paymentLinkId'); if (requestItem.eventCode == AdyenConstants.NOTIFICATION_REQUEST_TYPE_AUTHORISE) { if (requestItem.success == 'true' && payAuth.Status.equalsIgnoreCase(AdyenOMSConstants.PaymentAuthorizationStatus.PENDING.name())) { + if(String.isNotBlank(paymentLinkId)) { + payAuth.Adyen_Payment_Method_Variant__c = requestItem.paymentMethod; + Payment_Link__c paymentLink = getPaymentLinkByExternalId(paymentLinkId); + paymentLink.Payment_Method_Used__c = requestItem.paymentMethod; + paymentLink.Status__c = AdyenOMSConstants.PaymentLinkStatus.COMPLETED.name(); + update paymentLink; + } payAuth.GatewayRefNumber = requestItem.pspReference; payAuth.Status = AdyenOMSConstants.PaymentAuthorizationStatus.PROCESSED.name(); update payAuth; @@ -78,6 +86,17 @@ global without sharing class NonPaymentWebhookHandler { } } + private static Payment_Link__c getPaymentLinkByExternalId(String externalId) { + List paymentLinks = [ + SELECT Id, Name, Payment_Method_Used__c, Status__c + FROM Payment_Link__c + WHERE Name = :externalId + LIMIT 1 + ]; + + return paymentLinks.isEmpty() ? null : paymentLinks[0]; + } + private static PaymentAuthorization findPaymentAuthorization(NotificationRequestItem requestItem) { if (requestItem.eventCode == AdyenConstants.NOTIFICATION_REQUEST_TYPE_AUTHORISE) { return findPaymentAuthByMerchantRef(requestItem.merchantReference); diff --git a/force-app/main/default/classes/NonPaymentWebhookHandlerTest.cls b/force-app/main/default/classes/NonPaymentWebhookHandlerTest.cls index bb90125..88cccd3 100644 --- a/force-app/main/default/classes/NonPaymentWebhookHandlerTest.cls +++ b/force-app/main/default/classes/NonPaymentWebhookHandlerTest.cls @@ -1,5 +1,7 @@ @IsTest private class NonPaymentWebhookHandlerTest { + private static final String ACTIVE_STATUS = AdyenOMSConstants.PaymentLinkStatus.ACTIVE.name().toLowerCase(); + private static final String COMPLETED_STATUS = AdyenOMSConstants.PaymentLinkStatus.COMPLETED.name().toLowerCase(); @IsTest static void unsupportedNotificationTypeTest() { @@ -126,6 +128,36 @@ private class NonPaymentWebhookHandlerTest { Assert.areEqual(AdyenOMSConstants.PaymentGatewayLogStatus.SUCCESS.name(), payGatewayLog.InteractionStatus.toUpperCase()); } + @IsTest(SeeAllData = true) + static void authWebhookWithPaymentLinkTest() { + // given + PaymentAuthorization payAuth = TestDataFactory.insertCartAndRelatedPA(); + PaymentAuthorization payAuthWithOrderSummary = [SELECT Id, OrderPaymentSummary.OrderSummary.OrderNumber FROM PaymentAuthorization WHERE Id =:payAuth.Id LIMIT 1]; + String orderNumber = payAuthWithOrderSummary.OrderPaymentSummary.OrderSummary.OrderNumber; + Datetime dateInTheFuture = Datetime.now().addDays(+1); + Payment_Link__c paymentLink = TestDataFactory.createPaymentLink(payAuthWithOrderSummary.OrderPaymentSummary.orderSummaryId, ACTIVE_STATUS, dateInTheFuture); + insert paymentLink; + String successfulPblAuthWebhook = TestDataFactory.mockPblWebhookRequest(AdyenConstants.NOTIFICATION_REQUEST_TYPE_AUTHORISE, TestDataFactory.TEST_PSP_REFERENCE, paymentLink.Name, orderNumber, true); + RestContext.request = createRestRequest(successfulPblAuthWebhook); + + // when + Test.startTest(); + String response = NonPaymentWebhookHandler.doPost(); + Test.stopTest(); + + // then + payAuth = [SELECT Status, GatewayRefNumber, Adyen_Payment_Method_Variant__c FROM PaymentAuthorization WHERE Id = :payAuth.Id]; + PaymentGatewayLog payGatewayLog = [SELECT GatewayRefNumber, InteractionStatus FROM PaymentGatewayLog WHERE ReferencedEntityId = :payAuth.Id]; + Payment_Link__c updatedPaymentLink = [SELECT Status__c, Payment_Method_Used__c FROM Payment_Link__c WHERE Id = :paymentLink.Id]; + Assert.areEqual(NonPaymentWebhookHandler.ACCEPTED_RESPONSE, response); + Assert.areEqual(AdyenOMSConstants.PaymentAuthorizationStatus.PROCESSED.name(), payAuth.Status.toUpperCase()); + Assert.areEqual(COMPLETED_STATUS, updatedPaymentLink.Status__c?.toLowerCase()); + Assert.isNotNull(updatedPaymentLink.Payment_Method_Used__c); + Assert.areEqual(TestDataFactory.TEST_PSP_REFERENCE, payAuth.GatewayRefNumber); + Assert.isNotNull(payAuth.Adyen_Payment_Method_Variant__c); + Assert.areEqual(AdyenOMSConstants.PaymentGatewayLogStatus.SUCCESS.name(), payGatewayLog.InteractionStatus.toUpperCase()); + } + @IsTest(SeeAllData = true) static void unsuccessfulAuthorizationWebhookTest() { // given diff --git a/force-app/main/default/classes/TestDataFactory.cls b/force-app/main/default/classes/TestDataFactory.cls index b598699..6d6f8ca 100644 --- a/force-app/main/default/classes/TestDataFactory.cls +++ b/force-app/main/default/classes/TestDataFactory.cls @@ -401,4 +401,9 @@ public class TestDataFactory { String merchantAccountName = [SELECT Merchant_Account__c FROM Adyen_Adapter__mdt LIMIT 1].Merchant_Account__c; return '{"live": "false", "notificationItems": [{"NotificationRequestItem": {"additionalData": {"hmacSignature": "testsignature"}, "amount": {"currency": "'+ ACTIVE_CURRENCY +'", "value": 1000}, "eventCode": "' + eventCode + '", "eventDate": "2024-01-01T01:00:00+01:00", "merchantAccountCode": "' + merchantAccountName + '", "merchantReference": "' + merchantRef + '", "paymentMethod": "visa", "pspReference": "' + pspReference + '", "originalReference": "' + originalReference + '", "reason": "null", "success": "' + success + '"}}]}'; } + + public static String mockPblWebhookRequest(String eventCode, String pspReference, String paymentLinkId, String merchantRef, Boolean success) { + String merchantAccountName = [SELECT Merchant_Account__c FROM Adyen_Adapter__mdt LIMIT 1].Merchant_Account__c; + return '{"live": "false", "notificationItems": [{"NotificationRequestItem": {"additionalData": {"hmacSignature": "testsignature", "paymentLinkId": "'+ paymentLinkId +'"}, "amount": {"currency": "'+ ACTIVE_CURRENCY +'", "value": 1000}, "eventCode": "' + eventCode + '", "eventDate": "2024-01-01T01:00:00+01:00", "merchantAccountCode": "' + merchantAccountName + '", "merchantReference": "' + merchantRef + '", "paymentMethod": "visa", "pspReference": "' + pspReference + '", "reason": "null", "success": "' + success + '"}}]}'; + } }