Skip to content

Commit

Permalink
Merge pull request #468 from Adyen/feature/AD-341
Browse files Browse the repository at this point in the history
Feature/ad 341
  • Loading branch information
pjaneta authored Oct 31, 2024
2 parents 887eb62 + dce85fc commit a80c3da
Show file tree
Hide file tree
Showing 18 changed files with 1,406 additions and 71 deletions.
5 changes: 5 additions & 0 deletions adyenocc/resources/adyenocc-spring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@
<property name="configurationService" ref="configurationService"/>
</bean>

<bean id="paymentRedirectReturnUrlResolver" class="com.adyen.commerce.resolver.PaymentRedirectReturnUrlResolver">
<property name="baseSiteService" ref="baseSiteService"/>
<property name="commerceCommonI18NService" ref="commerceCommonI18NService"/>
<property name="webServicesBaseUrlResolver" ref="webServicesBaseUrlResolver"/>
</bean>
</beans>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -91,12 +87,7 @@ public ResponseEntity<String> 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
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
Original file line number Diff line number Diff line change
@@ -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<String> 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<String> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);

Expand Down
Loading

0 comments on commit a80c3da

Please sign in to comment.