From e1e0b65ccd04cff2ec912eaf6d7b3c4350d7612c Mon Sep 17 00:00:00 2001
From: kpieloch <113994423+kpieloch@users.noreply.github.com>
Date: Mon, 21 Oct 2024 09:25:36 +0200
Subject: [PATCH 1/2] AD-301: Add support for Enhanced Scheme Data (L2/L3 data)
---
.../v6/facades/AdyenCheckoutFacadeTest.java | 2 +-
.../adyenv6backoffice-backoffice-config.xml | 1 +
adyenv6core/resources/adyenv6core-beans.xml | 5 +
adyenv6core/resources/adyenv6core-items.xml | 13 ++
adyenv6core/resources/adyenv6core-spring.xml | 14 ++
.../adyenv6core-locales_en.properties | 2 +
.../impl/DefaultAdyenCheckoutApiFacade.java | 2 +-
.../services/AdyenRequestService.java | 34 +++++
.../impl/DefaultAdyenRequestService.java | 132 ++++++++++++++++++
.../impl/DefaultAdyenCheckoutFacade.java | 4 +-
.../factory/AdyenPaymentServiceFactory.java | 13 +-
.../adyen/v6/factory/AdyenRequestFactory.java | 12 +-
.../com/adyen/v6/populator/CartPopulator.java | 1 +
.../adyen/v6/populator/ProductPopulator.java | 15 ++
.../v6/service/AbstractAdyenApiService.java | 6 +-
.../v6/service/AdyenCheckoutApiService.java | 6 +-
.../DefaultAdyenCheckoutApiService.java | 36 ++---
.../DefaultAdyenModificationsApiService.java | 5 +-
.../v6/facades/AdyenCheckoutFacadeTest.java | 2 +-
19 files changed, 257 insertions(+), 48 deletions(-)
create mode 100644 adyenv6core/src/com/adyen/commerce/services/AdyenRequestService.java
create mode 100644 adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
create mode 100644 adyenv6core/src/com/adyen/v6/populator/ProductPopulator.java
diff --git a/adyenv6b2ccheckoutaddon/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java b/adyenv6b2ccheckoutaddon/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
index 06777d8c5..1dc8a2dd1 100644
--- a/adyenv6b2ccheckoutaddon/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
+++ b/adyenv6b2ccheckoutaddon/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
@@ -251,7 +251,7 @@ public void testAuthorizeCardPayment() throws Exception {
paymentsResponse.setResultCode(PaymentResponse.ResultCodeEnum.AUTHORISED);
when(checkoutCustomerStrategyMock.isAnonymousCheckout()).thenReturn(true);
when(checkoutCustomerStrategyMock.getCurrentUserForCheckout()).thenReturn(null);
- when(adyenPaymentServiceMock.authorisePayment(any(CartData.class), any(RequestInfo.class), any(CustomerModel.class))).thenReturn(paymentsResponse);
+ when(adyenPaymentServiceMock.processPaymentRequest(any(CartData.class),null, any(RequestInfo.class), any(CustomerModel.class))).thenReturn(paymentsResponse);
when(orderRepositoryMock.getOrderModel(CODE)).thenReturn(orderModelMock);
when(cartDataMock.getAdyenPaymentMethod()).thenReturn(PAYMENT_METHOD_CC);
when(requestMock.getHeader(USER_AGENT_HEADER)).thenReturn("userAgent");
diff --git a/adyenv6backoffice/resources/adyenv6backoffice-backoffice-config.xml b/adyenv6backoffice/resources/adyenv6backoffice-backoffice-config.xml
index 933b56e3f..de9acccf0 100644
--- a/adyenv6backoffice/resources/adyenv6backoffice-backoffice-config.xml
+++ b/adyenv6backoffice/resources/adyenv6backoffice-backoffice-config.xml
@@ -82,6 +82,7 @@
+
diff --git a/adyenv6core/resources/adyenv6core-beans.xml b/adyenv6core/resources/adyenv6core-beans.xml
index f2648c15e..0d4f0119e 100644
--- a/adyenv6core/resources/adyenv6core-beans.xml
+++ b/adyenv6core/resources/adyenv6core-beans.xml
@@ -65,6 +65,11 @@
+
+
+
+
+
diff --git a/adyenv6core/resources/adyenv6core-items.xml b/adyenv6core/resources/adyenv6core-items.xml
index 9a192199c..34a3837a9 100644
--- a/adyenv6core/resources/adyenv6core-items.xml
+++ b/adyenv6core/resources/adyenv6core-items.xml
@@ -100,6 +100,14 @@
+
+
+
+
+
+
+
+
@@ -332,6 +340,11 @@
Merchant config list
+
+
+ Boolean.FALSE
+
+
diff --git a/adyenv6core/resources/adyenv6core-spring.xml b/adyenv6core/resources/adyenv6core-spring.xml
index 0269acbdc..0f9b8299c 100644
--- a/adyenv6core/resources/adyenv6core-spring.xml
+++ b/adyenv6core/resources/adyenv6core-spring.xml
@@ -124,6 +124,13 @@
+
+
+
+
+
+
+
@@ -275,6 +282,11 @@
+
+
+
+
+
@@ -302,6 +314,8 @@
+
+
diff --git a/adyenv6core/resources/localization/adyenv6core-locales_en.properties b/adyenv6core/resources/localization/adyenv6core-locales_en.properties
index 4978016f3..08a087d1c 100644
--- a/adyenv6core/resources/localization/adyenv6core-locales_en.properties
+++ b/adyenv6core/resources/localization/adyenv6core-locales_en.properties
@@ -62,6 +62,8 @@ type.basestore.amazonpayRegion.name=AmazonPay Region
type.basestore.amazonpayRegion.description=The region of the Amazon Seller shop
type.basestore.adyenMerchantConfig.name=Adyen Merchant Config
type.basestore.adyenMerchantConfig.description=List of merchants that can be used for payments
+type.basestore.l2L3ESDEnabled.name=L2/L3 Enhanced Data Support
+type.BaseStore.l2L3ESDEnabled.description=Enable or disable L2/L3 EDS for US MasterCard and Visa transactions (only for US merchants)
type.paymentinfo.adyenPaymentMethod.name=Payment Method
type.paymentinfo.adyenIssuerId.name=Issuer ID
diff --git a/adyenv6core/src/com/adyen/commerce/facades/impl/DefaultAdyenCheckoutApiFacade.java b/adyenv6core/src/com/adyen/commerce/facades/impl/DefaultAdyenCheckoutApiFacade.java
index 80ced5305..1303d6fa1 100644
--- a/adyenv6core/src/com/adyen/commerce/facades/impl/DefaultAdyenCheckoutApiFacade.java
+++ b/adyenv6core/src/com/adyen/commerce/facades/impl/DefaultAdyenCheckoutApiFacade.java
@@ -101,7 +101,7 @@ public OrderData placeOrderWithPayment(final HttpServletRequest request, final C
RequestInfo requestInfo = new RequestInfo(request);
requestInfo.setShopperLocale(getShopperLocale());
- PaymentResponse paymentResponse = getAdyenPaymentService().componentPayment(cartData, paymentRequest, requestInfo, getCheckoutCustomerStrategy().getCurrentUserForCheckout());
+ PaymentResponse paymentResponse = getAdyenPaymentService().processPaymentRequest(cartData, paymentRequest, requestInfo, getCheckoutCustomerStrategy().getCurrentUserForCheckout());
if (PaymentResponse.ResultCodeEnum.PENDING == paymentResponse.getResultCode()
|| PaymentResponse.ResultCodeEnum.REDIRECTSHOPPER == paymentResponse.getResultCode()
|| PaymentResponse.ResultCodeEnum.CHALLENGESHOPPER == paymentResponse.getResultCode()
diff --git a/adyenv6core/src/com/adyen/commerce/services/AdyenRequestService.java b/adyenv6core/src/com/adyen/commerce/services/AdyenRequestService.java
new file mode 100644
index 000000000..b72513a50
--- /dev/null
+++ b/adyenv6core/src/com/adyen/commerce/services/AdyenRequestService.java
@@ -0,0 +1,34 @@
+package com.adyen.commerce.services;
+
+import com.adyen.model.checkout.PaymentRequest;
+import de.hybris.platform.commercefacades.order.data.CartData;
+
+import java.util.Map;
+
+public interface AdyenRequestService {
+
+ String TOTAL_TAX_AMOUNT = "enhancedSchemeData.totalTaxAmount";
+ String CUSTOMER_REFERENCE = "enhancedSchemeData.customerReference";
+ String FREIGHT_AMOUNT = "enhancedSchemeData.freightAmount";
+ String SHIP_FROM_POSTAL_CODE = "enhancedSchemeData.shipFromPostalCode";
+ String ORDER_DATE = "enhancedSchemeData.orderDate";
+ String DESTINATION_POSTAL_CODE = "enhancedSchemeData.destinationPostalCode";
+ String DESTINATION_STATE_PROVINCE_CODE = "enhancedSchemeData.destinationStateProvinceCode";
+ String DESTINATION_COUNTRY_CODE = "enhancedSchemeData.destinationCountryCode";
+ String DUTY_AMOUNT = "enhancedSchemeData.dutyAmount";
+
+ String ITEM_DETAIL_DESCRIPTION = "enhancedSchemeData.itemDetailLine%d.description";
+ String ITEM_DETAIL_PRODUCT_CODE = "enhancedSchemeData.itemDetailLine%d.productCode";
+ String ITEM_DETAIL_COMMODITY_CODE = "enhancedSchemeData.itemDetailLine%d.commodityCode";
+ String ITEM_DETAIL_QUANTITY = "enhancedSchemeData.itemDetailLine%d.quantity";
+ String ITEM_DETAIL_UNIT_OF_MEASURE = "enhancedSchemeData.itemDetailLine%d.unitOfMeasure";
+ String ITEM_DETAIL_UNIT_PRICE = "enhancedSchemeData.itemDetailLine%d.unitPrice";
+ String ITEM_DETAIL_DISCOUNT_AMOUNT = "enhancedSchemeData.itemDetailLine%d.discountAmount";
+ String ITEM_DETAIL_TOTAL_AMOUNT = "enhancedSchemeData.itemDetailLine%d.totalAmount";
+
+
+ void populateL2L3AdditionalData(final Map additionalData, final CartData cartData);
+
+
+ void applyAdditionalData(CartData cartData, PaymentRequest paymentsRequest);
+}
diff --git a/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java b/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
new file mode 100644
index 000000000..914cc1f86
--- /dev/null
+++ b/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
@@ -0,0 +1,132 @@
+package com.adyen.commerce.services.impl;
+
+import com.adyen.commerce.services.AdyenRequestService;
+import com.adyen.model.checkout.CardDetails;
+import com.adyen.model.checkout.PaymentRequest;
+import de.hybris.platform.commercefacades.order.data.CartData;
+import de.hybris.platform.commercefacades.order.data.OrderEntryData;
+import de.hybris.platform.core.model.order.CartModel;
+import de.hybris.platform.order.CartService;
+import de.hybris.platform.servicelayer.config.ConfigurationService;
+import de.hybris.platform.store.services.BaseStoreService;
+import org.apache.commons.lang3.StringUtils;
+import org.spockframework.util.CollectionUtil;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.IntStream;
+
+public class DefaultAdyenRequestService implements AdyenRequestService {
+
+
+ private BaseStoreService baseStoreService;
+ private CartService cartService;
+ private ConfigurationService configurationService;
+
+ private static final String L2L3_EDS_SUPPORTED_BRANDS = "adyen.l2l3eds.supported.brands";
+ private static final String L2L3_EDS_SUPPORTED_COUNTRIES = "adyen.l2l3eds.supported.countries";
+
+ public DefaultAdyenRequestService(BaseStoreService baseStoreService, CartService cartService, ConfigurationService configurationService) {
+ this.baseStoreService = baseStoreService;
+ this.cartService = cartService;
+ this.configurationService = configurationService;
+ }
+
+ @Override
+ public void populateL2L3AdditionalData(final Map additionalData, final CartData cartData) {
+ // required fields
+ if (cartData.getTotalTax() != null) {
+ additionalData.put(TOTAL_TAX_AMOUNT, String.valueOf(cartData.getTotalTax().getValue()));
+ }
+ if (cartData.getMerchantCustomerId() != null) {
+ additionalData.put(CUSTOMER_REFERENCE, cartData.getMerchantCustomerId());
+ }
+ // not required but available
+ if (cartData.getDeliveryCost() != null) {
+ additionalData.put(FREIGHT_AMOUNT, String.valueOf(cartData.getDeliveryCost().getValue()));
+ }
+ if (cartData.getDeliveryAddress() != null) {
+ if (cartData.getDeliveryAddress().getPostalCode() != null) {
+ additionalData.put(DESTINATION_POSTAL_CODE, cartData.getDeliveryAddress().getPostalCode());
+ }
+ if (cartData.getDeliveryAddress().getCountry() != null && cartData.getDeliveryAddress().getCountry().getIsocode() != null) {
+ additionalData.put(DESTINATION_COUNTRY_CODE, cartData.getDeliveryAddress().getCountry().getIsocode());
+ }
+ }
+
+ // Extract item details from cartData and populate additionalData using a stream
+ if (cartData.getEntries() != null) {
+ IntStream.range(0, cartData.getEntries().size()).forEach(i -> {
+ OrderEntryData entry = cartData.getEntries().get(i);
+ if (entry != null && entry.getProduct() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_PRODUCT_CODE, i + 1),
+ Optional.ofNullable(entry.getProduct().getCode()).orElse(StringUtils.EMPTY));
+ additionalData.put(String.format(ITEM_DETAIL_DESCRIPTION, i + 1),
+ Optional.ofNullable(entry.getProduct().getName()).orElse(StringUtils.EMPTY));
+
+ additionalData.put(String.format(ITEM_DETAIL_QUANTITY, i + 1), String.valueOf(entry.getQuantity()));
+
+ additionalData.put(String.format(ITEM_DETAIL_UNIT_OF_MEASURE, i + 1),
+ Optional.ofNullable(entry.getUnitOfMeasure()).orElse(StringUtils.EMPTY));
+
+ additionalData.put(String.format(ITEM_DETAIL_COMMODITY_CODE, i + 1),
+ Optional.ofNullable(entry.getProduct().getCommodityCode()).orElse(StringUtils.EMPTY));
+
+ if (entry.getTotalPrice() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_TOTAL_AMOUNT, i + 1),
+ String.valueOf(Optional.ofNullable(entry.getTotalPrice().getValue()).orElse(BigDecimal.ZERO)));
+ }
+
+ if (entry.getBasePrice() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_UNIT_PRICE, i + 1),
+ String.valueOf(Optional.ofNullable(entry.getBasePrice().getValue()).orElse(BigDecimal.ZERO)));
+ }
+ }
+
+ });
+ }
+ }
+
+ @Override
+ public void applyAdditionalData(CartData cartData, PaymentRequest paymentsRequest) {
+ Map additionalData = new HashMap<>();
+ CartModel sessionCart = cartService.getSessionCart();
+ if(canL23EdsBeSent(paymentsRequest, sessionCart)) {
+ populateL2L3AdditionalData(additionalData, cartData);
+ }
+
+ paymentsRequest.setAdditionalData(additionalData);
+
+ }
+
+ protected boolean canL23EdsBeSent(PaymentRequest paymentsRequest, CartModel sessionCart) {
+ return Optional.ofNullable(baseStoreService.getCurrentBaseStore())
+ .map(store -> store.getL2L3ESDEnabled())
+ .orElse(false) &&
+ Optional.ofNullable(paymentsRequest.getPaymentMethod())
+ .map(method -> method.getActualInstance())
+ .filter(instance -> instance instanceof CardDetails)
+ .map(instance -> (CardDetails) instance)
+ .map(cardDetails -> getL2L3SupportedBrands().contains(cardDetails.getBrand()))
+ .orElse(false) &&
+ Optional.ofNullable(sessionCart.getDeliveryAddress())
+ .map(address -> address.getCountry())
+ .map(country -> getL2L3SupportedCountries().contains(country.getIsocode()))
+ .orElse(false);
+ }
+
+ protected List getL2L3SupportedBrands() {
+ String property = configurationService.getConfiguration().getString(L2L3_EDS_SUPPORTED_BRANDS);
+ return property != null ? List.of(property.split(",")) : new ArrayList<>();
+ }
+
+ protected List getL2L3SupportedCountries() {
+ String property = configurationService.getConfiguration().getString(L2L3_EDS_SUPPORTED_COUNTRIES);
+ return property != null ? List.of(property.split(",")) : new ArrayList<>();
+ }
+}
diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java
index 09a8d50db..fea5b0f9d 100644
--- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java
+++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java
@@ -430,7 +430,7 @@ public OrderData authorisePayment(final HttpServletRequest request, final CartDa
RequestInfo requestInfo = new RequestInfo(request);
requestInfo.setShopperLocale(getShopperLocale());
- PaymentResponse paymentResponse = getAdyenPaymentService().authorisePayment(cartData, requestInfo, customer);
+ PaymentResponse paymentResponse = getAdyenPaymentService().processPaymentRequest(cartData,null, requestInfo, customer);
PaymentResponse.ResultCodeEnum resultCode = paymentResponse.getResultCode();
PaymentResponseAction action = paymentResponse.getAction();
@@ -477,7 +477,7 @@ public PaymentResponse componentPayment(final HttpServletRequest request, final
RequestInfo requestInfo = new RequestInfo(request);
requestInfo.setShopperLocale(getShopperLocale());
- PaymentResponse paymentResponse = getAdyenPaymentService().componentPayment(cartData, paymentRequest, requestInfo, getCheckoutCustomerStrategy().getCurrentUserForCheckout());
+ PaymentResponse paymentResponse = getAdyenPaymentService().processPaymentRequest(cartData, paymentRequest, requestInfo, getCheckoutCustomerStrategy().getCurrentUserForCheckout());
if (PaymentResponse.ResultCodeEnum.PENDING == paymentResponse.getResultCode() ||
PaymentResponse.ResultCodeEnum.REDIRECTSHOPPER == paymentResponse.getResultCode() ||
PaymentResponse.ResultCodeEnum.PRESENTTOSHOPPER == paymentResponse.getResultCode()) {
diff --git a/adyenv6core/src/com/adyen/v6/factory/AdyenPaymentServiceFactory.java b/adyenv6core/src/com/adyen/v6/factory/AdyenPaymentServiceFactory.java
index 5f1509269..b20762dbf 100644
--- a/adyenv6core/src/com/adyen/v6/factory/AdyenPaymentServiceFactory.java
+++ b/adyenv6core/src/com/adyen/v6/factory/AdyenPaymentServiceFactory.java
@@ -20,6 +20,7 @@
*/
package com.adyen.v6.factory;
+import com.adyen.commerce.services.impl.DefaultAdyenRequestService;
import com.adyen.v6.service.AdyenCheckoutApiService;
import com.adyen.v6.service.AdyenModificationsApiService;
import com.adyen.v6.service.DefaultAdyenCheckoutApiService;
@@ -27,30 +28,30 @@
import com.adyen.v6.strategy.AdyenMerchantAccountStrategy;
import de.hybris.platform.store.BaseStoreModel;
-/**
- * Factory class for AdyenPaymentService
- */
+
public class AdyenPaymentServiceFactory {
private final AdyenRequestFactory adyenRequestFactory;
protected final AdyenMerchantAccountStrategy adyenMerchantAccountStrategy;
+ private final DefaultAdyenRequestService defaultAdyenRequestService;
- public AdyenPaymentServiceFactory(final AdyenRequestFactory adyenRequestFactory, final AdyenMerchantAccountStrategy adyenMerchantAccountStrategy) {
+ public AdyenPaymentServiceFactory(final AdyenRequestFactory adyenRequestFactory, final AdyenMerchantAccountStrategy adyenMerchantAccountStrategy, DefaultAdyenRequestService defaultAdyenRequestService) {
this.adyenRequestFactory = adyenRequestFactory;
this.adyenMerchantAccountStrategy = adyenMerchantAccountStrategy;
+ this.defaultAdyenRequestService = defaultAdyenRequestService;
}
public AdyenCheckoutApiService createAdyenCheckoutApiService(final BaseStoreModel baseStoreModel) {
String webMerchantAccount = adyenMerchantAccountStrategy.getWebMerchantAccount(baseStoreModel);
- DefaultAdyenCheckoutApiService defaultAdyenCheckoutApiService = new DefaultAdyenCheckoutApiService(baseStoreModel, webMerchantAccount);
+ DefaultAdyenCheckoutApiService defaultAdyenCheckoutApiService = new DefaultAdyenCheckoutApiService(baseStoreModel, webMerchantAccount, defaultAdyenRequestService);
defaultAdyenCheckoutApiService.setAdyenRequestFactory(adyenRequestFactory);
return defaultAdyenCheckoutApiService;
}
public AdyenModificationsApiService createAdyenModificationsApiService(final BaseStoreModel baseStoreModel) {
String webMerchantAccount = adyenMerchantAccountStrategy.getWebMerchantAccount(baseStoreModel);
- DefaultAdyenModificationsApiService adyenModificationsApiService = new DefaultAdyenModificationsApiService(baseStoreModel, webMerchantAccount);
+ DefaultAdyenModificationsApiService adyenModificationsApiService = new DefaultAdyenModificationsApiService(baseStoreModel, webMerchantAccount, defaultAdyenRequestService);
adyenModificationsApiService.setAdyenRequestFactory(adyenRequestFactory);
return adyenModificationsApiService;
}
diff --git a/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java b/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java
index d6a7981a6..fe15a9366 100644
--- a/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java
+++ b/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java
@@ -50,7 +50,6 @@
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.servicelayer.config.ConfigurationService;
import de.hybris.platform.util.TaxValue;
-import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@@ -78,6 +77,14 @@
import static com.adyen.v6.constants.Adyenv6coreConstants.PLUGIN_VERSION;
import static com.adyen.v6.constants.Adyenv6coreConstants.RATEPAY;
+/**
+ * Factory class to create Adyen API requests, do not add new code to this class.
+ * This class is deprecated and will be removed in future versions.
+ * Please use the new {@link com.adyen.commerce.services.AdyenRequestService} instead.
+ * @deprecated since v13.1. Please use the new {@link com.adyen.commerce.services.AdyenRequestService} instead.
+ * @see com.adyen.commerce.services.AdyenRequestService
+ */
+@Deprecated(since = "v13.1", forRemoval = true)
public class AdyenRequestFactory {
private static final Logger LOG = Logger.getLogger(AdyenRequestFactory.class);
@@ -794,4 +801,7 @@ public ConfigurationService getConfigurationService() {
return configurationService;
}
+
}
+
+
diff --git a/adyenv6core/src/com/adyen/v6/populator/CartPopulator.java b/adyenv6core/src/com/adyen/v6/populator/CartPopulator.java
index f45fe81ef..b39d8ef82 100644
--- a/adyenv6core/src/com/adyen/v6/populator/CartPopulator.java
+++ b/adyenv6core/src/com/adyen/v6/populator/CartPopulator.java
@@ -66,6 +66,7 @@ public void populate(final CartModel source, final CartData target) throws Conve
target.setAdyenGiftCardBrand(paymentInfo.getAdyenGiftCardBrand());
target.setAdyenAmazonPayConfiguration(source.getAdyenAmazonPayConfiguration());
}
+
}
protected boolean isAdyenPaymentInfo(final PaymentInfoModel paymentInfo) {
diff --git a/adyenv6core/src/com/adyen/v6/populator/ProductPopulator.java b/adyenv6core/src/com/adyen/v6/populator/ProductPopulator.java
new file mode 100644
index 000000000..013118116
--- /dev/null
+++ b/adyenv6core/src/com/adyen/v6/populator/ProductPopulator.java
@@ -0,0 +1,15 @@
+package com.adyen.v6.populator;
+
+import de.hybris.platform.commercefacades.order.data.CartData;
+import de.hybris.platform.commercefacades.product.data.ProductData;
+import de.hybris.platform.converters.Populator;
+import de.hybris.platform.core.model.order.CartModel;
+import de.hybris.platform.core.model.product.ProductModel;
+import de.hybris.platform.servicelayer.dto.converter.ConversionException;
+
+public class ProductPopulator implements Populator {
+ @Override
+ public void populate(ProductModel productModel, ProductData productData) throws ConversionException {
+ productData.setCommodityCode(productModel.getCommodityCode());
+ }
+}
diff --git a/adyenv6core/src/com/adyen/v6/service/AbstractAdyenApiService.java b/adyenv6core/src/com/adyen/v6/service/AbstractAdyenApiService.java
index 98a3d375c..96eb1e52e 100644
--- a/adyenv6core/src/com/adyen/v6/service/AbstractAdyenApiService.java
+++ b/adyenv6core/src/com/adyen/v6/service/AbstractAdyenApiService.java
@@ -2,6 +2,7 @@
import com.adyen.Client;
import com.adyen.Config;
+import com.adyen.commerce.services.AdyenRequestService;
import com.adyen.enums.Environment;
import com.adyen.v6.factory.AdyenRequestFactory;
import de.hybris.platform.store.BaseStoreModel;
@@ -14,6 +15,7 @@ public abstract class AbstractAdyenApiService {
protected BaseStoreModel baseStore;
protected String merchantAccount;
protected AdyenRequestFactory adyenRequestFactory;
+ protected AdyenRequestService adyenRequestService;
protected Config config;
protected Client client;
protected Config posConfig;
@@ -26,8 +28,7 @@ public abstract class AbstractAdyenApiService {
private AbstractAdyenApiService() {
}
-
- public AbstractAdyenApiService(final BaseStoreModel baseStore, final String merchantAccount) {
+ public AbstractAdyenApiService(final BaseStoreModel baseStore, final String merchantAccount, final AdyenRequestService adyenRequestService) {
this.baseStore = baseStore;
this.merchantAccount = merchantAccount;
@@ -57,7 +58,6 @@ public AbstractAdyenApiService(final BaseStoreModel baseStore, final String merc
this.config.setTerminalApiCloudEndpoint(Client.TERMINAL_API_ENDPOINT_LIVE);
this.config.setLiveEndpointUrlPrefix(baseStore.getAdyenAPIEndpointPrefix());
}
-
}
public AdyenRequestFactory getAdyenRequestFactory() {
diff --git a/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java b/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java
index c7a4cfc3d..b1b3135af 100644
--- a/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java
+++ b/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java
@@ -22,7 +22,6 @@
import com.adyen.httpclient.HTTPClientException;
import com.adyen.model.checkout.Amount;
-import com.adyen.model.checkout.CheckoutPaymentMethod;
import com.adyen.model.checkout.CreateCheckoutSessionResponse;
import com.adyen.model.checkout.PaymentCompletionDetails;
import com.adyen.model.checkout.PaymentDetailsRequest;
@@ -37,7 +36,6 @@
import com.adyen.service.exception.ApiException;
import com.adyen.v6.model.RequestInfo;
import de.hybris.platform.commercefacades.order.data.CartData;
-import de.hybris.platform.core.model.order.AbstractOrderModel;
import de.hybris.platform.core.model.user.CustomerModel;
import java.io.IOException;
@@ -49,9 +47,7 @@ public interface AdyenCheckoutApiService {
ConnectedTerminalsResponse getConnectedTerminals() throws IOException, ApiException;
- PaymentResponse authorisePayment(CartData cartData, RequestInfo requestInfo, CustomerModel customerModel) throws Exception;
-
- PaymentResponse componentPayment(CartData cartData, PaymentRequest originPaymentsRequest, RequestInfo requestInfo, CustomerModel customerModel) throws Exception;
+ PaymentResponse processPaymentRequest(CartData cartData, PaymentRequest originPaymentsRequest, RequestInfo requestInfo, CustomerModel customerModel) throws Exception;
PaymentDetailsResponse authorise3DSPayment(PaymentDetailsRequest paymentsDetailsRequest) throws Exception;
diff --git a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java
index 79355cd75..01352f110 100644
--- a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java
+++ b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java
@@ -20,6 +20,8 @@
*/
package com.adyen.v6.service;
+import com.adyen.commerce.services.AdyenRequestService;
+import com.adyen.commerce.services.impl.DefaultAdyenRequestService;
import com.adyen.model.checkout.Amount;
import com.adyen.model.checkout.CheckoutPaymentMethod;
import com.adyen.model.checkout.CreateCheckoutSessionRequest;
@@ -49,13 +51,16 @@
import com.adyen.service.exception.ApiException;
import com.adyen.terminal.serialization.TerminalAPIGsonBuilder;
import com.adyen.v6.enums.RecurringContractMode;
+import com.adyen.v6.factory.AdyenRequestFactory;
import com.adyen.v6.model.RequestInfo;
+import com.adyen.v6.strategy.AdyenMerchantAccountStrategy;
import com.adyen.v6.util.AmountUtil;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commercefacades.product.data.PriceData;
import de.hybris.platform.core.model.order.AbstractOrderModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.store.BaseStoreModel;
+import de.hybris.platform.store.services.BaseStoreService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@@ -76,31 +81,8 @@ public class DefaultAdyenCheckoutApiService extends AbstractAdyenApiService impl
private static final Logger LOG = Logger.getLogger(DefaultAdyenCheckoutApiService.class);
- public DefaultAdyenCheckoutApiService(BaseStoreModel baseStore, String merchantAccount) {
- super(baseStore, merchantAccount);
- }
-
-
- @Override
- @Deprecated
- public PaymentResponse authorisePayment(final CartData cartData, final RequestInfo requestInfo, final CustomerModel customerModel) throws Exception {
- LOG.debug("Authorize payment");
-
- PaymentsApi paymentsApi = new PaymentsApi(client);
-
- PaymentRequest paymentsRequest = getAdyenRequestFactory().createPaymentsRequest(merchantAccount,
- cartData,
- null,
- requestInfo,
- customerModel,
- baseStore.getAdyenRecurringContractMode(),
- baseStore.getAdyenGuestUserTokenization());
-
- LOG.debug(paymentsRequest);
- PaymentResponse payments = paymentsApi.payments(paymentsRequest);
- LOG.debug(payments);
-
- return payments;
+ public DefaultAdyenCheckoutApiService(BaseStoreModel baseStore, String merchantAccount, AdyenRequestService adyenRequestService) {
+ super(baseStore, merchantAccount, adyenRequestService);
}
@Override
@@ -121,7 +103,7 @@ public ConnectedTerminalsResponse getConnectedTerminals() throws IOException, Ap
}
@Override
- public PaymentResponse componentPayment(final CartData cartData, PaymentRequest originPaymentsRequest, final RequestInfo requestInfo, final CustomerModel customerModel) throws Exception {
+ public PaymentResponse processPaymentRequest(final CartData cartData, PaymentRequest originPaymentsRequest, final RequestInfo requestInfo, final CustomerModel customerModel) throws Exception {
LOG.debug("Component payment");
PaymentsApi checkoutApi = new PaymentsApi(client);
@@ -132,6 +114,8 @@ public PaymentResponse componentPayment(final CartData cartData, PaymentRequest
requestInfo,
customerModel, baseStore.getAdyenRecurringContractMode(), baseStore.getAdyenGuestUserTokenization());
+ adyenRequestService.applyAdditionalData(cartData, paymentsRequest);
+
LOG.debug(paymentsRequest);
PaymentResponse paymentsResponse = checkoutApi.payments(paymentsRequest);
LOG.debug(paymentsResponse);
diff --git a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenModificationsApiService.java b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenModificationsApiService.java
index 1cd06a62e..4d0d83208 100644
--- a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenModificationsApiService.java
+++ b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenModificationsApiService.java
@@ -1,5 +1,6 @@
package com.adyen.v6.service;
+import com.adyen.commerce.services.AdyenRequestService;
import com.adyen.model.checkout.PaymentCaptureRequest;
import com.adyen.model.checkout.PaymentCaptureResponse;
import com.adyen.model.checkout.PaymentRefundRequest;
@@ -18,8 +19,8 @@ public class DefaultAdyenModificationsApiService extends AbstractAdyenApiService
private static final Logger LOG = Logger.getLogger(DefaultAdyenModificationsApiService.class);
- public DefaultAdyenModificationsApiService(BaseStoreModel baseStore, String merchantAccount) {
- super(baseStore, merchantAccount);
+ public DefaultAdyenModificationsApiService(BaseStoreModel baseStore, String merchantAccount, final AdyenRequestService adyenRequestService) {
+ super(baseStore, merchantAccount, adyenRequestService);
}
@Override
diff --git a/adyenv6core/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java b/adyenv6core/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
index 0382ccb67..c9e6f579e 100644
--- a/adyenv6core/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
+++ b/adyenv6core/testsrc/com/adyen/v6/facades/AdyenCheckoutFacadeTest.java
@@ -492,7 +492,7 @@ public void testAuthorisePaymentRedirect() throws Exception {
adyenCheckoutFacade.authorisePayment(request, cartData);
fail("Expected AdyenNonAuthorizedPaymentException");
} catch (AdyenNonAuthorizedPaymentException e) {
- verify(adyenCheckoutApiService).authorisePayment(eq(cartData), any(), any());
+ verify(adyenCheckoutApiService).processPaymentRequest(eq(cartData),null, any(), any());
verify(cartModel).setStatus(OrderStatus.PAYMENT_PENDING);
verify(checkoutFacade).placeOrder();
assertNotNull(e.getPaymentsResponse());
From f971936fe6f8226c9feea8979d75af3d8126b9d9 Mon Sep 17 00:00:00 2001
From: kpieloch <113994423+kpieloch@users.noreply.github.com>
Date: Wed, 23 Oct 2024 10:04:24 +0200
Subject: [PATCH 2/2] AD-301: Add support for Enhanced Scheme Data (L2/L3 data)
---
.../impl/DefaultAdyenRequestService.java | 56 +++++++++----------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java b/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
index 914cc1f86..ba991ab46 100644
--- a/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
+++ b/adyenv6core/src/com/adyen/commerce/services/impl/DefaultAdyenRequestService.java
@@ -43,7 +43,7 @@ public void populateL2L3AdditionalData(final Map additionalData,
if (cartData.getTotalTax() != null) {
additionalData.put(TOTAL_TAX_AMOUNT, String.valueOf(cartData.getTotalTax().getValue()));
}
- if (cartData.getMerchantCustomerId() != null) {
+ if (StringUtils.isNotEmpty(cartData.getMerchantCustomerId())) {
additionalData.put(CUSTOMER_REFERENCE, cartData.getMerchantCustomerId());
}
// not required but available
@@ -61,34 +61,34 @@ public void populateL2L3AdditionalData(final Map additionalData,
// Extract item details from cartData and populate additionalData using a stream
if (cartData.getEntries() != null) {
- IntStream.range(0, cartData.getEntries().size()).forEach(i -> {
- OrderEntryData entry = cartData.getEntries().get(i);
- if (entry != null && entry.getProduct() != null) {
- additionalData.put(String.format(ITEM_DETAIL_PRODUCT_CODE, i + 1),
- Optional.ofNullable(entry.getProduct().getCode()).orElse(StringUtils.EMPTY));
- additionalData.put(String.format(ITEM_DETAIL_DESCRIPTION, i + 1),
- Optional.ofNullable(entry.getProduct().getName()).orElse(StringUtils.EMPTY));
-
- additionalData.put(String.format(ITEM_DETAIL_QUANTITY, i + 1), String.valueOf(entry.getQuantity()));
-
- additionalData.put(String.format(ITEM_DETAIL_UNIT_OF_MEASURE, i + 1),
- Optional.ofNullable(entry.getUnitOfMeasure()).orElse(StringUtils.EMPTY));
-
- additionalData.put(String.format(ITEM_DETAIL_COMMODITY_CODE, i + 1),
- Optional.ofNullable(entry.getProduct().getCommodityCode()).orElse(StringUtils.EMPTY));
-
- if (entry.getTotalPrice() != null) {
- additionalData.put(String.format(ITEM_DETAIL_TOTAL_AMOUNT, i + 1),
- String.valueOf(Optional.ofNullable(entry.getTotalPrice().getValue()).orElse(BigDecimal.ZERO)));
+ cartData.getEntries().forEach(
+ entry -> {
+ if (entry != null && entry.getProduct() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_PRODUCT_CODE, entry.getEntryNumber()),
+ Optional.ofNullable(entry.getProduct().getCode()).orElse(StringUtils.EMPTY));
+ additionalData.put(String.format(ITEM_DETAIL_DESCRIPTION, entry.getEntryNumber()),
+ Optional.ofNullable(entry.getProduct().getName()).orElse(StringUtils.EMPTY));
+
+ additionalData.put(String.format(ITEM_DETAIL_QUANTITY, entry.getEntryNumber()), String.valueOf(entry.getQuantity()));
+
+ additionalData.put(String.format(ITEM_DETAIL_UNIT_OF_MEASURE, entry.getEntryNumber()),
+ Optional.ofNullable(entry.getUnitOfMeasure()).orElse(StringUtils.EMPTY));
+
+ additionalData.put(String.format(ITEM_DETAIL_COMMODITY_CODE, entry.getEntryNumber()),
+ Optional.ofNullable(entry.getProduct().getCommodityCode()).orElse(StringUtils.EMPTY));
+
+ if (entry.getTotalPrice() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_TOTAL_AMOUNT, entry.getEntryNumber()),
+ String.valueOf(Optional.ofNullable(entry.getTotalPrice().getValue()).orElse(BigDecimal.ZERO)));
+ }
+
+ if (entry.getBasePrice() != null) {
+ additionalData.put(String.format(ITEM_DETAIL_UNIT_PRICE, entry.getEntryNumber()),
+ String.valueOf(Optional.ofNullable(entry.getBasePrice().getValue()).orElse(BigDecimal.ZERO)));
+ }
+ }
}
-
- if (entry.getBasePrice() != null) {
- additionalData.put(String.format(ITEM_DETAIL_UNIT_PRICE, i + 1),
- String.valueOf(Optional.ofNullable(entry.getBasePrice().getValue()).orElse(BigDecimal.ZERO)));
- }
- }
-
- });
+ );
}
}