diff --git a/force-app/main/default/classes/AdyenAsyncAdapter.cls b/force-app/main/default/classes/AdyenAsyncAdapter.cls
index e82068b..3f94429 100644
--- a/force-app/main/default/classes/AdyenAsyncAdapter.cls
+++ b/force-app/main/default/classes/AdyenAsyncAdapter.cls
@@ -1,30 +1,12 @@
/**
- * This adapter is called by the Payment Gateway.
- * The http calls are delegated to the AdyenPaymentHelper Class.
- *
- * This will process a CAPTURE and a REFUND Request as well as the corresponding Async callbacks.
- *
- * @see AdyenPaymentHelper
- * @see AdyenClient
+ * This class is being deprecated after v2 due to the introduction of the payment gateway provider metadata.
+ * This way when upgrading the package conflicts will be avoided.
+ * The new one should be AdyenGatewayAdapter.
*/
global with sharing class AdyenAsyncAdapter implements CommercePayments.PaymentGatewayAdapter, CommercePayments.PaymentGatewayAsyncAdapter {
global AdyenAsyncAdapter() {}
- /**
- * The entry point for processing payment requests. Returns the response from the payment gateway.
- * Accepts the gateway context request and handover the operation to AdyenPaymentHelper to call the appropriate capture or refund operation.
- *
- * @param paymentGatewayContext from SF Commerce Payments
- * @return CommercePayments.GatewayResponse
- *
- * @implNotes
- * [CAPTURE] is called after setting Fulfillment.Status to 'Fulfilled' which in turns fires processes
- * and flows to create invoices which ultimately fires this.
- *
- * [REFUND] is called by using the action on the order summary page (left hand side).
- *
- */
global CommercePayments.GatewayResponse processRequest(CommercePayments.PaymentGatewayContext paymentGatewayContext) {
try {
return AdyenPaymentHelper.handleFulfillmentOrderStatusChange(paymentGatewayContext);
@@ -33,12 +15,6 @@ global with sharing class AdyenAsyncAdapter implements CommercePayments.PaymentG
}
}
- /**
- * Listens to the incoming async notification callback from Adyen and handover to AdyenPaymentHelper for processing
- *
- * @param gatewayNotificationContext from SF Commerce Payments
- * @return CommercePayments.GatewayNotificationResponse
- */
global CommercePayments.GatewayNotificationResponse processNotification(CommercePayments.PaymentGatewayNotificationContext gatewayNotificationContext) {
return AdyenPaymentHelper.handleAsyncNotificationCallback(gatewayNotificationContext);
}
diff --git a/force-app/main/default/classes/AdyenAuthorisationHelperTest.cls b/force-app/main/default/classes/AdyenAuthorisationHelperTest.cls
index 6bc2573..90ced69 100644
--- a/force-app/main/default/classes/AdyenAuthorisationHelperTest.cls
+++ b/force-app/main/default/classes/AdyenAuthorisationHelperTest.cls
@@ -90,7 +90,7 @@ private class AdyenAuthorisationHelperTest {
AdyenAuthorisationHelper.authorise(TestDataFactory.createAuthorisationRequest(null));
Assert.fail();
} catch (Exception ex) {
- Assert.isInstanceOfType(ex, AdyenAsyncAdapter.GatewayException.class);
+ Assert.isInstanceOfType(ex, AdyenGatewayAdapter.GatewayException.class);
Assert.isTrue(ex.getMessage().containsIgnoreCase('400'));
}
Test.stopTest();
diff --git a/force-app/main/default/classes/AdyenCaptureHelper.cls b/force-app/main/default/classes/AdyenCaptureHelper.cls
index 7b84443..73340d2 100644
--- a/force-app/main/default/classes/AdyenCaptureHelper.cls
+++ b/force-app/main/default/classes/AdyenCaptureHelper.cls
@@ -17,7 +17,7 @@ public with sharing class AdyenCaptureHelper {
errorMessage = 'Payment Amount Missing';
}
if (String.isNotBlank(errorMessage)) {
- throw new AdyenAsyncAdapter.GatewayException(errorMessage);
+ throw new AdyenGatewayAdapter.GatewayException(errorMessage);
}
String pspReference = paymentAuth.GatewayRefNumber;
diff --git a/force-app/main/default/classes/AdyenGatewayAdapter.cls b/force-app/main/default/classes/AdyenGatewayAdapter.cls
new file mode 100644
index 0000000..a96b119
--- /dev/null
+++ b/force-app/main/default/classes/AdyenGatewayAdapter.cls
@@ -0,0 +1,18 @@
+global with sharing class AdyenGatewayAdapter implements CommercePayments.PaymentGatewayAdapter, CommercePayments.PaymentGatewayAsyncAdapter {
+
+ global AdyenGatewayAdapter() {}
+
+ global CommercePayments.GatewayResponse processRequest(CommercePayments.PaymentGatewayContext paymentGatewayContext) {
+ try {
+ return AdyenPaymentHelper.handleFulfillmentOrderStatusChange(paymentGatewayContext);
+ } catch (Exception ex) {
+ return new CommercePayments.GatewayErrorResponse('500', ex.getMessage());
+ }
+ }
+
+ global CommercePayments.GatewayNotificationResponse processNotification(CommercePayments.PaymentGatewayNotificationContext gatewayNotificationContext) {
+ return AdyenPaymentHelper.handleAsyncNotificationCallback(gatewayNotificationContext);
+ }
+
+ public class GatewayException extends Exception {}
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/AdyenGatewayAdapter.cls-meta.xml b/force-app/main/default/classes/AdyenGatewayAdapter.cls-meta.xml
new file mode 100644
index 0000000..f5e18fd
--- /dev/null
+++ b/force-app/main/default/classes/AdyenGatewayAdapter.cls-meta.xml
@@ -0,0 +1,5 @@
+
+
+ 60.0
+ Active
+
diff --git a/force-app/main/default/classes/AdyenGatewayAdapterTest.cls b/force-app/main/default/classes/AdyenGatewayAdapterTest.cls
new file mode 100644
index 0000000..952a23e
--- /dev/null
+++ b/force-app/main/default/classes/AdyenGatewayAdapterTest.cls
@@ -0,0 +1,131 @@
+@IsTest
+private class AdyenGatewayAdapterTest {
+ @TestSetup
+ static void makeData() {
+ Account acct = TestDataFactory.createAccount();
+ insert acct;
+ TestDataFactory.insertBasicPaymentRecords(acct.Id, null);
+ }
+
+ @IsTest
+ static void testCaptureOutboundSuccess() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+
+ Test.startTest();
+ Id authId = [SELECT Id FROM PaymentAuthorization ORDER BY CreatedDate DESC LIMIT 1].Id;
+ CommercePayments.CaptureRequest captureRequest = new CommercePayments.CaptureRequest(TestDataFactory.TEST_AMOUNT, authId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(captureRequest, CommercePayments.RequestType.Capture);
+ CommercePayments.GatewayResponse captureResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+
+ Assert.isTrue(captureResponse.toString().contains('[capture-received]'));
+ Assert.isTrue(captureResponse.toString().contains(TestDataFactory.TEST_PSP_REFERENCE));
+ }
+
+ @IsTest
+ static void testCaptureOutboundFailure() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.FailureResponse());
+
+ Test.startTest();
+ Id authId = [SELECT Id FROM PaymentAuthorization ORDER BY CreatedDate DESC LIMIT 1].Id;
+ CommercePayments.CaptureRequest captureRequest = new CommercePayments.CaptureRequest(TestDataFactory.TEST_AMOUNT, authId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(captureRequest, CommercePayments.RequestType.Capture);
+ CommercePayments.GatewayResponse gatewayResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+
+ Assert.isInstanceOfType(gatewayResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(gatewayResponse.toString().containsIgnoreCase('400'));
+ }
+
+ @IsTest
+ static void testCaptureOutboundMissingPaymentAuthorization() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+
+ Test.startTest();
+ CommercePayments.CaptureRequest captureRequest = new CommercePayments.CaptureRequest(TestDataFactory.TEST_AMOUNT, null);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(captureRequest, CommercePayments.RequestType.Capture);
+ CommercePayments.GatewayResponse gatewayResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+
+ Assert.isInstanceOfType(gatewayResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(gatewayResponse.toString().containsIgnoreCase(AdyenPaymentUtility.NO_PAYMENT_AUTH_FOUND_BY_ID));
+ }
+
+ @IsTest
+ static void testCaptureOutboundMissingAmount() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+ Id authId = [SELECT Id FROM PaymentAuthorization ORDER BY CreatedDate DESC LIMIT 1].Id;
+ Test.startTest();
+ CommercePayments.CaptureRequest captureRequest = new CommercePayments.CaptureRequest(null, authId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(captureRequest, CommercePayments.RequestType.Capture);
+ CommercePayments.GatewayResponse gatewayResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+ Assert.isInstanceOfType(gatewayResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(gatewayResponse.toString().containsIgnoreCase('Payment Amount Missing'));
+ }
+
+ @IsTest
+ static void testCaptureInboundSuccess() {
+ AdyenPaymentHelper.TEST_NOTIFICATION_REQUEST_BODY = TestDataFactory.createNotificationRequestBody('CAPTURE', TestDataFactory.TEST_PSP_REFERENCE);
+
+ Test.startTest();
+ CommercePayments.GatewayNotificationResponse captureResponse = TestDataFactory.adyenAdapter.processNotification(null);
+ Test.stopTest();
+
+ Assert.isFalse(captureResponse.toString().containsIgnoreCase('error'));
+ }
+
+ @IsTest
+ static void testRefundOutboundSuccess() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+
+ Test.startTest();
+ Id paymentId = [SELECT Id FROM Payment ORDER BY CreatedDate DESC LIMIT 1].Id;
+ CommercePayments.ReferencedRefundRequest refundRequest = new CommercePayments.ReferencedRefundRequest(TestDataFactory.TEST_AMOUNT, paymentId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(refundRequest, CommercePayments.RequestType.ReferencedRefund);
+ CommercePayments.GatewayResponse refundResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+
+ Assert.isTrue(refundResponse.toString().contains('received'));
+ }
+
+ @IsTest
+ static void testRefundOutboundFailure() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.FailureResponse());
+
+ Test.startTest();
+ Id paymentId = [SELECT Id FROM Payment ORDER BY CreatedDate DESC LIMIT 1].Id;
+ CommercePayments.ReferencedRefundRequest refundRequest = new CommercePayments.ReferencedRefundRequest(TestDataFactory.TEST_AMOUNT, paymentId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(refundRequest, CommercePayments.RequestType.ReferencedRefund);
+ CommercePayments.GatewayResponse refundResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+
+ Assert.isInstanceOfType(refundResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(refundResponse.toString().containsIgnoreCase('400'));
+ }
+
+ @IsTest
+ static void testRefundOutboundMissingPayment() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+ Test.startTest();
+ CommercePayments.ReferencedRefundRequest refundRequest = new CommercePayments.ReferencedRefundRequest(TestDataFactory.TEST_AMOUNT, null);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(refundRequest, CommercePayments.RequestType.ReferencedRefund);
+ CommercePayments.GatewayResponse gatewayResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+ Assert.isInstanceOfType(gatewayResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(gatewayResponse.toString().containsIgnoreCase(AdyenPaymentUtility.NO_PAYMENT_FOUND_BY_ID));
+ }
+
+ @IsTest
+ static void testRefundOutboundMissingAmount() {
+ Test.setMock(HttpCalloutMock.class, new TestDataFactory.EchoHttpMock());
+ Id paymentId = [SELECT Id FROM Payment ORDER BY CreatedDate DESC LIMIT 1].Id;
+ Test.startTest();
+ CommercePayments.ReferencedRefundRequest refundRequest = new CommercePayments.ReferencedRefundRequest(null, paymentId);
+ CommercePayments.PaymentGatewayContext context = new CommercePayments.PaymentGatewayContext(refundRequest, CommercePayments.RequestType.ReferencedRefund);
+ CommercePayments.GatewayResponse gatewayResponse = TestDataFactory.adyenAdapter.processRequest(context);
+ Test.stopTest();
+ Assert.isInstanceOfType(gatewayResponse, CommercePayments.GatewayErrorResponse.class);
+ Assert.isTrue(gatewayResponse.toString().containsIgnoreCase('Payment Amount Missing'));
+ }
+}
\ No newline at end of file
diff --git a/force-app/main/default/classes/AdyenGatewayAdapterTest.cls-meta.xml b/force-app/main/default/classes/AdyenGatewayAdapterTest.cls-meta.xml
new file mode 100644
index 0000000..f5e18fd
--- /dev/null
+++ b/force-app/main/default/classes/AdyenGatewayAdapterTest.cls-meta.xml
@@ -0,0 +1,5 @@
+
+
+ 60.0
+ Active
+
diff --git a/force-app/main/default/classes/AdyenPaymentHelper.cls b/force-app/main/default/classes/AdyenPaymentHelper.cls
index c38787f..92a577a 100644
--- a/force-app/main/default/classes/AdyenPaymentHelper.cls
+++ b/force-app/main/default/classes/AdyenPaymentHelper.cls
@@ -107,7 +107,7 @@ public with sharing class AdyenPaymentHelper {
notification = new CommercePayments.ReferencedRefundNotification();
gatewayMessageTemplate = '[refund-{0}] {1}';
} else {
- throw new AdyenAsyncAdapter.GatewayException('Notification of type ' + notificationRequestItem.eventCode + ' does not match criteria');
+ throw new AdyenGatewayAdapter.GatewayException('Notification of type ' + notificationRequestItem.eventCode + ' does not match criteria');
}
String result;
diff --git a/force-app/main/default/classes/AdyenPaymentHelperTest.cls b/force-app/main/default/classes/AdyenPaymentHelperTest.cls
index f5fb43d..502dfcd 100644
--- a/force-app/main/default/classes/AdyenPaymentHelperTest.cls
+++ b/force-app/main/default/classes/AdyenPaymentHelperTest.cls
@@ -61,7 +61,7 @@ private class AdyenPaymentHelperTest {
AdyenPaymentHelper.createNotificationSaveResult(nri);
Assert.fail();
} catch (Exception ex) { // then
- Assert.isInstanceOfType(ex, AdyenAsyncAdapter.GatewayException.class);
+ Assert.isInstanceOfType(ex, AdyenGatewayAdapter.GatewayException.class);
}
}
}
diff --git a/force-app/main/default/classes/AdyenPaymentUtility.cls b/force-app/main/default/classes/AdyenPaymentUtility.cls
index 0864bdc..6bce282 100644
--- a/force-app/main/default/classes/AdyenPaymentUtility.cls
+++ b/force-app/main/default/classes/AdyenPaymentUtility.cls
@@ -27,7 +27,7 @@ public with sharing class AdyenPaymentUtility {
Id = :paymentId
];
if (payments.isEmpty()) {
- throw new AdyenAsyncAdapter.GatewayException(NO_PAYMENT_FOUND_BY_ID + paymentId);
+ throw new AdyenGatewayAdapter.GatewayException(NO_PAYMENT_FOUND_BY_ID + paymentId);
}
return payments[0];
}
@@ -48,7 +48,7 @@ public with sharing class AdyenPaymentUtility {
WHERE DeveloperName = :developerName
];
if (adyenAdapters.isEmpty()) {
- throw new AdyenAsyncAdapter.GatewayException(NO_ADYEN_ADAPTER_BY_NAME + developerName);
+ throw new AdyenGatewayAdapter.GatewayException(NO_ADYEN_ADAPTER_BY_NAME + developerName);
}
return adyenAdapters[0];
}
@@ -63,7 +63,7 @@ public with sharing class AdyenPaymentUtility {
WHERE Merchant_Account__c = :merchantAccountName
];
if (adyenAdapters.isEmpty()) {
- throw new AdyenAsyncAdapter.GatewayException(NO_ADYEN_ADAPTER_BY_MERCHANT + merchantAccountName);
+ throw new AdyenGatewayAdapter.GatewayException(NO_ADYEN_ADAPTER_BY_MERCHANT + merchantAccountName);
}
return adyenAdapters[0];
}
@@ -109,7 +109,7 @@ public with sharing class AdyenPaymentUtility {
Id = :paymentAuthId
];
if (paymentAuthorizations.isEmpty()) {
- throw new AdyenAsyncAdapter.GatewayException(NO_PAYMENT_AUTH_FOUND_BY_ID + paymentAuthId);
+ throw new AdyenGatewayAdapter.GatewayException(NO_PAYMENT_AUTH_FOUND_BY_ID + paymentAuthId);
}
return paymentAuthorizations[0];
}
@@ -383,7 +383,7 @@ public with sharing class AdyenPaymentUtility {
CommercePayments.PaymentsHttp paymentsHttp = new CommercePayments.PaymentsHttp();
HttpResponse response = paymentsHttp.send(request);
if (response.getStatusCode() != 200 && response.getStatusCode() != 201) {
- throw new AdyenAsyncAdapter.GatewayException('Adyen Checkout API returned: ' + response.getStatusCode() + ', body: ' + response.getBody());
+ throw new AdyenGatewayAdapter.GatewayException('Adyen Checkout API returned: ' + response.getStatusCode() + ', body: ' + response.getBody());
} else {
return response;
}
diff --git a/force-app/main/default/classes/AdyenRefundHelper.cls b/force-app/main/default/classes/AdyenRefundHelper.cls
index 8419653..6deccd5 100644
--- a/force-app/main/default/classes/AdyenRefundHelper.cls
+++ b/force-app/main/default/classes/AdyenRefundHelper.cls
@@ -8,7 +8,6 @@ public with sharing class AdyenRefundHelper {
* @param refundRequest The CommercePayments.ReferencedRefundRequest Object.
* @return refundResponse The CommercePayments.ReferencedRefundResponse Object.
*
- * @see AdyenClient
*/
public static CommercePayments.GatewayResponse refund(CommercePayments.ReferencedRefundRequest refundRequest) {
Payment payment = AdyenPaymentUtility.retrievePayment(refundRequest.paymentId);
@@ -22,7 +21,7 @@ public with sharing class AdyenRefundHelper {
errorMessage = 'Payment Amount Missing';
}
if (errorMessage != null) {
- throw new AdyenAsyncAdapter.GatewayException(errorMessage);
+ throw new AdyenGatewayAdapter.GatewayException(errorMessage);
}
String pspReference = payment.PaymentAuthorization?.GatewayRefNumber != null ? payment.PaymentAuthorization.GatewayRefNumber : payment.GatewayRefNumber;
diff --git a/force-app/main/default/classes/TestDataFactory.cls b/force-app/main/default/classes/TestDataFactory.cls
index cda35b3..bf773ee 100644
--- a/force-app/main/default/classes/TestDataFactory.cls
+++ b/force-app/main/default/classes/TestDataFactory.cls
@@ -11,7 +11,7 @@ public class TestDataFactory {
public static final String ACTIVE_CURRENCY = [SELECT IsoCode FROM CurrencyType WHERE IsActive = TRUE LIMIT 1].IsoCode;
public static final String ASSERT_PRICE_MESSAGE = 'For input price of ';
- public static AdyenAsyncAdapter adyenAdapter = new AdyenAsyncAdapter();
+ public static AdyenGatewayAdapter adyenAdapter = new AdyenGatewayAdapter();
public static Account createAccount() {
return new Account(Name = 'Test Account');
diff --git a/force-app/main/default/gatewayProviderPaymentMethodTypes/AlternativePaymentMethod.gatewayProviderPaymentMethodType-meta.xml b/force-app/main/default/gatewayProviderPaymentMethodTypes/AlternativePaymentMethod.gatewayProviderPaymentMethodType-meta.xml
index b6cd26e..ac31588 100644
--- a/force-app/main/default/gatewayProviderPaymentMethodTypes/AlternativePaymentMethod.gatewayProviderPaymentMethodType-meta.xml
+++ b/force-app/main/default/gatewayProviderPaymentMethodTypes/AlternativePaymentMethod.gatewayProviderPaymentMethodType-meta.xml
@@ -2,7 +2,7 @@
AdyenComponent
Alternative Payment Method
- Adyen
+ Adyen_OMS_Provider
AlternativePaymentMethod
AlternativePaymentMethod.Alternative_Payment_Method
diff --git a/force-app/main/default/paymentGatewayProviders/Adyen.paymentGatewayProvider-meta.xml b/force-app/main/default/paymentGatewayProviders/Adyen_OMS_Provider.paymentGatewayProvider-meta.xml
similarity index 63%
rename from force-app/main/default/paymentGatewayProviders/Adyen.paymentGatewayProvider-meta.xml
rename to force-app/main/default/paymentGatewayProviders/Adyen_OMS_Provider.paymentGatewayProvider-meta.xml
index fa2a9ad..a1a215b 100644
--- a/force-app/main/default/paymentGatewayProviders/Adyen.paymentGatewayProvider-meta.xml
+++ b/force-app/main/default/paymentGatewayProviders/Adyen_OMS_Provider.paymentGatewayProvider-meta.xml
@@ -1,6 +1,6 @@
- AdyenAsyncAdapter
+ AdyenGatewayAdapter
Yes
- SalesforceOrderManagement-Adyen
+ Adyen OMS Provider
diff --git a/manifest/package.xml b/manifest/package.xml
index 5550f09..cf8a41f 100644
--- a/manifest/package.xml
+++ b/manifest/package.xml
@@ -13,6 +13,8 @@
AdyenPaymentUtilityTest
AdyenRefundHelper
TestDataFactory
+ AdyenGatewayAdapter
+ AdyenGatewayAdapterTest
ApexClass