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 4a9fc848..678a7cae 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 81e0502b..528ae66a 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 00000000..16f8b903 --- /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 700402a8..b0d28fa1 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 702561d7..33d2fb0b 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 271d2d91..ceea5691 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 09a8d50d..ce1c990e 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()); }