diff --git a/README.md b/README.md
index d1e9a580b..fac115681 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,10 @@ Required for the checkout:
```
+Required for the notifications:
+```
+
+```
Additionally, required when using yacceleratorordermanagement (b2c_acc_oms recipe):
```
@@ -33,9 +37,9 @@ Additionally, required when using yacceleratorfulfilment (b2c_acc recipe):
```
-### 3. Modify local.properties
+### 3. Modify local.properties
-Modify config/local.properties file:
+Modify config/local.properties file:
append ,/[^/]+(/[^?]*)+(adyen-response)$,/adyen(/[^?]*)+$ to the value of csrf.allowed.url.patterns
### 4. Build
@@ -56,12 +60,11 @@ Please make sure your merchant has Variant true in API and responses section so
### Credit Cards
-Credit Card payments are supported using [Client Side Encryption](https://docs.adyen.com/support/payment-glossary/client-side-encryption-cse).
+Credit Card payments are supported using Checkout Components.
-### Klarna
+### Ratepay
-Klarna is supported via Adyen API.
-Requires shopper data listed in: https://developers.klarna.com/en/se/kpm/test-credentials
+Ratepay is supported via Adyen API.
### Boleto
@@ -79,7 +82,7 @@ More details can be found here: https://docs.adyen.com/developers/payment-method
### Other alternative payment methods
-Supported via Adyen [Hosted Payment Pages](https://docs.adyen.com/developers/products-and-subscriptions/hosted-payment-pages).
+Supported via Adyen Checkout.
## Usage with OCC
@@ -109,7 +112,7 @@ For Credit Card payments - it expects encrypted card holder data obtained from y
For Stored Cards payments - selected Adyen recurringReference of the card and encrypted cvc
For Boleto payments - social security number
-
+
3. OrderData authorisePayment(CartData cartData) throws Exception;
@@ -124,13 +127,18 @@ It returns an instance of OrderWSDTO obtained from OrderData of the placed order
For Boleto, it will contain the pdf url, the base64 encoded data, expiration date and due date
https://docs.adyen.com/developers/payment-methods/boleto-bancario/boleto-payment-request
+ ## 3DS2 configuration
+ By default 3DS2 is disabled. If you want to enable 3DS2 in your system, please set following property in local.properties file, build your environment and restart the server.
+```
+is3DS2allowed = true
+```
## Documentation
https://docs.adyen.com/developers/plugins/hybris
-
+
## Support
You can create issues on our Magento Repository. In case of specific problems with your account, please contact
support@adyen.com.
-
+
## License
MIT license. For more information, see the LICENSE file.
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/constants/AdyenControllerConstants.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/constants/AdyenControllerConstants.java
index 3b691a568..5225a374f 100644
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/constants/AdyenControllerConstants.java
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/constants/AdyenControllerConstants.java
@@ -24,7 +24,6 @@ public interface AdyenControllerConstants
{
String ADDON_PREFIX = "addon:/adyenv6b2ccheckoutaddon/";
String SUMMARY_CHECKOUT_PREFIX = "/checkout/multi/adyen/summary";
- String NOTIFICATION_PREFIX = "/adyen/v6/notification";
String PAYPAL_ECS_PREFIX = "/adyen/paypal-ecs";
/**
@@ -42,6 +41,7 @@ interface MultiStepCheckout
String SelectPaymentMethod = ADDON_PREFIX + "pages/checkout/multi/selectPaymentMethodPage";
String Validate3DSecurePaymentPage = ADDON_PREFIX + "pages/checkout/multi/3d-secure-payment-validation";
String HppPaymentPage = ADDON_PREFIX + "pages/checkout/multi/hpp-payment";
+ String Validate3DS2PaymentPage = ADDON_PREFIX + "pages/checkout/multi/3ds2_payment";
}
}
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenNotificationController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenNotificationController.java
deleted file mode 100644
index 5e47460da..000000000
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenNotificationController.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ######
- * ######
- * ############ ####( ###### #####. ###### ############ ############
- * ############# #####( ###### #####. ###### ############# #############
- * ###### #####( ###### #####. ###### ##### ###### ##### ######
- * ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
- * ###### ###### #####( ###### #####. ###### ##### ##### ######
- * ############# ############# ############# ############# ##### ######
- * ############ ############ ############# ############ ##### ######
- * ######
- * #############
- * ############
- *
- * Adyen Hybris Extension
- *
- * Copyright (c) 2017 Adyen B.V.
- * This file is open source and available under the MIT license.
- * See the LICENSE file for more info.
- */
-package com.adyen.v6.controllers.pages;
-
-import java.io.IOException;
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-import org.apache.commons.io.IOUtils;
-import org.apache.log4j.Logger;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.ResponseBody;
-import com.adyen.v6.constants.AdyenControllerConstants;
-import com.adyen.v6.security.AdyenNotificationAuthenticationProvider;
-import com.adyen.v6.service.AdyenNotificationService;
-
-@Controller
-@RequestMapping(value = AdyenControllerConstants.NOTIFICATION_PREFIX)
-public class AdyenNotificationController {
- private static final Logger LOG = Logger.getLogger(AdyenNotificationController.class);
-
- @Resource(name = "adyenNotificationAuthenticationProvider")
- private AdyenNotificationAuthenticationProvider adyenNotificationAuthenticationProvider;
-
- @Resource(name = "adyenNotificationService")
- private AdyenNotificationService adyenNotificationService;
-
- private static final String RESPONSE_ACCEPTED = "[accepted]";
- private static final String RESPONSE_NOT_ACCEPTED = "[not-accepted]";
-
- @RequestMapping(value = "/json", method = RequestMethod.POST)
- @ResponseBody
- public String onReceive(final HttpServletRequest request) {
- String requestString = null;
- try {
- //Parse response body by request input stream so that Spring doesn't try to deserialize
- requestString = IOUtils.toString(request.getInputStream());
- } catch (IOException e) {
- LOG.error(e);
- return RESPONSE_NOT_ACCEPTED;
- }
-
- LOG.debug("Received Adyen notification:" + requestString);
- if (! adyenNotificationAuthenticationProvider.authenticateBasic(request)) {
- throw new AccessDeniedException("Wrong credentials");
- }
-
- adyenNotificationService.saveNotifications(requestString);
-
- return RESPONSE_ACCEPTED;
- }
-}
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java
index 63035096b..c21db4b6a 100644
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java
@@ -64,7 +64,15 @@
import de.hybris.platform.site.BaseSiteService;
import static com.adyen.constants.ApiConstants.Redirect.Data.MD;
import static com.adyen.constants.ApiConstants.Redirect.Data.PAREQ;
+import static com.adyen.constants.ApiConstants.Redirect.Data.PAYMENT_DATA;
+import static com.adyen.constants.ApiConstants.ThreeDS2Property.CHALLENGE_TOKEN;
+import static com.adyen.constants.ApiConstants.ThreeDS2Property.FINGERPRINT_TOKEN;
+import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_CHALLENGE_TOKEN;
+import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_FINGERPRINT_TOKEN;
import static com.adyen.constants.BrandCodes.PAYPAL_ECS;
+import static com.adyen.constants.HPPConstants.Response.SHOPPER_LOCALE;
+import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.CHALLENGESHOPPER;
+import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.IDENTIFYSHOPPER;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.REDIRECTSHOPPER;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.REFUSED;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_BOLETO;
@@ -72,6 +80,8 @@
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_ONECLICK;
import static com.adyen.v6.constants.Adyenv6coreConstants.RATEPAY;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_MULTIBANCO;
+import static com.adyen.v6.facades.DefaultAdyenCheckoutFacade.MODEL_CHECKOUT_SHOPPER_HOST;
+import static com.adyen.v6.facades.DefaultAdyenCheckoutFacade.MODEL_ORIGIN_KEY;
@Controller
@RequestMapping(value = AdyenControllerConstants.SUMMARY_CHECKOUT_PREFIX)
@@ -173,9 +183,7 @@ public String placeOrder(@ModelAttribute("placeOrderForm") final PlaceOrderForm
//In case of Boleto, show link to pdf
if (PAYMENT_METHOD_BOLETO.equals(cartData.getAdyenPaymentMethod())) {
addBoletoMessage(redirectModel, orderData.getCode());
- }
-
- else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
+ } else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
addMultibancoMessage(redirectModel, orderData.getCode());
}
@@ -199,6 +207,26 @@ else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
if (REFUSED == paymentsResponse.getResultCode()) {
errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason());
}
+ if (IDENTIFYSHOPPER == paymentsResponse.getResultCode()) {
+ if (adyenPaymentMethod.equals(PAYMENT_METHOD_CC)|| adyenPaymentMethod.indexOf(PAYMENT_METHOD_ONECLICK) == 0) {
+ model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
+ model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
+ model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
+ model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
+ model.addAttribute(FINGERPRINT_TOKEN, paymentsResponse.getAuthentication().get(THREEDS2_FINGERPRINT_TOKEN));
+ return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
+ }
+ }
+ if (CHALLENGESHOPPER == paymentsResponse.getResultCode()) {
+ if (adyenPaymentMethod.equals(PAYMENT_METHOD_CC)|| adyenPaymentMethod.indexOf(PAYMENT_METHOD_ONECLICK) == 0) {
+ model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
+ model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
+ model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
+ model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
+ model.addAttribute(CHALLENGE_TOKEN, paymentsResponse.getAuthentication().get(THREEDS2_CHALLENGE_TOKEN));
+ return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
+ }
+ }
} catch (Exception e) {
LOGGER.error(ExceptionUtils.getStackTrace(e));
}
@@ -208,6 +236,38 @@ else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
return enterStep(model, redirectModel);
}
+ @RequestMapping(value = "/3ds2-adyen-response", method = RequestMethod.POST)
+ @RequireHardLogIn
+ public String authorise3DS2Payment(final Model model,
+ final RedirectAttributes redirectModel,
+ final HttpServletRequest request) throws CMSItemNotFoundException, CommerceCartModificationException, UnknownHostException {
+
+ String errorMessage = "checkout.error.authorization.failed";
+ try {
+ OrderData orderData = adyenCheckoutFacade.handle3DS2Response(request);
+ LOGGER.debug("Redirecting to confirmation");
+ return redirectToOrderConfirmationPage(orderData);
+ } catch (AdyenNonAuthorizedPaymentException e) {
+ PaymentsResponse paymentsResponse = e.getPaymentsResponse();
+ if (paymentsResponse != null && paymentsResponse.getResultCode() == CHALLENGESHOPPER) {
+ model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
+ model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
+ model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
+ model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
+ model.addAttribute(CHALLENGE_TOKEN, paymentsResponse.getAuthentication().get("threeds2.challengeToken"));
+ return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
+ }
+ if (paymentsResponse != null && paymentsResponse.getResultCode() == PaymentsResponse.ResultCodeEnum.REFUSED) {
+ errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason());
+ }
+ } catch (Exception e) {
+ LOGGER.debug("Redirecting to summary" + errorMessage);
+ return redirectToSummaryWithError(redirectModel, errorMessage);
+ }
+ LOGGER.debug("Redirecting to final step of checkout" +errorMessage);
+ return redirectToSummaryWithError(redirectModel, errorMessage);
+ }
+
@RequestMapping(value = AUTHORISE_3D_SECURE_PAYMENT_URL, method = RequestMethod.POST)
@RequireHardLogIn
public String authorise3DSecurePayment(final Model model,
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/messages/base.properties b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/messages/base.properties
index f0f72980d..7495c9274 100644
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/messages/base.properties
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/messages/base.properties
@@ -1,6 +1,6 @@
checkout.error.authorization.transaction.not.permitted=The transaction is not permitted.
-checkout.error.authorization.cvc.declined=Declined due to the Card Security Code(CVC) being incorrect. Please check your CVC code!
+checkout.error.authorization.cvc.declined=The payment is REFUSED. Please check your Card details.
checkout.error.authorization.restricted.card=The card is restricted.
checkout.error.authorization.payment.detail.not.found=The payment is REFUSED because the saved card is removed. Please try an other payment method.
checkout.error.authorization.payment.refused=The payment is REFUSED.
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/securedFieldsMethod.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/securedFieldsMethod.tag
index 299bc826e..034a91760 100644
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/securedFieldsMethod.tag
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/securedFieldsMethod.tag
@@ -35,15 +35,6 @@
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds2_payment.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds2_payment.jsp
new file mode 100644
index 000000000..57b307413
--- /dev/null
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds2_payment.jsp
@@ -0,0 +1,97 @@
+<%@ page trimDirectiveWhitespaces="true" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp
index 3b9f325d6..1de2c6d57 100644
--- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp
+++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp
@@ -17,9 +17,9 @@
-
+
-
+