From 484886371322660657dda97045a09fdc0556f395 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Fri, 11 Oct 2024 09:17:36 +0200 Subject: [PATCH 1/4] AD-319 Create CMS Components for Express Payment Methods Placeholder on Cart and PDP Pages --- ...artExpressCheckoutComponentController.java | 19 +++++++++++++ ...uctExpressCheckoutComponentController.java | 19 +++++++++++++ ...yenaccexpresscheckoutcartpagecomponent.jsp | 10 +++++++ ...accexpresscheckoutproductpagecomponent.jsp | 8 ++++++ .../adyenv6b2ccheckoutaddon-items.xml | 8 ++++++ .../impex/projectdata-cms-config.impex | 27 ++++++++++++++----- 6 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp 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 new file mode 100644 index 000000000..4a9fc8488 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccCartExpressCheckoutComponentController.java @@ -0,0 +1,19 @@ +package com.adyen.v6.controllers.cms; + +import com.adyen.v6.model.contents.components.AdyenAccExpressCheckoutCartPageComponentModel; +import de.hybris.platform.addonsupport.controllers.cms.AbstractCMSAddOnComponentController; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; + +@Controller(AdyenAccExpressCheckoutCartPageComponentModel._TYPECODE + "Controller") +@RequestMapping(value = "/view/" + AdyenAccExpressCheckoutCartPageComponentModel._TYPECODE + "Controller") +public class AdyenAccCartExpressCheckoutComponentController extends AbstractCMSAddOnComponentController { + + @Override + protected void fillModel(final HttpServletRequest request, final Model model, final AdyenAccExpressCheckoutCartPageComponentModel component) { + model.addAttribute("test", "testValue"); + } +} 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 new file mode 100644 index 000000000..81e0502b7 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/cms/AdyenAccProductExpressCheckoutComponentController.java @@ -0,0 +1,19 @@ +package com.adyen.v6.controllers.cms; + +import com.adyen.v6.model.contents.components.AdyenAccExpressCheckoutProductPageComponentModel; +import de.hybris.platform.addonsupport.controllers.cms.AbstractCMSAddOnComponentController; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +import javax.servlet.http.HttpServletRequest; + +@Controller(AdyenAccExpressCheckoutProductPageComponentModel._TYPECODE + "Controller") +@RequestMapping(value = "/view/" + AdyenAccExpressCheckoutProductPageComponentModel._TYPECODE + "Controller") +public class AdyenAccProductExpressCheckoutComponentController extends AbstractCMSAddOnComponentController { + + @Override + protected void fillModel(final HttpServletRequest request, final Model model, final AdyenAccExpressCheckoutProductPageComponentModel component) { + model.addAttribute("test", "testValue"); + } +} 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 new file mode 100644 index 000000000..700402a84 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutcartpagecomponent.jsp @@ -0,0 +1,10 @@ +<%@ page trimDirectiveWhitespaces="true" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +
+
+ Cart Page Express Checkout component +
+ ${test} +
+
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 new file mode 100644 index 000000000..702561d7d --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/cms/adyenaccexpresscheckoutproductpagecomponent.jsp @@ -0,0 +1,8 @@ +<%@ page trimDirectiveWhitespaces="true" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +
+ Product Page Express Checkout component +
+ ${test} +
\ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/resources/adyenv6b2ccheckoutaddon-items.xml b/adyenv6b2ccheckoutaddon/resources/adyenv6b2ccheckoutaddon-items.xml index 19dc5fa6c..dabc6f54e 100644 --- a/adyenv6b2ccheckoutaddon/resources/adyenv6b2ccheckoutaddon-items.xml +++ b/adyenv6b2ccheckoutaddon/resources/adyenv6b2ccheckoutaddon-items.xml @@ -19,5 +19,13 @@ xsi:noNamespaceSchemaLocation="items.xsd"> + + Represents express checkout options for product page. + + + Represents express checkout options for product page. + diff --git a/adyenv6b2ccheckoutaddon/resources/impex/projectdata-cms-config.impex b/adyenv6b2ccheckoutaddon/resources/impex/projectdata-cms-config.impex index ab834040c..4ae5791b8 100644 --- a/adyenv6b2ccheckoutaddon/resources/impex/projectdata-cms-config.impex +++ b/adyenv6b2ccheckoutaddon/resources/impex/projectdata-cms-config.impex @@ -1,10 +1,23 @@ -$contentCatalog=electronicsContentCatalog -$contentCVS=catalogVersion(CatalogVersion.catalog(Catalog.id[default=$contentCatalog]),CatalogVersion.version[default=Staged])[default=$contentCatalog:Staged] -$contentCVO=catalogVersion(CatalogVersion.catalog(Catalog.id[default=$contentCatalog]),CatalogVersion.version[default=Online])[default=$contentCatalog:Online] +$contentCatalog = electronicsContentCatalog +$contentCVS = catalogVersion(CatalogVersion.catalog(Catalog.id[default = $contentCatalog]), CatalogVersion.version[default = Staged])[default = $contentCatalog:Staged] +$contentCVO = catalogVersion(CatalogVersion.catalog(Catalog.id[default = $contentCatalog]), CatalogVersion.version[default = Online])[default = $contentCatalog:Online] -INSERT_UPDATE JspIncludeComponent;uid[unique=true];page;$contentCVS[unique=true] - ;CartComponent;/WEB-INF/views/responsive/pages/cart/cartDisplay.jsp +INSERT_UPDATE JspIncludeComponent; uid[unique = true]; page; $contentCVS[unique = true] + ; CartComponent ; /WEB-INF/views/responsive/pages/cart/cartDisplay.jsp -INSERT_UPDATE JspIncludeComponent;uid[unique=true];page;$contentCVO[unique=true] - ;CartComponent;/WEB-INF/views/responsive/pages/cart/cartDisplay.jsp \ No newline at end of file +INSERT_UPDATE JspIncludeComponent; uid[unique = true]; page; $contentCVO[unique = true] + ; CartComponent ; /WEB-INF/views/responsive/pages/cart/cartDisplay.jsp + +INSERT_UPDATE ContentSlot; $contentCVS[unique = true]; uid[unique = true]; cmsComponents(&componentRef)[mode = merge] + ; ; AddToCartSlot ; AccAdyenProductExpressCheckout + +INSERT_UPDATE AdyenAccExpressCheckoutProductPageComponent; $contentCVS[unique = true]; uid[unique = true] ; name ; &componentRef + ; ; AccAdyenProductExpressCheckout ; Adyen Accelerator Product Page Express Checkout ; AccAdyenProductExpressCheckout + +INSERT_UPDATE ContentSlot; $contentCVS[unique = true]; uid[unique = true] ; cmsComponents($contentCVS, uid) + ; ; TopContent-cartPage ; AccAdyenCartExpressCheckout,CartComponent + ; ; BottomContentSlot-cartPage ; CheckoutComponent,AccAdyenCartExpressCheckout,CartSuggestions + +INSERT_UPDATE AdyenAccExpressCheckoutCartPageComponent; $contentCVS[unique = true]; uid[unique = true] ; name ; &componentRef + ; ; AccAdyenCartExpressCheckout ; Adyen Accelerator Cart Page Express Checkout ; AccAdyenCartExpressCheckout From daa0dbf67825e34d9ee11e4234f96eb4a8b817a2 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Thu, 17 Oct 2024 12:16:09 +0200 Subject: [PATCH 2/4] AD-335 Add Google Pay Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages --- ...artExpressCheckoutComponentController.java | 18 +- ...uctExpressCheckoutComponentController.java | 24 ++- .../tags/responsive/expressCheckoutConfig.tag | 49 +++++ ...yenaccexpresscheckoutcartpagecomponent.jsp | 16 +- ...accexpresscheckoutproductpagecomponent.jsp | 10 +- .../common/js/adyen_express_checkout.js | 187 +++++++++++++++++- .../impl/DefaultAdyenCheckoutFacade.java | 2 + 7 files changed, 287 insertions(+), 19 deletions(-) create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag 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 4a9fc8488..678a7cae3 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 @@ -1,7 +1,12 @@ package com.adyen.v6.controllers.cms; +import com.adyen.service.exception.ApiException; +import com.adyen.v6.facades.AdyenCheckoutFacade; +import com.adyen.v6.facades.AdyenExpressCheckoutFacade; import com.adyen.v6.model.contents.components.AdyenAccExpressCheckoutCartPageComponentModel; import de.hybris.platform.addonsupport.controllers.cms.AbstractCMSAddOnComponentController; +import de.hybris.platform.order.exceptions.CalculationException; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @@ -12,8 +17,19 @@ @RequestMapping(value = "/view/" + AdyenAccExpressCheckoutCartPageComponentModel._TYPECODE + "Controller") public class AdyenAccCartExpressCheckoutComponentController extends AbstractCMSAddOnComponentController { + @Autowired + private AdyenCheckoutFacade adyenCheckoutFacade; + + @Autowired + private AdyenExpressCheckoutFacade adyenExpressCheckoutFacade; + @Override protected void fillModel(final HttpServletRequest request, final Model model, final AdyenAccExpressCheckoutCartPageComponentModel component) { - model.addAttribute("test", "testValue"); + try { + adyenExpressCheckoutFacade.removeDeliveryModeFromSessionCart(); + adyenCheckoutFacade.initializeApplePayExpressCartPageData(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 81e0502b7..528ae66a1 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 @@ -1,19 +1,41 @@ package com.adyen.v6.controllers.cms; +import com.adyen.service.exception.ApiException; +import com.adyen.v6.facades.AdyenCheckoutFacade; import com.adyen.v6.model.contents.components.AdyenAccExpressCheckoutProductPageComponentModel; +import de.hybris.platform.acceleratorservices.data.RequestContextData; import de.hybris.platform.addonsupport.controllers.cms.AbstractCMSAddOnComponentController; +import de.hybris.platform.commercefacades.product.ProductFacade; +import de.hybris.platform.commercefacades.product.ProductOption; +import de.hybris.platform.commercefacades.product.data.ProductData; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; @Controller(AdyenAccExpressCheckoutProductPageComponentModel._TYPECODE + "Controller") @RequestMapping(value = "/view/" + AdyenAccExpressCheckoutProductPageComponentModel._TYPECODE + "Controller") public class AdyenAccProductExpressCheckoutComponentController extends AbstractCMSAddOnComponentController { + @Autowired + private AdyenCheckoutFacade adyenCheckoutFacade; + + @Autowired + private ProductFacade productFacade; + @Override protected void fillModel(final HttpServletRequest request, final Model model, final AdyenAccExpressCheckoutProductPageComponentModel component) { - model.addAttribute("test", "testValue"); + try { + RequestContextData requestContextData = getRequestContextData(request); + requestContextData.getProduct(); + final ProductData productData = productFacade.getProductForCodeAndOptions(requestContextData.getProduct().getCode(), Arrays.asList(ProductOption.BASIC, ProductOption.PRICE)); + + adyenCheckoutFacade.initializeApplePayExpressPDPData(model, productData); + } catch (ApiException e) { + throw new RuntimeException(e); + } } } diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag new file mode 100644 index 000000000..16f8b9030 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag @@ -0,0 +1,49 @@ +<%@ taglib prefix="adyen" tagdir="/WEB-INF/tags/addons/adyenv6b2ccheckoutaddon/responsive" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ attribute name="pageType" required="true" type="java.lang.String"%> + + + + + + + + + + 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 700402a84..b0d28fa19 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 @@ -1,10 +1,14 @@ <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="adyen" tagdir="/WEB-INF/tags/addons/adyenv6b2ccheckoutaddon/responsive" %> -
-
- Cart Page Express Checkout component -
- ${test} + + +
+
+
+
+
+
-
+
\ 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 702561d7d..33d2fb0ba 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 @@ -1,8 +1,8 @@ <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="adyen" tagdir="/WEB-INF/tags/addons/adyenv6b2ccheckoutaddon/responsive" %> -
- Product Page Express Checkout component -
- ${test} -
\ 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 271d2d910..ceea56910 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 @@ -33,6 +33,12 @@ var AdyenExpressCheckoutHybris = (function() { return await AdyenCheckout(configuration); }, + initExpressCheckout: async function (params, config) { + var checkoutPromise = this.initiateCheckout(config); + checkoutPromise.then((checkout) => { + this.initiateGooglePayExpress(checkout, params) + }); + }, initiateApplePayExpress: async function(params, config) { var checkoutPromise = this.initiateCheckout(config); const { @@ -92,8 +98,8 @@ var AdyenExpressCheckoutHybris = (function() { // empty to block session flow, submit logic done in onAuthorized }, onAuthorized: (resolve, reject, event) => { - var data = this.prepareData(event); - this.makePayment(data, resolve, reject); + var data = this.prepareDataApple(event); + this.makePayment(data, this.getAppleUrl(), resolve, reject); } }); applePayComponent.isAvailable() @@ -106,9 +112,135 @@ var AdyenExpressCheckoutHybris = (function() { }); }) }, - makePayment: function(data, resolve, reject) { + initiateGooglePayExpress: function (checkout, params) { + const { + amount, + amountDecimal, + countryCode, + pageType, + productCode + } = params; + + this.adyenConfig.pageType = pageType; + this.adyenConfig.productCode = productCode; + + const googlePayNodes = document.getElementsByClassName('adyen-google-pay-button'); + + for (let googlePayNode of googlePayNodes) { + let googlePayComponent = checkout.create('googlepay', { + + // Step 2: Set the callback intents. + buttonSizeMode: "fill", + buttonType: "checkout", + + callbackIntents: ['SHIPPING_ADDRESS'], + + // Step 3: Set shipping configurations. + + shippingAddressRequired: true, + emailRequired: true, + + shippingAddressParameters: { + allowedCountryCodes: [], + phoneNumberRequired: false + }, + + // Shipping options configurations. + shippingOptionRequired: false, + + // Step 4: Pass the default shipping options. + + // shippingOptions: { + // defaultSelectedOptionId: 'shipping-001', + // shippingOptions: [ + // { + // id: 'shipping-001', + // label: '$0.00: Free shipping', + // description: 'Free shipping: delivered in 10 business days.' + // }, + // { + // id: 'shipping-002', + // label: '$1.99: Standard shipping', + // description: 'Standard shipping: delivered in 3 business days.' + // }, + // ] + // }, + + // Step 5: Set the transaction information. + + //Required for v6.0.0 or later. + isExpress: true, + + + transactionInfo: { + countryCode: countryCode, + currencyCode: amount.currency, + totalPriceStatus: 'FINAL', + totalPrice: amountDecimal, + totalPriceLabel: 'Total' + }, + + // Step 6: Update the payment data. + + paymentDataCallbacks: { + onPaymentDataChanged(intermediatePaymentData) { + return new Promise(async resolve => { + const { + callbackTrigger, + shippingAddress, + shippingOptionData + } = intermediatePaymentData; + const paymentDataRequestUpdate = {}; + + // Validate the country/region and address selection. + if (shippingAddress.countryCode !== 'US' && shippingAddress.countryCode !== 'BR') { + paymentDataRequestUpdate.error = { + reason: 'SHIPPING_ADDRESS_UNSERVICEABLE', + message: 'Cannot ship to the selected address', + intent: 'SHIPPING_ADDRESS' + }; + } + + // If it initializes or changes the shipping address, calculate the shipping options and transaction info. + if (callbackTrigger === 'INITIALIZE' || callbackTrigger === 'SHIPPING_ADDRESS') { + // paymentDataRequestUpdate.newShippingOptionParameters = await fetchNewShippingOptions(shippingAddress.countryCode); + // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); + } + + // If SHIPPING_OPTION changes, calculate the new shipping amount. + if (callbackTrigger === 'SHIPPING_OPTION') { + // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); + } + + resolve(paymentDataRequestUpdate); + }); + } + }, + + // Step 7: Configure the callback to get the shopper's information. + + onAuthorized: (paymentData) => { + console.log('Shopper details'); + console.log(paymentData) + this.makePayment(this.prepareDataGoogle(paymentData), this.getGoogleUrl()) + }, + onError: function (error) { + console.log(error) + } + }); + googlePayComponent.isAvailable() + .then(function () { + googlePayComponent.mount(googlePayNode); + }) + .catch(function (e) { + // Google Pay is not available + console.log('Something went wrong trying to mount the Google Pay component'); + }); + } + }, + makePayment: function(data, url, resolve = ()=>{}, reject = ()=>{}) { $.ajax({ - url: this.getUrl(), + url: url, type: "POST", data: JSON.stringify(data), contentType: "application/json; charset=utf-8", @@ -147,7 +279,8 @@ var AdyenExpressCheckoutHybris = (function() { } document.querySelector("#handleComponentResultForm").submit(); }, - prepareData: function(event) { + prepareDataApple: function(event) { + //TODO: Refactor as google data if (this.adyenConfig.pageType === 'PDP') { return { productCode: this.adyenConfig.productCode, @@ -192,7 +325,39 @@ var AdyenExpressCheckoutHybris = (function() { console.error('unknown page type') return {}; }, - getUrl: function() { + prepareDataGoogle: function(paymentData) { + const baseData = { + googlePayToken: paymentData.paymentMethodData.tokenizationData.token, + googlePayCardNetwork: paymentData.paymentMethodData.info.cardNetwork, + addressData: { + email: paymentData.email, + firstName: paymentData.shippingAddress.name, + // lastName: paymentData.payment.shippingContact.familyName, + line1: paymentData.shippingAddress.address1, + line2: paymentData.shippingAddress.address2, + postalCode: paymentData.shippingAddress.postalCode, + town: paymentData.shippingAddress.locality, + country: { + isocode: paymentData.shippingAddress.countryCode, + }, + region: { + isocode: paymentData.shippingAddress.administrativeArea + } + } + } + if (this.adyenConfig.pageType === 'PDP') { + return { + productCode: this.adyenConfig.productCode, + ...baseData + } + } + if (this.adyenConfig.pageType === 'cart') { + return baseData; + } + console.error('unknown page type') + return {}; + }, + getAppleUrl: function() { if (this.adyenConfig.pageType === 'PDP') { return ACC.config.encodedContextPath + '/expressCheckout/applePayPDP' } @@ -201,6 +366,16 @@ var AdyenExpressCheckoutHybris = (function() { } console.error('unknown page type') return null; + }, + getGoogleUrl: function() { + if (this.adyenConfig.pageType === 'PDP') { + return ACC.config.encodedContextPath + '/expressCheckout/googlePayPDP' + } + if (this.adyenConfig.pageType === 'cart') { + return ACC.config.encodedContextPath + '/expressCheckout/googlePayCart' + } + console.error('unknown page type') + return null; } } })(); \ No newline at end of file diff --git a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java index 09a8d50db..ce1c990ed 100644 --- a/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java +++ b/adyenv6core/src/com/adyen/v6/facades/impl/DefaultAdyenCheckoutFacade.java @@ -222,6 +222,7 @@ 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_IMMEDIATE_CAPTURE = "immediateCapture"; public static final String MODEL_PAYPAL_MERCHANT_ID = "paypalMerchantId"; public static final String MODEL_COUNTRY_CODE = "countryCode"; @@ -1093,6 +1094,7 @@ protected void initializeApplePayExpressDataInternal(BigDecimal amountValue, Str 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()); model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, getCheckoutShopperHost()); } From cc9c862013621addbe381d7e77b523031a75b863 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Wed, 23 Oct 2024 14:50:11 +0200 Subject: [PATCH 3/4] AD-335 Add Google Pay Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages - add jalo classes --- ...enAccExpressCheckoutCartPageComponent.java | 25 +++++++++++++++++++ ...ccExpressCheckoutProductPageComponent.java | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutCartPageComponent.java create mode 100644 adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutProductPageComponent.java diff --git a/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutCartPageComponent.java b/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutCartPageComponent.java new file mode 100644 index 000000000..00ea25c89 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutCartPageComponent.java @@ -0,0 +1,25 @@ +package com.adyen.v6.jalo.contents.components; + +import de.hybris.platform.jalo.Item; +import de.hybris.platform.jalo.JaloBusinessException; +import de.hybris.platform.jalo.SessionContext; +import de.hybris.platform.jalo.type.ComposedType; +import org.apache.log4j.Logger; + +public class AdyenAccExpressCheckoutCartPageComponent extends GeneratedAdyenAccExpressCheckoutCartPageComponent +{ + @SuppressWarnings("unused") + private static final Logger LOG = Logger.getLogger( AdyenAccExpressCheckoutCartPageComponent.class.getName() ); + + @Override + protected Item createItem(final SessionContext ctx, final ComposedType type, final ItemAttributeMap allAttributes) throws JaloBusinessException + { + // business code placed here will be executed before the item is created + // then create the item + final Item item = super.createItem( ctx, type, allAttributes ); + // business code placed here will be executed after the item was created + // and return the item + return item; + } + +} diff --git a/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutProductPageComponent.java b/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutProductPageComponent.java new file mode 100644 index 000000000..ba36119b6 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/src/com/adyen/v6/jalo/contents/components/AdyenAccExpressCheckoutProductPageComponent.java @@ -0,0 +1,25 @@ +package com.adyen.v6.jalo.contents.components; + +import de.hybris.platform.jalo.Item; +import de.hybris.platform.jalo.JaloBusinessException; +import de.hybris.platform.jalo.SessionContext; +import de.hybris.platform.jalo.type.ComposedType; +import org.apache.log4j.Logger; + +public class AdyenAccExpressCheckoutProductPageComponent extends GeneratedAdyenAccExpressCheckoutProductPageComponent +{ + @SuppressWarnings("unused") + private static final Logger LOG = Logger.getLogger( AdyenAccExpressCheckoutProductPageComponent.class.getName() ); + + @Override + protected Item createItem(final SessionContext ctx, final ComposedType type, final ItemAttributeMap allAttributes) throws JaloBusinessException + { + // business code placed here will be executed before the item is created + // then create the item + final Item item = super.createItem( ctx, type, allAttributes ); + // business code placed here will be executed after the item was created + // and return the item + return item; + } + +} From eb5743dc1aa58d80bf3c820dcebf5fbb5d578932 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Wed, 30 Oct 2024 12:01:43 +0100 Subject: [PATCH 4/4] AD-335 Add Google Pay Express Button with Frontend Logic and API Calls to CMS Components on PDP and Cart Pages - adyen-web version upgrade --- .../tags/responsive/expressCheckoutConfig.tag | 5 +- .../common/js/adyen_express_checkout.js | 188 +++++++++--------- 2 files changed, 96 insertions(+), 97 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 16f8b9030..b14f22313 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/expressCheckoutConfig.tag @@ -27,12 +27,11 @@ shopperLocale: '${shopperLocale}', environment: '${environmentMode}', clientKey: '${clientKey}', - sessionId: '${sessionData.id}', - sessionData: '${sessionData.sessionData}', session: { id: '${sessionData.id}', sessionData: '${sessionData.sessionData}' - } + }, + countryCode: 'US' } 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 ceea56910..ac79f6499 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 @@ -30,8 +30,8 @@ var AdyenExpressCheckoutHybris = (function() { console.error("Checkout error occured"); }, }; - - return await AdyenCheckout(configuration); + console.log(configuration) + return await AdyenWeb.AdyenCheckout(configuration); }, initExpressCheckout: async function (params, config) { var checkoutPromise = this.initiateCheckout(config); @@ -126,108 +126,108 @@ var AdyenExpressCheckoutHybris = (function() { const googlePayNodes = document.getElementsByClassName('adyen-google-pay-button'); - for (let googlePayNode of googlePayNodes) { - let googlePayComponent = checkout.create('googlepay', { + const googlePayConfig = { - // Step 2: Set the callback intents. - buttonSizeMode: "fill", - buttonType: "checkout", + // Step 2: Set the callback intents. + buttonSizeMode: "fill", + buttonType: "checkout", - callbackIntents: ['SHIPPING_ADDRESS'], + callbackIntents: ['SHIPPING_ADDRESS'], - // Step 3: Set shipping configurations. + // Step 3: Set shipping configurations. - shippingAddressRequired: true, - emailRequired: true, + shippingAddressRequired: true, + emailRequired: true, - shippingAddressParameters: { - allowedCountryCodes: [], - phoneNumberRequired: false - }, + shippingAddressParameters: { + allowedCountryCodes: [], + phoneNumberRequired: false + }, - // Shipping options configurations. - shippingOptionRequired: false, + // Shipping options configurations. + shippingOptionRequired: false, - // Step 4: Pass the default shipping options. + // Step 4: Pass the default shipping options. - // shippingOptions: { - // defaultSelectedOptionId: 'shipping-001', - // shippingOptions: [ - // { - // id: 'shipping-001', - // label: '$0.00: Free shipping', - // description: 'Free shipping: delivered in 10 business days.' - // }, - // { - // id: 'shipping-002', - // label: '$1.99: Standard shipping', - // description: 'Standard shipping: delivered in 3 business days.' - // }, - // ] - // }, + // shippingOptions: { + // defaultSelectedOptionId: 'shipping-001', + // shippingOptions: [ + // { + // id: 'shipping-001', + // label: '$0.00: Free shipping', + // description: 'Free shipping: delivered in 10 business days.' + // }, + // { + // id: 'shipping-002', + // label: '$1.99: Standard shipping', + // description: 'Standard shipping: delivered in 3 business days.' + // }, + // ] + // }, - // Step 5: Set the transaction information. + // Step 5: Set the transaction information. - //Required for v6.0.0 or later. - isExpress: true, + //Required for v6.0.0 or later. + isExpress: true, - transactionInfo: { - countryCode: countryCode, - currencyCode: amount.currency, - totalPriceStatus: 'FINAL', - totalPrice: amountDecimal, - totalPriceLabel: 'Total' - }, + transactionInfo: { + countryCode: countryCode, + currencyCode: amount.currency, + totalPriceStatus: 'FINAL', + totalPrice: amountDecimal, + totalPriceLabel: 'Total' + }, - // Step 6: Update the payment data. + // Step 6: Update the payment data. - paymentDataCallbacks: { - onPaymentDataChanged(intermediatePaymentData) { - return new Promise(async resolve => { - const { - callbackTrigger, - shippingAddress, - shippingOptionData - } = intermediatePaymentData; - const paymentDataRequestUpdate = {}; + paymentDataCallbacks: { + onPaymentDataChanged(intermediatePaymentData) { + return new Promise(async resolve => { + const { + callbackTrigger, + shippingAddress, + shippingOptionData + } = intermediatePaymentData; + const paymentDataRequestUpdate = {}; - // Validate the country/region and address selection. - if (shippingAddress.countryCode !== 'US' && shippingAddress.countryCode !== 'BR') { - paymentDataRequestUpdate.error = { - reason: 'SHIPPING_ADDRESS_UNSERVICEABLE', - message: 'Cannot ship to the selected address', - intent: 'SHIPPING_ADDRESS' - }; - } + // Validate the country/region and address selection. + if (shippingAddress.countryCode !== 'US' && shippingAddress.countryCode !== 'BR') { + paymentDataRequestUpdate.error = { + reason: 'SHIPPING_ADDRESS_UNSERVICEABLE', + message: 'Cannot ship to the selected address', + intent: 'SHIPPING_ADDRESS' + }; + } - // If it initializes or changes the shipping address, calculate the shipping options and transaction info. - if (callbackTrigger === 'INITIALIZE' || callbackTrigger === 'SHIPPING_ADDRESS') { - // paymentDataRequestUpdate.newShippingOptionParameters = await fetchNewShippingOptions(shippingAddress.countryCode); - // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); - } + // If it initializes or changes the shipping address, calculate the shipping options and transaction info. + if (callbackTrigger === 'INITIALIZE' || callbackTrigger === 'SHIPPING_ADDRESS') { + // paymentDataRequestUpdate.newShippingOptionParameters = await fetchNewShippingOptions(shippingAddress.countryCode); + // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); + } - // If SHIPPING_OPTION changes, calculate the new shipping amount. - if (callbackTrigger === 'SHIPPING_OPTION') { - // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); - } + // If SHIPPING_OPTION changes, calculate the new shipping amount. + if (callbackTrigger === 'SHIPPING_OPTION') { + // paymentDataRequestUpdate.newTransactionInfo = calculateNewTransactionInfo(/* ... */); + } - resolve(paymentDataRequestUpdate); - }); - } - }, + resolve(paymentDataRequestUpdate); + }); + } + }, - // Step 7: Configure the callback to get the shopper's information. + // Step 7: Configure the callback to get the shopper's information. - onAuthorized: (paymentData) => { - console.log('Shopper details'); - console.log(paymentData) - this.makePayment(this.prepareDataGoogle(paymentData), this.getGoogleUrl()) - }, - onError: function (error) { - console.log(error) - } - }); + onAuthorized: (paymentData) => { + this.makePayment(this.prepareDataGoogle(paymentData), this.getGoogleUrl()) + }, + onError: function (error) { + console.log(error) + } + } + + for (let googlePayNode of googlePayNodes) { + let googlePayComponent = new AdyenWeb.GooglePay(checkout, googlePayConfig); googlePayComponent.isAvailable() .then(function () { googlePayComponent.mount(googlePayNode); @@ -327,21 +327,21 @@ var AdyenExpressCheckoutHybris = (function() { }, prepareDataGoogle: function(paymentData) { const baseData = { - googlePayToken: paymentData.paymentMethodData.tokenizationData.token, - googlePayCardNetwork: paymentData.paymentMethodData.info.cardNetwork, + googlePayToken: paymentData.authorizedEvent.paymentMethodData.tokenizationData.token, + googlePayCardNetwork: paymentData.authorizedEvent.paymentMethodData.info.cardNetwork, addressData: { - email: paymentData.email, - firstName: paymentData.shippingAddress.name, + email: paymentData.authorizedEvent.email, + firstName: paymentData.deliveryAddress.firstName, // lastName: paymentData.payment.shippingContact.familyName, - line1: paymentData.shippingAddress.address1, - line2: paymentData.shippingAddress.address2, - postalCode: paymentData.shippingAddress.postalCode, - town: paymentData.shippingAddress.locality, + line1: paymentData.deliveryAddress.street, + line2: paymentData.deliveryAddress.houseNumberOrName, + postalCode: paymentData.deliveryAddress.postalCode, + town: paymentData.deliveryAddress.city, country: { - isocode: paymentData.shippingAddress.countryCode, + isocode: paymentData.deliveryAddress.country, }, region: { - isocode: paymentData.shippingAddress.administrativeArea + isocodeShort: paymentData.deliveryAddress.stateOrProvince } } }