diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/constants/AdyencheckoutaddonapiWebConstants.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/constants/AdyencheckoutaddonapiWebConstants.java index 44557a95..cadc6679 100644 --- a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/constants/AdyencheckoutaddonapiWebConstants.java +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/constants/AdyencheckoutaddonapiWebConstants.java @@ -13,11 +13,9 @@ private AdyencheckoutaddonapiWebConstants() //empty to avoid instantiating this constant class } - public static final String ADYEN_CHECKOUT_API_PREFIX = "/api/checkout"; public static final String ADYEN_CHECKOUT_PAGE_PREFIX = "/checkout/multi"; public static final String ADYEN_CHECKOUT_ORDER_CONFIRMATION = "/adyen/order-confirmation"; public static final String ADYEN_CHECKOUT_SELECT_PAYMENT = "/adyen/payment-method"; - public static final String AUTHORISE_3D_SECURE_PAYMENT_URL = "/authorise-3d-adyen-response"; public static final String CART_PREFIX = "/cart"; diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenPlaceOrderController.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenPlaceOrderController.java index 8124bdef..c0f7ee8a 100644 --- a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenPlaceOrderController.java +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenPlaceOrderController.java @@ -1,61 +1,30 @@ package com.adyen.commerce.controllers.api; import com.adyen.commerce.controllerbase.PlaceOrderControllerBase; -import com.adyen.commerce.exception.AdyenControllerException; import com.adyen.commerce.facades.AdyenCheckoutApiFacade; import com.adyen.commerce.request.PlaceOrderRequest; import com.adyen.commerce.response.PlaceOrderResponse; -import com.adyen.commerce.validators.PaymentRequestValidator; import com.adyen.model.checkout.PaymentDetailsRequest; -import com.adyen.model.checkout.PaymentResponse; -import com.adyen.service.exception.ApiException; -import com.adyen.v6.exceptions.AdyenNonAuthorizedPaymentException; import de.hybris.platform.acceleratorfacades.flow.CheckoutFlowFacade; import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService; import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn; -import de.hybris.platform.basecommerce.model.site.BaseSiteModel; import de.hybris.platform.commercefacades.order.CartFacade; -import de.hybris.platform.commercefacades.order.data.CartData; -import de.hybris.platform.commercefacades.order.data.OrderData; -import de.hybris.platform.servicelayer.config.ConfigurationService; import de.hybris.platform.site.BaseSiteService; -import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.support.DefaultMessageSourceResolvable; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import java.lang.reflect.InvocationTargetException; - -import static com.adyen.commerce.constants.AdyencheckoutaddonapiWebConstants.ADYEN_CHECKOUT_API_PREFIX; -import static com.adyen.commerce.constants.AdyencheckoutaddonapiWebConstants.AUTHORISE_3D_SECURE_PAYMENT_URL; -import static com.adyen.commerce.constants.AdyenwebcommonsConstants.CHECKOUT_ERROR_AUTHORIZATION_FAILED; -import static com.adyen.commerce.util.ErrorMessageUtil.getErrorMessageByRefusalReason; -import static com.adyen.commerce.util.FieldValidationUtil.getFieldCodesFromValidation; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.CHALLENGESHOPPER; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.IDENTIFYSHOPPER; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.PENDING; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.PRESENTTOSHOPPER; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.REDIRECTSHOPPER; -import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.REFUSED; @RequestMapping("/api/checkout") @Controller public class AdyenPlaceOrderController extends PlaceOrderControllerBase { - private static final Logger LOGGER = Logger.getLogger(AdyenPlaceOrderController.class); - - private static final String CHECKOUT_ERROR_FORM_ENTRY_INVALID = "checkout.error.paymentethod.formentry.invalid"; - public static final String GET_TYPE = "getType"; - @Autowired private CheckoutFlowFacade checkoutFlowFacade; @@ -66,9 +35,6 @@ public class AdyenPlaceOrderController extends PlaceOrderControllerBase { @Autowired private AdyenCheckoutApiFacade adyenCheckoutApiFacade; - @Autowired - private ConfigurationService configurationService; - @Resource(name = "siteBaseUrlResolutionService") private SiteBaseUrlResolutionService siteBaseUrlResolutionService; @@ -77,163 +43,43 @@ public class AdyenPlaceOrderController extends PlaceOrderControllerBase { @RequireHardLogIn @PostMapping("/place-order") - public ResponseEntity placeOrder(@RequestBody PlaceOrderRequest placeOrderRequest, HttpServletRequest request) throws Exception { + public ResponseEntity onPlaceOrder(@RequestBody PlaceOrderRequest placeOrderRequest, HttpServletRequest request) throws Exception { + PlaceOrderResponse placeOrderResponse = super.placeOrder(placeOrderRequest, request); - String adyenPaymentMethodType = extractPaymentMethodType(placeOrderRequest); - - preHandleAndValidateRequest(placeOrderRequest, adyenPaymentMethodType); - - if (!isCartValid()) { - LOGGER.warn("Cart is invalid."); - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } - - return handlePayment(request, placeOrderRequest, adyenPaymentMethodType); + return ResponseEntity.ok(placeOrderResponse); } @RequireHardLogIn @PostMapping("/additional-details") public ResponseEntity onAdditionalDetails(@RequestBody PaymentDetailsRequest detailsRequest, HttpServletRequest request) throws Exception { - try { - OrderData orderData = adyenCheckoutApiFacade.placeOrderWithAdditionalDetails(detailsRequest); - PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse(); - placeOrderResponse.setOrderNumber(orderData.getCode()); - return ResponseEntity.status(HttpStatus.OK).body(placeOrderResponse); - } catch (ApiException e) { - LOGGER.error("ApiException: " + e); - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } catch (Exception e) { - LOGGER.error("Exception", e); - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } - } + PlaceOrderResponse placeOrderResponse = super.handleAdditionalDetails(detailsRequest); - private static String extractPaymentMethodType(PlaceOrderRequest placeOrderRequest) throws AdyenControllerException { - if (placeOrderRequest == null || placeOrderRequest.getPaymentRequest() == null || placeOrderRequest.getPaymentRequest().getPaymentMethod() == null) { - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } - Object actualInstance = placeOrderRequest.getPaymentRequest().getPaymentMethod().getActualInstance(); - if (actualInstance == null) { - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } - Class aClass = actualInstance.getClass(); - try { - return aClass.getMethod(GET_TYPE).invoke(actualInstance).toString(); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); - } - } - - private ResponseEntity handlePayment(HttpServletRequest request, PlaceOrderRequest placeOrderRequest, String adyenPaymentMethod) { - final CartData cartData = cartFacade.getSessionCart(); - - String errorMessage = CHECKOUT_ERROR_AUTHORIZATION_FAILED; - - try { - cartData.setAdyenReturnUrl(getPaymentRedirectReturnUrl()); - OrderData orderData = adyenCheckoutApiFacade.placeOrderWithPayment(request, cartData, placeOrderRequest.getPaymentRequest()); - - PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse(); - placeOrderResponse.setOrderNumber(orderData.getCode()); - return ResponseEntity.status(HttpStatus.OK).body(placeOrderResponse); - - } catch (ApiException e) { - LOGGER.error("API exception: ", e); - } catch (AdyenNonAuthorizedPaymentException e) { - LOGGER.info("Handling AdyenNonAuthorizedPaymentException. Checking PaymentResponse."); - PaymentResponse paymentsResponse = e.getPaymentsResponse(); - if (REDIRECTSHOPPER == paymentsResponse.getResultCode() || CHALLENGESHOPPER == paymentsResponse.getResultCode() || - IDENTIFYSHOPPER == paymentsResponse.getResultCode() || PENDING == paymentsResponse.getResultCode() || - PRESENTTOSHOPPER == paymentsResponse.getResultCode()) { - LOGGER.debug("PaymentResponse is " + paymentsResponse.getResultCode() + ", executing action for pspReference: " + paymentsResponse.getPspReference()); - return executeAction(paymentsResponse); - } else if (REFUSED == paymentsResponse.getResultCode()) { - LOGGER.info("PaymentResponse is REFUSED, pspReference: " + paymentsResponse.getPspReference()); - errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason()); - } else if (PaymentResponse.ResultCodeEnum.ERROR == paymentsResponse.getResultCode()) { - LOGGER.error("PaymentResponse is ERROR, reason: " + paymentsResponse.getRefusalReason() + " pspReference: " + paymentsResponse.getPspReference()); - } - } catch (Exception e) { - LOGGER.error(ExceptionUtils.getStackTrace(e)); - } - - throw new AdyenControllerException(errorMessage); + return ResponseEntity.ok(placeOrderResponse); } - private void preHandleAndValidateRequest(PlaceOrderRequest placeOrderRequest, String adyenPaymentMethod) { - final BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(placeOrderRequest, "placeOrderRequest"); - - boolean showRememberDetails = adyenCheckoutApiFacade.showRememberDetails(); - boolean holderNameRequired = adyenCheckoutApiFacade.getHolderNameRequired(); - - PaymentRequestValidator paymentRequestValidator = new PaymentRequestValidator(adyenCheckoutApiFacade.getStoredCards(), showRememberDetails, holderNameRequired); - paymentRequestValidator.validate(placeOrderRequest, bindingResult); - if (bindingResult.hasErrors()) { - LOGGER.warn("Payment form is invalid."); - LOGGER.warn(bindingResult.getAllErrors().stream().map(DefaultMessageSourceResolvable::getCode).reduce((x, y) -> (x + " " + y))); - throw new AdyenControllerException(CHECKOUT_ERROR_FORM_ENTRY_INVALID, getFieldCodesFromValidation(bindingResult)); - } - - adyenCheckoutApiFacade.preHandlePlaceOrder(placeOrderRequest.getPaymentRequest(),adyenPaymentMethod, - placeOrderRequest.getBillingAddress(), placeOrderRequest.isUseAdyenDeliveryAddress()); + @Override + public AdyenCheckoutApiFacade getAdyenCheckoutApiFacade() { + return adyenCheckoutApiFacade; } - private ResponseEntity executeAction(PaymentResponse paymentsResponse) { - PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse(); - placeOrderResponse.setPaymentsResponse(paymentsResponse); - placeOrderResponse.setExecuteAction(true); - placeOrderResponse.setPaymentsAction(paymentsResponse.getAction()); - return ResponseEntity.ok(placeOrderResponse); + @Override + public CheckoutFlowFacade getCheckoutFlowFacade() { + return checkoutFlowFacade; } - private boolean isCartValid() { - - if (checkoutFlowFacade.hasNoDeliveryAddress()) { - LOGGER.error("No delivery address."); - return false; - } - - if (checkoutFlowFacade.hasNoDeliveryMode()) { - LOGGER.error("No delivery mode."); - return false; - } - - if (checkoutFlowFacade.hasNoPaymentInfo()) { - LOGGER.error("No payment info."); - return false; - } - - final CartData cartData = checkoutFlowFacade.getCheckoutCart(); - - if (!checkoutFlowFacade.containsTaxValues()) { - LOGGER.error(String.format("Cart %s does not have any tax values, which means the tax cacluation was not properly done, placement of order can't continue", cartData.getCode())); - LOGGER.error("Tax missing."); - return false; - - } - - if (!cartData.isCalculated()) { - LOGGER.error(String.format("Cart %s has a calculated flag of FALSE, placement of order can't continue", cartData.getCode())); - LOGGER.error("Cart not calculated."); - return false; - - } - - return true; + @Override + public CartFacade getCartFacade() { + return cartFacade; } - private String getPaymentRedirectReturnUrl() { - String url = ADYEN_CHECKOUT_API_PREFIX + AUTHORISE_3D_SECURE_PAYMENT_URL; - - BaseSiteModel currentBaseSite = baseSiteService.getCurrentBaseSite(); - - return siteBaseUrlResolutionService.getWebsiteUrlForSite(currentBaseSite, true, url); + @Override + public BaseSiteService getBaseSiteService() { + return baseSiteService; } - @Override - public AdyenCheckoutApiFacade getAdyenCheckoutApiFacade() { - return adyenCheckoutApiFacade; + public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService() { + return siteBaseUrlResolutionService; } } diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenRedirectResponseController.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenRedirectResponseController.java index 08f8f369..f6534335 100644 --- a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenRedirectResponseController.java +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenRedirectResponseController.java @@ -15,6 +15,8 @@ import java.util.Base64; import static com.adyen.commerce.constants.AdyencheckoutaddonapiWebConstants.*; +import static com.adyen.commerce.constants.AdyenwebcommonsConstants.ADYEN_CHECKOUT_API_PREFIX; +import static com.adyen.commerce.constants.AdyenwebcommonsConstants.AUTHORISE_3D_SECURE_PAYMENT_URL; import static de.hybris.platform.acceleratorstorefrontcommons.controllers.AbstractController.REDIRECT_PREFIX; @Controller diff --git a/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java b/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java index 12d7c6f2..53cc0c6e 100644 --- a/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java +++ b/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java @@ -3,10 +3,15 @@ import com.adyen.commerce.constants.AdyenoccConstants; import com.adyen.commerce.controllerbase.PlaceOrderControllerBase; import com.adyen.commerce.facades.AdyenCheckoutApiFacade; +import com.adyen.commerce.request.PlaceOrderRequest; import com.adyen.commerce.response.PlaceOrderResponse; import com.adyen.model.checkout.PaymentDetailsRequest; import com.fasterxml.jackson.core.JsonProcessingException; +import de.hybris.platform.acceleratorfacades.flow.CheckoutFlowFacade; +import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService; +import de.hybris.platform.commercefacades.order.CartFacade; import de.hybris.platform.commerceservices.request.mapping.annotation.ApiVersion; +import de.hybris.platform.site.BaseSiteService; import de.hybris.platform.webservicescommons.swagger.ApiBaseSiteIdUserIdAndCartIdParam; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -19,6 +24,9 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + @Controller @RequestMapping(value = AdyenoccConstants.ADYEN_USER_CART_PREFIX) @ApiVersion("v2") @@ -28,9 +36,31 @@ public class PlaceOrderController extends PlaceOrderControllerBase { @Autowired private AdyenCheckoutApiFacade adyenCheckoutApiFacade; + @Autowired + private CheckoutFlowFacade checkoutFlowFacade; + + @Autowired + private CartFacade cartFacade; + + @Resource(name = "siteBaseUrlResolutionService") + private SiteBaseUrlResolutionService siteBaseUrlResolutionService; + + @Resource(name = "baseSiteService") + private BaseSiteService baseSiteService; - @Secured({ "ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT" }) - @PostMapping(value = "/additional-details", produces= MediaType.APPLICATION_JSON_VALUE) + @Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"}) + @PostMapping(value = "/place-order", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(operationId = "placeOrder", summary = "Handle place order request", description = + "Places order based on request data") + @ApiBaseSiteIdUserIdAndCartIdParam + public ResponseEntity onPlaceOrder(@RequestBody PlaceOrderRequest placeOrderRequest, HttpServletRequest request) throws Exception { + PlaceOrderResponse placeOrderResponse = super.placeOrder(placeOrderRequest, request); + + return ResponseEntity.ok(placeOrderResponse); + } + + @Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"}) + @PostMapping(value = "/additional-details", produces = MediaType.APPLICATION_JSON_VALUE) @Operation(operationId = "additionalDetails", summary = "Handle additional details action", description = "Places pending order based on additional details request") @ApiBaseSiteIdUserIdAndCartIdParam @@ -45,4 +75,24 @@ public ResponseEntity onAdditionalDetails(@RequestBody PaymentDetailsReq public AdyenCheckoutApiFacade getAdyenCheckoutApiFacade() { return adyenCheckoutApiFacade; } + + @Override + public CheckoutFlowFacade getCheckoutFlowFacade() { + return checkoutFlowFacade; + } + + @Override + public CartFacade getCartFacade() { + return cartFacade; + } + + @Override + public BaseSiteService getBaseSiteService() { + return baseSiteService; + } + + @Override + public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService() { + return siteBaseUrlResolutionService; + } } diff --git a/adyenwebcommons/src/com/adyen/commerce/constants/AdyenwebcommonsConstants.java b/adyenwebcommons/src/com/adyen/commerce/constants/AdyenwebcommonsConstants.java index f7d1dfbf..30181f8c 100644 --- a/adyenwebcommons/src/com/adyen/commerce/constants/AdyenwebcommonsConstants.java +++ b/adyenwebcommons/src/com/adyen/commerce/constants/AdyenwebcommonsConstants.java @@ -13,6 +13,10 @@ public final class AdyenwebcommonsConstants extends GeneratedAdyenwebcommonsCons public static final String CHECKOUT_ERROR_AUTHORIZATION_FAILED = "checkout.error.authorization.failed"; + public static final String ADYEN_CHECKOUT_API_PREFIX = "/api/checkout"; + public static final String AUTHORISE_3D_SECURE_PAYMENT_URL = "/authorise-3d-adyen-response"; + + private AdyenwebcommonsConstants() { diff --git a/adyenwebcommons/src/com/adyen/commerce/controllerbase/PlaceOrderControllerBase.java b/adyenwebcommons/src/com/adyen/commerce/controllerbase/PlaceOrderControllerBase.java index 5266fc5d..7ffadd52 100644 --- a/adyenwebcommons/src/com/adyen/commerce/controllerbase/PlaceOrderControllerBase.java +++ b/adyenwebcommons/src/com/adyen/commerce/controllerbase/PlaceOrderControllerBase.java @@ -2,19 +2,56 @@ import com.adyen.commerce.exception.AdyenControllerException; import com.adyen.commerce.facades.AdyenCheckoutApiFacade; +import com.adyen.commerce.request.PlaceOrderRequest; import com.adyen.commerce.response.PlaceOrderResponse; +import com.adyen.commerce.validators.PaymentRequestValidator; import com.adyen.model.checkout.PaymentDetailsRequest; +import com.adyen.model.checkout.PaymentResponse; import com.adyen.service.exception.ApiException; +import com.adyen.v6.exceptions.AdyenNonAuthorizedPaymentException; import com.fasterxml.jackson.databind.ObjectMapper; +import de.hybris.platform.acceleratorfacades.flow.CheckoutFlowFacade; +import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService; +import de.hybris.platform.basecommerce.model.site.BaseSiteModel; +import de.hybris.platform.commercefacades.order.CartFacade; +import de.hybris.platform.commercefacades.order.data.CartData; import de.hybris.platform.commercefacades.order.data.OrderData; +import de.hybris.platform.site.BaseSiteService; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.log4j.Logger; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.validation.BeanPropertyBindingResult; -import static com.adyen.commerce.constants.AdyenwebcommonsConstants.CHECKOUT_ERROR_AUTHORIZATION_FAILED; +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.InvocationTargetException; + +import static com.adyen.commerce.constants.AdyenwebcommonsConstants.*; +import static com.adyen.commerce.util.ErrorMessageUtil.getErrorMessageByRefusalReason; +import static com.adyen.commerce.util.FieldValidationUtil.getFieldCodesFromValidation; +import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.*; public abstract class PlaceOrderControllerBase { private static final Logger LOGGER = Logger.getLogger(PlaceOrderControllerBase.class); protected static final ObjectMapper objectMapper = new ObjectMapper(); + private static final String CHECKOUT_ERROR_FORM_ENTRY_INVALID = "checkout.error.paymentethod.formentry.invalid"; + private static final String GET_TYPE = "getType"; + + + public PlaceOrderResponse placeOrder(PlaceOrderRequest placeOrderRequest, HttpServletRequest request) { + + String adyenPaymentMethodType = extractPaymentMethodType(placeOrderRequest); + + preHandleAndValidateRequest(placeOrderRequest, adyenPaymentMethodType); + + if (!isCartValid()) { + LOGGER.warn("Cart is invalid."); + throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); + } + + return handlePayment(request, placeOrderRequest); + } + public PlaceOrderResponse handleAdditionalDetails(final PaymentDetailsRequest paymentDetailsRequest) { try { @@ -31,5 +68,137 @@ public PlaceOrderResponse handleAdditionalDetails(final PaymentDetailsRequest pa } } + + private static String extractPaymentMethodType(PlaceOrderRequest placeOrderRequest) throws AdyenControllerException { + if (placeOrderRequest == null || placeOrderRequest.getPaymentRequest() == null || placeOrderRequest.getPaymentRequest().getPaymentMethod() == null) { + throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); + } + Object actualInstance = placeOrderRequest.getPaymentRequest().getPaymentMethod().getActualInstance(); + if (actualInstance == null) { + throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); + } + Class aClass = actualInstance.getClass(); + try { + return aClass.getMethod(GET_TYPE).invoke(actualInstance).toString(); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new AdyenControllerException(CHECKOUT_ERROR_AUTHORIZATION_FAILED); + } + } + + private void preHandleAndValidateRequest(PlaceOrderRequest placeOrderRequest, String adyenPaymentMethod) { + final BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(placeOrderRequest, "placeOrderRequest"); + + boolean showRememberDetails = getAdyenCheckoutApiFacade().showRememberDetails(); + boolean holderNameRequired = getAdyenCheckoutApiFacade().getHolderNameRequired(); + + PaymentRequestValidator paymentRequestValidator = new PaymentRequestValidator(getAdyenCheckoutApiFacade().getStoredCards(), showRememberDetails, holderNameRequired); + paymentRequestValidator.validate(placeOrderRequest, bindingResult); + + if (bindingResult.hasErrors()) { + LOGGER.warn("Payment form is invalid."); + LOGGER.warn(bindingResult.getAllErrors().stream().map(DefaultMessageSourceResolvable::getCode).reduce((x, y) -> (x + " " + y))); + throw new AdyenControllerException(CHECKOUT_ERROR_FORM_ENTRY_INVALID, getFieldCodesFromValidation(bindingResult)); + } + + getAdyenCheckoutApiFacade().preHandlePlaceOrder(placeOrderRequest.getPaymentRequest(),adyenPaymentMethod, + placeOrderRequest.getBillingAddress(), placeOrderRequest.isUseAdyenDeliveryAddress()); + } + + private boolean isCartValid() { + + if (getCheckoutFlowFacade().hasNoDeliveryAddress()) { + LOGGER.error("No delivery address."); + return false; + } + + if (getCheckoutFlowFacade().hasNoDeliveryMode()) { + LOGGER.error("No delivery mode."); + return false; + } + + if (getCheckoutFlowFacade().hasNoPaymentInfo()) { + LOGGER.error("No payment info."); + return false; + } + + final CartData cartData = getCheckoutFlowFacade().getCheckoutCart(); + + if (!getCheckoutFlowFacade().containsTaxValues()) { + LOGGER.error(String.format("Cart %s does not have any tax values, which means the tax cacluation was not properly done, placement of order can't continue", cartData.getCode())); + LOGGER.error("Tax missing."); + return false; + + } + + if (!cartData.isCalculated()) { + LOGGER.error(String.format("Cart %s has a calculated flag of FALSE, placement of order can't continue", cartData.getCode())); + LOGGER.error("Cart not calculated."); + return false; + + } + + return true; + } + + private PlaceOrderResponse handlePayment(HttpServletRequest request, PlaceOrderRequest placeOrderRequest) { + final CartData cartData = getCartFacade().getSessionCart(); + + String errorMessage = CHECKOUT_ERROR_AUTHORIZATION_FAILED; + + try { + cartData.setAdyenReturnUrl(getPaymentRedirectReturnUrl()); + OrderData orderData = getAdyenCheckoutApiFacade().placeOrderWithPayment(request, cartData, placeOrderRequest.getPaymentRequest()); + + PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse(); + placeOrderResponse.setOrderNumber(orderData.getCode()); + return placeOrderResponse; + + } catch (ApiException e) { + LOGGER.error("API exception: ", e); + } catch (AdyenNonAuthorizedPaymentException e) { + LOGGER.info("Handling AdyenNonAuthorizedPaymentException. Checking PaymentResponse."); + PaymentResponse paymentsResponse = e.getPaymentsResponse(); + if (REDIRECTSHOPPER == paymentsResponse.getResultCode() || CHALLENGESHOPPER == paymentsResponse.getResultCode() || + IDENTIFYSHOPPER == paymentsResponse.getResultCode() || PENDING == paymentsResponse.getResultCode() || + PRESENTTOSHOPPER == paymentsResponse.getResultCode()) { + LOGGER.debug("PaymentResponse is " + paymentsResponse.getResultCode() + ", executing action for pspReference: " + paymentsResponse.getPspReference()); + return executeAction(paymentsResponse); + } else if (REFUSED == paymentsResponse.getResultCode()) { + LOGGER.info("PaymentResponse is REFUSED, pspReference: " + paymentsResponse.getPspReference()); + errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason()); + } else if (PaymentResponse.ResultCodeEnum.ERROR == paymentsResponse.getResultCode()) { + LOGGER.error("PaymentResponse is ERROR, reason: " + paymentsResponse.getRefusalReason() + " pspReference: " + paymentsResponse.getPspReference()); + } + } catch (Exception e) { + LOGGER.error(ExceptionUtils.getStackTrace(e)); + } + + throw new AdyenControllerException(errorMessage); + } + + private PlaceOrderResponse executeAction(PaymentResponse paymentsResponse) { + PlaceOrderResponse placeOrderResponse = new PlaceOrderResponse(); + placeOrderResponse.setPaymentsResponse(paymentsResponse); + placeOrderResponse.setExecuteAction(true); + placeOrderResponse.setPaymentsAction(paymentsResponse.getAction()); + return placeOrderResponse; + } + + private String getPaymentRedirectReturnUrl() { + String url = ADYEN_CHECKOUT_API_PREFIX + AUTHORISE_3D_SECURE_PAYMENT_URL; + + BaseSiteModel currentBaseSite = getBaseSiteService().getCurrentBaseSite(); + + return getSiteBaseUrlResolutionService().getWebsiteUrlForSite(currentBaseSite, true, url); + } + public abstract AdyenCheckoutApiFacade getAdyenCheckoutApiFacade(); + + public abstract CheckoutFlowFacade getCheckoutFlowFacade(); + + public abstract CartFacade getCartFacade(); + + public abstract BaseSiteService getBaseSiteService(); + + public abstract SiteBaseUrlResolutionService getSiteBaseUrlResolutionService(); } diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/request/PlaceOrderRequest.java b/adyenwebcommons/src/com/adyen/commerce/request/PlaceOrderRequest.java similarity index 100% rename from adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/request/PlaceOrderRequest.java rename to adyenwebcommons/src/com/adyen/commerce/request/PlaceOrderRequest.java diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/util/FieldValidationUtil.java b/adyenwebcommons/src/com/adyen/commerce/util/FieldValidationUtil.java similarity index 100% rename from adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/util/FieldValidationUtil.java rename to adyenwebcommons/src/com/adyen/commerce/util/FieldValidationUtil.java diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/validators/PaymentRequestValidator.java b/adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java similarity index 100% rename from adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/validators/PaymentRequestValidator.java rename to adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java