From 1731474c049c62cddc1caf5e2be0b2ae995df765 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Wed, 23 Oct 2024 14:28:53 +0200 Subject: [PATCH 1/2] AD-341 Develop Backend Logic for Place Order Endpoints to Handle Google Pay Express Checkout in Accelerator Storefront and OCC Backend --- adyenocc/resources/adyenocc-spring.xml | 5 + .../controllers/PlaceOrderController.java | 25 +- .../ExpressCheckoutControllerBase.java | 92 +++ .../GooglePayExpressCheckoutController.java | 95 +++ .../request/GooglePayExpressCartRequest.java | 27 + .../request/GooglePayExpressPDPRequest.java | 14 + .../PaymentRedirectReturnUrlResolver.java | 33 + ...dyenApplePayExpressCheckoutController.java | 4 +- ...yenGooglePayExpressCheckoutController.java | 72 ++ .../request/GooglePayExpressCartRequest.java | 27 + .../request/GooglePayExpressPDPRequest.java | 15 + .../tags/responsive/expressCheckoutConfig.tag | 6 +- .../common/js/adyen_express_checkout.js | 36 +- adyenv6core/resources/adyenv6core-spring.xml | 4 +- .../v6/constants/Adyenv6coreConstants.java | 1 + .../facades/AdyenExpressCheckoutFacade.java | 22 +- .../DefaultAdyenExpressCheckoutFacade.java | 296 +++++++- ...DefaultAdyenExpressCheckoutFacadeTest.java | 695 ++++++++++++++++++ 18 files changed, 1401 insertions(+), 68 deletions(-) create mode 100644 adyenocc/src/com/adyen/commerce/controllers/expresscheckout/ExpressCheckoutControllerBase.java create mode 100644 adyenocc/src/com/adyen/commerce/controllers/expresscheckout/GooglePayExpressCheckoutController.java create mode 100644 adyenocc/src/com/adyen/commerce/request/GooglePayExpressCartRequest.java create mode 100644 adyenocc/src/com/adyen/commerce/request/GooglePayExpressPDPRequest.java create mode 100644 adyenocc/src/com/adyen/commerce/resolver/PaymentRedirectReturnUrlResolver.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressCartRequest.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressPDPRequest.java create mode 100644 adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java diff --git a/adyenocc/resources/adyenocc-spring.xml b/adyenocc/resources/adyenocc-spring.xml index f122a40b1..d6aeedbf6 100644 --- a/adyenocc/resources/adyenocc-spring.xml +++ b/adyenocc/resources/adyenocc-spring.xml @@ -19,4 +19,9 @@ + + + + + diff --git a/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java b/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java index 58fc5d00c..4b5c2a4e9 100644 --- a/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java +++ b/adyenocc/src/com/adyen/commerce/controllers/PlaceOrderController.java @@ -4,20 +4,16 @@ import com.adyen.commerce.controllerbase.PlaceOrderControllerBase; import com.adyen.commerce.facades.AdyenCheckoutApiFacade; import com.adyen.commerce.request.PlaceOrderRequest; +import com.adyen.commerce.resolver.PaymentRedirectReturnUrlResolver; import com.adyen.commerce.response.OCCPlaceOrderResponse; -import com.adyen.commerce.response.PlaceOrderResponse; -import com.adyen.commerce.utils.WebServicesBaseUrlResolver; import com.adyen.model.checkout.PaymentDetailsRequest; import com.adyen.v6.facades.AdyenCheckoutFacade; 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.i18n.CommerceCommonI18NService; import de.hybris.platform.commerceservices.request.mapping.annotation.ApiVersion; import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy; -import de.hybris.platform.order.InvalidCartException; -import de.hybris.platform.order.exceptions.CalculationException; import de.hybris.platform.site.BaseSiteService; import de.hybris.platform.webservicescommons.swagger.ApiBaseSiteIdUserIdAndCartIdParam; import io.swagger.v3.oas.annotations.Operation; @@ -26,7 +22,10 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; @@ -55,14 +54,11 @@ public class PlaceOrderController extends PlaceOrderControllerBase { @Autowired private AdyenCheckoutFacade adyenCheckoutFacade; - @Autowired - private WebServicesBaseUrlResolver webServicesBaseUrlResolver; - @Resource(name = "checkoutCustomerStrategy") private CheckoutCustomerStrategy checkoutCustomerStrategy; - @Resource(name = "commerceCommonI18NService") - private CommerceCommonI18NService commerceCommonI18NService; + @Autowired + private PaymentRedirectReturnUrlResolver paymentRedirectReturnUrlResolver; @Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"}) @PostMapping(value = "/place-order", produces = MediaType.APPLICATION_JSON_VALUE) @@ -91,12 +87,7 @@ public ResponseEntity onAdditionalDetails(@RequestBody PaymentDetailsReq @Override public String getPaymentRedirectReturnUrl() { - String occBaseUrl = webServicesBaseUrlResolver.getOCCBaseUrl(true); - String currency = commerceCommonI18NService.getCurrentCurrency().getIsocode(); - String language = commerceCommonI18NService.getCurrentLanguage().getIsocode(); - String baseSiteUid = baseSiteService.getCurrentBaseSite().getUid(); - - return occBaseUrl + "/v2/" + baseSiteUid + "/adyen/redirect?lang=" + language + "&curr=" + currency; + return paymentRedirectReturnUrlResolver.resolvePaymentRedirectReturnUrl(); } @Override diff --git a/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/ExpressCheckoutControllerBase.java b/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/ExpressCheckoutControllerBase.java new file mode 100644 index 000000000..9e4338c41 --- /dev/null +++ b/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/ExpressCheckoutControllerBase.java @@ -0,0 +1,92 @@ +package com.adyen.commerce.controllers.expresscheckout; + +import com.adyen.commerce.exception.AdyenControllerException; +import com.adyen.commerce.response.OCCPlaceOrderResponse; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.model.checkout.PaymentResponse; +import com.adyen.service.exception.ApiException; +import com.adyen.v6.exceptions.AdyenNonAuthorizedPaymentException; +import com.adyen.v6.facades.AdyenExpressCheckoutFacade; +import com.fasterxml.jackson.databind.ObjectMapper; +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.commercefacades.user.data.AddressData; +import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; + +import static com.adyen.commerce.constants.AdyenwebcommonsConstants.CHECKOUT_ERROR_AUTHORIZATION_FAILED; +import static com.adyen.commerce.util.ErrorMessageUtil.getErrorMessageByRefusalReason; +import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.*; + +public abstract class ExpressCheckoutControllerBase { + private static final Logger LOGGER = Logger.getLogger(ExpressCheckoutControllerBase.class); + protected static final ObjectMapper objectMapper = new ObjectMapper(); + + + protected OCCPlaceOrderResponse handlePayment(HttpServletRequest request, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, String productCode, boolean isPDPCheckout) { + final CartData cartData = getCartFacade().getSessionCart(); + + String errorMessage = CHECKOUT_ERROR_AUTHORIZATION_FAILED; + + try { + cartData.setAdyenReturnUrl(getPaymentRedirectReturnUrl()); + + OrderData orderData; + + if (isPDPCheckout) { + orderData = getAdyenCheckoutApiFacade().expressCheckoutPDPOCC(productCode, paymentRequest, paymentMethod, addressData, request); + } else { + orderData = getAdyenCheckoutApiFacade().expressCheckoutCartOCC(paymentRequest, paymentMethod, addressData, request); + } + + String orderCode = getCheckoutCustomerStrategy().isAnonymousCheckout() ? orderData.getGuid() : orderData.getCode(); + + OCCPlaceOrderResponse placeOrderResponse = new OCCPlaceOrderResponse(); + placeOrderResponse.setOrderNumber(orderCode); + placeOrderResponse.setOrderData(orderData); + 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); + } + + protected OCCPlaceOrderResponse executeAction(PaymentResponse paymentsResponse) { + OCCPlaceOrderResponse placeOrderResponse = new OCCPlaceOrderResponse(); + placeOrderResponse.setPaymentsResponse(paymentsResponse); + placeOrderResponse.setExecuteAction(true); + placeOrderResponse.setPaymentsAction(paymentsResponse.getAction()); + placeOrderResponse.setOrderNumber(paymentsResponse.getMerchantReference()); + return placeOrderResponse; + } + + public abstract CartFacade getCartFacade(); + + public abstract CheckoutCustomerStrategy getCheckoutCustomerStrategy(); + + public abstract String getPaymentRedirectReturnUrl(); + + public abstract AdyenExpressCheckoutFacade getAdyenCheckoutApiFacade(); +} diff --git a/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/GooglePayExpressCheckoutController.java b/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/GooglePayExpressCheckoutController.java new file mode 100644 index 000000000..8704ec5a8 --- /dev/null +++ b/adyenocc/src/com/adyen/commerce/controllers/expresscheckout/GooglePayExpressCheckoutController.java @@ -0,0 +1,95 @@ +package com.adyen.commerce.controllers.expresscheckout; + +import com.adyen.commerce.constants.AdyenoccConstants; +import com.adyen.commerce.request.GooglePayExpressCartRequest; +import com.adyen.commerce.request.GooglePayExpressPDPRequest; +import com.adyen.commerce.resolver.PaymentRedirectReturnUrlResolver; +import com.adyen.commerce.response.OCCPlaceOrderResponse; +import com.adyen.model.checkout.CheckoutPaymentMethod; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.v6.constants.Adyenv6coreConstants; +import com.adyen.v6.facades.AdyenExpressCheckoutFacade; +import de.hybris.platform.commercefacades.order.CartFacade; +import de.hybris.platform.commerceservices.request.mapping.annotation.ApiVersion; +import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy; +import de.hybris.platform.webservicescommons.swagger.ApiBaseSiteIdUserIdAndCartIdParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +@RestController +@RequestMapping(value = AdyenoccConstants.ADYEN_USER_CART_PREFIX + "/express-checkout/google") +@ApiVersion("v2") +@Tag(name = "Adyen") +public class GooglePayExpressCheckoutController extends ExpressCheckoutControllerBase { + + @Autowired + private CartFacade cartFacade; + + @Autowired + private CheckoutCustomerStrategy checkoutCustomerStrategy; + + @Autowired + private AdyenExpressCheckoutFacade adyenExpressCheckoutFacade; + + @Autowired + private PaymentRedirectReturnUrlResolver paymentRedirectReturnUrlResolver; + + + @Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"}) + @PostMapping(value = "/PDP", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(operationId = "placeOrderGooglePayExpressPDP", summary = "Handle googlePayExpress place order request", description = + "Places order based on request data") + @ApiBaseSiteIdUserIdAndCartIdParam + public ResponseEntity googlePayCartExpressCheckout(final HttpServletRequest request, @RequestBody GooglePayExpressPDPRequest googlePayExpressPDPRequest) throws Exception { + PaymentRequest paymentRequest = new PaymentRequest(); + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(googlePayExpressPDPRequest.getGooglePayDetails())); + + OCCPlaceOrderResponse placeOrderResponse = handlePayment(request, paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_GOOGLE_PAY, googlePayExpressPDPRequest.getAddressData(), googlePayExpressPDPRequest.getProductCode(), true); + String response = objectMapper.writeValueAsString(placeOrderResponse); + return ResponseEntity.ok(response); + } + + @Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"}) + @PostMapping(value = "/cart", produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(operationId = "placeOrderGooglePayExpressCart", summary = "Handle googlePayExpress place order request", description = + "Places order based on request data") + @ApiBaseSiteIdUserIdAndCartIdParam + public ResponseEntity googlePayCartExpressCheckout(final HttpServletRequest request, @RequestBody GooglePayExpressCartRequest googlePayExpressCartRequest) throws Exception { + PaymentRequest paymentRequest = new PaymentRequest(); + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(googlePayExpressCartRequest.getGooglePayDetails())); + + OCCPlaceOrderResponse placeOrderResponse = handlePayment(request, paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_GOOGLE_PAY, googlePayExpressCartRequest.getAddressData(), null, false); + String response = objectMapper.writeValueAsString(placeOrderResponse); + return ResponseEntity.ok(response); + } + + @Override + public CartFacade getCartFacade() { + return cartFacade; + } + + @Override + public CheckoutCustomerStrategy getCheckoutCustomerStrategy() { + return checkoutCustomerStrategy; + } + + @Override + public String getPaymentRedirectReturnUrl() { + return paymentRedirectReturnUrlResolver.resolvePaymentRedirectReturnUrl(); + } + + @Override + public AdyenExpressCheckoutFacade getAdyenCheckoutApiFacade() { + return adyenExpressCheckoutFacade; + } +} diff --git a/adyenocc/src/com/adyen/commerce/request/GooglePayExpressCartRequest.java b/adyenocc/src/com/adyen/commerce/request/GooglePayExpressCartRequest.java new file mode 100644 index 000000000..33c6c63bf --- /dev/null +++ b/adyenocc/src/com/adyen/commerce/request/GooglePayExpressCartRequest.java @@ -0,0 +1,27 @@ +package com.adyen.commerce.request; + +import com.adyen.model.checkout.GooglePayDetails; +import de.hybris.platform.commercefacades.user.data.AddressData; + +import java.io.Serializable; + +public class GooglePayExpressCartRequest implements Serializable { + private GooglePayDetails googlePayDetails; + private AddressData addressData; + + public GooglePayDetails getGooglePayDetails() { + return googlePayDetails; + } + + public void setGooglePayDetails(GooglePayDetails googlePayDetails) { + this.googlePayDetails = googlePayDetails; + } + + public AddressData getAddressData() { + return addressData; + } + + public void setAddressData(AddressData addressData) { + this.addressData = addressData; + } +} diff --git a/adyenocc/src/com/adyen/commerce/request/GooglePayExpressPDPRequest.java b/adyenocc/src/com/adyen/commerce/request/GooglePayExpressPDPRequest.java new file mode 100644 index 000000000..167d24357 --- /dev/null +++ b/adyenocc/src/com/adyen/commerce/request/GooglePayExpressPDPRequest.java @@ -0,0 +1,14 @@ +package com.adyen.commerce.request; + + +public class GooglePayExpressPDPRequest extends GooglePayExpressCartRequest { + private String productCode; + + public String getProductCode() { + return productCode; + } + + public void setProductCode(String productCode) { + this.productCode = productCode; + } +} diff --git a/adyenocc/src/com/adyen/commerce/resolver/PaymentRedirectReturnUrlResolver.java b/adyenocc/src/com/adyen/commerce/resolver/PaymentRedirectReturnUrlResolver.java new file mode 100644 index 000000000..caf817a0e --- /dev/null +++ b/adyenocc/src/com/adyen/commerce/resolver/PaymentRedirectReturnUrlResolver.java @@ -0,0 +1,33 @@ +package com.adyen.commerce.resolver; + +import com.adyen.commerce.utils.WebServicesBaseUrlResolver; +import de.hybris.platform.commerceservices.i18n.CommerceCommonI18NService; +import de.hybris.platform.site.BaseSiteService; + +public class PaymentRedirectReturnUrlResolver { + private WebServicesBaseUrlResolver webServicesBaseUrlResolver; + private CommerceCommonI18NService commerceCommonI18NService; + private BaseSiteService baseSiteService; + + + public String resolvePaymentRedirectReturnUrl() { + String occBaseUrl = webServicesBaseUrlResolver.getOCCBaseUrl(true); + String currency = commerceCommonI18NService.getCurrentCurrency().getIsocode(); + String language = commerceCommonI18NService.getCurrentLanguage().getIsocode(); + String baseSiteUid = baseSiteService.getCurrentBaseSite().getUid(); + + return occBaseUrl + "/v2/" + baseSiteUid + "/adyen/redirect?lang=" + language + "&curr=" + currency; + } + + public void setWebServicesBaseUrlResolver(WebServicesBaseUrlResolver webServicesBaseUrlResolver) { + this.webServicesBaseUrlResolver = webServicesBaseUrlResolver; + } + + public void setCommerceCommonI18NService(CommerceCommonI18NService commerceCommonI18NService) { + this.commerceCommonI18NService = commerceCommonI18NService; + } + + public void setBaseSiteService(BaseSiteService baseSiteService) { + this.baseSiteService = baseSiteService; + } +} diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenApplePayExpressCheckoutController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenApplePayExpressCheckoutController.java index 9b78fa65e..16748c4a2 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenApplePayExpressCheckoutController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenApplePayExpressCheckoutController.java @@ -36,7 +36,7 @@ public class AdyenApplePayExpressCheckoutController { @PostMapping("/expressCheckout/applePayPDP") public ResponseEntity applePayExpressPDP(final HttpServletRequest request, final HttpServletResponse response, @RequestBody ApplePayExpressPDPRequest applePayExpressPDPRequest) throws Exception { - PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressPDPCheckout(applePayExpressPDPRequest.getAddressData(), applePayExpressPDPRequest.getProductCode(), + PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.appleExpressPDPCheckout(applePayExpressPDPRequest.getAddressData(), applePayExpressPDPRequest.getProductCode(), applePayExpressPDPRequest.getAdyenApplePayMerchantIdentifier(), applePayExpressPDPRequest.getAdyenApplePayMerchantName(), applePayExpressPDPRequest.getApplePayToken(), request); @@ -49,7 +49,7 @@ public ResponseEntity applePayExpressPDP(final HttpServletRequest request, final @PostMapping("/expressCheckout/cart") public ResponseEntity cartExpressCheckout(final HttpServletRequest request, final HttpServletResponse response, @RequestBody ApplePayExpressCartRequest applePayExpressCartRequest) throws Exception { - PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressCartCheckout(applePayExpressCartRequest.getAddressData(), + PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.appleEexpressCartCheckout(applePayExpressCartRequest.getAddressData(), applePayExpressCartRequest.getAdyenApplePayMerchantIdentifier(), applePayExpressCartRequest.getAdyenApplePayMerchantName(), applePayExpressCartRequest.getApplePayToken(), request); diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java new file mode 100644 index 000000000..ac0c66dda --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java @@ -0,0 +1,72 @@ +package com.adyen.v6.controllers.checkout; + +import com.adyen.model.checkout.CheckoutPaymentMethod; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.model.checkout.PaymentResponse; +import com.adyen.v6.constants.Adyenv6coreConstants; +import com.adyen.v6.facades.AdyenExpressCheckoutFacade; +import com.adyen.v6.request.GooglePayExpressCartRequest; +import com.adyen.v6.request.GooglePayExpressPDPRequest; +import de.hybris.platform.acceleratorstorefrontcommons.constants.WebConstants; +import de.hybris.platform.acceleratorstorefrontcommons.security.GUIDCookieStrategy; +import de.hybris.platform.servicelayer.session.SessionService; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Controller +@RequestMapping("/express-checkout/google/") +public class AdyenGooglePayExpressCheckoutController { + private static final Logger LOG = Logger.getLogger(AdyenApplePayExpressCheckoutController.class); + + @Autowired + private AdyenExpressCheckoutFacade adyenExpressCheckoutFacade; + + @Autowired + private SessionService sessionService; + + @Autowired + private GUIDCookieStrategy guidCookieStrategy; + + @PostMapping("PDP") + public ResponseEntity googlePayExpressPDP(final HttpServletRequest request, final HttpServletResponse response, @RequestBody GooglePayExpressPDPRequest googlePayExpressPDPRequest) throws Exception { + + PaymentRequest paymentRequest = new PaymentRequest(); + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(googlePayExpressPDPRequest.getGooglePayDetails())); + + PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressCheckoutPDP(googlePayExpressPDPRequest.getProductCode(), + paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_GOOGLE_PAY, googlePayExpressPDPRequest.getAddressData(), request); + + guidCookieStrategy.setCookie(request, response); + sessionService.setAttribute(WebConstants.ANONYMOUS_CHECKOUT, Boolean.TRUE); + + return new ResponseEntity<>(paymentsResponse, HttpStatus.OK); + } + + @PostMapping("cart") + public ResponseEntity googlePayCartExpressCheckout(final HttpServletRequest request, final HttpServletResponse response, @RequestBody GooglePayExpressCartRequest googlePayExpressCartRequest) throws Exception { + + PaymentRequest paymentRequest = new PaymentRequest(); + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(googlePayExpressCartRequest.getGooglePayDetails())); + + PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressCheckoutCart(paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_GOOGLE_PAY, + googlePayExpressCartRequest.getAddressData(), request); + + guidCookieStrategy.setCookie(request, response); + sessionService.setAttribute(WebConstants.ANONYMOUS_CHECKOUT, Boolean.TRUE); + + return new ResponseEntity<>(paymentsResponse, HttpStatus.OK); + } + + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ExceptionHandler(value = Exception.class) + public void adyenComponentExceptionHandler(Exception e) { + LOG.error("Exception during GooglePayExpress processing", e); + } +} diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressCartRequest.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressCartRequest.java new file mode 100644 index 000000000..4807c4b5e --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressCartRequest.java @@ -0,0 +1,27 @@ +package com.adyen.v6.request; + +import com.adyen.model.checkout.GooglePayDetails; +import de.hybris.platform.commercefacades.user.data.AddressData; + +import java.io.Serializable; + +public class GooglePayExpressCartRequest implements Serializable { + private GooglePayDetails googlePayDetails; + private AddressData addressData; + + public GooglePayDetails getGooglePayDetails() { + return googlePayDetails; + } + + public void setGooglePayDetails(GooglePayDetails googlePayDetails) { + this.googlePayDetails = googlePayDetails; + } + + public AddressData getAddressData() { + return addressData; + } + + public void setAddressData(AddressData addressData) { + this.addressData = addressData; + } +} diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressPDPRequest.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressPDPRequest.java new file mode 100644 index 000000000..7c1078376 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/GooglePayExpressPDPRequest.java @@ -0,0 +1,15 @@ +package com.adyen.v6.request; + +import java.io.Serializable; + +public class GooglePayExpressPDPRequest extends GooglePayExpressCartRequest { + private String productCode; + + public String getProductCode() { + return productCode; + } + + public void setProductCode(String productCode) { + this.productCode = productCode; + } +} diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag index 16f8b9030..2e95eb7bf 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag @@ -1,7 +1,10 @@ <%@ taglib prefix="adyen" tagdir="/WEB-INF/tags/addons/adyenv6b2ccheckoutaddon/responsive" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ attribute name="pageType" required="true" type="java.lang.String"%> + + - + + diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js index ceea56910..494c328d3 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js @@ -192,15 +192,6 @@ var AdyenExpressCheckoutHybris = (function() { } = intermediatePaymentData; const paymentDataRequestUpdate = {}; - // Validate the country/region and address selection. - if (shippingAddress.countryCode !== 'US' && shippingAddress.countryCode !== 'BR') { - paymentDataRequestUpdate.error = { - reason: 'SHIPPING_ADDRESS_UNSERVICEABLE', - message: 'Cannot ship to the selected address', - intent: 'SHIPPING_ADDRESS' - }; - } - // If it initializes or changes the shipping address, calculate the shipping options and transaction info. if (callbackTrigger === 'INITIALIZE' || callbackTrigger === 'SHIPPING_ADDRESS') { // paymentDataRequestUpdate.newShippingOptionParameters = await fetchNewShippingOptions(shippingAddress.countryCode); @@ -220,8 +211,6 @@ var AdyenExpressCheckoutHybris = (function() { // Step 7: Configure the callback to get the shopper's information. onAuthorized: (paymentData) => { - console.log('Shopper details'); - console.log(paymentData) this.makePayment(this.prepareDataGoogle(paymentData), this.getGoogleUrl()) }, onError: function (error) { @@ -230,7 +219,7 @@ var AdyenExpressCheckoutHybris = (function() { }); googlePayComponent.isAvailable() .then(function () { - googlePayComponent.mount(googlePayNode); + googlePayComponent.mount(googlePayNode); }) .catch(function (e) { // Google Pay is not available @@ -272,10 +261,14 @@ var AdyenExpressCheckoutHybris = (function() { }, handleResult: function(data, error) { if (error) { - document.querySelector("#resultData").value = data; + if (data) { + document.querySelector("#resultCode").value = data.resultCode; + document.querySelector("#merchantReference").value = data.merchantReference; + } document.querySelector("#isResultError").value = error; } else { - document.querySelector("#resultData").value = JSON.stringify(data); + document.querySelector("#resultCode").value = data.resultCode; + document.querySelector("#merchantReference").value = data.merchantReference; } document.querySelector("#handleComponentResultForm").submit(); }, @@ -326,9 +319,11 @@ var AdyenExpressCheckoutHybris = (function() { return {}; }, prepareDataGoogle: function(paymentData) { - const baseData = { - googlePayToken: paymentData.paymentMethodData.tokenizationData.token, - googlePayCardNetwork: paymentData.paymentMethodData.info.cardNetwork, + let baseData = { + googlePayDetails: { + googlePayToken: paymentData.paymentMethodData.tokenizationData.token, + googlePayCardNetwork: paymentData.paymentMethodData.info.cardNetwork + }, addressData: { email: paymentData.email, firstName: paymentData.shippingAddress.name, @@ -341,10 +336,11 @@ var AdyenExpressCheckoutHybris = (function() { isocode: paymentData.shippingAddress.countryCode, }, region: { - isocode: paymentData.shippingAddress.administrativeArea + isocodeShort: paymentData.shippingAddress.administrativeArea } } } + if (this.adyenConfig.pageType === 'PDP') { return { productCode: this.adyenConfig.productCode, @@ -369,10 +365,10 @@ var AdyenExpressCheckoutHybris = (function() { }, getGoogleUrl: function() { if (this.adyenConfig.pageType === 'PDP') { - return ACC.config.encodedContextPath + '/expressCheckout/googlePayPDP' + return ACC.config.encodedContextPath + '/express-checkout/google/PDP' } if (this.adyenConfig.pageType === 'cart') { - return ACC.config.encodedContextPath + '/expressCheckout/googlePayCart' + return ACC.config.encodedContextPath + '/express-checkout/google/cart' } console.error('unknown page type') return null; diff --git a/adyenv6core/resources/adyenv6core-spring.xml b/adyenv6core/resources/adyenv6core-spring.xml index 0269acbdc..0b6e2b3f7 100644 --- a/adyenv6core/resources/adyenv6core-spring.xml +++ b/adyenv6core/resources/adyenv6core-spring.xml @@ -411,12 +411,12 @@ + - - + diff --git a/adyenv6core/src/com/adyen/v6/constants/Adyenv6coreConstants.java b/adyenv6core/src/com/adyen/v6/constants/Adyenv6coreConstants.java index b7ae599f3..dcc5c4b02 100644 --- a/adyenv6core/src/com/adyen/v6/constants/Adyenv6coreConstants.java +++ b/adyenv6core/src/com/adyen/v6/constants/Adyenv6coreConstants.java @@ -54,6 +54,7 @@ public final class Adyenv6coreConstants extends GeneratedAdyenv6coreConstants { public static final String PAYMENT_METHOD_BCMC = "bcmc"; public static final String PAYMENT_METHOD_BCMC_MOBILE = "bcmc_mobile"; public static final String PAYMENT_METHOD_GOOGLE = "paywithgoogle"; + public static final String PAYMENT_METHOD_GOOGLE_PAY = "googlepay"; public static final String PAYMENT_METHOD_TRUSTLY = "trustly"; public static final String PAYMENT_METHOD_INTERAC = "interac"; public static final String PAYMENT_METHOD_SOFORT = "directEbanking"; diff --git a/adyenv6core/src/com/adyen/v6/facades/AdyenExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/AdyenExpressCheckoutFacade.java index 9316174cb..a50e79f50 100644 --- a/adyenv6core/src/com/adyen/v6/facades/AdyenExpressCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/AdyenExpressCheckoutFacade.java @@ -1,6 +1,8 @@ package com.adyen.v6.facades; +import com.adyen.model.checkout.PaymentRequest; import com.adyen.model.checkout.PaymentResponse; +import de.hybris.platform.commercefacades.order.data.OrderData; import de.hybris.platform.commercefacades.user.data.AddressData; import de.hybris.platform.deliveryzone.model.ZoneDeliveryModeValueModel; import de.hybris.platform.order.exceptions.CalculationException; @@ -10,11 +12,23 @@ public interface AdyenExpressCheckoutFacade { - PaymentResponse expressPDPCheckout(AddressData addressData, String productCode, String merchantId, String merchantName, - String applePayToken, HttpServletRequest request) throws Exception; + PaymentResponse appleExpressPDPCheckout(AddressData addressData, String productCode, String merchantId, String merchantName, + String applePayToken, HttpServletRequest request) throws Exception; - PaymentResponse expressCartCheckout(AddressData addressData, String merchantId, String merchantName, - String applePayToken, HttpServletRequest request) throws Exception; + PaymentResponse appleEexpressCartCheckout(AddressData addressData, String merchantId, String merchantName, + String applePayToken, HttpServletRequest request) throws Exception; + + PaymentResponse expressCheckoutPDP(String productCode, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception ; + + PaymentResponse expressCheckoutCart(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception; + + OrderData expressCheckoutPDPOCC(String productCode, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception; + + OrderData expressCheckoutCartOCC(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception; Optional getExpressDeliveryModePrice(); diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java index 4ed9bcfe3..334045dd0 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java @@ -1,16 +1,16 @@ package com.adyen.v6.facades.impl; -import com.adyen.model.checkout.ApplePayDetails; -import com.adyen.model.checkout.CheckoutPaymentMethod; -import com.adyen.model.checkout.PaymentRequest; -import com.adyen.model.checkout.PaymentResponse; +import com.adyen.commerce.facades.AdyenCheckoutApiFacade; +import com.adyen.model.checkout.*; import com.adyen.v6.constants.Adyenv6coreConstants; import com.adyen.v6.facades.AdyenCheckoutFacade; import com.adyen.v6.facades.AdyenExpressCheckoutFacade; import de.hybris.platform.commercefacades.customer.CustomerFacade; -import de.hybris.platform.commercefacades.order.CheckoutFacade; +import de.hybris.platform.commercefacades.i18n.I18NFacade; import de.hybris.platform.commercefacades.order.data.CartData; +import de.hybris.platform.commercefacades.order.data.OrderData; import de.hybris.platform.commercefacades.user.data.AddressData; +import de.hybris.platform.commercefacades.user.data.RegionData; import de.hybris.platform.commerceservices.customer.CustomerAccountService; import de.hybris.platform.commerceservices.customer.DuplicateUidException; import de.hybris.platform.commerceservices.enums.CustomerType; @@ -29,7 +29,6 @@ import de.hybris.platform.order.CartService; import de.hybris.platform.order.DeliveryModeService; import de.hybris.platform.order.InvalidCartException; -import de.hybris.platform.order.ZoneDeliveryModeService; import de.hybris.platform.order.exceptions.CalculationException; import de.hybris.platform.product.ProductService; import de.hybris.platform.servicelayer.dto.converter.Converter; @@ -44,6 +43,7 @@ import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -52,9 +52,9 @@ public class DefaultAdyenExpressCheckoutFacade implements AdyenExpressCheckoutFacade { private static final Logger LOG = Logger.getLogger(DefaultAdyenExpressCheckoutFacade.class); - private static final String USER_NAME = "ApplePayExpressGuest"; + protected static final String USER_NAME = "ExpressCheckoutGuest"; private static final String DELIVERY_MODE_CODE = "adyen-express-checkout"; - private static final String ANONYMOUS_CHECKOUT_GUID = "anonymous_checkout_guid"; + protected static final String ANONYMOUS_CHECKOUT_GUID = "anonymous_checkout_guid"; private CartFactory cartFactory; private CartService cartService; @@ -62,20 +62,172 @@ public class DefaultAdyenExpressCheckoutFacade implements AdyenExpressCheckoutFa private ModelService modelService; private CustomerFacade customerFacade; private CommonI18NService commonI18NService; + private I18NFacade i18NFacade; private CustomerAccountService customerAccountService; - private CheckoutFacade checkoutFacade; private CommerceCartService commerceCartService; private DeliveryModeService deliveryModeService; - private ZoneDeliveryModeService zoneDeliveryModeService; private AdyenCheckoutFacade adyenCheckoutFacade; private SessionService sessionService; private UserService userService; + private AdyenCheckoutApiFacade adyenCheckoutApiFacade; private Converter addressReverseConverter; private Converter cartConverter; + public PaymentResponse expressCheckoutPDP(String productCode, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception { + Assert.notNull(paymentMethod, "Payment method must not be null"); - public PaymentResponse expressPDPCheckout(AddressData addressData, String productCode, String merchantId, String merchantName, - String applePayToken, HttpServletRequest request) throws Exception { + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + updateRegionData(addressData); + + return expressPDPCheckout(paymentRequest,addressData,paymentInfoModel,productCode,request); + } + + public OrderData expressCheckoutPDPOCC(String productCode, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception { + Assert.notNull(paymentMethod, "Payment method must not be null"); + + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + updateRegionData(addressData); + + return expressPDPCheckoutOCC(paymentRequest,addressData,paymentInfoModel,productCode,request); + } + + + public PaymentResponse expressCheckoutCart(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception { + Assert.notNull(paymentMethod, "Payment method must not be null"); + + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + updateRegionData(addressData); + + return expressCartCheckout(paymentRequest,addressData,paymentInfoModel,request); + } + + public OrderData expressCheckoutCartOCC(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, + HttpServletRequest request) throws Exception { + Assert.notNull(paymentMethod, "Payment method must not be null"); + + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + updateRegionData(addressData); + + return expressCartCheckoutOCC(paymentRequest,addressData,paymentInfoModel,request); + } + + protected PaymentResponse expressPDPCheckout(PaymentRequest paymentRequest, AddressData addressData, PaymentInfoModel paymentInfoModel, String productCode, + HttpServletRequest request) throws Exception { + validateParameterNotNull(addressData, "Empty address"); + if (StringUtils.isEmpty(addressData.getEmail())) { + throw new IllegalArgumentException("Empty email address"); + } + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + } + + CartModel cart = createCartForExpressCheckout(user); + + DeliveryModeModel deliveryMode = deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); + validateParameterNotNull(deliveryMode, "Delivery mode for Adyen express checkout not configured"); + + AddressModel addressModel = prepareAddressModel(addressData, user); + updatePaymentInfoWithCartAndUser(paymentInfoModel, user,addressModel,cart); + + prepareCart(cart, deliveryMode, addressModel, paymentInfoModel); + + addProductToCart(productCode, cart); + + if (cartHasEntries(cart)) { + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.calculateCart(commerceCartParameter); + + CartModel sessionCart = null; + if (cartService.hasSessionCart()) { + sessionCart = cartService.getSessionCart(); + } + cartService.setSessionCart(cart); + + CartData cartData = cartConverter.convert(cart); + + PaymentResponse paymentsResponse = adyenCheckoutFacade.componentPayment(request, cartData, paymentRequest); + + if (userService.isAnonymousUser(user)) { + sessionService.setAttribute(ANONYMOUS_CHECKOUT_GUID, + org.apache.commons.lang.StringUtils.substringBefore(cart.getUser().getUid(), "|")); + } + + if (sessionCart != null) { + cartService.setSessionCart(sessionCart); + } + + return paymentsResponse; + } else { + throw new InvalidCartException("Checkout attempt on empty cart"); + } + } + + protected OrderData expressPDPCheckoutOCC(PaymentRequest paymentRequest, AddressData addressData, PaymentInfoModel paymentInfoModel, String productCode, + HttpServletRequest request) throws Exception { + validateParameterNotNull(addressData, "Empty address"); + if (StringUtils.isEmpty(addressData.getEmail())) { + throw new IllegalArgumentException("Empty email address"); + } + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + } + + CartModel cart = createCartForExpressCheckout(user); + + DeliveryModeModel deliveryMode = deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); + validateParameterNotNull(deliveryMode, "Delivery mode for Adyen express checkout not configured"); + + AddressModel addressModel = prepareAddressModel(addressData, user); + updatePaymentInfoWithCartAndUser(paymentInfoModel, user,addressModel,cart); + + prepareCart(cart, deliveryMode, addressModel, paymentInfoModel); + + addProductToCart(productCode, cart); + + if (cartHasEntries(cart)) { + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.calculateCart(commerceCartParameter); + + CartModel sessionCart = null; + if (cartService.hasSessionCart()) { + sessionCart = cartService.getSessionCart(); + } + cartService.setSessionCart(cart); + + CartData cartData = cartConverter.convert(cart); + + OrderData orderData = adyenCheckoutApiFacade.placeOrderWithPayment(request, cartData, paymentRequest); + + + if (sessionCart != null) { + cartService.setSessionCart(sessionCart); + } + + return orderData; + } else { + throw new InvalidCartException("Checkout attempt on empty cart"); + } + } + + + //TODO: Remove after applepay + public PaymentResponse appleExpressPDPCheckout(AddressData addressData, String productCode, String merchantId, String merchantName, + String applePayToken, HttpServletRequest request) throws Exception { validateParameterNotNull(addressData, "Empty address"); if (StringUtils.isEmpty(addressData.getEmail())) { throw new IllegalArgumentException("Empty email address"); @@ -131,8 +283,76 @@ public PaymentResponse expressPDPCheckout(AddressData addressData, String produc } } - public PaymentResponse expressCartCheckout(AddressData addressData, String merchantId, String merchantName, - String applePayToken, HttpServletRequest request) throws Exception { + protected PaymentResponse expressCartCheckout(PaymentRequest paymentRequest, AddressData addressData, PaymentInfoModel paymentInfoModel, + HttpServletRequest request) throws Exception { + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + cartService.changeCurrentCartUser(user); + } + + CartModel cart = cartService.getSessionCart(); + + DeliveryModeModel deliveryMode = deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); + validateParameterNotNull(deliveryMode, "Delivery mode for Adyen express checkout not configured"); + + AddressModel addressModel = prepareAddressModel(addressData, user); + updatePaymentInfoWithCartAndUser(paymentInfoModel, user,addressModel,cart); + + prepareCart(cart, deliveryMode, addressModel, paymentInfoModel); + + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.recalculateCart(commerceCartParameter); + + if (cartHasEntries(cart)) { + CartData cartData = cartConverter.convert(cart); + + if (userService.isAnonymousUser(user)) { + sessionService.setAttribute(ANONYMOUS_CHECKOUT_GUID, + org.apache.commons.lang.StringUtils.substringBefore(cart.getUser().getUid(), "|")); + } + + return adyenCheckoutFacade.componentPayment(request, cartData, paymentRequest); + } else { + throw new InvalidCartException("Checkout attempt on empty cart"); + } + } + + protected OrderData expressCartCheckoutOCC(PaymentRequest paymentRequest, AddressData addressData, PaymentInfoModel paymentInfoModel, + HttpServletRequest request) throws Exception { + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + cartService.changeCurrentCartUser(user); + } + + CartModel cart = cartService.getSessionCart(); + + DeliveryModeModel deliveryMode = deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); + validateParameterNotNull(deliveryMode, "Delivery mode for Adyen express checkout not configured"); + + AddressModel addressModel = prepareAddressModel(addressData, user); + updatePaymentInfoWithCartAndUser(paymentInfoModel, user,addressModel,cart); + + prepareCart(cart, deliveryMode, addressModel, paymentInfoModel); + + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.recalculateCart(commerceCartParameter); + + if (cartHasEntries(cart)) { + CartData cartData = cartConverter.convert(cart); + + return adyenCheckoutApiFacade.placeOrderWithPayment(request, cartData, paymentRequest); + } else { + throw new InvalidCartException("Checkout attempt on empty cart"); + } + } + + //TODO: Remove after applepay + public PaymentResponse appleEexpressCartCheckout(AddressData addressData, String merchantId, String merchantName, + String applePayToken, HttpServletRequest request) throws Exception { CustomerModel user = (CustomerModel) userService.getCurrentUser(); if (userService.isAnonymousUser(user)) { user = createGuestCustomer(addressData.getEmail()); @@ -212,6 +432,26 @@ protected void addProductToCart(String productCode, CartModel cart) { modelService.save(cart); } + protected void updateRegionData(AddressData addressData) { + if (addressData.getRegion() != null) { + if (StringUtils.isNotEmpty(addressData.getRegion().getIsocodeShort())) { + List regionsForCountry = i18NFacade.getRegionsForCountryIso(addressData.getCountry().getIsocode()); + Optional regionData = regionsForCountry.stream() + .filter(region -> region.getIsocodeShort().equals(addressData.getRegion().getIsocodeShort())) + .findFirst(); + + if (regionData.isPresent()) { + addressData.setRegion(regionData.get()); + } else { + addressData.setRegion(null); + } + + } else { + addressData.setRegion(null); + } + } + } + public Optional getExpressDeliveryModePrice() { ZoneDeliveryModeModel deliveryMode = (ZoneDeliveryModeModel) deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); CurrencyModel currentCurrency = commonI18NService.getCurrentCurrency(); @@ -249,6 +489,18 @@ protected CartModel createCartForExpressCheckout(CustomerModel guestUser) { return cart; } + protected PaymentInfoModel updatePaymentInfoWithCartAndUser(PaymentInfoModel paymentInfo, CustomerModel customerModel, AddressModel addressModel, CartModel cartModel) { + Assert.notNull(paymentInfo, "Payment info must not be null"); + + paymentInfo.setUser(customerModel); + paymentInfo.setCode(generateCcPaymentInfoCode(cartModel)); + paymentInfo.setBillingAddress(addressModel); + + modelService.save(paymentInfo); + + return paymentInfo; + } + protected PaymentInfoModel createPaymentInfoForCart(CustomerModel customerModel, AddressModel addressModel, CartModel cartModel, String paymentMethod, String merchantId, String merchantName) { final PaymentInfoModel paymentInfo = modelService.create(PaymentInfoModel.class); paymentInfo.setUser(customerModel); @@ -304,10 +556,6 @@ public void setCustomerAccountService(CustomerAccountService customerAccountServ this.customerAccountService = customerAccountService; } - public void setCheckoutFacade(CheckoutFacade checkoutFacade) { - this.checkoutFacade = checkoutFacade; - } - public void setCommerceCartService(CommerceCartService commerceCartService) { this.commerceCartService = commerceCartService; } @@ -316,10 +564,6 @@ public void setDeliveryModeService(DeliveryModeService deliveryModeService) { this.deliveryModeService = deliveryModeService; } - public void setZoneDeliveryModeService(ZoneDeliveryModeService zoneDeliveryModeService) { - this.zoneDeliveryModeService = zoneDeliveryModeService; - } - public void setAdyenCheckoutFacade(AdyenCheckoutFacade adyenCheckoutFacade) { this.adyenCheckoutFacade = adyenCheckoutFacade; } @@ -335,4 +579,12 @@ public void setSessionService(SessionService sessionService) { public void setUserService(UserService userService) { this.userService = userService; } + + public void setI18NFacade(I18NFacade i18NFacade) { + this.i18NFacade = i18NFacade; + } + + public void setAdyenCheckoutApiFacade(AdyenCheckoutApiFacade adyenCheckoutApiFacade) { + this.adyenCheckoutApiFacade = adyenCheckoutApiFacade; + } } diff --git a/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java b/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java new file mode 100644 index 000000000..e5c513154 --- /dev/null +++ b/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java @@ -0,0 +1,695 @@ +package com.adyen.v6.facades.impl; + +import com.adyen.commerce.facades.AdyenCheckoutApiFacade; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.v6.facades.AdyenCheckoutFacade; +import de.hybris.bootstrap.annotations.UnitTest; +import de.hybris.platform.commercefacades.customer.CustomerFacade; +import de.hybris.platform.commercefacades.i18n.I18NFacade; +import de.hybris.platform.commercefacades.order.data.CartData; +import de.hybris.platform.commercefacades.user.data.AddressData; +import de.hybris.platform.commercefacades.user.data.CountryData; +import de.hybris.platform.commercefacades.user.data.RegionData; +import de.hybris.platform.commerceservices.customer.CustomerAccountService; +import de.hybris.platform.commerceservices.customer.DuplicateUidException; +import de.hybris.platform.commerceservices.enums.CustomerType; +import de.hybris.platform.commerceservices.order.CommerceCartService; +import de.hybris.platform.commerceservices.service.data.CommerceCartParameter; +import de.hybris.platform.core.model.c2l.CurrencyModel; +import de.hybris.platform.core.model.c2l.LanguageModel; +import de.hybris.platform.core.model.order.CartModel; +import de.hybris.platform.core.model.order.OrderEntryModel; +import de.hybris.platform.core.model.order.delivery.DeliveryModeModel; +import de.hybris.platform.core.model.order.payment.PaymentInfoModel; +import de.hybris.platform.core.model.product.ProductModel; +import de.hybris.platform.core.model.product.UnitModel; +import de.hybris.platform.core.model.user.AddressModel; +import de.hybris.platform.core.model.user.CustomerModel; +import de.hybris.platform.deliveryzone.model.ZoneDeliveryModeModel; +import de.hybris.platform.deliveryzone.model.ZoneDeliveryModeValueModel; +import de.hybris.platform.order.CartFactory; +import de.hybris.platform.order.CartService; +import de.hybris.platform.order.DeliveryModeService; +import de.hybris.platform.order.exceptions.CalculationException; +import de.hybris.platform.product.ProductService; +import de.hybris.platform.servicelayer.dto.converter.Converter; +import de.hybris.platform.servicelayer.i18n.CommonI18NService; +import de.hybris.platform.servicelayer.model.ModelService; +import de.hybris.platform.servicelayer.session.SessionService; +import de.hybris.platform.servicelayer.user.UserService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; + +import static com.adyen.v6.facades.impl.DefaultAdyenExpressCheckoutFacade.USER_NAME; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@UnitTest +@RunWith(MockitoJUnitRunner.class) +public class DefaultAdyenExpressCheckoutFacadeTest { + + @Mock + private ModelService modelService; + + @Mock + private CartService cartService; + + @Mock + private CommerceCartService commerceCartService; + + @Mock + private Converter addressReverseConverter; + + @Mock + private ProductService productService; + + @Mock + private I18NFacade i18NFacade; + + @Mock + private DeliveryModeService deliveryModeService; + + @Mock + private CommonI18NService commonI18NService; + + @Mock + private CustomerFacade customerFacade; + + @Mock + private CustomerAccountService customerAccountService; + + @Mock + private CartFactory cartFactory; + + @Mock + private UserService userService; + + @Mock + private Converter cartConverter; + + @Mock + private AdyenCheckoutFacade adyenCheckoutFacade; + + @Mock + private SessionService sessionService; + + @Mock + private AdyenCheckoutApiFacade adyenCheckoutApiFacade; + + @Mock + private HttpServletRequest request; + + @InjectMocks + private DefaultAdyenExpressCheckoutFacade defaultAdyenExpressCheckoutFacade; + + + @Test + public void expressCheckoutPDP() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = "paymentMethod"; + PaymentInfoModel paymentInfoModel = new PaymentInfoModel(); + CustomerModel customerModel = new CustomerModel(); + CartModel sessionCartModel = new CartModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + AddressModel addressModel = new AddressModel(); + ProductModel productModel = new ProductModel(); + UnitModel unitModel = new UnitModel(); + CartModel cartWithEntry = new CartModel(); + OrderEntryModel entry = new OrderEntryModel(); + cartWithEntry.setEntries(Arrays.asList(entry)); + + productModel.setUnit(unitModel); + + AddressData addressData = setUpAddressData(); + + when(modelService.create(PaymentInfoModel.class)).thenReturn(paymentInfoModel); + when(userService.getCurrentUser()).thenReturn(customerModel); + when(userService.isAnonymousUser(any())).thenReturn(false); + when(cartFactory.createCart()).thenReturn(cartWithEntry); + when(deliveryModeService.getDeliveryModeForCode(any())).thenReturn(deliveryModeModel); + when(modelService.create(AddressModel.class)).thenReturn(addressModel); + when(productService.getProductForCode(productCode)).thenReturn(productModel); + + when(cartService.hasSessionCart()).thenReturn(true); + when(cartService.getSessionCart()).thenReturn(sessionCartModel); + + ArgumentCaptor cartModelArgumentCaptor = ArgumentCaptor.forClass(CartModel.class); + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutPDP(productCode, paymentRequest, paymentMethod, addressData, request); + + //then + verify(cartService).addNewEntry(cartWithEntry, productModel, 1L, unitModel); + verify(commerceCartService, times(1)).calculateCart((CommerceCartParameter) any()); + verify(cartService, times(2)).setSessionCart(cartModelArgumentCaptor.capture()); + + List cartsSetInSession = cartModelArgumentCaptor.getAllValues(); + assertEquals(cartWithEntry, cartsSetInSession.get(0)); + assertEquals(sessionCartModel, cartsSetInSession.get(1)); + + verify(adyenCheckoutFacade, times(1)).componentPayment(any(), any(), any()); + } + + + @Test + public void expressCheckoutPDPOCC() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = "paymentMethod"; + PaymentInfoModel paymentInfoModel = new PaymentInfoModel(); + CustomerModel customerModel = new CustomerModel(); + CartModel sessionCartModel = new CartModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + AddressModel addressModel = new AddressModel(); + ProductModel productModel = new ProductModel(); + UnitModel unitModel = new UnitModel(); + CartModel cartWithEntry = new CartModel(); + OrderEntryModel entry = new OrderEntryModel(); + cartWithEntry.setEntries(Arrays.asList(entry)); + + productModel.setUnit(unitModel); + + AddressData addressData = setUpAddressData(); + + when(modelService.create(PaymentInfoModel.class)).thenReturn(paymentInfoModel); + when(userService.getCurrentUser()).thenReturn(customerModel); + when(userService.isAnonymousUser(any())).thenReturn(false); + when(cartFactory.createCart()).thenReturn(cartWithEntry); + when(deliveryModeService.getDeliveryModeForCode(any())).thenReturn(deliveryModeModel); + when(modelService.create(AddressModel.class)).thenReturn(addressModel); + when(productService.getProductForCode(productCode)).thenReturn(productModel); + + when(cartService.hasSessionCart()).thenReturn(true); + when(cartService.getSessionCart()).thenReturn(sessionCartModel); + + ArgumentCaptor cartModelArgumentCaptor = ArgumentCaptor.forClass(CartModel.class); + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutPDPOCC(productCode, paymentRequest, paymentMethod, addressData, request); + + //then + verify(cartService).addNewEntry(cartWithEntry, productModel, 1L, unitModel); + verify(commerceCartService, times(1)).calculateCart((CommerceCartParameter) any()); + verify(cartService, times(2)).setSessionCart(cartModelArgumentCaptor.capture()); + + List cartsSetInSession = cartModelArgumentCaptor.getAllValues(); + assertEquals(cartWithEntry, cartsSetInSession.get(0)); + assertEquals(sessionCartModel, cartsSetInSession.get(1)); + + verify(adyenCheckoutApiFacade, times(1)).placeOrderWithPayment(any(), any(), any()); + } + + @Test + public void expressCheckoutCart() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = "paymentMethod"; + PaymentInfoModel paymentInfoModel = new PaymentInfoModel(); + CustomerModel customerModel = new CustomerModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + AddressModel addressModel = new AddressModel(); + ProductModel productModel = new ProductModel(); + UnitModel unitModel = new UnitModel(); + CartModel cartWithEntry = new CartModel(); + OrderEntryModel entry = new OrderEntryModel(); + cartWithEntry.setEntries(Arrays.asList(entry)); + + productModel.setUnit(unitModel); + + AddressData addressData = setUpAddressData(); + + when(modelService.create(PaymentInfoModel.class)).thenReturn(paymentInfoModel); + when(userService.getCurrentUser()).thenReturn(customerModel); + when(userService.isAnonymousUser(any())).thenReturn(false); + when(cartService.getSessionCart()).thenReturn(cartWithEntry); + when(deliveryModeService.getDeliveryModeForCode(any())).thenReturn(deliveryModeModel); + when(modelService.create(AddressModel.class)).thenReturn(addressModel); + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutCart(paymentRequest, paymentMethod, addressData, request); + + //then + verify(commerceCartService, times(1)).recalculateCart((CommerceCartParameter) any()); + + verify(adyenCheckoutFacade, times(1)).componentPayment(any(), any(), any()); + } + + @Test + public void expressCheckoutCartOCC() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = "paymentMethod"; + PaymentInfoModel paymentInfoModel = new PaymentInfoModel(); + CustomerModel customerModel = new CustomerModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + AddressModel addressModel = new AddressModel(); + ProductModel productModel = new ProductModel(); + UnitModel unitModel = new UnitModel(); + CartModel cartWithEntry = new CartModel(); + OrderEntryModel entry = new OrderEntryModel(); + cartWithEntry.setEntries(Arrays.asList(entry)); + + productModel.setUnit(unitModel); + + AddressData addressData = setUpAddressData(); + + when(modelService.create(PaymentInfoModel.class)).thenReturn(paymentInfoModel); + when(userService.getCurrentUser()).thenReturn(customerModel); + when(userService.isAnonymousUser(any())).thenReturn(false); + when(cartService.getSessionCart()).thenReturn(cartWithEntry); + when(deliveryModeService.getDeliveryModeForCode(any())).thenReturn(deliveryModeModel); + when(modelService.create(AddressModel.class)).thenReturn(addressModel); + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutCartOCC(paymentRequest, paymentMethod, addressData, request); + + //then + verify(commerceCartService, times(1)).recalculateCart((CommerceCartParameter) any()); + + verify(adyenCheckoutApiFacade, times(1)).placeOrderWithPayment(any(), any(), any()); + } + + + @Test(expected = IllegalArgumentException.class) + public void expressCheckoutPDPNullPaymentMethod() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = null; + + AddressData addressData = setUpAddressData(); + + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutPDP(productCode, paymentRequest, paymentMethod, addressData, request); + } + + @Test(expected = IllegalArgumentException.class) + public void expressCheckoutPDPOCCNullPaymentMethod() throws Exception { + //given + String productCode = "productCode"; + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = null; + + AddressData addressData = setUpAddressData(); + + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutPDPOCC(productCode, paymentRequest, paymentMethod, addressData, request); + } + + @Test(expected = IllegalArgumentException.class) + public void expressCheckoutCartNullPaymentMethod() throws Exception { + //given + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = null; + + AddressData addressData = setUpAddressData(); + + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutCart(paymentRequest, paymentMethod, addressData, request); + } + + @Test(expected = IllegalArgumentException.class) + public void expressCheckoutCartOCCNullPaymentMethod() throws Exception { + //given + PaymentRequest paymentRequest = new PaymentRequest(); + String paymentMethod = null; + + AddressData addressData = setUpAddressData(); + + //when + defaultAdyenExpressCheckoutFacade.expressCheckoutCartOCC(paymentRequest, paymentMethod, addressData, request); + } + + @Test + public void removeDeliveryModeFromSessionCart() throws CalculationException { + //given + CartModel cartModel = new CartModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + cartModel.setDeliveryMode(deliveryModeModel); + + when(cartService.getSessionCart()).thenReturn(cartModel); + when(cartService.hasSessionCart()).thenReturn(true); + + ArgumentCaptor cartCaptor = ArgumentCaptor.forClass(CartModel.class); + + //when + defaultAdyenExpressCheckoutFacade.removeDeliveryModeFromSessionCart(); + + //then + verify(modelService).save(cartCaptor.capture()); + CartModel capturedCart = cartCaptor.getValue(); + assertNull(capturedCart.getDeliveryMode()); + + verify(commerceCartService).recalculateCart((CommerceCartParameter) any()); + } + + @Test + public void prepareCart() { + //given + CartModel cartModel = new CartModel(); + DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); + AddressModel addressModel = new AddressModel(); + PaymentInfoModel paymentInfo = new PaymentInfoModel(); + + ArgumentCaptor cartCaptor = ArgumentCaptor.forClass(CartModel.class); + + //when + defaultAdyenExpressCheckoutFacade.prepareCart(cartModel, deliveryModeModel, addressModel, paymentInfo); + + //then + verify(modelService).save(cartCaptor.capture()); + CartModel capturedCart = cartCaptor.getValue(); + + assertNotNull(capturedCart.getDeliveryMode()); + assertNotNull(capturedCart.getDeliveryAddress()); + assertNotNull(capturedCart.getPaymentAddress()); + assertNotNull(capturedCart.getPaymentInfo()); + + } + + @Test + public void prepareAddressModel() { + //given + AddressData addressData = new AddressData(); + AddressModel addressModel = new AddressModel(); + CustomerModel customerModel = new CustomerModel(); + + when(modelService.create(AddressModel.class)).thenReturn(addressModel); + + ArgumentCaptor addressCaptor = ArgumentCaptor.forClass(AddressModel.class); + + //when + defaultAdyenExpressCheckoutFacade.prepareAddressModel(addressData, customerModel); + + //then + verify(modelService).save(addressCaptor.capture()); + AddressModel capturedAddress = addressCaptor.getValue(); + + assertEquals(customerModel, capturedAddress.getOwner()); + assertTrue(capturedAddress.getBillingAddress()); + assertTrue(capturedAddress.getShippingAddress()); + } + + @Test(expected = IllegalArgumentException.class) + public void prepareAddressModelException() { + //given + AddressData addressData = new AddressData(); + CustomerModel customerModel = new CustomerModel(); + + when(modelService.create(AddressModel.class)).thenReturn(null); + + + //when + defaultAdyenExpressCheckoutFacade.prepareAddressModel(addressData, customerModel); + } + + @Test + public void addProductToCart() { + //given + CartModel cartModel = new CartModel(); + ProductModel productModel = new ProductModel(); + UnitModel unitModel = new UnitModel(); + productModel.setUnit(unitModel); + + when(productService.getProductForCode(any())).thenReturn(productModel); + + //when + defaultAdyenExpressCheckoutFacade.addProductToCart("code", cartModel); + + //then + verify(cartService).addNewEntry(cartModel, productModel, 1L, unitModel); + } + + @Test + public void addProductToCartProductNotFound() { + //given + CartModel cartModel = new CartModel(); + + + when(productService.getProductForCode(any())).thenReturn(null); + + //when + defaultAdyenExpressCheckoutFacade.addProductToCart("code", cartModel); + + //then + verifyNoInteractions(cartService); + } + + @Test + public void updateRegionData() { + //given + AddressData addressData = setUpAddressData(); + + //when + defaultAdyenExpressCheckoutFacade.updateRegionData(addressData); + + //then + assertNotNull(addressData.getRegion()); + assertEquals("US-CA", addressData.getRegion().getIsocode()); + } + + private AddressData setUpAddressData() { + AddressData addressData = new AddressData(); + addressData.setEmail("test@address.com"); + + String isocodeShort = "CA"; + + RegionData addressRegion = new RegionData(); + addressRegion.setIsocodeShort(isocodeShort); + CountryData countryData = new CountryData(); + countryData.setIsocode("US"); + addressData.setRegion(addressRegion); + addressData.setCountry(countryData); + + RegionData region1 = new RegionData(); + RegionData region2 = new RegionData(); + + region2.setIsocodeShort(isocodeShort); + region2.setIsocode("US-CA"); + region1.setIsocodeShort("test"); + region1.setIsocode("test"); + + when(i18NFacade.getRegionsForCountryIso(any())).thenReturn(Arrays.asList(region1, region2)); + return addressData; + } + + @Test + public void updateRegionDataNotInList() { + //given + AddressData addressData = new AddressData(); + String isocodeShort = "CA"; + + RegionData addressRegion = new RegionData(); + addressRegion.setIsocodeShort(isocodeShort); + CountryData countryData = new CountryData(); + countryData.setIsocode("US"); + addressData.setRegion(addressRegion); + addressData.setCountry(countryData); + + RegionData region1 = new RegionData(); + RegionData region2 = new RegionData(); + + region2.setIsocodeShort("NY"); + region2.setIsocode("US-CA"); + region1.setIsocodeShort("test"); + region1.setIsocode("test"); + + when(i18NFacade.getRegionsForCountryIso(any())).thenReturn(Arrays.asList(region1, region2)); + + //when + defaultAdyenExpressCheckoutFacade.updateRegionData(addressData); + + //then + assertNull(addressData.getRegion()); + } + + @Test + public void updateRegionDataNull() { + //given + AddressData addressData = new AddressData(); + + CountryData countryData = new CountryData(); + countryData.setIsocode("US"); + addressData.setRegion(null); + addressData.setCountry(countryData); + + //when + defaultAdyenExpressCheckoutFacade.updateRegionData(addressData); + + //then + assertNull(addressData.getRegion()); + } + + @Test + public void updateRegionDataEmpty() { + //given + AddressData addressData = new AddressData(); + + CountryData countryData = new CountryData(); + countryData.setIsocode("US"); + RegionData regionData = new RegionData(); + regionData.setIsocodeShort(""); + addressData.setRegion(regionData); + addressData.setCountry(countryData); + + //when + defaultAdyenExpressCheckoutFacade.updateRegionData(addressData); + + //then + assertNull(addressData.getRegion()); + } + + @Test + public void getExpressDeliveryModePrice() { + //given + ZoneDeliveryModeModel zoneDeliveryMode = new ZoneDeliveryModeModel(); + ZoneDeliveryModeValueModel zoneDeliveryModeValue1 = new ZoneDeliveryModeValueModel(); + ZoneDeliveryModeValueModel zoneDeliveryModeValue2 = new ZoneDeliveryModeValueModel(); + CurrencyModel currencyModel1 = new CurrencyModel(); + CurrencyModel currencyModel2 = new CurrencyModel(); + currencyModel1.setIsocode("USD"); + currencyModel2.setIsocode("EUR"); + zoneDeliveryModeValue1.setCurrency(currencyModel1); + zoneDeliveryModeValue2.setCurrency(currencyModel2); + zoneDeliveryMode.setValues(new HashSet<>(Arrays.asList(zoneDeliveryModeValue1, zoneDeliveryModeValue2))); + + when(deliveryModeService.getDeliveryModeForCode(any())).thenReturn(zoneDeliveryMode); + when(commonI18NService.getCurrentCurrency()).thenReturn(currencyModel2); + + //when + Optional expressDeliveryModePrice = defaultAdyenExpressCheckoutFacade.getExpressDeliveryModePrice(); + + //then + assertTrue(expressDeliveryModePrice.isPresent()); + assertEquals(zoneDeliveryModeValue2, expressDeliveryModePrice.get()); + } + + @Test + public void createGuestCustomer() throws DuplicateUidException { + //given + String email = "test@address.com"; + String expectedUid = "GUID|test@address.com"; + + CustomerModel customerModel = new CustomerModel(); + + when(modelService.create(CustomerModel.class)).thenReturn(customerModel); + + when(customerFacade.generateGUID()).thenReturn("GUID"); + when(commonI18NService.getCurrentCurrency()).thenReturn(new CurrencyModel()); + when(commonI18NService.getCurrentLanguage()).thenReturn(new LanguageModel()); + + ArgumentCaptor customerModelArgumentCaptor = ArgumentCaptor.forClass(CustomerModel.class); + ArgumentCaptor guidArgumentCaptor = ArgumentCaptor.forClass(String.class); + + //when + defaultAdyenExpressCheckoutFacade.createGuestCustomer(email); + + //then + verify(customerAccountService).registerGuestForAnonymousCheckout(customerModelArgumentCaptor.capture(), guidArgumentCaptor.capture()); + + CustomerModel customerValue = customerModelArgumentCaptor.getValue(); + String guidValue = guidArgumentCaptor.getValue(); + + assertEquals("GUID", guidValue); + + assertEquals(expectedUid, customerValue.getUid()); + assertEquals(USER_NAME, customerValue.getName()); + assertEquals(CustomerType.GUEST, customerValue.getType()); + assertNotNull(customerValue.getSessionCurrency()); + assertNotNull(customerValue.getSessionLanguage()); + } + + @Test(expected = IllegalArgumentException.class) + public void createGuestCustomerBadEmail() throws DuplicateUidException { + //given + String email = "test@address"; + String expectedUid = "GUID|test@address"; + + CustomerModel customerModel = new CustomerModel(); + + + //when + defaultAdyenExpressCheckoutFacade.createGuestCustomer(email); + } + + + @Test(expected = IllegalArgumentException.class) + public void createGuestCustomerNullEmail() throws DuplicateUidException { + //given + String email = null; + + //when + defaultAdyenExpressCheckoutFacade.createGuestCustomer(email); + } + + @Test + public void createCartForExpressCheckout() { + //given + CustomerModel customerModel = new CustomerModel(); + CartModel cartModel = new CartModel(); + + when(cartFactory.createCart()).thenReturn(cartModel); + + //when + CartModel cartForExpressCheckout = defaultAdyenExpressCheckoutFacade.createCartForExpressCheckout(customerModel); + + //then + assertEquals(customerModel, cartForExpressCheckout.getUser()); + verify(modelService, times(1)).save(cartModel); + } + + @Test + public void updatePaymentInfoWithCartAndUser() { + //given + PaymentInfoModel paymentInfoModel = new PaymentInfoModel(); + CustomerModel customerModel = new CustomerModel(); + AddressModel addressModel = new AddressModel(); + CartModel cartModel = new CartModel(); + + cartModel.setCode("cartCode"); + + //when + PaymentInfoModel result = defaultAdyenExpressCheckoutFacade.updatePaymentInfoWithCartAndUser(paymentInfoModel, customerModel, addressModel, cartModel); + + //then + + assertEquals(customerModel, result.getUser()); + assertEquals(addressModel, result.getBillingAddress()); + assertTrue(result.getCode().contains("cartCode")); + + verify(modelService, times(1)).save(paymentInfoModel); + } + + @Test(expected = IllegalArgumentException.class) + public void updatePaymentInfoWithCartAndUserPINull() { + //given + PaymentInfoModel paymentInfoModel = null; + CustomerModel customerModel = new CustomerModel(); + AddressModel addressModel = new AddressModel(); + CartModel cartModel = new CartModel(); + + cartModel.setCode("cartCode"); + + //when + PaymentInfoModel result = defaultAdyenExpressCheckoutFacade.updatePaymentInfoWithCartAndUser(paymentInfoModel, customerModel, addressModel, cartModel); + } +} \ No newline at end of file From 5b917d49c864a519d116ecf8599b9bdd773dc6c0 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Wed, 30 Oct 2024 12:06:09 +0100 Subject: [PATCH 2/2] AD-341 Develop Backend Logic for Place Order Endpoints to Handle Google Pay Express Checkout in Accelerator Storefront and OCC Backend - adjust data after adyen-web upgrade --- .../common/js/adyen_express_checkout.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js index 494c328d3..93ea3b486 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_express_checkout.js @@ -321,22 +321,22 @@ var AdyenExpressCheckoutHybris = (function() { prepareDataGoogle: function(paymentData) { let baseData = { googlePayDetails: { - googlePayToken: paymentData.paymentMethodData.tokenizationData.token, - googlePayCardNetwork: paymentData.paymentMethodData.info.cardNetwork + googlePayToken: paymentData.authorizedEvent.paymentMethodData.tokenizationData.token, + googlePayCardNetwork: paymentData.authorizedEvent.paymentMethodData.info.cardNetwork }, addressData: { - email: paymentData.email, - firstName: paymentData.shippingAddress.name, + email: paymentData.authorizedEvent.email, + firstName: paymentData.deliveryAddress.firstName, // lastName: paymentData.payment.shippingContact.familyName, - line1: paymentData.shippingAddress.address1, - line2: paymentData.shippingAddress.address2, - postalCode: paymentData.shippingAddress.postalCode, - town: paymentData.shippingAddress.locality, + line1: paymentData.deliveryAddress.street, + line2: paymentData.deliveryAddress.houseNumberOrName, + postalCode: paymentData.deliveryAddress.postalCode, + town: paymentData.deliveryAddress.city, country: { - isocode: paymentData.shippingAddress.countryCode, + isocode: paymentData.deliveryAddress.country, }, region: { - isocodeShort: paymentData.shippingAddress.administrativeArea + isocodeShort: paymentData.deliveryAddress.stateOrProvince } } }