From f6c846c41b4e74580ba7668fdfc379618b4ebd62 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Mon, 16 Dec 2024 14:37:37 +0100 Subject: [PATCH 1/5] AD-337 Add PayPal Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages --- .../AdyenExpressCheckoutControllerBase.java | 28 +++ ...yenGooglePayExpressCheckoutController.java | 2 +- .../AdyenPayPalExpressCheckoutController.java | 91 ++++++-- ...artExpressCheckoutComponentController.java | 2 +- ...uctExpressCheckoutComponentController.java | 2 +- .../v6/request/PayPalExpressPDPRequest.java | 10 +- .../PayPalExpressSubmitPDPRequest.java | 26 +++ .../tags/responsive/expressCheckoutConfig.tag | 9 +- ...yenaccexpresscheckoutcartpagecomponent.jsp | 4 + ...accexpresscheckoutproductpagecomponent.jsp | 2 + .../common/js/adyen_express_checkout.js | 182 +++++++++++++-- adyenv6core/resources/adyenv6core-spring.xml | 21 ++ .../adyen/v6/facades/AdyenCheckoutFacade.java | 18 +- .../AdyenPayPalExpressCheckoutFacade.java | 23 ++ .../impl/DefaultAdyenCheckoutFacade.java | 89 +++----- .../DefaultAdyenExpressCheckoutFacade.java | 172 ++++++-------- ...faultAdyenPayPalExpressCheckoutFacade.java | 216 ++++++++++++++++++ .../adyen/v6/factory/AdyenRequestFactory.java | 34 +-- .../response/PayPalExpressSubmitResponse.java | 26 +++ .../v6/service/AdyenCheckoutApiService.java | 12 +- .../DefaultAdyenCheckoutApiService.java | 42 ++-- ...DefaultAdyenExpressCheckoutFacadeTest.java | 4 +- 22 files changed, 750 insertions(+), 265 deletions(-) create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenExpressCheckoutControllerBase.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressSubmitPDPRequest.java create mode 100644 adyenv6core/src/com/adyen/v6/facades/AdyenPayPalExpressCheckoutFacade.java create mode 100644 adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java create mode 100644 adyenv6core/src/com/adyen/v6/response/PayPalExpressSubmitResponse.java diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenExpressCheckoutControllerBase.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenExpressCheckoutControllerBase.java new file mode 100644 index 00000000..6d25f9f5 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenExpressCheckoutControllerBase.java @@ -0,0 +1,28 @@ +package com.adyen.v6.controllers.checkout; + +import com.adyen.model.checkout.GooglePayDetails; +import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService; +import de.hybris.platform.basecommerce.model.site.BaseSiteModel; +import de.hybris.platform.site.BaseSiteService; + +import static com.adyen.v6.constants.AdyenControllerConstants.CHECKOUT_RESULT_URL; +import static com.adyen.v6.constants.AdyenControllerConstants.SUMMARY_CHECKOUT_PREFIX; + +public abstract class AdyenExpressCheckoutControllerBase { + + protected String getReturnUrl(String paymentMethod) { + String url; + if (GooglePayDetails.TypeEnum.GOOGLEPAY.getValue().equals(paymentMethod)) { + //Google Pay will only use returnUrl if redirected to 3DS authentication + url = SUMMARY_CHECKOUT_PREFIX + "/authorise-3d-adyen-response"; + } else { + url = SUMMARY_CHECKOUT_PREFIX + CHECKOUT_RESULT_URL; + } + BaseSiteModel currentBaseSite = getBaseSiteService().getCurrentBaseSite(); + return getSiteBaseUrlResolutionService().getWebsiteUrlForSite(currentBaseSite, true, url); + } + + abstract public BaseSiteService getBaseSiteService(); + + abstract public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService(); +} 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 index 96d990c1..996f1200 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenGooglePayExpressCheckoutController.java @@ -22,7 +22,7 @@ @Controller @RequestMapping("/express-checkout/google/") public class AdyenGooglePayExpressCheckoutController { - private static final Logger LOG = Logger.getLogger(AdyenApplePayExpressCheckoutController.class); + private static final Logger LOG = Logger.getLogger(AdyenGooglePayExpressCheckoutController.class); @Autowired private AdyenExpressCheckoutFacade adyenExpressCheckoutFacade; diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java index 7ccf9d73..5c3e3994 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java @@ -4,11 +4,16 @@ import com.adyen.model.checkout.PayPalDetails; import com.adyen.model.checkout.PaymentRequest; import com.adyen.model.checkout.PaymentResponse; +import com.adyen.service.exception.ApiException; import com.adyen.v6.constants.Adyenv6coreConstants; -import com.adyen.v6.facades.AdyenExpressCheckoutFacade; +import com.adyen.v6.facades.AdyenPayPalExpressCheckoutFacade; import com.adyen.v6.request.PayPalExpressCartRequest; import com.adyen.v6.request.PayPalExpressPDPRequest; +import com.adyen.v6.request.PayPalExpressSubmitPDPRequest; +import com.adyen.v6.response.PayPalExpressSubmitResponse; +import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService; import de.hybris.platform.acceleratorstorefrontcommons.security.GUIDCookieStrategy; +import de.hybris.platform.site.BaseSiteService; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -21,46 +26,94 @@ @Controller @RequestMapping("/express-checkout/paypal/") -public class AdyenPayPalExpressCheckoutController { +public class AdyenPayPalExpressCheckoutController extends AdyenExpressCheckoutControllerBase { private static final Logger LOG = Logger.getLogger(AdyenApplePayExpressCheckoutController.class); @Autowired - private AdyenExpressCheckoutFacade adyenExpressCheckoutFacade; + private AdyenPayPalExpressCheckoutFacade adyenPayPalExpressCheckoutFacade; @Autowired private GUIDCookieStrategy guidCookieStrategy; + @Autowired + private SiteBaseUrlResolutionService siteBaseUrlResolutionService; + + @Autowired + private BaseSiteService baseSiteService; + + @PostMapping("submit/PDP") + public ResponseEntity onSubmitPDP(final HttpServletRequest request, final HttpServletResponse response, @RequestBody PayPalExpressSubmitPDPRequest payPalSubmitRequest) throws Exception { + PayPalDetails payPalDetails = payPalSubmitRequest.getPayPalDetails(); + PaymentRequest paymentRequest = new PaymentRequest(); + payPalDetails.setType(PayPalDetails.TypeEnum.PAYPAL); + payPalDetails.setSubtype(PayPalDetails.SubtypeEnum.EXPRESS); + + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(payPalDetails)); + paymentRequest.setReturnUrl(getReturnUrl(PayPalDetails.TypeEnum.PAYPAL.getValue())); + + try { + PayPalExpressSubmitResponse paymentResponse = adyenPayPalExpressCheckoutFacade.onPayPalPDPSubmit(paymentRequest, payPalSubmitRequest.getProductCode()); + return new ResponseEntity<>(paymentResponse, HttpStatus.OK); + + } catch (ApiException e){ + LOG.error(e.getError()); + LOG.error(e.getMessage()); + + return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + } + + @PostMapping("submit/cart") + public ResponseEntity onSubmitCart(final HttpServletRequest request, final HttpServletResponse response, @RequestBody PayPalDetails payPalDetails) throws Exception { + PaymentRequest paymentRequest = new PaymentRequest(); + payPalDetails.setType(PayPalDetails.TypeEnum.PAYPAL); + payPalDetails.setSubtype(PayPalDetails.SubtypeEnum.EXPRESS); + + paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(payPalDetails)); + paymentRequest.setReturnUrl(getReturnUrl(PayPalDetails.TypeEnum.PAYPAL.getValue())); + + try { + PaymentResponse paymentResponse = adyenPayPalExpressCheckoutFacade.onPayPalCartSubmit(paymentRequest); + return new ResponseEntity<>(paymentResponse, HttpStatus.OK); + + } catch (ApiException e){ + LOG.error(e.getError()); + LOG.error(e.getMessage()); + + return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + } + @PostMapping("PDP") public ResponseEntity payPalExpressPDP(final HttpServletRequest request, final HttpServletResponse response, @RequestBody PayPalExpressPDPRequest paypalExpressPDPRequest) throws Exception { - PaymentRequest paymentRequest = getPaymentRequest(paypalExpressPDPRequest); - - PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressCheckoutPDP(paypalExpressPDPRequest.getProductCode(), - paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_PAYPAL, paypalExpressPDPRequest.getAddressData(), request); + adyenPayPalExpressCheckoutFacade.onPayPalAuthorizedPDP(paypalExpressPDPRequest.getCartGuid(), + paypalExpressPDPRequest.getAddressData(), Adyenv6coreConstants.PAYMENT_METHOD_PAYPAL); guidCookieStrategy.setCookie(request, response); - return new ResponseEntity<>(paymentsResponse, HttpStatus.OK); + return ResponseEntity.ok().build(); } @PostMapping("cart") public ResponseEntity paypalCartExpressCheckout(final HttpServletRequest request, final HttpServletResponse response, @RequestBody PayPalExpressCartRequest paypalExpressCartRequest) throws Exception { - PaymentRequest paymentRequest = getPaymentRequest(paypalExpressCartRequest); - - PaymentResponse paymentsResponse = adyenExpressCheckoutFacade.expressCheckoutCart(paymentRequest, Adyenv6coreConstants.PAYMENT_METHOD_PAYPAL, - paypalExpressCartRequest.getAddressData(), request); + adyenPayPalExpressCheckoutFacade.onPayPalAuthorizedCart(paypalExpressCartRequest.getAddressData(), Adyenv6coreConstants.PAYMENT_METHOD_PAYPAL); guidCookieStrategy.setCookie(request, response); - return new ResponseEntity<>(paymentsResponse, HttpStatus.OK); + return ResponseEntity.ok().build(); } - private static PaymentRequest getPaymentRequest(T request) { + private PaymentRequest getPaymentRequest(T request) { PaymentRequest paymentRequest = new PaymentRequest(); PayPalDetails paypalDetails = request.getPayPalDetails(); paypalDetails.setType(PayPalDetails.TypeEnum.PAYPAL); + paypalDetails.setSubtype(PayPalDetails.SubtypeEnum.EXPRESS); paymentRequest.setPaymentMethod(new CheckoutPaymentMethod(paypalDetails)); + paymentRequest.setReturnUrl(getReturnUrl(PayPalDetails.TypeEnum.PAYPAL.getValue())); return paymentRequest; } @@ -69,4 +122,14 @@ private static PaymentRequest getPaymentReq public void adyenComponentExceptionHandler(Exception e) { LOG.error("Exception during PaypalExpress processing", e); } + + @Override + public BaseSiteService getBaseSiteService() { + return baseSiteService; + } + + @Override + public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService() { + return siteBaseUrlResolutionService; + } } diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java index 678a7cae..c86e1778 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java @@ -27,7 +27,7 @@ public class AdyenAccCartExpressCheckoutComponentController extends AbstractCMSA protected void fillModel(final HttpServletRequest request, final Model model, final AdyenAccExpressCheckoutCartPageComponentModel component) { try { adyenExpressCheckoutFacade.removeDeliveryModeFromSessionCart(); - adyenCheckoutFacade.initializeApplePayExpressCartPageData(model); + adyenCheckoutFacade.initializeExpressCartPageData(model); } catch (ApiException | CalculationException e) { throw new RuntimeException(e); } diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java index 528ae66a..4912e74a 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java @@ -33,7 +33,7 @@ protected void fillModel(final HttpServletRequest request, final Model model, fi requestContextData.getProduct(); final ProductData productData = productFacade.getProductForCodeAndOptions(requestContextData.getProduct().getCode(), Arrays.asList(ProductOption.BASIC, ProductOption.PRICE)); - adyenCheckoutFacade.initializeApplePayExpressPDPData(model, productData); + adyenCheckoutFacade.initializeExpressPDPData(model, productData); } catch (ApiException e) { throw new RuntimeException(e); } diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressPDPRequest.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressPDPRequest.java index a55dc490..21d76bbc 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressPDPRequest.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressPDPRequest.java @@ -1,13 +1,13 @@ package com.adyen.v6.request; public class PayPalExpressPDPRequest extends PayPalExpressCartRequest { - private String productCode; + private String cartGuid; - public String getProductCode() { - return productCode; + public String getCartGuid() { + return cartGuid; } - public void setProductCode(String productCode) { - this.productCode = productCode; + public void setCartGuid(String cartGuid) { + this.cartGuid = cartGuid; } } diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressSubmitPDPRequest.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressSubmitPDPRequest.java new file mode 100644 index 00000000..d847c20f --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/request/PayPalExpressSubmitPDPRequest.java @@ -0,0 +1,26 @@ +package com.adyen.v6.request; + +import com.adyen.model.checkout.PayPalDetails; + +import java.io.Serializable; + +public class PayPalExpressSubmitPDPRequest implements Serializable { + private PayPalDetails payPalDetails; + private String productCode; + + public PayPalDetails getPayPalDetails() { + return payPalDetails; + } + + public void setPayPalDetails(PayPalDetails payPalDetails) { + this.payPalDetails = payPalDetails; + } + + public String getProductCode() { + return productCode; + } + + public void setProductCode(String productCode) { + this.productCode = productCode; + } +} \ No newline at end of file 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 77c19013..4f983a84 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag @@ -21,18 +21,15 @@ merchantAccount: '${merchantAccount}', label: ['visible-xs', 'hidden-xs'], pageType: '${pageType}', - productCode: '${product.code}' + productCode: '${product.code}', + payPalIntent: '${paypalIntent}' } var checkoutConfig = { shopperLocale: '${shopperLocale}', environment: '${environmentMode}', clientKey: '${clientKey}', - session: { - id: '${sessionData.id}', - sessionData: '${sessionData.sessionData}' - }, - countryCode: 'US' + countryCode: 'US', } window.onload = function() { diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp index 58f65d5e..9d2207e2 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp @@ -14,5 +14,9 @@
+
+
+
+
\ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp index 7785092d..a577d9e7 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp @@ -7,4 +7,6 @@
+
+
\ No newline at end of file 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 ef74c703..caf96e4e 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 @@ -12,7 +12,8 @@ var AdyenExpressCheckoutHybris = (function () { adyenConfig: { pageType: null, - productCode: null + productCode: null, + expressCartGuid: null }, initiateCheckout: async function (initConfig) { @@ -25,7 +26,7 @@ var AdyenExpressCheckoutHybris = (function () { enabled: false }, onError: (error, component) => { - console.error("Checkout error occured"); + console.error("Checkout error occurred"); }, }; return await AdyenWeb.AdyenCheckout(configuration); @@ -33,23 +34,21 @@ var AdyenExpressCheckoutHybris = (function () { initExpressCheckout: async function (params, config) { var checkoutPromise = this.initiateCheckout(config); checkoutPromise.then((checkout) => { + this.adyenConfig.pageType = params.pageType; + this.adyenConfig.productCode = params.productCode; + this.initiateGooglePayExpress(checkout, params) this.initiateApplePayExpress(checkout, params) + this.initiatePayPalExpress(checkout, params) }); }, initiateApplePayExpress: async function (checkout, params) { const { amount, - pageType, - productCode } = params; const applePayNodes = document.getElementsByClassName('adyen-apple-pay-button'); - this.adyenConfig.pageType = pageType; - this.adyenConfig.productCode = productCode; - - for (let applePayNode of applePayNodes) { let applePayComponent = new AdyenWeb.ApplePay(checkout, { amount: { @@ -96,13 +95,8 @@ var AdyenExpressCheckoutHybris = (function () { amount, amountDecimal, countryCode, - pageType, - productCode } = params; - this.adyenConfig.pageType = pageType; - this.adyenConfig.productCode = productCode; - const googlePayNodes = document.getElementsByClassName('adyen-google-pay-button'); const googlePayConfig = { @@ -208,7 +202,115 @@ var AdyenExpressCheckoutHybris = (function () { }); } }, - makePayment: function(data, url, resolve = ()=>{}, reject = ()=>{}) { + initiatePayPalExpress: function (checkout, params) { + const { + amount, + payPalIntent + } = params; + + const payPalNodes = document.getElementsByClassName('adyen-paypal-button'); + + let payPalComponent; + + const payPalConfig = { + amount: { + currency: amount.currency, + value: amount.value + }, + + isExpress: true, + blockPayPalVenmoButton: true, + blockPayPalCreditButton: true, + blockPayPalPayLaterButton: true, + + intent: payPalIntent, + + onSubmit: (state, component, actions) => { + if (this.adyenConfig.pageType === "PDP") { + this.onPayPalPDPSubmit(state.data, actions.resolve, actions.reject, component); + } + + if (this.adyenConfig.pageType === "cart") { + this.onPayPalCartSubmit(state.data, actions.resolve, actions.reject, component) + } + }, + onAuthorized: (paymentData, actions) => { + this.onPayPalAuthorize(this.getPayPalUrl(), this.prepareDataPayPal(paymentData), actions.resolve, actions.reject) + }, + onAdditionalDetails: (state) => { + this.makePayment(state.data, this.getAdditionalDataUrl()) + } + } + + if (payPalNodes.length > 0) { + payPalComponent = new AdyenWeb.PayPal(checkout, payPalConfig); + payPalComponent.isAvailable() + .then(function () { + payPalComponent.mount(payPalNodes[0]); + }) + .catch(function (e) { + // PayPal is not available + console.log('Something went wrong trying to mount the PayPal component'); + }); + + if (payPalNodes.length > 1) { + console.warn("More than one PayPal placeholder") + } + } + }, + onPayPalCartSubmit: function (data, resolve, reject, component) { + $.ajax({ + url: ACC.config.encodedContextPath + '/express-checkout/paypal/submit/cart', + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + success: function (response) { + console.log(response) + if (response.action) { + component.handleAction(response.action) + } + }, + error: function () { + reject(); + } + }) + }, + onPayPalPDPSubmit: function (data, resolve, reject, component) { + $.ajax({ + url: ACC.config.encodedContextPath + '/express-checkout/paypal/submit/PDP', + type: "POST", + data: JSON.stringify({ + payPalDetails: data, + productCode: this.adyenConfig.productCode + }), + contentType: "application/json; charset=utf-8", + success: function (response) { + console.log(response) + AdyenExpressCheckoutHybris.adyenConfig.expressCartGuid = response.expressCartGuid; + if (response.paymentResponse.action) { + component.handleAction(response.paymentResponse.action) + } + }, + error: function () { + reject(); + } + }) + }, + onPayPalAuthorize: function (url, data, resolve, reject) { + $.ajax({ + url: url, + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + success: function () { + resolve(); + }, + error: function () { + reject(); + } + }) + }, + makePayment: function (data, url, resolve = () => {}, reject = () => {}) { $.ajax({ url: url, type: "POST", @@ -287,7 +389,7 @@ var AdyenExpressCheckoutHybris = (function () { console.error('unknown page type') return {}; }, - prepareDataGoogle: function(paymentData) { + prepareDataGoogle: function (paymentData) { let baseData = { googlePayDetails: { googlePayToken: paymentData.authorizedEvent.paymentMethodData.tokenizationData.token, @@ -322,6 +424,46 @@ var AdyenExpressCheckoutHybris = (function () { console.error('unknown page type') return {}; }, + prepareDataPayPal: function (paymentData) { + console.log(JSON.stringify(paymentData)) + + let baseData = { + payPalDetails: { + orderID: paymentData.authorizedEvent.id, + payerID: paymentData.authorizedEvent.payer.payer_id + }, + addressData: { + email: paymentData.authorizedEvent.payer.email_address, + firstName: paymentData.authorizedEvent.payer.name.given_name, + lastName: paymentData.authorizedEvent.payer.name.surname, + line1: paymentData.deliveryAddress.street, + line2: paymentData.deliveryAddress.houseNumberOrName, + postalCode: paymentData.deliveryAddress.postalCode, + town: paymentData.deliveryAddress.city, + country: { + isocode: paymentData.deliveryAddress.country, + }, + region: { + isocodeShort: paymentData.deliveryAddress.stateOrProvince + } + } + } + + if (this.adyenConfig.pageType === 'PDP') { + return { + cartGuid: this.adyenConfig.expressCartGuid, + ...baseData + } + } + if (this.adyenConfig.pageType === 'cart') { + return baseData; + } + console.error('unknown page type') + return {}; + }, + getAdditionalDataUrl: function () { + return ACC.config.encodedContextPath + '/adyen/component/submit-details' + }, getAppleUrl: function () { if (this.adyenConfig.pageType === 'PDP') { return ACC.config.encodedContextPath + '/express-checkout/apple/PDP' @@ -341,6 +483,16 @@ var AdyenExpressCheckoutHybris = (function () { } console.error('unknown page type') return null; + }, + getPayPalUrl: function () { + if (this.adyenConfig.pageType === 'PDP') { + return ACC.config.encodedContextPath + '/express-checkout/paypal/PDP' + } + if (this.adyenConfig.pageType === 'cart') { + return ACC.config.encodedContextPath + '/express-checkout/paypal/cart' + } + console.error('unknown page type') + return null; } } })(); \ No newline at end of file diff --git a/adyenv6core/resources/adyenv6core-spring.xml b/adyenv6core/resources/adyenv6core-spring.xml index 450acd16..93563063 100644 --- a/adyenv6core/resources/adyenv6core-spring.xml +++ b/adyenv6core/resources/adyenv6core-spring.xml @@ -437,6 +437,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/adyenv6core/src/com/adyen/v6/facades/AdyenCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/AdyenCheckoutFacade.java index 2d543e4f..1e0bb5bb 100644 --- a/adyenv6core/src/com/adyen/v6/facades/AdyenCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/AdyenCheckoutFacade.java @@ -20,27 +20,21 @@ */ package com.adyen.v6.facades; -import com.adyen.model.checkout.CheckoutPaymentMethod; -import com.adyen.model.checkout.PaymentCompletionDetails; -import com.adyen.model.checkout.PaymentDetailsRequest; -import com.adyen.model.checkout.PaymentDetailsResponse; -import com.adyen.model.checkout.PaymentRequest; -import com.adyen.model.checkout.PaymentResponse; +import com.adyen.model.checkout.*; import com.adyen.service.exception.ApiException; import com.adyen.v6.controllers.dtos.PaymentResultDTO; import com.adyen.v6.dto.CheckoutConfigDTO; import com.adyen.v6.forms.AdyenPaymentForm; +import com.adyen.v6.service.AdyenCheckoutApiService; import de.hybris.platform.commercefacades.order.data.CartData; import de.hybris.platform.commercefacades.order.data.OrderData; import de.hybris.platform.commercefacades.product.data.ProductData; -import de.hybris.platform.commercefacades.user.data.AddressData; import de.hybris.platform.commercewebservicescommons.dto.order.PaymentDetailsWsDTO; import de.hybris.platform.core.model.order.CartModel; import de.hybris.platform.core.model.order.payment.PaymentInfoModel; import de.hybris.platform.order.InvalidCartException; import de.hybris.platform.order.exceptions.CalculationException; import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; import org.springframework.validation.Errors; import javax.servlet.http.HttpServletRequest; @@ -149,9 +143,9 @@ public interface AdyenCheckoutFacade { void initializeSummaryData(Model model) throws ApiException; - void initializeApplePayExpressCartPageData(Model model) throws ApiException; + void initializeExpressCartPageData(Model model) throws ApiException; - void initializeApplePayExpressPDPData(Model model, ProductData productData) throws ApiException; + void initializeExpressPDPData(Model model, ProductData productData) throws ApiException; /** * Returns whether Boleto should be shown as an available payment method on the checkout page @@ -218,4 +212,8 @@ public interface AdyenCheckoutFacade { CheckoutConfigDTO getCheckoutConfig() throws ApiException; CheckoutConfigDTO getReactCheckoutConfig() throws ApiException; + + AdyenCheckoutApiService getAdyenPaymentService(); + + OrderData placePendingOrder() throws InvalidCartException; } \ No newline at end of file diff --git a/adyenv6core/src/com/adyen/v6/facades/AdyenPayPalExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/AdyenPayPalExpressCheckoutFacade.java new file mode 100644 index 00000000..86490fa6 --- /dev/null +++ b/adyenv6core/src/com/adyen/v6/facades/AdyenPayPalExpressCheckoutFacade.java @@ -0,0 +1,23 @@ +package com.adyen.v6.facades; + +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.model.checkout.PaymentResponse; +import com.adyen.service.exception.ApiException; +import com.adyen.v6.response.PayPalExpressSubmitResponse; +import de.hybris.platform.commercefacades.user.data.AddressData; +import de.hybris.platform.commerceservices.customer.DuplicateUidException; +import de.hybris.platform.order.InvalidCartException; +import de.hybris.platform.order.exceptions.CalculationException; + +import java.io.IOException; + +public interface AdyenPayPalExpressCheckoutFacade { + PayPalExpressSubmitResponse onPayPalPDPSubmit(PaymentRequest paymentRequest, String productCode) throws IOException, ApiException; + + PaymentResponse onPayPalCartSubmit(PaymentRequest paymentRequest) throws IOException, ApiException; + + void onPayPalAuthorizedPDP(String cartGuid, AddressData addressData, String paymentMethod) throws DuplicateUidException, InvalidCartException, CalculationException; + + void onPayPalAuthorizedCart(AddressData addressData, String paymentMethod) throws DuplicateUidException, InvalidCartException, CalculationException; + +} diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java index a051ff15..822ec7f0 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java @@ -22,17 +22,7 @@ import com.adyen.commerce.data.PaymentMethodsCartData; -import com.adyen.model.checkout.Amount; -import com.adyen.model.checkout.CreateCheckoutSessionResponse; -import com.adyen.model.checkout.PaymentCompletionDetails; -import com.adyen.model.checkout.PaymentDetailsRequest; -import com.adyen.model.checkout.PaymentDetailsResponse; -import com.adyen.model.checkout.PaymentMethod; -import com.adyen.model.checkout.PaymentMethodsResponse; -import com.adyen.model.checkout.PaymentRequest; -import com.adyen.model.checkout.PaymentResponse; -import com.adyen.model.checkout.PaymentResponseAction; -import com.adyen.model.checkout.StoredPaymentMethod; +import com.adyen.model.checkout.*; import com.adyen.model.nexo.ErrorConditionType; import com.adyen.model.nexo.ResultType; import com.adyen.model.recurring.Recurring; @@ -121,21 +111,7 @@ import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_CHALLENGE_TOKEN; import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_FINGERPRINT_TOKEN; -import static com.adyen.v6.constants.Adyenv6coreConstants.ISSUER_PAYMENT_METHODS; -import static com.adyen.v6.constants.Adyenv6coreConstants.OPENINVOICE_METHODS_ALLOW_SOCIAL_SECURITY_NUMBER; -import static com.adyen.v6.constants.Adyenv6coreConstants.OPENINVOICE_METHODS_API; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYBRIGHT; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHODS_ALLOW_SOCIAL_SECURITY_NUMBER; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_AMAZONPAY; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_APPLEPAY; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_BOLETO; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_KLARNA; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_ONLINEBANKING_IN; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_ONLINEBANKING_PL; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_SCHEME; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_SEPA_DIRECTDEBIT; -import static com.adyen.v6.constants.Adyenv6coreConstants.SHOPPER_LOCALE; +import static com.adyen.v6.constants.Adyenv6coreConstants.*; import static de.hybris.platform.order.impl.DefaultCartService.SESSION_CART_PARAMETER_NAME; /** @@ -222,9 +198,10 @@ public class DefaultAdyenCheckoutFacade implements AdyenCheckoutFacade { public static final String MODEL_CONNECTED_TERMINAL_LIST = "connectedTerminalList"; public static final String MODEL_ENVIRONMENT_MODE = "environmentMode"; public static final String MODEL_AMOUNT = "amount"; - public static final String MODEL_AMOUNT_DECIMAL= "amountDecimal"; + public static final String MODEL_AMOUNT_DECIMAL = "amountDecimal"; public static final String MODEL_IMMEDIATE_CAPTURE = "immediateCapture"; public static final String MODEL_PAYPAL_MERCHANT_ID = "paypalMerchantId"; + public static final String MODEL_PAYPAL_INTENT = "paypalIntent"; public static final String MODEL_COUNTRY_CODE = "countryCode"; public static final String MODEL_APPLEPAY_MERCHANT_IDENTIFIER = "applePayMerchantIdentifier"; public static final String MODEL_APPLEPAY_MERCHANT_NAME = "applePayMerchantName"; @@ -548,6 +525,10 @@ public OrderData handle3DSResponse(PaymentDetailsRequest paymentsDetailsRequest) throw new AdyenNonAuthorizedPaymentException(paymentsDetailsResponse); } + public OrderData placePendingOrder() throws InvalidCartException { + return placePendingOrder(PaymentDetailsResponse.ResultCodeEnum.PENDING.getValue()); + } + /** * Create order and authorized TX */ @@ -974,15 +955,23 @@ protected PaymentMethodsResponse getPaymentMethods(AdyenCheckoutApiService adyen protected Map getApplePayConfigFromPaymentMethods(List paymentMethods) { + return getPaymentMethodConfigFromPaymentMethods(paymentMethods, PAYMENT_METHOD_APPLEPAY); + } + + protected Map getPayPalConfigFromPaymentMethods(List paymentMethods) { + return getPaymentMethodConfigFromPaymentMethods(paymentMethods, PAYMENT_METHOD_PAYPAL); + } + + protected Map getPaymentMethodConfigFromPaymentMethods(List paymentMethods, String paymentMethodName) { if (paymentMethods != null) { - Optional applePayMethod = paymentMethods.stream() - .filter(paymentMethod -> !paymentMethod.getType().isEmpty() - && PAYMENT_METHOD_APPLEPAY.contains(paymentMethod.getType())) + Optional paymentMethod = paymentMethods.stream() + .filter(pm -> !pm.getType().isEmpty() + && paymentMethodName.contains(pm.getType())) .findFirst(); - if (applePayMethod.isPresent()) { - Map applePayConfiguration = applePayMethod.get().getConfiguration(); - if (!CollectionUtils.isEmpty(applePayConfiguration)) { - return applePayConfiguration; + if (paymentMethod.isPresent()) { + Map paymentMethodConfiguration = paymentMethod.get().getConfiguration(); + if (!CollectionUtils.isEmpty(paymentMethodConfiguration)) { + return paymentMethodConfiguration; } } } @@ -1003,18 +992,6 @@ protected CreateCheckoutSessionResponse getAdyenSessionData() throws ApiExceptio } } - protected CreateCheckoutSessionResponse getAdyenSessionData(Amount amount) throws ApiException { - try { - return getAdyenPaymentService().getPaymentSessionData(amount); - } catch (JsonProcessingException e) { - LOGGER.error("Processing json failed. ", e); - return null; - } catch (IOException e) { - LOGGER.error("Exception during geting Adyen session data. ", e); - return null; - } - } - @Override public void initializeSummaryData(Model model) throws ApiException { final CartData cartData = getCheckoutFacade().getCheckoutCart(); @@ -1049,7 +1026,7 @@ public void initializeSummaryData(Model model) throws ApiException { model.addAttribute(LOCALE, gson.toJson(setLocale(cartData.getAdyenAmazonPayConfiguration(), shopperLocale))); } - public void initializeApplePayExpressCartPageData(Model model) throws ApiException { + public void initializeExpressCartPageData(Model model) throws ApiException { final CartData cartData = getCheckoutFacade().getCheckoutCart(); if (cartData != null && cartData.getTotalPriceWithTax() != null && cartData.getTotalPriceWithTax().getCurrencyIso() != null) { final String currencyIso = cartData.getTotalPriceWithTax().getCurrencyIso(); @@ -1057,21 +1034,21 @@ public void initializeApplePayExpressCartPageData(Model model) throws ApiExcepti BigDecimal expressDeliveryModeValue = getExpressDeliveryModeValue(currencyIso); amountValue = amountValue.add(expressDeliveryModeValue); - initializeApplePayExpressDataInternal(amountValue, currencyIso, model); + initializeExpressDataInternal(amountValue, currencyIso, model); } } - public void initializeApplePayExpressPDPData(Model model, ProductData productData) throws ApiException { + public void initializeExpressPDPData(Model model, ProductData productData) throws ApiException { final String currencyIso = productData.getPrice().getCurrencyIso(); BigDecimal amountValue = productData.getPrice().getValue(); BigDecimal expressDeliveryModeValue = getExpressDeliveryModeValue(currencyIso); - amountValue = amountValue.add(expressDeliveryModeValue); + BigDecimal totalAmount = amountValue.add(expressDeliveryModeValue); - initializeApplePayExpressDataInternal(amountValue, currencyIso, model); + initializeExpressDataInternal(totalAmount, currencyIso, model); } - protected void initializeApplePayExpressDataInternal(BigDecimal amountValue, String currency, Model model) throws ApiException { + protected void initializeExpressDataInternal(BigDecimal amountValue, String currency, Model model) throws ApiException { final BaseStoreModel baseStore = baseStoreService.getCurrentBaseStore(); try { @@ -1089,6 +1066,13 @@ protected void initializeApplePayExpressDataInternal(BigDecimal amountValue, Str LOGGER.warn("Empty apple pay config"); } + Map payPalConfig = getPayPalConfigFromPaymentMethods(paymentMethodsResponse.getPaymentMethods()); + if (!CollectionUtils.isEmpty(payPalConfig)) { + model.addAttribute(MODEL_PAYPAL_INTENT, payPalConfig.get("intent")); + } else { + LOGGER.warn("Empty PayPal config"); + } + } catch (IOException e) { LOGGER.error("Payment methods request failed", e); } @@ -1099,7 +1083,6 @@ protected void initializeApplePayExpressDataInternal(BigDecimal amountValue, Str model.addAttribute(MODEL_ENVIRONMENT_MODE, getEnvironmentMode()); model.addAttribute(MODEL_CLIENT_KEY, baseStore.getAdyenClientKey()); model.addAttribute(MODEL_MERCHANT_ACCOUNT, adyenMerchantAccountStrategy.getWebMerchantAccount()); - model.addAttribute(SESSION_DATA, getAdyenSessionData(amount)); model.addAttribute(MODEL_AMOUNT, amount); model.addAttribute(MODEL_AMOUNT_DECIMAL, amountValue); model.addAttribute(MODEL_DF_URL, getAdyenPaymentService().getDeviceFingerprintUrl()); diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java index 3c47bbd3..4055b98a 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java @@ -53,30 +53,31 @@ public class DefaultAdyenExpressCheckoutFacade implements AdyenExpressCheckoutFacade { private static final Logger LOG = Logger.getLogger(DefaultAdyenExpressCheckoutFacade.class); protected static final String USER_NAME = "ExpressCheckoutGuest"; - private static final String DELIVERY_MODE_CODE = "adyen-express-checkout"; + protected static final String DELIVERY_MODE_CODE = "adyen-express-checkout"; protected static final String ANONYMOUS_CHECKOUT_GUID = "anonymous_checkout_guid"; protected static final String ANONYMOUS_CHECKOUT = "anonymous_checkout"; - private CartFactory cartFactory; - private CartService cartService; - private ProductService productService; - private ModelService modelService; - private CustomerFacade customerFacade; - private CommonI18NService commonI18NService; - private I18NFacade i18NFacade; - private CustomerAccountService customerAccountService; - private CommerceCartService commerceCartService; - private DeliveryModeService deliveryModeService; - private AdyenCheckoutFacade adyenCheckoutFacade; - private SessionService sessionService; - private UserService userService; - private AdyenCheckoutApiFacade adyenCheckoutApiFacade; - private Converter addressReverseConverter; - private Converter cartConverter; + protected CartFactory cartFactory; + protected CartService cartService; + protected ProductService productService; + protected ModelService modelService; + protected CustomerFacade customerFacade; + protected CommonI18NService commonI18NService; + protected I18NFacade i18NFacade; + protected CustomerAccountService customerAccountService; + protected CommerceCartService commerceCartService; + protected DeliveryModeService deliveryModeService; + protected AdyenCheckoutFacade adyenCheckoutFacade; + protected SessionService sessionService; + protected UserService userService; + protected AdyenCheckoutApiFacade adyenCheckoutApiFacade; + protected Converter addressReverseConverter; + protected 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"); + validateAddress(addressData); PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); paymentInfoModel.setAdyenPaymentMethod(paymentMethod); @@ -89,6 +90,7 @@ public PaymentResponse expressCheckoutPDP(String productCode, PaymentRequest pay public OrderData expressCheckoutPDPOCC(String productCode, PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, HttpServletRequest request) throws Exception { Assert.notNull(paymentMethod, "Payment method must not be null"); + validateAddress(addressData); PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); paymentInfoModel.setAdyenPaymentMethod(paymentMethod); @@ -102,6 +104,7 @@ public OrderData expressCheckoutPDPOCC(String productCode, PaymentRequest paymen public PaymentResponse expressCheckoutCart(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, HttpServletRequest request) throws Exception { Assert.notNull(paymentMethod, "Payment method must not be null"); + validateAddress(addressData); PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); paymentInfoModel.setAdyenPaymentMethod(paymentMethod); @@ -114,6 +117,7 @@ public PaymentResponse expressCheckoutCart(PaymentRequest paymentRequest, String public OrderData expressCheckoutCartOCC(PaymentRequest paymentRequest, String paymentMethod, AddressData addressData, HttpServletRequest request) throws Exception { Assert.notNull(paymentMethod, "Payment method must not be null"); + validateAddress(addressData); PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); paymentInfoModel.setAdyenPaymentMethod(paymentMethod); @@ -125,10 +129,6 @@ public OrderData expressCheckoutCartOCC(PaymentRequest paymentRequest, String pa 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(); boolean isGuestUser = false; if (userService.isAnonymousUser(user)) { @@ -136,22 +136,10 @@ protected PaymentResponse expressPDPCheckout(PaymentRequest paymentRequest, Addr isGuestUser = true; } - 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); + CartModel cart = prepareCartForPDPExpressCheckout(addressData, paymentInfoModel, productCode, user); if (cartHasEntries(cart)) { - CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); - commerceCartParameter.setCart(cart); - commerceCartService.calculateCart(commerceCartParameter); + recalculateCart(cart); CartModel sessionCart = null; if (cartService.hasSessionCart()) { @@ -181,31 +169,15 @@ protected PaymentResponse expressPDPCheckout(PaymentRequest paymentRequest, Addr 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); + CartModel cart = prepareCartForPDPExpressCheckout(addressData, paymentInfoModel, productCode, user); if (cartHasEntries(cart)) { - CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); - commerceCartParameter.setCart(cart); - commerceCartService.calculateCart(commerceCartParameter); + recalculateCart(cart); CartModel sessionCart = null; if (cartService.hasSessionCart()) { @@ -238,19 +210,7 @@ protected PaymentResponse expressCartCheckout(PaymentRequest paymentRequest, Add isGuestUser = true; } - 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); + CartModel cart = prepareCartForCartExpressCheckout(addressData, paymentInfoModel, user); if (cartHasEntries(cart)) { CartData cartData = cartConverter.convert(cart); @@ -276,19 +236,7 @@ protected OrderData expressCartCheckoutOCC(PaymentRequest paymentRequest, Addres 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); + CartModel cart = prepareCartForCartExpressCheckout(addressData, paymentInfoModel, user); if (cartHasEntries(cart)) { CartData cartData = cartConverter.convert(cart); @@ -311,7 +259,52 @@ public void removeDeliveryModeFromSessionCart() throws CalculationException { } } - protected void prepareCart(CartModel cart, DeliveryModeModel deliveryMode, AddressModel addressModel, PaymentInfoModel paymentInfo) { + protected void validateAddress(AddressData addressData) { + validateParameterNotNull(addressData, "Empty address"); + if (StringUtils.isEmpty(addressData.getEmail())) { + throw new IllegalArgumentException("Empty email address"); + } + } + + protected CartModel prepareCartForCartExpressCheckout(AddressData addressData, PaymentInfoModel paymentInfoModel, CustomerModel user) throws CalculationException { + 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); + + updateCart(cart, deliveryMode, addressModel, paymentInfoModel); + + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.recalculateCart(commerceCartParameter); + return cart; + } + + protected CartModel prepareCartForPDPExpressCheckout(AddressData addressData, PaymentInfoModel paymentInfoModel, String productCode, CustomerModel user) { + 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); + + updateCart(cart, deliveryMode, addressModel, paymentInfoModel); + + addProductToCart(productCode, cart); + return cart; + } + + protected void recalculateCart(CartModel cart) { + CommerceCartParameter commerceCartParameter = new CommerceCartParameter(); + commerceCartParameter.setCart(cart); + commerceCartService.calculateCart(commerceCartParameter); + } + + protected void updateCart(CartModel cart, DeliveryModeModel deliveryMode, AddressModel addressModel, PaymentInfoModel paymentInfo) { cart.setDeliveryMode(deliveryMode); cart.setDeliveryAddress(addressModel); cart.setPaymentAddress(addressModel); @@ -401,30 +394,15 @@ protected PaymentInfoModel updatePaymentInfoWithCartAndUser(PaymentInfoModel pay 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); - paymentInfo.setCode(generateCcPaymentInfoCode(cartModel)); + paymentInfo.setCode(generatePaymentInfoCode(cartModel)); paymentInfo.setBillingAddress(addressModel); - paymentInfo.setAdyenPaymentMethod(paymentMethod); - - paymentInfo.setAdyenApplePayMerchantName(merchantName); - paymentInfo.setAdyenApplePayMerchantIdentifier(merchantId); modelService.save(paymentInfo); return paymentInfo; } - protected String generateCcPaymentInfoCode(final CartModel cartModel) { + protected String generatePaymentInfoCode(final CartModel cartModel) { return cartModel.getCode() + "_" + UUID.randomUUID(); } diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java new file mode 100644 index 00000000..55573bf1 --- /dev/null +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java @@ -0,0 +1,216 @@ +package com.adyen.v6.facades.impl; + +import com.adyen.model.checkout.Amount; +import com.adyen.model.checkout.PaymentRequest; +import com.adyen.model.checkout.PaymentResponse; +import com.adyen.service.exception.ApiException; +import com.adyen.v6.facades.AdyenPayPalExpressCheckoutFacade; +import com.adyen.v6.response.PayPalExpressSubmitResponse; +import com.adyen.v6.util.AmountUtil; +import de.hybris.platform.basecommerce.model.site.BaseSiteModel; +import de.hybris.platform.commercefacades.user.data.AddressData; +import de.hybris.platform.commerceservices.customer.DuplicateUidException; +import de.hybris.platform.core.model.order.CartModel; +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.user.AddressModel; +import de.hybris.platform.core.model.user.CustomerModel; +import de.hybris.platform.core.model.user.UserModel; +import de.hybris.platform.order.CalculationService; +import de.hybris.platform.order.InvalidCartException; +import de.hybris.platform.order.exceptions.CalculationException; +import de.hybris.platform.site.BaseSiteService; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.springframework.util.Assert; + +import java.io.IOException; +import java.math.BigDecimal; + +import static de.hybris.platform.servicelayer.util.ServicesUtil.validateParameterNotNull; + +public class DefaultAdyenPayPalExpressCheckoutFacade extends DefaultAdyenExpressCheckoutFacade implements AdyenPayPalExpressCheckoutFacade { + private static final Logger LOG = Logger.getLogger(DefaultAdyenPayPalExpressCheckoutFacade.class); + + // private ProductService productService; +// private CartFactory cartFactory; +// private CartService cartService; +// private ModelService modelService; + private CalculationService calculationService; + // private AdyenCheckoutFacade adyenCheckoutFacade; +// private UserService userService; + private BaseSiteService baseSiteService; +// private CommerceCartService commerceCartService; +// private DeliveryModeService deliveryModeService; +// private SessionService sessionService; + + + @Override + public PayPalExpressSubmitResponse onPayPalPDPSubmit(PaymentRequest paymentRequest, String productCode) throws IOException, ApiException { + Assert.isTrue(StringUtils.isNotEmpty(productCode), "Product code must not be empty"); + + ProductModel productModel = productService.getProductForCode(productCode); + + CartModel expressCart = cartFactory.createCart(); + + expressCart.setDeliveryMode(getExpressDeliveryMode()); + + cartService.addNewEntry(expressCart, productModel, 1L, productModel.getUnit()); + modelService.save(expressCart); + + try { + calculationService.calculate(expressCart); + } catch (CalculationException e) { + LOG.error("Express checkout cart calculation failed"); + } + + Amount amount = AmountUtil.createAmount(BigDecimal.valueOf(expressCart.getTotalPrice()), expressCart.getCurrency().getIsocode()); + + + paymentRequest.setReference(expressCart.getCode()); + paymentRequest.setAmount(amount); + + PaymentResponse paymentResponse = adyenCheckoutFacade.getAdyenPaymentService().sendPaymentRequest(paymentRequest); + + PayPalExpressSubmitResponse payPalExpressSubmitResponse = new PayPalExpressSubmitResponse(); + + payPalExpressSubmitResponse.setPaymentResponse(paymentResponse); + payPalExpressSubmitResponse.setExpressCartGuid(expressCart.getGuid()); + + return payPalExpressSubmitResponse; + } + + @Override + public PaymentResponse onPayPalCartSubmit(PaymentRequest paymentRequest) throws IOException, ApiException { + CartModel sessionCart = cartService.getSessionCart(); + Assert.notNull(sessionCart, "Session cart must not be null"); + + sessionCart.setDeliveryMode(getExpressDeliveryMode()); + + Amount amount = AmountUtil.createAmount(BigDecimal.valueOf(sessionCart.getTotalPrice()), sessionCart.getCurrency().getIsocode()); + + paymentRequest.setAmount(amount); + paymentRequest.setReference(sessionCart.getCode()); + + return adyenCheckoutFacade.getAdyenPaymentService().sendPaymentRequest(paymentRequest); + } + + public void onPayPalAuthorizedPDP(String cartGuid, AddressData addressData, String paymentMethod) throws DuplicateUidException, InvalidCartException, CalculationException { + validateAddress(addressData); + + updateRegionData(addressData); + + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + boolean isGuestUser = false; + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + isGuestUser = true; + } + + CartModel expressCartForGuid = getExpressCartForGuid(cartGuid); + + if (expressCartForGuid != null && cartHasEntries(expressCartForGuid)) { + prepareCartForPayPalExpressCheckout(addressData, expressCartForGuid, user, paymentInfoModel); + + CartModel sessionCart = null; + if (cartService.hasSessionCart()) { + sessionCart = cartService.getSessionCart(); + } + cartService.setSessionCart(expressCartForGuid); + + adyenCheckoutFacade.placePendingOrder(); + + if (isGuestUser) { + sessionService.setAttribute(ANONYMOUS_CHECKOUT_GUID, + org.apache.commons.lang.StringUtils.substringBefore(expressCartForGuid.getUser().getUid(), "|")); + sessionService.setAttribute(ANONYMOUS_CHECKOUT, Boolean.TRUE); + } + + if (sessionCart != null) { + cartService.setSessionCart(sessionCart); + } + return; + + } + throw new InvalidCartException("No cart for checkout or empty cart"); + } + + public void onPayPalAuthorizedCart(AddressData addressData, String paymentMethod) throws DuplicateUidException, InvalidCartException, CalculationException { + validateAddress(addressData); + + PaymentInfoModel paymentInfoModel = modelService.create(PaymentInfoModel.class); + paymentInfoModel.setAdyenPaymentMethod(paymentMethod); + + updateRegionData(addressData); + + CustomerModel user = (CustomerModel) userService.getCurrentUser(); + boolean isGuestUser = false; + if (userService.isAnonymousUser(user)) { + user = createGuestCustomer(addressData.getEmail()); + cartService.changeCurrentCartUser(user); + isGuestUser = true; + } + + CartModel sessionCart = cartService.getSessionCart(); + + if (sessionCart != null && cartHasEntries(sessionCart)) { + prepareCartForPayPalExpressCheckout(addressData, sessionCart, user, paymentInfoModel); + + adyenCheckoutFacade.placePendingOrder(); + + if (isGuestUser) { + sessionService.setAttribute(ANONYMOUS_CHECKOUT_GUID, + org.apache.commons.lang.StringUtils.substringBefore(sessionCart.getUser().getUid(), "|")); + sessionService.setAttribute(ANONYMOUS_CHECKOUT, Boolean.TRUE); + } + return; + } + throw new InvalidCartException("No cart for checkout or empty cart"); + } + + private void prepareCartForPayPalExpressCheckout(AddressData addressData, CartModel sessionCart, CustomerModel user, PaymentInfoModel paymentInfoModel) throws CalculationException { + sessionCart.setUser(user); + + AddressModel addressModel = prepareAddressModel(addressData, user); + updatePaymentInfoWithCartAndUser(paymentInfoModel, user, addressModel, sessionCart); + + sessionCart.setDeliveryAddress(addressModel); + sessionCart.setPaymentAddress(addressModel); + sessionCart.setPaymentInfo(paymentInfoModel); + modelService.save(sessionCart); + + calculationService.recalculate(sessionCart); + } + + protected CartModel getExpressCartForGuid(String expressCartGuid) { + CartModel expressCart = null; + if (StringUtils.isNotEmpty(expressCartGuid)) { + UserModel currentUser = userService.getCurrentUser(); + BaseSiteModel currentBaseSite = baseSiteService.getCurrentBaseSite(); + expressCart = commerceCartService.getCartForGuidAndSiteAndUser(expressCartGuid, currentBaseSite, currentUser); + } + return expressCart; + } + + protected DeliveryModeModel getExpressDeliveryMode() { + DeliveryModeModel deliveryMode = deliveryModeService.getDeliveryModeForCode(DELIVERY_MODE_CODE); + validateParameterNotNull(deliveryMode, "Delivery mode for Adyen express checkout not configured"); + + return deliveryMode; + } + + + public void setCalculationService(CalculationService calculationService) { + this.calculationService = calculationService; + } + + + public void setBaseSiteService(BaseSiteService baseSiteService) { + this.baseSiteService = baseSiteService; + } + +} diff --git a/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java b/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java index fe15a936..25aee2e1 100644 --- a/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java +++ b/adyenv6core/src/com/adyen/v6/factory/AdyenRequestFactory.java @@ -21,15 +21,10 @@ package com.adyen.v6.factory; import com.adyen.builders.terminal.TerminalAPIRequestBuilder; +import com.adyen.model.checkout.Amount; +import com.adyen.model.checkout.PaymentRequest; import com.adyen.model.checkout.*; -import com.adyen.model.nexo.AmountsReq; -import com.adyen.model.nexo.DocumentQualifierType; -import com.adyen.model.nexo.MessageCategoryType; -import com.adyen.model.nexo.MessageReference; -import com.adyen.model.nexo.PaymentTransaction; -import com.adyen.model.nexo.SaleData; -import com.adyen.model.nexo.TransactionIdentification; -import com.adyen.model.nexo.TransactionStatusRequest; +import com.adyen.model.nexo.*; import com.adyen.model.recurring.DisableRequest; import com.adyen.model.recurring.Recurring; import com.adyen.model.recurring.RecurringDetailsRequest; @@ -62,20 +57,7 @@ import java.util.*; import java.util.stream.Collectors; -import static com.adyen.v6.constants.Adyenv6coreConstants.AFTERPAY; -import static com.adyen.v6.constants.Adyenv6coreConstants.CARD_TYPE_DEBIT; -import static com.adyen.v6.constants.Adyenv6coreConstants.OPENINVOICE_METHODS_API; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYBRIGHT; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_BCMC; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_BOLETO; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_CC; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_FACILPAY_PREFIX; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_KLARNA; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_PIX; -import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_SCHEME; -import static com.adyen.v6.constants.Adyenv6coreConstants.PLUGIN_NAME; -import static com.adyen.v6.constants.Adyenv6coreConstants.PLUGIN_VERSION; -import static com.adyen.v6.constants.Adyenv6coreConstants.RATEPAY; +import static com.adyen.v6.constants.Adyenv6coreConstants.*; /** * Factory class to create Adyen API requests, do not add new code to this class. @@ -120,7 +102,12 @@ public PaymentRequest createPaymentsRequest(final String merchantAccount, setRiskData(paymentsRequest, cartData, originPaymentsRequest); - paymentsRequest.setReturnUrl(cartData.getAdyenReturnUrl()); + if (StringUtils.isNotEmpty(cartData.getAdyenReturnUrl()) || originPaymentsRequest == null) { + paymentsRequest.setReturnUrl(cartData.getAdyenReturnUrl()); + } else { + paymentsRequest.setReturnUrl(originPaymentsRequest.getReturnUrl()); + } + paymentsRequest.setRedirectFromIssuerMethod(RequestMethod.POST.toString()); paymentsRequest.setRedirectToIssuerMethod(RequestMethod.POST.toString()); if (originPaymentsRequest != null) { @@ -340,7 +327,6 @@ protected void updatePaymentRequestForAlternateMethod(final PaymentRequest payme final String adyenPaymentMethod = cartData.getAdyenPaymentMethod(); paymentsRequest.setShopperName(getShopperNameFromAddress(cartData.getDeliveryAddress())); - paymentsRequest.setReturnUrl(cartData.getAdyenReturnUrl()); if (adyenPaymentMethod.startsWith(PAYMENT_METHOD_KLARNA) || adyenPaymentMethod.startsWith(PAYMENT_METHOD_FACILPAY_PREFIX) diff --git a/adyenv6core/src/com/adyen/v6/response/PayPalExpressSubmitResponse.java b/adyenv6core/src/com/adyen/v6/response/PayPalExpressSubmitResponse.java new file mode 100644 index 00000000..06135147 --- /dev/null +++ b/adyenv6core/src/com/adyen/v6/response/PayPalExpressSubmitResponse.java @@ -0,0 +1,26 @@ +package com.adyen.v6.response; + +import com.adyen.model.checkout.PaymentResponse; + +import java.io.Serializable; + +public class PayPalExpressSubmitResponse implements Serializable { + private PaymentResponse paymentResponse; + private Serializable expressCartGuid; + + public PaymentResponse getPaymentResponse() { + return paymentResponse; + } + + public void setPaymentResponse(PaymentResponse paymentResponse) { + this.paymentResponse = paymentResponse; + } + + public Serializable getExpressCartGuid() { + return expressCartGuid; + } + + public void setExpressCartGuid(Serializable expressCartGuid) { + this.expressCartGuid = expressCartGuid; + } +} diff --git a/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java b/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java index b1b3135a..da312afb 100644 --- a/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java +++ b/adyenv6core/src/com/adyen/v6/service/AdyenCheckoutApiService.java @@ -21,15 +21,7 @@ package com.adyen.v6.service; import com.adyen.httpclient.HTTPClientException; -import com.adyen.model.checkout.Amount; -import com.adyen.model.checkout.CreateCheckoutSessionResponse; -import com.adyen.model.checkout.PaymentCompletionDetails; -import com.adyen.model.checkout.PaymentDetailsRequest; -import com.adyen.model.checkout.PaymentDetailsResponse; -import com.adyen.model.checkout.PaymentMethod; -import com.adyen.model.checkout.PaymentMethodsResponse; -import com.adyen.model.checkout.PaymentRequest; -import com.adyen.model.checkout.PaymentResponse; +import com.adyen.model.checkout.*; import com.adyen.model.recurring.RecurringDetail; import com.adyen.model.terminal.ConnectedTerminalsResponse; import com.adyen.model.terminal.TerminalAPIResponse; @@ -49,6 +41,8 @@ public interface AdyenCheckoutApiService { PaymentResponse processPaymentRequest(CartData cartData, PaymentRequest originPaymentsRequest, RequestInfo requestInfo, CustomerModel customerModel) throws Exception; + PaymentResponse sendPaymentRequest(final PaymentRequest paymentRequest) throws IOException, ApiException; + PaymentDetailsResponse authorise3DSPayment(PaymentDetailsRequest paymentsDetailsRequest) throws Exception; /** diff --git a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java index 01352f11..7c4d839f 100644 --- a/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java +++ b/adyenv6core/src/com/adyen/v6/service/DefaultAdyenCheckoutApiService.java @@ -21,25 +21,10 @@ package com.adyen.v6.service; import com.adyen.commerce.services.AdyenRequestService; -import com.adyen.commerce.services.impl.DefaultAdyenRequestService; import com.adyen.model.checkout.Amount; -import com.adyen.model.checkout.CheckoutPaymentMethod; -import com.adyen.model.checkout.CreateCheckoutSessionRequest; -import com.adyen.model.checkout.CreateCheckoutSessionResponse; -import com.adyen.model.checkout.PaymentCompletionDetails; -import com.adyen.model.checkout.PaymentDetailsRequest; -import com.adyen.model.checkout.PaymentDetailsResponse; -import com.adyen.model.checkout.PaymentMethod; -import com.adyen.model.checkout.PaymentMethodsRequest; -import com.adyen.model.checkout.PaymentMethodsResponse; -import com.adyen.model.checkout.PaymentRequest; -import com.adyen.model.checkout.PaymentResponse; -import com.adyen.model.recurring.DisableRequest; -import com.adyen.model.recurring.DisableResult; +import com.adyen.model.checkout.*; import com.adyen.model.recurring.RecurringDetail; -import com.adyen.model.recurring.RecurringDetailWrapper; -import com.adyen.model.recurring.RecurringDetailsRequest; -import com.adyen.model.recurring.RecurringDetailsResult; +import com.adyen.model.recurring.*; import com.adyen.model.terminal.ConnectedTerminalsRequest; import com.adyen.model.terminal.ConnectedTerminalsResponse; import com.adyen.model.terminal.TerminalAPIRequest; @@ -51,30 +36,21 @@ import com.adyen.service.exception.ApiException; import com.adyen.terminal.serialization.TerminalAPIGsonBuilder; import com.adyen.v6.enums.RecurringContractMode; -import com.adyen.v6.factory.AdyenRequestFactory; import com.adyen.v6.model.RequestInfo; -import com.adyen.v6.strategy.AdyenMerchantAccountStrategy; import com.adyen.v6.util.AmountUtil; import de.hybris.platform.commercefacades.order.data.CartData; import de.hybris.platform.commercefacades.product.data.PriceData; -import de.hybris.platform.core.model.order.AbstractOrderModel; import de.hybris.platform.core.model.user.CustomerModel; import de.hybris.platform.store.BaseStoreModel; -import de.hybris.platform.store.services.BaseStoreService; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import java.io.IOException; import java.math.BigDecimal; -import java.math.RoundingMode; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; public class DefaultAdyenCheckoutApiService extends AbstractAdyenApiService implements AdyenCheckoutApiService { @@ -123,6 +99,18 @@ public PaymentResponse processPaymentRequest(final CartData cartData, PaymentReq return paymentsResponse; } + public PaymentResponse sendPaymentRequest(final PaymentRequest paymentRequest) throws IOException, ApiException { + PaymentsApi checkoutApi = new PaymentsApi(client); + + paymentRequest.setMerchantAccount(merchantAccount); + + LOG.debug(paymentRequest); + PaymentResponse paymentsResponse = checkoutApi.payments(paymentRequest); + LOG.debug(paymentsResponse); + + return paymentsResponse; + } + @Override public PaymentDetailsResponse authorise3DSPayment(PaymentDetailsRequest paymentsDetailsRequest) throws Exception { LOG.debug("Authorize 3DS payment"); diff --git a/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java b/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java index e5c51315..40b9eb2c 100644 --- a/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java +++ b/adyenv6core/testsrc/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacadeTest.java @@ -363,7 +363,7 @@ public void removeDeliveryModeFromSessionCart() throws CalculationException { } @Test - public void prepareCart() { + public void updateCart() { //given CartModel cartModel = new CartModel(); DeliveryModeModel deliveryModeModel = new DeliveryModeModel(); @@ -373,7 +373,7 @@ public void prepareCart() { ArgumentCaptor cartCaptor = ArgumentCaptor.forClass(CartModel.class); //when - defaultAdyenExpressCheckoutFacade.prepareCart(cartModel, deliveryModeModel, addressModel, paymentInfo); + defaultAdyenExpressCheckoutFacade.updateCart(cartModel, deliveryModeModel, addressModel, paymentInfo); //then verify(modelService).save(cartCaptor.capture()); From f9753260ea65dcc9f7f6480073f99717e995bc7c Mon Sep 17 00:00:00 2001 From: PJaneta Date: Mon, 16 Dec 2024 14:47:24 +0100 Subject: [PATCH 2/5] AD-337 Add PayPal Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages - add configuration support --- .../WEB-INF/tags/responsive/expressCheckoutConfig.tag | 5 +++-- .../_ui/responsive/common/js/adyen_express_checkout.js | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) 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 1d9fade5..10d9ddbb 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag @@ -22,7 +22,9 @@ label: ['visible-xs', 'hidden-xs'], pageType: '${pageType}', productCode: '${product.code}', - payPalIntent: '${paypalIntent}' + payPalIntent: '${paypalIntent}', + payPalExpressEnabledOnProduct: ${expressPaymentConfig.paypalExpressEnabledOnProduct}, + payPalExpressEnabledOnCart: ${expressPaymentConfig.paypalExpressEnabledOnCart}, } var checkoutConfig = { @@ -34,7 +36,6 @@ applePayExpressEnabledOnCart: ${expressPaymentConfig.applePayExpressEnabledOnCart}, googlePayExpressEnabledOnProduct: ${expressPaymentConfig.googlePayExpressEnabledOnProduct}, applePayExpressEnabledOnProduct: ${expressPaymentConfig.applePayExpressEnabledOnProduct}, - } window.onload = function() { 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 40b6d628..107a8937 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 @@ -43,7 +43,9 @@ var AdyenExpressCheckoutHybris = (function () { if (params.pageType === 'cart' && config.applePayExpressEnabledOnCart || params.pageType === 'PDP' && config.applePayExpressEnabledOnProduct) { this.initiateApplePayExpress(checkout, params) } - this.initiatePayPalExpress(checkout, params) + if (params.pageType === 'cart' && params.payPalExpressEnabledOnCart || params.pageType === 'PDP' && params.payPalExpressEnabledOnProduct) { + this.initiatePayPalExpress(checkout, params) + } }); }, initiateApplePayExpress: async function (checkout, params) { From 3e87bdaa908d05e993d37cf58b7fd05fbecb46c7 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Mon, 16 Dec 2024 15:31:34 +0100 Subject: [PATCH 3/5] AD-337 Add PayPal Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages - remove console log --- .../webroot/_ui/responsive/common/js/adyen_express_checkout.js | 2 -- 1 file changed, 2 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 107a8937..7520fe17 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 @@ -431,8 +431,6 @@ var AdyenExpressCheckoutHybris = (function () { return {}; }, prepareDataPayPal: function (paymentData) { - console.log(JSON.stringify(paymentData)) - let baseData = { payPalDetails: { orderID: paymentData.authorizedEvent.id, From e5d9fc59d73af78b58db0aab25a15ea278c31575 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Tue, 28 Jan 2025 15:10:33 +0100 Subject: [PATCH 4/5] AD-337 Add PayPal Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages --- .../adyenaccexpresscheckoutcartpagecomponent.jsp | 6 +++--- .../facades/impl/DefaultAdyenCheckoutFacade.java | 15 +++++++++------ .../impl/DefaultAdyenExpressCheckoutFacade.java | 1 + 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp index b0476ff5..9a199e1e 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp @@ -15,9 +15,9 @@
- -
-
+
+
+
diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java index 071ce854..298c9a03 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java @@ -1118,7 +1118,7 @@ protected ExpressCheckoutConfigDTO initializeExpressCheckoutDataInternal(BigDeci Map payPalConfig = getPayPalConfigFromPaymentMethods(paymentMethodsResponse.getPaymentMethods()); if (!CollectionUtils.isEmpty(payPalConfig)) { - expressCheckoutConfigDTOBuilder.setPayPalIntent(payPalConfig.get("intent")) + expressCheckoutConfigDTOBuilder.setPayPalIntent(payPalConfig.get("intent")); } else { LOGGER.warn("Empty PayPal config"); } @@ -1145,21 +1145,24 @@ protected ExpressCheckoutConfigDTO initializeExpressCheckoutDataInternal(BigDeci return expressCheckoutConfigDTOBuilder.build(); } - protected void populateExpressCheckoutConfigModel(final Model model, final ExpressCheckoutConfigDTO expressCheckoutConfigDTO){ - if(StringUtils.isNotEmpty(expressCheckoutConfigDTO.getApplePayMerchantId())){ + protected void populateExpressCheckoutConfigModel(final Model model, final ExpressCheckoutConfigDTO expressCheckoutConfigDTO) { + if (StringUtils.isNotEmpty(expressCheckoutConfigDTO.getApplePayMerchantId())) { model.addAttribute(MODEL_APPLEPAY_MERCHANT_IDENTIFIER, expressCheckoutConfigDTO.getApplePayMerchantId()); } - if(StringUtils.isNotEmpty(expressCheckoutConfigDTO.getApplePayMerchantName())){ + if (StringUtils.isNotEmpty(expressCheckoutConfigDTO.getApplePayMerchantName())) { model.addAttribute(MODEL_APPLEPAY_MERCHANT_NAME, expressCheckoutConfigDTO.getApplePayMerchantName()); } - if(expressCheckoutConfigDTO.getExpressPaymentConfig() != null){ + if (expressCheckoutConfigDTO.getExpressPaymentConfig() != null) { model.addAttribute(EXPRESS_PAYMENT_CONFIG, expressCheckoutConfigDTO.getExpressPaymentConfig()); } + if (expressCheckoutConfigDTO.getPayPalIntent() != null) { + model.addAttribute(MODEL_PAYPAL_INTENT, expressCheckoutConfigDTO.getPayPalIntent()); + } model.addAttribute(SHOPPER_LOCALE, expressCheckoutConfigDTO.getShopperLocale()); model.addAttribute(MODEL_ENVIRONMENT_MODE, expressCheckoutConfigDTO.getEnvironmentMode()); model.addAttribute(MODEL_CLIENT_KEY, expressCheckoutConfigDTO.getClientKey()); - model.addAttribute(MODEL_MERCHANT_ACCOUNT,expressCheckoutConfigDTO.getMerchantAccount()); + model.addAttribute(MODEL_MERCHANT_ACCOUNT, expressCheckoutConfigDTO.getMerchantAccount()); model.addAttribute(MODEL_AMOUNT, expressCheckoutConfigDTO.getAmount()); model.addAttribute(MODEL_AMOUNT_DECIMAL, expressCheckoutConfigDTO.getAmountDecimal()); model.addAttribute(MODEL_DF_URL, expressCheckoutConfigDTO.getDfUrl()); diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java index 8a95990f..10d335a6 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenExpressCheckoutFacade.java @@ -30,6 +30,7 @@ import de.hybris.platform.order.CartService; import de.hybris.platform.order.DeliveryModeService; import de.hybris.platform.order.InvalidCartException; +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; From b907ba45004f1de0cdea0c67334737fb807af93f Mon Sep 17 00:00:00 2001 From: PJaneta Date: Tue, 28 Jan 2025 15:28:08 +0100 Subject: [PATCH 5/5] AD-337 Add PayPal Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages - PR fixes --- .../checkout/AdyenPayPalExpressCheckoutController.java | 8 ++++---- .../impl/DefaultAdyenPayPalExpressCheckoutFacade.java | 10 +--------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java index 5c3e3994..44974abd 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/checkout/AdyenPayPalExpressCheckoutController.java @@ -26,8 +26,8 @@ @Controller @RequestMapping("/express-checkout/paypal/") -public class AdyenPayPalExpressCheckoutController extends AdyenExpressCheckoutControllerBase { - private static final Logger LOG = Logger.getLogger(AdyenApplePayExpressCheckoutController.class); +public class AdyenPayPalExpressCheckoutController extends AdyenExpressCheckoutControllerBase { + private static final Logger LOG = Logger.getLogger(AdyenPayPalExpressCheckoutController.class); @Autowired private AdyenPayPalExpressCheckoutFacade adyenPayPalExpressCheckoutFacade; @@ -59,7 +59,7 @@ public ResponseEntity onSubmitPDP(final HttpServletRequest request, final HttpSe LOG.error(e.getError()); LOG.error(e.getMessage()); - return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } @@ -81,7 +81,7 @@ public ResponseEntity onSubmitCart(final HttpServletRequest request, final HttpS LOG.error(e.getError()); LOG.error(e.getMessage()); - return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java index 55573bf1..bbb1aa62 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenPayPalExpressCheckoutFacade.java @@ -33,17 +33,9 @@ public class DefaultAdyenPayPalExpressCheckoutFacade extends DefaultAdyenExpressCheckoutFacade implements AdyenPayPalExpressCheckoutFacade { private static final Logger LOG = Logger.getLogger(DefaultAdyenPayPalExpressCheckoutFacade.class); - // private ProductService productService; -// private CartFactory cartFactory; -// private CartService cartService; -// private ModelService modelService; private CalculationService calculationService; - // private AdyenCheckoutFacade adyenCheckoutFacade; -// private UserService userService; private BaseSiteService baseSiteService; -// private CommerceCartService commerceCartService; -// private DeliveryModeService deliveryModeService; -// private SessionService sessionService; + @Override