From 6fadf69fc8ca540909cd12e5f95a736ff6b8425c Mon Sep 17 00:00:00 2001 From: kpieloch <113994423+kpieloch@users.noreply.github.com> Date: Thu, 3 Oct 2024 09:24:39 +0200 Subject: [PATCH 1/2] AD-291: Upgrade Adyen web component to v6 --- .../common/js/adyen-checkout/package.json | 5 +- .../src/components/payment/Payment.tsx | 59 +- .../src/service/paymentService.ts | 2 +- .../src/types/adyenConfigData.ts | 53 +- .../AdyenSummaryCheckoutStepController.java | 29 +- .../WEB-INF/tags/responsive/adyenLibrary.tag | 6 +- .../paymentMethodsConfiguration.tag | 135 ++ .../pages/checkout/multi/3ds_payment.jsp | 10 + .../checkout/multi/checkoutSummaryPage.jsp | 43 +- .../multi/selectPaymentMethodPage.jsp | 56 +- .../responsive/common/js/adyen.checkout.js | 1488 ++++------------- .../common/js/adyen_component_factory.js | 605 +++++++ .../common/js/adyen_form_validator.js | 115 ++ adyenv6b2ccheckoutaddon/project.properties | 3 +- 14 files changed, 1299 insertions(+), 1310 deletions(-) create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_component_factory.js create mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_form_validator.js diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/package.json b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/package.json index bf8b7c96e..64d2db4c7 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/package.json +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "@adyen/adyen-web": "5.57.0", + "@adyen/adyen-web": "6.1.1", "@babel/core": "^7.16.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", "@reduxjs/toolkit": "^2.0.1", @@ -68,6 +68,9 @@ "webpack-manifest-plugin": "^4.0.2", "workbox-webpack-plugin": "^6.4.1" }, + "exports": { + "./dist/adyen.css": "./dist/adyen.css" + }, "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js", diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/payment/Payment.tsx b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/payment/Payment.tsx index b6c154b86..3f86d7506 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/payment/Payment.tsx +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/payment/Payment.tsx @@ -9,24 +9,19 @@ import {AddressData} from "../../types/addressData"; import {InputCheckbox} from "../controls/InputCheckbox"; import {AddressService} from "../../service/addressService"; import {AdyenConfigService} from "../../service/adyenConfigService"; -import AdyenCheckout from '@adyen/adyen-web'; -import '@adyen/adyen-web/dist/adyen.css'; +import { AdyenCheckout, Dropin,AdyenCheckoutError, ICore } from '@adyen/adyen-web/auto' +import '@adyen/adyen-web/styles/adyen.css'; import {AdyenConfigData} from "../../types/adyenConfigData"; import {isEmpty, isNotEmpty} from "../../util/stringUtil"; -import {CoreOptions} from "@adyen/adyen-web/dist/types/core/types"; -import {ActionHandledReturnObject, OnPaymentCompletedData} from "@adyen/adyen-web/dist/types/components/types"; -import AdyenCheckoutError from "@adyen/adyen-web/dist/types/core/Errors/AdyenCheckoutError"; -import Core from "@adyen/adyen-web/dist/types/core"; import {PlaceOrderRequest} from "../../types/paymentForm"; import {PaymentService, PlaceOrderResponse} from "../../service/paymentService"; -import {UIElement} from "@adyen/adyen-web/dist/types/components/UIElement"; import {translationsStore} from "../../store/translationsStore"; import AddressSection from "../common/AddressSection"; import {routes} from "../../router/routes"; import {Navigate} from "react-router-dom"; import {PaymentError} from "./PaymentError"; import {ScrollHere} from "../common/ScrollTo"; -import DropinElement from "@adyen/adyen-web/dist/types/components/Dropin"; +import {CoreConfiguration,CardConfiguration, UIElement} from "@adyen/adyen-web"; interface State { useDifferentBillingAddress: boolean @@ -68,7 +63,7 @@ class Payment extends React.Component { paymentRef: RefObject threeDSRef: RefObject - dropIn: DropinElement + dropIn: Dropin constructor(props: Props) { super(props); @@ -105,22 +100,14 @@ class Payment extends React.Component { this.initiateDropIn(adyenCheckout) } - private getAdyenCheckoutConfig(): CoreOptions { + private getAdyenCheckoutConfig(): CoreConfiguration { return { - paymentMethodsConfiguration: { - card: { - type: 'card', - hasHolderName: true, - holderNameRequired: this.props.adyenConfig.cardHolderNameRequired, - enableStoreDetails: this.props.adyenConfig.showRememberTheseDetails - } - }, paymentMethodsResponse: { paymentMethods: this.props.adyenConfig.paymentMethods, storedPaymentMethods: this.props.adyenConfig.storedPaymentMethodList }, locale: this.props.adyenConfig.shopperLocale, - environment: this.props.adyenConfig.environmentMode, + environment: this.castToEnvironment(this.props.adyenConfig.environmentMode), clientKey: this.props.adyenConfig.adyenClientKey, session: { id: this.props.adyenConfig.sessionData.id, @@ -133,25 +120,39 @@ class Payment extends React.Component { risk: { enabled: true }, - onPaymentCompleted(data: OnPaymentCompletedData, element?: UIElement) { - console.info(data, element); - }, onError: (error: AdyenCheckoutError, element?: UIElement) => { this.handleError() }, onSubmit: (state: any, element: UIElement) => this.handlePayment(state.data), - onAdditionalDetails: (state: any, element?: UIElement) => this.handleAdditionalDetails(state.data), - onActionHandled(data: ActionHandledReturnObject) { - console.log("onActionHandled", data); - } + onAdditionalDetails: (state: any, element?: UIElement) => this.handleAdditionalDetails(state.data) } } - private initiateDropIn(adyenCheckout: Core) { + private getAdyenCardConfig(): CardConfiguration { + return { + type: 'card', + hasHolderName: true, + holderNameRequired: this.props.adyenConfig.cardHolderNameRequired, + enableStoreDetails: this.props.adyenConfig.showRememberTheseDetails + } + } - this.dropIn = adyenCheckout.create("dropin"); + private castToEnvironment(env: string): CoreConfiguration['environment'] { + const validEnvironments: CoreConfiguration['environment'][] = ['test', 'live', 'live-us', 'live-au', 'live-apse', 'live-in']; + if (validEnvironments.includes(env as CoreConfiguration['environment'])) { + return env as CoreConfiguration['environment']; + } + throw new Error(`Invalid environment: ${env}`); + } + + private initiateDropIn(adyenCheckout: ICore) { + + this.dropIn = new Dropin(adyenCheckout, { + paymentMethodsConfiguration: { + card: this.getAdyenCardConfig() + } + }).mount(this.paymentRef.current); - this.dropIn.mount(this.paymentRef.current) } private async handleError(){ diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/paymentService.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/paymentService.ts index 2a75d3912..0ffec335e 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/paymentService.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/paymentService.ts @@ -2,7 +2,7 @@ import {AxiosError, AxiosResponse} from "axios"; import {CSRFToken, urlContextPath} from "../util/baseUrlUtil"; import {AddressData, PlaceOrderRequest} from "../types/paymentForm"; import {AddressModel} from "../reducers/types"; -import {PaymentAction} from "@adyen/adyen-web/dist/types/types"; +import {PaymentAction} from "@adyen/adyen-web"; import {ErrorResponse} from "../types/errorResponse"; import {adyenAxios} from "../axios/AdyenAxios"; diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/adyenConfigData.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/adyenConfigData.ts index 43d102785..577ea8ce2 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/adyenConfigData.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/adyenConfigData.ts @@ -1,5 +1,7 @@ +import {PaymentMethod} from "@adyen/adyen-web"; + export interface AdyenConfigData { - paymentMethods: PaymentMethodData[]; + paymentMethods: PaymentMethod[]; connectedTerminalList: string[]; storedPaymentMethodList: StoredPaymentMethodData[]; issuerLists: Map; @@ -31,55 +33,6 @@ interface SessionData { sessionData: string } -export interface PaymentMethodData { - brand?: string; - brands?: string[]; - configuration: object; - issuers?: PaymentMethodIssuerData[]; - fundingSource?: string; - group?: PaymentMethodGroupData; - inputDetails?: InputDetailData[]; - name: string; - type: string; -} - -interface PaymentMethodIssuerData { - disabled: boolean; - id: string; - name: string; -} - -interface InputDetailData { - onfiguration: Map - details: SubInputDetailData[]; - itemSearchUrl: string; - items: ItemData[]; - key: string; - optional: boolean; - type: string; - value: string; -} - -interface SubInputDetailData { - items: ItemData[]; - key: string; - optional: boolean; - type: string; - value: string; - configuration: Map; -} - -interface ItemData { - id: string; - name: string; -} - -interface PaymentMethodGroupData { - name: string; - paymentMethodData: string; - type: string; -} - interface StoredPaymentMethodData { brand: string; expiryMonth: string; diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java index 4580b38d6..151b06dec 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/src/com/adyen/v6/controllers/pages/AdyenSummaryCheckoutStepController.java @@ -47,11 +47,14 @@ import de.hybris.platform.basecommerce.model.site.BaseSiteModel; import de.hybris.platform.cms2.exceptions.CMSItemNotFoundException; import de.hybris.platform.commercefacades.order.OrderFacade; +import de.hybris.platform.commercefacades.order.data.CCPaymentInfoData; import de.hybris.platform.commercefacades.order.data.CartData; import de.hybris.platform.commercefacades.order.data.OrderData; import de.hybris.platform.commercefacades.order.data.OrderEntryData; import de.hybris.platform.commercefacades.product.ProductOption; import de.hybris.platform.commercefacades.product.data.ProductData; +import de.hybris.platform.commercefacades.user.data.AddressData; +import de.hybris.platform.commercefacades.user.data.CountryData; import de.hybris.platform.commerceservices.order.CommerceCartModificationException; import de.hybris.platform.order.InvalidCartException; import de.hybris.platform.order.exceptions.CalculationException; @@ -77,6 +80,7 @@ import java.net.SocketTimeoutException; import java.util.Arrays; import java.util.Objects; +import java.util.Optional; import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.CHALLENGESHOPPER; import static com.adyen.model.checkout.PaymentResponse.ResultCodeEnum.ERROR; @@ -183,6 +187,18 @@ public String enterStep(final Model model, final RedirectAttributes redirectAttr return AdyenControllerConstants.Views.Pages.MultiStepCheckout.CheckoutSummaryPage; } + protected String getCountryCode(final CartData cartData) { + //Identify country code based on shopper's delivery address + return Optional.ofNullable(cartData.getPaymentInfo()) + .map(CCPaymentInfoData::getBillingAddress) + .map(billingAddress -> Optional.ofNullable(billingAddress).or(() -> Optional.ofNullable(cartData.getDeliveryAddress()))) + .filter(Optional::isPresent) + .map(Optional::get) + .map(AddressData::getCountry) + .map(CountryData::getIsocode) + .orElse(""); + } + @PostMapping({"/placeOrder"}) @RequireHardLogIn public String placeOrder(@ModelAttribute("placeOrderForm") final PlaceOrderForm placeOrderForm, @@ -284,7 +300,7 @@ public String placeOrder(@ModelAttribute("placeOrderForm") final PlaceOrderForm if (REDIRECTSHOPPER == paymentsResponse.getResultCode()) { if (is3DSPaymentMethod(adyenPaymentMethod)) { LOGGER.debug("PaymentResponse resultCode is REDIRECTSHOPPER, redirecting shopper to 3DS flow"); - return redirectTo3DSValidation(model, paymentsResponse); + return redirectTo3DSValidation(model, paymentsResponse, cartData); } if (AFTERPAY_TOUCH.equals(adyenPaymentMethod)) { LOGGER.debug("PaymentResponse resultCode is REDIRECTSHOPPER, redirecting shopper to afterpaytouch page"); @@ -497,6 +513,17 @@ private String redirectToSelectPaymentMethodWithError(final RedirectAttributes r return REDIRECT_PREFIX + SELECT_PAYMENT_METHOD_PREFIX; } + protected String redirectTo3DSValidation(Model model, PaymentResponse paymentsResponse, CartData cartData) throws JsonProcessingException { + PaymentResponseAction action = paymentsResponse.getAction(); + model.addAttribute(MODEL_CLIENT_KEY, adyenCheckoutFacade.getClientKey()); + model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost()); + model.addAttribute(MODEL_ENVIRONMENT_MODE, adyenCheckoutFacade.getEnvironmentMode()); + model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale()); + model.addAttribute("countryCode", getCountryCode(cartData)); + model.addAttribute(ACTION, ( ((CheckoutRedirectAction) action.getActualInstance()).toJson())); + return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DSPaymentPage; + } + protected String redirectTo3DSValidation(Model model, PaymentResponse paymentsResponse) throws JsonProcessingException { PaymentResponseAction action = paymentsResponse.getAction(); model.addAttribute(MODEL_CLIENT_KEY, adyenCheckoutFacade.getClientKey()); diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/adyenLibrary.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/adyenLibrary.tag index ab85d1cc8..7d2d3a73b 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/adyenLibrary.tag +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/adyenLibrary.tag @@ -22,7 +22,7 @@ <%@ attribute name="dfUrl" required="false" type="java.lang.String"%> <%@ attribute name="showDefaultCss" required="false" type="java.lang.Boolean"%> - + @@ -35,9 +35,9 @@ crossorigin="anonymous"> - +--%> diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag new file mode 100644 index 000000000..2297459d0 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag @@ -0,0 +1,135 @@ + + + \ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds_payment.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds_payment.jsp index f775726e2..6f59682fb 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds_payment.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/3ds_payment.jsp @@ -10,12 +10,22 @@ + + + diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp index a1dcd37f6..5e915efd8 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/selectPaymentMethodPage.jsp @@ -20,8 +20,14 @@ dfUrl="${dfUrl}" showDefaultCss="${true}" /> - diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen.checkout.js b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen.checkout.js index 241b86a43..d0b4a1435 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen.checkout.js +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen.checkout.js @@ -1,1210 +1,332 @@ -var AdyenCheckoutHybris = (function () { - 'use strict'; - - var CardBrand = { - Visa: 'visa', - MasterCard: 'mc', - Elo: 'elo', - Maestro: 'maestro', - Electron: 'electron', - EloDebit: 'elodebit' - }; - - var ErrorMessages = { - PaymentCancelled: 'checkout.error.authorization.payment.cancelled', - PaymentError: 'checkout.error.authorization.payment.error', - PaymentNotAvailable: 'checkout.summary.component.notavailable', - TermsNotAccepted: 'checkout.error.terms.not.accepted' - }; - - return { - oneClickForms: [], - dobDateFormat: "yy-mm-dd", - securedFieldsData: {}, - allowedCards: [], - cseEncryptedForm: null, - checkout: null, - card: null, - oneClickCards: {}, - selectedCardBrand: null, - sepaDirectDebit: null, - afterPay: null, - bcmc: null, - paypalButton: null, - - convertCardBrand: function () { - var cardBrand = this.selectedCardBrand; - - if (cardBrand === CardBrand.Visa) { +// Constants +const CardBrand = { + Visa: 'visa', + MasterCard: 'mc', + Elo: 'elo', + Maestro: 'maestro', + Electron: 'electron', + EloDebit: 'elodebit' +}; + +const ErrorMessages = { + PaymentCancelled: 'checkout.error.authorization.payment.cancelled', + PaymentError: 'checkout.error.authorization.payment.error', + PaymentNotAvailable: 'checkout.summary.component.notavailable', + TermsNotAccepted: 'checkout.error.terms.not.accepted' +}; + +// Helper Functions +function showAlert(message) { + window.alert(message); +} + +function isValidCard(card, isDebitCard, isValidBrandType) { + return card.isValid && (!isDebitCard || isValidBrandType); +} + +class AdyenCheckoutHelper { + + constructor() { + this.oneClickForms = []; + this.dobDateFormat = "yy-mm-dd"; + this.securedFieldsData = {}; + this.allowedCards = []; + this.cseEncryptedForm = null; + this.checkout = null; + this.card = null; + this.oneClickCards = {}; + this.selectedCardBrand = null; + this.sepaDirectDebit = null; + this.afterPay = null; + this.bcmc = null; + this.paypalButton = null; + this.formValidator = new AdyenFormValidator(this); + this.factory = null; + } + i =0; + + async initiateCheckout(initConfig, paymentMethodConfigs) { + const configuration = { + ...initConfig, + analytics: { + enabled: false // Set to false to not send analytics data to Adyen. + }, + risk: { + enabled: false + }, + onPaymentCompleted: (result, component) => { + console.info(result, component); + }, + onError: (error, component) => { + console.error(error.name, error.message, error.stack, component); + }, + }; + console.log("Execution of initiateCheckout: ", this.i++); + this.checkout = await AdyenCheckout(configuration); + this.factory = new PaymentComponentFactory(this.checkout, this); + this.factory.createFromConfigs(paymentMethodConfigs); + } + + convertCardBrand() { + switch (this.selectedCardBrand) { + case CardBrand.Visa: return CardBrand.Electron; - } - - if (cardBrand === CardBrand.MasterCard) { + case CardBrand.MasterCard: return CardBrand.Maestro; - } - if (cardBrand === CardBrand.Elo) { + case CardBrand.Elo: return CardBrand.EloDebit; - } - }, - - isValidBrandType: function () { - var cardBrand = this.selectedCardBrand; - return cardBrand === CardBrand.Visa || cardBrand === CardBrand.MasterCard || cardBrand === CardBrand.Elo; - }, - - getCardType: function () { - var cardType = $('#adyen_combo_card_type').val(); - if (cardType === "" || cardType == undefined) - cardType = "credit"; - return cardType; - }, - - isDebitCard: function () { - return this.getCardType() === 'debit'; - }, - - validateForm: function () { - var paymentMethod = $('input[type=radio][name=paymentMethod]:checked').val(); - - if (paymentMethod === "") { - window.alert("Please select a payment method"); - return false; - } - - // Check if it is a valid card and encrypt - if (paymentMethod === "adyen_cc") { - var isInvalidCard = !this.card.isValid || - (this.isDebitCard() && !this.isValidBrandType()); - - if (isInvalidCard) { - window.alert('Please check your card details.'); - this.card.showValidation(); - document.getElementById("card-div").scrollIntoView(); - return false; - } - this.copyCardData(); - } - - if (paymentMethod.indexOf("adyen_oneclick_") === 0) { - var recurringReference = paymentMethod.slice("adyen_oneclick_".length); - var oneClickCard = this.oneClickCards[recurringReference]; - - if (!(oneClickCard && oneClickCard.isValid)) { - window.alert('This credit card is not allowed'); - return false; - } - if (['bcmc', 'maestro'].indexOf(oneClickCard.props.brand) >= 0) { - this.copyOneClickCardBrandData(recurringReference, oneClickCard.props.brand) - } else { - this.copyOneClickCardData(recurringReference, oneClickCard.data.paymentMethod.encryptedSecurityCode, oneClickCard.props.brand); - } - } - $('input[name="txvariant"]').remove(); - - if (['eps', 'ideal','onlinebanking_IN', 'onlineBanking_PL'].indexOf(paymentMethod) >= 0) { - var issuerIdField = document.getElementById('issuerId'); - if (issuerIdField.value === "") { - window.alert("Please select an issuer"); - return false; - } - } - - if (paymentMethod === "pos") { - var terminalId = $('#adyen_pos_terminal'); - if (terminalId.val() === "") { - window.alert("Please select a terminal"); - return false; - } - } - - if (paymentMethod === "sepadirectdebit") { - if (!this.sepaDirectDebit.state.isValid) { - window.alert("Invalid SEPA Owner Name and IBAN number"); - return false; - } - } - - if (paymentMethod === "afterpay_default") { - if (!this.afterPay.state.isValid) { - window.alert("Please fill all the details"); - this.afterPay.showValidation(); - document.getElementById("afterpay-container").scrollIntoView(); - return false; - } - var dob = $("input[name=dateOfBirth]").val(); - if (dob) { - $("#dob").val(dob); - } - } - - if (paymentMethod === "paybright") { - var phoneNumber = $("#p_method_adyen_hpp_paybright_telephonenumber").val(); - if (!phoneNumber) { - window.alert("Please fill phone number"); - document.getElementById("p_method_adyen_hpp_paybright_telephonenumber").scrollIntoView(); - return false; - } - } - if (paymentMethod === "giftcard") { - $('input[name="giftCardBrand"]').val($('input[type=radio][name=paymentMethod]:checked').attr('brand')); - } - - if (paymentMethod === "bcmc") { - if (!this.bcmc.state.isValid) { - window.alert("Please fill all the details"); - this.bcmc.showValidation(); - document.getElementById("bcmc-container").scrollIntoView(); - return false; - } - var state = this.bcmc.data.paymentMethod; - $('input[name="encryptedCardNumber"]').val(state.encryptedCardNumber); - $('input[name="encryptedExpiryMonth"]').val(state.encryptedExpiryMonth); - $('input[name="encryptedExpiryYear"]').val(state.encryptedExpiryYear); - $('input[name="cardHolder"]').val(state.holderName); - $('input[name="cardBrand"]').val('bcmc'); - $('input[name="cardType"]').val('debit'); - $('input[name="browserInfo"]').val(JSON.stringify(this.bcmc.data.browserInfo)); - } - - return true; - }, - - copyCardData: function () { - var state = this.card.data.paymentMethod; - $('input[name="encryptedCardNumber"]').val(state.encryptedCardNumber); - $('input[name="encryptedExpiryMonth"]').val(state.encryptedExpiryMonth); - $('input[name="encryptedExpiryYear"]').val(state.encryptedExpiryYear); - $('input[name="encryptedSecurityCode"]').val(state.encryptedSecurityCode); - $('input[name="cardHolder"]').val(state.holderName); - if (this.card.data.storePaymentMethod != null) { - $('input[name="rememberTheseDetails"]').val(this.card.data.storePaymentMethod); - } - - if (this.isDebitCard()) { - $('input[name="cardBrand"]').val(this.convertCardBrand()); - $('input[name="cardType"]').val(this.getCardType()); - } else { - $('input[name="cardBrand"]').val(this.selectedCardBrand); - } - $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); - }, - - copyOneClickCardData: function (recurringReference, cvc, brand) { - $("#selectedReference").val(recurringReference); - $('input[name="encryptedSecurityCode"]').val(cvc); - $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); - if (brand) { - $('input[name="cardBrand"]').val(brand); - } + default: + return this.selectedCardBrand; + } + } + + isValidBrandType() { + return [CardBrand.Visa, CardBrand.MasterCard, CardBrand.Elo].includes(this.selectedCardBrand); + } + + getCardType() { + let cardType = $('#adyen_combo_card_type').val(); + return cardType ? cardType : "credit"; + } + + isDebitCard() { + return this.getCardType() === 'debit'; + } + + validateForm() { + return this.formValidator.validateForm(); + } + + copyCardData() { + const state = this.card.data.paymentMethod; + $('input[name="encryptedCardNumber"]').val(state.encryptedCardNumber); + $('input[name="encryptedExpiryMonth"]').val(state.encryptedExpiryMonth); + $('input[name="encryptedExpiryYear"]').val(state.encryptedExpiryYear); + $('input[name="encryptedSecurityCode"]').val(state.encryptedSecurityCode); + $('input[name="cardHolder"]').val(state.holderName); + if (this.card.data.storePaymentMethod != null) { + $('input[name="rememberTheseDetails"]').val(this.card.data.storePaymentMethod); + } - }, - copyOneClickCardBrandData: function (recurringReference, brand) { - $("#selectedReference").val(recurringReference); + if (this.isDebitCard()) { + $('input[name="cardBrand"]').val(this.convertCardBrand()); + $('input[name="cardType"]').val(this.getCardType()); + } else { + $('input[name="cardBrand"]').val(this.selectedCardBrand); + } + $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); + } + + copyOneClickCardData(recurringReference, cvc, brand) { + $("#selectedReference").val(recurringReference); + $('input[name="encryptedSecurityCode"]').val(cvc); + $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); + if (brand) { $('input[name="cardBrand"]').val(brand); - $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); - }, - - /** - * Set Custom values for certain payment methods - */ - setCustomPaymentMethodValues: function () { - var paymentMethod = $('input[type=radio][name=paymentMethod]:checked').val(); - var dob = $('#p_method_adyen_hpp_' + paymentMethod + '_dob').val(); - if (dob) { - $("#dob").val(dob); - } - - var ssn = $('#p_method_adyen_hpp_' + paymentMethod + '_ssn'); - if (ssn) { - $("#socialSecurityNumber").val(ssn.val()); - } - - var terminalId = $('#adyen_pos_terminal'); - if (terminalId) { - $("#terminalId").val(terminalId.val()); - } - - var firstName = $('#p_method_adyen_hpp_' + paymentMethod + '_first_name').val(); - if (firstName) { - $("#firstName").val(firstName); - } - - var lastName = $('#p_method_adyen_hpp_' + paymentMethod + '_last_name').val(); - if (lastName) { - $("#lastName").val(lastName); - } - }, - - /** - * Create DatePicker for Date of Birth field - * - * @param element - */ - createDobDatePicker: function (element) { - $("." + element).datepicker({ - dateFormat: this.dobDateFormat, - changeMonth: true, - changeYear: true, - yearRange: "-120:+0" - }); - }, - - - togglePaymentMethod: function (paymentMethod) { - $(".payment_method_details").hide(); - $(".chckt-pm__details").hide(); - - $("#dd_method_" + paymentMethod).show(); - $("#adyen_hpp_" + paymentMethod + "_container").show(); - }, - - createDfValue: function () { - window.dfDo("dfValue"); - }, - - checkTermsAndConditions: function (checked) { - $('.adyen-terms-conditions-check').prop('checked', checked) - if (checked) { - actions.enable(); - $('.adyen-terms-conditions-check-error').addClass('hidden'); - } else { - actions.disable(); - $('.adyen-terms-conditions-check-error').removeClass('hidden'); - } - }, - - showCheckTermsAndConditionsError: function (checked) { - const $errorMessage = $('.adyen-terms-conditions-check-error'); - if ($('.adyen-terms-conditions-check').prop('checked')) { - $errorMessage.addClass('hidden'); - } else { - $errorMessage.removeClass('hidden'); - } - }, - - /** - * - * @returns {Promise} - * @param initConfig - * @param fnCallbackArray - */ - initiateCheckout: async function (initConfig, fnCallbackArray) { - const configuration = { - ...initConfig, - analytics: { - enabled: false // Set to false to not send analytics data to Adyen. - }, - risk: { - enabled: false - }, - onPaymentCompleted: (result, component) => { - console.info(result, component); - }, - onError: (error, component) => { - console.error(error.name, error.message, error.stack, component); - }, - }; - - this.checkout = await AdyenCheckout(configuration); - for (let callback of Object.keys(fnCallbackArray)) { - const params = fnCallbackArray[callback]; - if (params && params.hasOwnProperty('label') && !!params.label) { - for (const label of params.label) { - const paramsWithLabel = { - ...params, - label: label - }; - this[callback](paramsWithLabel); - } - } else { - this[callback](params); - } - } - }, - - initiateOneClickCard: function (storedCardList) { - if (storedCardList && storedCardList.length) { - for (const storedCard of storedCardList) { - const oneClickCardNode = document.getElementById("one-click-card_" + storedCard.storedPaymentMethodId); - const oneClickCard = this.checkout.create('card', storedCard); - oneClickCard.mount(oneClickCardNode); - this.oneClickCards[storedCard.storedPaymentMethodId] = oneClickCard; - } - } - }, - - /** - * - * @param functionParameters - */ - initiateCard: function (functionParameters) { - const {allowedCards, showRememberDetails, cardHolderNameRequired} = functionParameters; - const context = this; - this.card = this.checkout.create('card', { - type: 'card', - hasHolderName: true, - holderNameRequired: cardHolderNameRequired, - enableStoreDetails: showRememberDetails, - brands: allowedCards, - onBrand: copyCardBrand - - }); - - function copyCardBrand (event) { - context.selectedCardBrand = event.brand; - } - - this.card.mount(document.getElementById('card-div')); - }, - - /** - * - */ - initiateSepaDirectDebit: function () { - const sepaDirectDebitNode = document.getElementById('adyen_hpp_sepadirectdebit_container'); - if (this.checkout) { - this.sepaDirectDebit = this.checkout.create('sepadirectdebit', { - onChange: handleOnChange - }); - - function handleOnChange (event) { - var sepaOwnerNameField = document.getElementById('sepaOwnerName'); - var sepaIbanNumberField = document.getElementById('sepaIbanNumber'); - - var sepaOwnerName = event.data.paymentMethod["ownerName"] - var sepaIbanNumber = event.data.paymentMethod["iban"] - - sepaOwnerNameField.value = sepaOwnerName; - sepaIbanNumberField.value = sepaIbanNumber; - } - - this.sepaDirectDebit.mount(sepaDirectDebitNode); - } - }, - - initiateIdeal: function (idealDetails) { - var idealNode = document.getElementById('adyen_hpp_ideal_container'); - var ideal = this.checkout.create('ideal', { - details: idealDetails, // The array of issuers coming from the /paymentMethods api call - showImage: true, // Optional, defaults to true - onChange: handleChange // Gets triggered whenever a user selects a bank// Gets triggered once the state is valid - }); - - function handleChange (event) { - var issuerIdField = document.getElementById('issuerId'); - var issuerId = event.data.paymentMethod.issuer; - issuerIdField.value = issuerId; - } - - try { - ideal.mount(idealNode); - } catch (e) { - console.log('Something went wrong trying to mount the iDEAL component: ${e}'); - } - }, - - initiateOnlinebankingIN: function () { - let onlineBankingInNode = document.getElementById('adyen_hpp_onlinebanking_IN_container'); - let onlineBankingIn = this.checkout.create('onlinebanking_IN', { - onChange: handleChange // Gets triggered whenever a user selects a bank// Gets triggered once the state is valid - }); - - function handleChange (event) { - let issuerIdField = document.getElementById('issuerId'); - let issuerId = event.data.paymentMethod.issuer; - issuerIdField.value = issuerId; - } - - try { - onlineBankingIn.mount(onlineBankingInNode); - } catch (e) { - console.log('Something went wrong trying to mount the onlineBanking_In component: ${e}'); - } - }, - initiateOnlineBankingPL: function () { - let onlineBankingPlNode = document.getElementById('adyen_hpp_onlineBanking_PL_container'); - let onlineBankingPl = this.checkout.create('onlineBanking_PL', { - onChange: handleChange // Gets triggered whenever a user selects a bank// Gets triggered once the state is valid - }); - - function handleChange (event) { - let issuerIdField = document.getElementById('issuerId'); - let issuerId = event.data.paymentMethod.issuer; - issuerIdField.value = issuerId; - } - - try { - onlineBankingPl.mount(onlineBankingPlNode); - } catch (e) { - console.log('Something went wrong trying to mount the onlineBanking_PL component: ${e}'); - } - }, - - initiateWalletIN: function () { - let walletInNode = document.getElementById('adyen_hpp_wallet_IN_container'); - let walletIn = this.checkout.create('wallet_IN', { - onChange: handleChange // Gets triggered whenever a user selects a bank// Gets triggered once the state is valid - }); - - function handleChange (event) { - let issuerIdField = document.getElementById('issuerId'); - let issuerId = event.data.paymentMethod.issuer; - issuerIdField.value = issuerId; - } - - try { - walletIn.mount(walletInNode); - } catch (e) { - console.log('Something went wrong trying to mount the upi_In component: ${e}'); - } - }, - - initiateUPI: function () { - const label = this.getVisibleLabel(); - const self = this; - const uPINode = document.getElementById('adyen-component-button-container-' + label); - let upi = this.checkout.create('upi', { - onPaymentCompleted: handlePaymentResult, - defaultMode:'vpa', - showPayButton:true, - }); - - function handlePaymentResult(result, component){ - $.ajax({ - url: ACC.config.encodedContextPath + '/adyen/component/resultHandler', - type: "POST", - data: JSON.stringify({ - resultCode: result.resultCode, - sessionData: result.sessionData - }), - contentType: "application/json; charset=utf-8", - success: function (data) { - try { - window.location.href = ACC.config.encodedContextPath + "/" + data.replace("redirect:/",""); - } catch (e) { - console.log('Error redirecting the user to the placeOrder page'); - AdyenCheckoutHybris.handleResult(ErrorMessages.PaymentError, true); - } - }, - error: function (xmlHttpResponse, exception) { - var responseMessage = xmlHttpResponse.responseJSON; - if (xmlHttpResponse.status === 400) { - AdyenCheckoutHybris.handleResult(responseMessage, true); - } else { - console.log('Error on handling the redirect to the placeOrder page: ' + responseMessage); - handleResult(ErrorMessages.PaymentError, true); - } - } - }) - } - try { - upi.mount(uPINode); - } catch (e) { - console.log('Something went wrong trying to mount the upi component: ${e}'); - } - }, - - initiatePaytm: function () { - let payTmNode = document.getElementById('adyen_hpp_paytm_container'); - let payTm = this.checkout.create('paytm'); - try { - payTm.mount(payTmNode); - } catch (e) { - console.log('Something went wrong trying to mount the paytm component: ${e}'); - } - }, - - initiateEps: function (epsDetails) { - var epsNode = document.getElementById('adyen_hpp_eps_container'); - var eps = this.checkout.create('eps', { - issuers: epsDetails, // The array of issuers coming from the /paymentMethods api call - showImage: true, // Optional, defaults to true - onChange: handleOnChange // Gets triggered once the shopper selects an issuer - }); - - function handleOnChange (event) { - var issuerIdField = document.getElementById('issuerId'); - var issuerId = event.data.paymentMethod.issuer; - issuerIdField.value = issuerId; - } - - try { - eps.mount(epsNode); - } catch (e) { - console.log('Something went wrong trying to mount the EPS component: ${e}'); - } - }, - - /** - * - * @param params - */ - initiatePaypal: function (params) { - const {amount, isImmediateCapture, paypalMerchantId, label} = params; - const paypalNode = document.getElementById('adyen-component-button-container-' + label); - const self = this; + } - const adyenComponent = this.checkout.create("paypal", { - style: { // Optional configuration for PayPal payment buttons. - layout: "vertical", - color: "gold" - }, - environment: this.checkout.options.environment, - amount: { - currency: amount.currency, - value: amount.value - }, - configuration: { - intent: isImmediateCapture ? "capture" : "authorize", - merchantId: (this.checkout.options.environment === 'test') ? null : paypalMerchantId, // Your PayPal Merchant ID. Required for accepting live payments. - }, - blockPayPalCreditButton: true, - blockPayPalPayLaterButton: true, - onInit: (data, actions) => { - actions.enable(); - $(document).on('change', '.adyen-terms-conditions-check', function (event) { - const checked = (event.target.checked) - $('.adyen-terms-conditions-check').prop('checked', checked) - if (checked) { - actions.enable(); - } else { - actions.disable(); - } - self.showCheckTermsAndConditionsError(); - }); - }, - onClick: function () { - // Show a validation error if the checkbox is not checked - self.showCheckTermsAndConditionsError(); - }, - onChange: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return false; - } - self.makePayment(state.data, component, self.handleResult, label); - }, - onCancel: function (data, component) { - // Sets your prefered status of the component when a PayPal payment is cancelled. - self.handleResult(ErrorMessages.PaymentCancelled, true); - }, - onError: function (error, component) { - // Sets your prefered status of the component when an error occurs. - if (error.name === 'CANCEL') { - self.handleResult(ErrorMessages.PaymentCancelled, true); - } else { - self.handleResult(ErrorMessages.PaymentError, true); - } - }, - onAdditionalDetails: function (state, component) { - self.submitDetails(state.data, self.handleResult); - } - }); + } + + copyOneClickCardBrandData(recurringReference, brand) { + $("#selectedReference").val(recurringReference); + $('input[name="cardBrand"]').val(brand); + $('input[name="browserInfo"]').val(JSON.stringify(this.card.data.browserInfo)); + } + + /** + * Set Custom values for certain payment methods + */ + setCustomPaymentMethodValues() { + var paymentMethod = $('input[type=radio][name=paymentMethod]:checked').val(); + var dob = $('#p_method_adyen_hpp_' + paymentMethod + '_dob').val(); + if (dob) { + $("#dob").val(dob); + } - try { - adyenComponent.mount(paypalNode); - } catch (e) { - console.log('Something went wrong trying to mount the PayPal component: ' + e); - } - }, + var ssn = $('#p_method_adyen_hpp_' + paymentMethod + '_ssn'); + if (ssn) { + $("#socialSecurityNumber").val(ssn.val()); + } - initiateApplePay: function (params) { - const {amount, countryCode, applePayMerchantIdentifier, applePayMerchantName, label} = params; - const applePayNode = document.getElementById('adyen-component-button-container-' + label); - const self = this; - const applePayConfiguration = { - //onValidateMerchant is required if you're using your own Apple Pay certificate - onValidateMerchant: (resolve, reject, validationURL) => { - if (self.isTermsAccepted(label)) { - resolve(); - } else { - reject(); - self.handleResult(ErrorMessages.TermsNotAccepted, true); - } - // Your server uses the validation URL to request a session from the Apple Pay server. - // Call resolve(MERCHANTSESSION) or reject() to complete merchant validation. - /*validateMerchant(validationURL) - .then(response => { - // Complete merchant validation with resolve(MERCHANTSESSION) after receiving an opaque merchant session object, MerchantSession - resolve(response); - }) - .catch(error => { - // Complete merchant validation with reject() if any error occurs - reject(); - });*/ - console.log(validationURL, reject, resolve); - } - }; - const adyenComponent = this.checkout.create("applepay", { - amount: { - currency: amount.currency, - value: amount.value - }, - countryCode: countryCode, - configuration: { - merchantName: applePayMerchantName, - merchantId: applePayMerchantIdentifier - }, - // Button config - buttonType: "plain", - buttonColor: "black", - onChange: function(state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function(state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return false; - } - self.makePayment(state.data, component, self.handleResult, label); - }, - onClick: function(resolve, reject) { - if (self.isTermsAccepted(label)) { - resolve(); - } else { - reject(); - self.handleResult(ErrorMessages.TermsNotAccepted, true); - } - } - }); + var terminalId = $('#adyen_pos_terminal'); + if (terminalId) { + $("#terminalId").val(terminalId.val()); + } - adyenComponent.isAvailable() - .then(function () { - adyenComponent.mount(applePayNode); - }) - .catch(function (e) { - // Apple Pay is not available - console.log('Something went wrong trying to mount the Apple Pay component: ' + e); - self.handleResult(ErrorMessages.PaymentNotAvailable, true); - }); - }, + var firstName = $('#p_method_adyen_hpp_' + paymentMethod + '_first_name').val(); + if (firstName) { + $("#firstName").val(firstName); + } - /** - * - * @param params - */ - initiateGooglePay: function (params) { - const {amount, merchantAccount, label} = params; - const googlePayNode = document.getElementById('adyen-component-button-container-' + label); - const self = this; - const adyenComponent = this.checkout.create("paywithgoogle", { - environment: this.checkout.options.environment, - amount: { - currency: amount.currency, - value: amount.value - }, - configuration: { - gatewayMerchantId: merchantAccount, - merchantName: merchantAccount - }, - buttonColor: "white", - onChange: function (state, component) { - if (!state.isValid) { - self.hideSpinner(); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.hideSpinner(); - return false; - } - self.showSpinner(); - self.makePayment(state.data, component, self.handleResult, label); - }, - onClick: function (resolve, reject) { - if (self.isTermsAccepted(label)) { - resolve(); - } else { - reject(); - self.handleResult(ErrorMessages.TermsNotAccepted, true); - } + var lastName = $('#p_method_adyen_hpp_' + paymentMethod + '_last_name').val(); + if (lastName) { + $("#lastName").val(lastName); + } + } + + /** + * Create DatePicker for Date of Birth field + * + * @param element + */ + createDobDatePicker(element) { + $("." + element).datepicker({ + dateFormat: this.dobDateFormat, + changeMonth: true, + changeYear: true, + yearRange: "-120:+0" + }); + } + + + togglePaymentMethod(paymentMethod) { + $(".payment_method_details").hide(); + $(".chckt-pm__details").hide(); + + $("#dd_method_" + paymentMethod).show(); + $("#adyen_hpp_" + paymentMethod + "_container").show(); + } + + createDfValue() { + window.dfDo("dfValue"); + } + + checkTermsAndConditions(checked) { + $('.adyen-terms-conditions-check').prop('checked', checked) + if (checked) { + actions.enable(); + $('.adyen-terms-conditions-check-error').addClass('hidden'); + } else { + actions.disable(); + $('.adyen-terms-conditions-check-error').removeClass('hidden'); + } + } + + showCheckTermsAndConditionsError(checked) { + const $errorMessage = $('.adyen-terms-conditions-check-error'); + if ($('.adyen-terms-conditions-check').prop('checked')) { + $errorMessage.addClass('hidden'); + } else { + $errorMessage.removeClass('hidden'); + } + } + + configureButton(form, useSpinner, label) { + $(document).ready(() => { + $("#placeOrder-" + label).click(() => { + $(this).prop('disabled', true); + if (useSpinner) { + this.showSpinner(); } + form.submit(); }); - - adyenComponent.isAvailable() - .then(function () { - adyenComponent.mount(googlePayNode); - }) - .catch(function (e) { - // Google Pay is not available - console.log('Something went wrong trying to mount the Google Pay component: ' + e); - self.handleResult(ErrorMessages.PaymentNotAvailable, true); - }); - }, - - /** - * - * @param params - */ - initiateAmazonPay: function (params) { - const {amount, deliveryAddress, amazonPayConfiguration, locale} = params; - const label = this.getVisibleLabel(); - let componentConfiguration; - let state = ''; - if (deliveryAddress.country.isocode === 'US') { - state = deliveryAddress.region.isocodeShort; - } - - componentConfiguration = { - environment: this.checkout.options.environment, - addressDetails: { - name: deliveryAddress.firstName + ' ' + deliveryAddress.lastName, - addressLine1: deliveryAddress.line1, - addressLine2: deliveryAddress.line2, - city: deliveryAddress.town, - stateOrRegion: state, - postalCode: deliveryAddress.postalCode, - countryCode: deliveryAddress.country.isocode, - phoneNumber: deliveryAddress.phone || '0' - }, - region: amazonPayConfiguration.region, - amount: amount, - locale: locale, - configuration: amazonPayConfiguration, - checkoutMode: 'ProcessOrder', - productType: 'PayAndShip', - placement: 'Checkout', - returnUrl: window.location.origin + ACC.config.encodedContextPath + '/checkout/multi/adyen/summary/amazonpay/placeorder', - onClick: (resolve, reject) => { - if (this.isTermsAccepted(label)) { - resolve(); + }); + } + + makePayment(data, component, handleResult, label) { + $.ajax({ + url: ACC.config.encodedContextPath + '/adyen/component/payment', + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + success: function (response) { + try { + if (response.action && (response.resultCode && (response.resultCode === 'Pending' || + response.resultCode === 'RedirectShopper' || response.resultCode === 'IdentifyShopper' || + response.resultCode === 'ChallengeShopper' || response.resultCode === 'PresentToShopper' || + response.resultCode === 'Await') || (response.action && response.action.type))) { + component.handleAction(response.action); + } else if (response.resultCode && (response.resultCode === 'Authorised')) { + handleResult(response, false); } else { - reject(); - this.handleResult(ErrorMessages.TermsNotAccepted, true); - } - } - }; - const amazonPayNode = document.getElementById('adyen-component-button-container-' + label); - const adyenComponent = this.checkout.create("amazonpay", componentConfiguration); - try { - adyenComponent.mount(amazonPayNode); - } catch (e) { - console.log('Something went wrong trying to mount the Amazon Pay component: ' + e); - this.handleResult(ErrorMessages.PaymentNotAvailable, true); - } - }, - - initiateMbway: function (params) { - const {label} = params; - var mbwayNode = document.getElementById('adyen-component-container-' + label); - var self = this; - - var adyenComponent = this.checkout.create("mbway", { - showPayButton: false, - onChange: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return; - } - self.makePayment(state.data, component, self.handleResult, label); - }, - onAdditionalDetails: function (state, component) { - self.submitDetails(state.data, self.handleResult); - }, - onError: function (error, component) { - console.log('Something went wrong trying to make the MBWay payment: ' + error); - self.handleResult(ErrorMessages.PaymentError, true); - } - }); - - try { - adyenComponent.mount(mbwayNode); - self.configureButton(adyenComponent, false, label); - } catch (e) { - console.log('Something went wrong trying to mount the MBWay component: ' + e); - } - }, - - initiateBlik: function (params) { - const {label} = params; - var blikNode = document.getElementById('adyen-component-container-' + label); - var self = this; - - var adyenComponent = this.checkout.create("blik", { - showPayButton: false, - onChange: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return; - } - self.makePayment(state.data, component, self.handleResult, label); - }, - onAdditionalDetails: function (state, component) { - self.submitDetails(state.data, self.handleResult); - }, - onError: function (error, component) { - console.log('Something went wrong trying to make the BLIK payment: ' + error); - self.handleResult(ErrorMessages.PaymentError, true); - } - }); - - try { - adyenComponent.mount(blikNode); - self.configureButton(adyenComponent, false, label); - } catch (e) { - console.log('Something went wrong trying to mount the BLIK component: ' + e); - } - }, - - initiateGiftCard: function (params) { - const {label} = params; - var giftCardNode = document.getElementById('adyen-component-container-' + label); - var self = this; - - var adyenComponent = this.checkout.create("giftcard", { - showPayButton: false, - onChange: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return; + handleResult(ErrorMessages.PaymentError, true); } - self.makePayment(state.data, component, self.handleResult, label); - }, - onAdditionalDetails: function (state, component) { - self.submitDetails(state.data, self.handleResult); - }, - onError: function (error, component) { - console.log('Something went wrong trying to make the Gift Card payment: ' + error); - self.handleResult(ErrorMessages.PaymentError, true); - } - }); - - try { - adyenComponent.mount(giftCardNode); - self.configureButton(adyenComponent, false, label); - } catch (e) { - console.log('Something went wrong trying to mount the Gift Card component: ' + e); - } - }, - - initiateAfterPay: function (countryCode) { - this.afterPay = this.checkout.create("afterpay_default", { - countryCode: countryCode, - visibility: { // Optional configuration - personalDetails: "editable", - billingAddress: "hidden", - deliveryAddress: "hidden" + } catch (e) { + console.log('Error parsing makePayment response: ' + response); + handleResult(ErrorMessages.PaymentError, true); } - }); - - try { - this.afterPay.mount('#afterpay-container'); - } catch (e) { - console.log('Something went wrong trying to mount the afterpay component: ' + e); - } - }, - - initiatePix: function (params) { - const {label, issuers} = params; - $("#generateqr-" + label).click(function () { - AdyenCheckoutHybris.showSpinner(); - if (!AdyenCheckoutHybris.isTermsAccepted(label)) { - AdyenCheckoutHybris.handleResult(ErrorMessages.TermsNotAccepted, true) + }, + error: function (xmlHttpResponse, exception) { + var responseMessage = xmlHttpResponse.responseJSON; + if (xmlHttpResponse.status === 400) { + handleResult(responseMessage, true); } else { - $("#generateqr-" + label).hide(); - $(".checkbox").hide(); - var actionHandler = { - handleAction: function (action) { - AdyenCheckoutHybris.checkout.createFromAction(action, { - issuers: issuers, - onAdditionalDetails: function (state) { - AdyenCheckoutHybris.hideSpinner(); - AdyenCheckoutHybris.submitDetails(state.data, AdyenCheckoutHybris.handleResult); - } - }).mount('#qrcode-container-' + label); - AdyenCheckoutHybris.hideSpinner(); - } - }; - AdyenCheckoutHybris.makePayment({type: "pix"}, actionHandler, AdyenCheckoutHybris.handleResult, label); - } - }); - }, - - initiateBcmc: function () { - this.bcmc = this.checkout.create("bcmc", { - hasHolderName: true, - holderNameRequired: true - }); - - try { - this.bcmc.mount('#bcmc-container'); - } catch (e) { - console.log('Something went wrong trying to mount the BCMC component: ' + e); - } - }, - - initiateBcmcMobile: function (params) { - const {label} = params; - $("#generateqr-" + label).click(function () { - AdyenCheckoutHybris.showSpinner(); - if (!AdyenCheckoutHybris.isTermsAccepted(label)) { - AdyenCheckoutHybris.handleResult(ErrorMessages.TermsNotAccepted, true) - } else { - $("#generateqr-" + label).hide(); - $(".checkbox").hide(); - var actionHandler = { - handleAction: function (action) { - AdyenCheckoutHybris.checkout.createFromAction(action, { - onAdditionalDetails: function (state) { - AdyenCheckoutHybris.hideSpinner(); - AdyenCheckoutHybris.submitDetails(state.data, AdyenCheckoutHybris.handleResult); - } - }).mount('#qrcode-container-' + label); - AdyenCheckoutHybris.hideSpinner(); - } - }; - AdyenCheckoutHybris.makePayment({type: "bcmc_mobile"}, actionHandler, AdyenCheckoutHybris.handleResult, label); - } - }); - }, - - initiateBizum: function (params) { - const {label} = params; - const self = this; - - $(document).ready(function () { - $("#placeOrder-" + label).click(function () { - $(this).prop('disabled', true); - - AdyenCheckoutHybris.showSpinner(); - - let termsCheck = document.getElementById('terms-conditions-check-' + label).checked - - if (termsCheck === false) { - self.handleResult(ErrorMessages.TermsNotAccepted, true); - return; - } - - const placeOrderForm = { - "securityCode": null, - "termsCheck": termsCheck, - }; - - $.ajax({ - url: ACC.config.encodedContextPath + '/checkout/multi/adyen/summary/placeOrder', - type: "POST", - data: placeOrderForm, - success: function (data) { - try { - let response = JSON.parse(data); - - const form = document.createElement('form'); - form.method = 'POST'; - form.action = response.url; - - for (const key in response.data) { - form.innerHTML+=' '; - } - - document.body.appendChild(form); - form.submit(); - } catch (e) { - console.log('Error place order: ' + e); - AdyenCheckoutHybris.hideSpinner(); - $("#placeOrder-" + label).prop('disabled', false); - self.handleResult(data, true); - } - }, - error: function (xmlHttpResponse, exception) { - console.log(exception); - AdyenCheckoutHybris.hideSpinner(); - $("#placeOrder-" + label).prop('disabled', false); - self.handleResult(responseMessage, true); - } - }); - }); - }); - }, - - initiatePayment: function (params) { - const {label, paymentType} = params; - var paymentNode = document.getElementById('adyen-component-container-' + label); - var self = this; - - var adyenComponent = this.checkout.create(paymentType, { - showPayButton: false, - onChange: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - } - }, - onSubmit: function (state, component) { - if (!state.isValid) { - self.enablePlaceOrder(label); - return; - } - self.makePayment(state.data, component, self.handleResult, label); - }, - onAdditionalDetails: function (state, component) { - self.submitDetails(state.data, self.handleResult); - }, - onError: function (error, component) { - console.log('Something went wrong trying to make a payment: ' + error); - self.handleResult(ErrorMessages.PaymentError, true); + console.log('Error on makePayment: ' + responseMessage); + handleResult(ErrorMessages.PaymentError, true); } - }); - - try { - adyenComponent.mount(paymentNode); - self.configureButton(adyenComponent, false, label); - } catch (e) { - console.log('Something went wrong trying to mount component: ' + e); } - }, - - /** - * @param form - * @param useSpinner - * @param label - */ - configureButton: function (form, useSpinner, label) { - $(document).ready(function () { - $("#placeOrder-" + label).click(function () { - $(this).prop('disabled', true); - if (useSpinner) { - AdyenCheckoutHybris.showSpinner(); - } - form.submit(); - }); - }); - }, - - makePayment: function (data, component, handleResult, label) { - $.ajax({ - url: ACC.config.encodedContextPath + '/adyen/component/payment', - type: "POST", - data: JSON.stringify( data ), - contentType: "application/json; charset=utf-8", - success: function (response) { - try { - if (response.action && (response.resultCode && (response.resultCode === 'Pending' || - response.resultCode === 'RedirectShopper' || response.resultCode === 'IdentifyShopper' || - response.resultCode === 'ChallengeShopper' || response.resultCode === 'PresentToShopper' || - response.resultCode === 'Await') || (response.action && response.action.type))) { - component.handleAction(response.action); - } else if (response.resultCode && (response.resultCode === 'Authorised')) { - handleResult(response, false); - } else { - handleResult(ErrorMessages.PaymentError, true); - } - } catch (e) { - console.log('Error parsing makePayment response: ' + response); - handleResult(ErrorMessages.PaymentError, true); - } - }, - error: function (xmlHttpResponse, exception) { - var responseMessage = xmlHttpResponse.responseJSON; - if (xmlHttpResponse.status === 400) { - handleResult(responseMessage, true); + }) + } + + submitDetails(data, handleResult) { + $.ajax({ + url: ACC.config.encodedContextPath + '/adyen/component/submit-details', + type: "POST", + data: JSON.stringify(data), + contentType: "application/json; charset=utf-8", + success: function (response) { + try { + if (response.resultCode) { + handleResult(response, false); } else { - console.log('Error on makePayment: ' + responseMessage); handleResult(ErrorMessages.PaymentError, true); } + } catch (e) { + console.log('Error parsing submitDetails response: ' + response); + handleResult(ErrorMessages.PaymentError, true); } - }) - }, - - submitDetails: function (data, handleResult) { - $.ajax({ - url: ACC.config.encodedContextPath + '/adyen/component/submit-details', - type: "POST", - data: JSON.stringify(data), - contentType: "application/json; charset=utf-8", - success: function (response) { - try { - if (response.resultCode) { - handleResult(response, false); - } else { - handleResult(ErrorMessages.PaymentError, true); - } - } catch (e) { - console.log('Error parsing submitDetails response: ' + response); - handleResult(ErrorMessages.PaymentError, true); - } - }, - error: function (xhr, exception) { - var responseMessage = xhr.responseJSON; - if (xhr.status === 400) { - handleResult(responseMessage, true); - } else { - console.log('Error on submitDetails: ' + responseMessage); - handleResult(ErrorMessages.PaymentError, true); - } + }, + error: function (xhr, exception) { + var responseMessage = xhr.responseJSON; + if (xhr.status === 400) { + handleResult(responseMessage, true); + } else { + console.log('Error on submitDetails: ' + responseMessage); + handleResult(ErrorMessages.PaymentError, true); } - }) - }, - - isTermsAccepted: function (label) { - return document.getElementById('terms-conditions-check-' + label).checked; - }, - - handleResult: function (data, error) { - if (error) { - document.querySelector("#resultCode").value = data.resultCode; - document.querySelector("#merchantReference").value = data.merchantReference; - document.querySelector("#isResultError").value = error; - } else { - document.querySelector("#resultCode").value = data.resultCode; - document.querySelector("#merchantReference").value = data.merchantReference; } - document.querySelector("#handleComponentResultForm").submit(); - }, - - showSpinner: function () { - document.getElementById("spinner_wrapper").style.display = "flex"; - }, - - hideSpinner: function () { - document.getElementById("spinner_wrapper").style.display = "none"; - }, + }) + } + + isTermsAccepted(label) { + return document.getElementById('terms-conditions-check-' + label).checked; + } + + handleResult(data, error) { + if (error) { + document.querySelector("#resultCode").value = data.resultCode; + document.querySelector("#merchantReference").value = data.merchantReference; + document.querySelector("#isResultError").value = error; + } else { + document.querySelector("#resultCode").value = data.resultCode; + document.querySelector("#merchantReference").value = data.merchantReference; + } + document.querySelector("#handleComponentResultForm").submit(); + } + + showSpinner() { + document.getElementById("spinner_wrapper").style.display = "flex"; + } + + hideSpinner() { + document.getElementById("spinner_wrapper").style.display = "none"; + } + + enablePlaceOrder(label) { + //hide spinner + this.hideSpinner(); + //enable button + $("#placeOrder-" + label).prop('disabled', false); + } + + addRiskData() { + try { + $('input[name="riskData"]').val(getData()); + } catch (e) { + //in case of risk data collection script not enabled + } - enablePlaceOrder: function (label) { - //hide spinner - this.hideSpinner(); - //enable button - $("#placeOrder-" + label).prop('disabled', false); - }, + } +} - getVisibleLabel: function () { - if (!(window.getComputedStyle(document.getElementById('adyen-checkout-visible-xs')).display === "none")) { - return 'visible-xs'; - } - if (!(window.getComputedStyle(document.getElementById('adyen-checkout-hidden-xs')).display === "none")) { - return 'hidden-xs'; - } - console.log('Something went wrong while trying to compute current visible label'); - return ''; - }, - addRiskData: function () { - try { - $('input[name="riskData"]').val(getData()); - } catch (e) { - //in case of risk data collection script not enabled - } - - } - }; -})(); diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_component_factory.js b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_component_factory.js new file mode 100644 index 000000000..fd4a43344 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_component_factory.js @@ -0,0 +1,605 @@ +class PaymentComponentFactory { + + constructor(checkout, checkoutHelper) { + this.checkout = checkout; + this.helper = checkoutHelper; + + } + + paymentConfiguration(label) { + return { + showPayButton: false, + onChange: (state, component) =>{ + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + } + }, + onSubmit: (state, component) => { + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + return; + } + this.helper.makePayment(state.data, component, this.helper.handleResult, label); + }, + onAdditionalDetails: (state, component) => { + this.helper.submitDetails(state.data, this.helper.handleResult); + }, + onError: (error, component) => { + console.log('Something went wrong trying to make the Gift Card payment: ' + error); + this.helper.handleResult(ErrorMessages.PaymentError, true); + } + }; + } + + createFromConfigs(paymentMethodConfigs) { + for (let callback of Object.keys(paymentMethodConfigs)) { + const params = paymentMethodConfigs[callback]; + if (params && params.hasOwnProperty('label') && !!params.label) { + for (const label of params.label) { + const paramsWithLabel = { + ...params, + label: label + }; + this[callback](paramsWithLabel); + } + } else { + this[callback](params); + } + } + } + + createCard(params) { + const {allowedCards, showRememberDetails, cardHolderNameRequired} = params; + + const copyCardBrand= (event) => { + context.selectedCardBrand = event.brand; + } + + this.helper.card = new Card(this.checkout, { + showPayButton: false, + type: 'card', + hasHolderName: true, + holderNameRequired: cardHolderNameRequired, + enableStoreDetails: showRememberDetails, + brands: allowedCards, + onBrand: copyCardBrand + }).mount("#card-div"); + + } + + createOneClickCard(storedCardList) { + if (storedCardList && storedCardList.length) { + for (const storedCard of storedCardList) { + const oneClickCardNode = document.getElementById("one-click-card_" + storedCard.storedPaymentMethodId); + const oneClickCard = new Card(this.checkout, { + showPayButton: false, + storedPaymentMethods: storedCard, + }).mount(oneClickCardNode); + this.helper.oneClickCards[storedCard.storedPaymentMethodId] = oneClickCard; + } + } + } + + createSepaDirectDebit() { + + const handleOnChange = (event) => { + var sepaOwnerNameField = document.getElementById('sepaOwnerName'); + var sepaIbanNumberField = document.getElementById('sepaIbanNumber'); + + var sepaOwnerName = event.data.paymentMethod["ownerName"] + var sepaIbanNumber = event.data.paymentMethod["iban"] + + sepaOwnerNameField.value = sepaOwnerName; + sepaIbanNumberField.value = sepaIbanNumber; + } + + this.helper.sepaDirectDebit = new Sepa(this.checkout, { + showPayButton: false, + onChange: handleOnChange + }).mount('#adyen_hpp_sepadirectdebit_container') + } + + createOnlinebankingIN() { + new OnlineBankingIN(this.checkout, {onChange: this.handleOnChange}).mount('#adyen_hpp_onlinebanking_IN_container'); + + } + + createOnlineBankingPL() { + new OnlineBankingIN(this.checkout, {onChange: this.handleOnChange}).mount('#adyen_hpp_onlineBanking_PL_container'); + } + + createEps(epsDetails) { + const eps = new EPS(this.checkout, { + issuers: epsDetails, // The array of issuers coming from the /paymentMethods api call + onChange: this.handleOnChange // Gets triggered once the shopper selects an issuer + }).mount('#adyen_hpp_eps_container'); + } + + // TODO: to check + createUPI() { + const label = this.getVisibleLabel(); + const uPINode = document.getElementById('adyen-component-button-container-' + label); + + const handlePaymentResult = (result, component) => { + $.ajax({ + url: ACC.config.encodedContextPath + '/adyen/component/resultHandler', + type: "POST", + data: JSON.stringify({ + resultCode: result.resultCode, + sessionData: result.sessionData + }), + contentType: "application/json; charset=utf-8", + success: (data) => { + try { + window.location.href = ACC.config.encodedContextPath + "/" + data.replace("redirect:/", ""); + } catch (e) { + console.log('Error redirecting the user to the placeOrder page'); + this.helper.handleResult(ErrorMessages.PaymentError, true); + } + }, + error: (xmlHttpResponse, exception) => { + var responseMessage = xmlHttpResponse.responseJSON; + if (xmlHttpResponse.status === 400) { + this.helper.handleResult(responseMessage, true); + } else { + console.log('Error on handling the redirect to the placeOrder page: ' + responseMessage); + this.helper.handleResult(ErrorMessages.PaymentError, true); + } + } + }) + } + + + let upi = this.checkout.create('upi', { + onPaymentCompleted: handlePaymentResult, + defaultMode: 'vpa', + showPayButton: true, + }).mount(uPINode); + } + + createPaypal(params) { + const {amount, isImmediateCapture, paypalMerchantId, label} = params; + const paypal = new PayPal(this.checkout, { + style: { // Optional configuration for PayPal payment buttons. + layout: "vertical", + color: "gold" + }, + environment: this.checkout.options.environment, + amount: { + currency: amount.currency, + value: amount.value + }, + configuration: { + intent: isImmediateCapture ? "capture" : "authorize", + merchantId: (this.checkout.options.environment === 'test') ? null : paypalMerchantId, // Your PayPal Merchant ID. Required for accepting live payments. + }, + blockPayPalCreditButton: true, + blockPayPalPayLaterButton: true, + onInit: (data, actions) => { + actions.enable(); + $(document).on('change', '.adyen-terms-conditions-check', (event) => { + const checked = (event.target.checked) + $('.adyen-terms-conditions-check').prop('checked', checked) + if (checked) { + actions.enable(); + } else { + actions.disable(); + } + this.helper.showCheckTermsAndConditionsError(); + }); + }, + onClick: ()=> { + // Show a validation error if the checkbox is not checked + this.helper.showCheckTermsAndConditionsError(); + }, + onChange: (state, component)=> { + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + } + }, + onSubmit: (state, component)=> { + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + return false; + } + this.helper.makePayment(state.data, component, this.helper.handleResult, label); + }, + onCancel: (data, component) => { + // Sets your prefered status of the component when a PayPal payment is cancelled. + this.helper.handleResult(ErrorMessages.PaymentCancelled, true); + }, + onError: (error, component) =>{ + // Sets your prefered status of the component when an error occurs. + if (error.name === 'CANCEL') { + this.helper.handleResult(ErrorMessages.PaymentCancelled, true); + } else { + this.helper.handleResult(ErrorMessages.PaymentError, true); + } + }, + onAdditionalDetails: (state, component) => { + this.helper.submitDetails(state.data, this.helper.handleResult); + } + }).mount('#adyen-component-button-container-' + label); + + } + + createApplePay(params) { + const {amount, countryCode, applePayMerchantIdentifier, applePayMerchantName, label} = params; + const applePayConfiguration = { + //onValidateMerchant is required if you're using your own Apple Pay certificate + onValidateMerchant: (resolve, reject, validationURL) => { + if (this.helper.isTermsAccepted(label)) { + resolve(); + } else { + reject(); + this.helper.handleResult(ErrorMessages.TermsNotAccepted, true); + } + // Your server uses the validation URL to request a session from the Apple Pay server. + // Call resolve(MERCHANTSESSION) or reject() to complete merchant validation. + /*validateMerchant(validationURL) + .then(response => { + // Complete merchant validation with resolve(MERCHANTSESSION) after receiving an opaque merchant session object, MerchantSession + resolve(response); + }) + .catch(error => { + // Complete merchant validation with reject() if any error occurs + reject(); + });*/ + console.log(validationURL, reject, resolve); + } + }; + const adyenComponent = new ApplePay(this.checkout, { + amount: { + currency: amount.currency, + value: amount.value + }, + countryCode: countryCode, + configuration: { + merchantName: applePayMerchantName, + merchantId: applePayMerchantIdentifier + }, + // Button config + buttonType: "plain", + buttonColor: "black", + onChange: (state, component) => { + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + } + }, + onSubmit: (state, component) => { + if (!state.isValid) { + this.helper.enablePlaceOrder(label); + return false; + } + this.helper.makePayment(state.data, component, this.helper.handleResult, label); + }, + onClick: (resolve, reject) => { + if (this.helper.isTermsAccepted(label)) { + resolve(); + } else { + reject(); + this.helper.handleResult(ErrorMessages.TermsNotAccepted, true); + } + } + }).mount('adyen-component-button-container-' + label); + + adyenComponent.isAvailable() + .then( () => { + adyenComponent.mount(applePayNode); + }) + .catch( (e) => { + // Apple Pay is not available + console.log('Something went wrong trying to mount the Apple Pay component: ' + e); + this.helper.handleResult(ErrorMessages.PaymentNotAvailable, true); + }); + } + + createGooglePay(params) { + const {amount, merchantAccount, label} = params; + const googlePayNode = document.getElementById('adyen-component-button-container-' + label); + const adyenComponent = this.checkout.create("paywithgoogle", { + environment: this.checkout.options.environment, + amount: { + currency: amount.currency, + value: amount.value + }, + configuration: { + gatewayMerchantId: merchantAccount, + merchantName: merchantAccount + }, + buttonColor: "white", + onChange: (state, component) => { + if (!state.isValid) { + this.helper.helper.hideSpinner(); + } + }, + onSubmit: (state, component) => { + if (!state.isValid) { + this.helper.helper.hideSpinner(); + return false; + } + this.helper.helper.showSpinner(); + this.helper.helper.makePayment(state.data, component, this.helper.handleResult, label); + }, + onClick: (resolve, reject) => { + if (this.helper.helper.isTermsAccepted(label)) { + resolve(); + } else { + reject(); + this.helper.helper.handleResult(ErrorMessages.TermsNotAccepted, true); + } + } + }); + + adyenComponent.isAvailable() + .then( () => { + adyenComponent.mount(googlePayNode); + }) + .catch( (e) => { + // Google Pay is not available + console.log('Something went wrong trying to mount the Google Pay component: ' + e); + this.helper.handleResult(ErrorMessages.PaymentNotAvailable, true); + }); + } + + // TODO: to check + createAmazonPay(params) { + const {amount, deliveryAddress, amazonPayConfiguration, locale} = params; + const label = this.getVisibleLabel(); + let componentConfiguration; + let state = ''; + if (deliveryAddress.country.isocode === 'US') { + state = deliveryAddress.region.isocodeShort; + } + + componentConfiguration = { + environment: this.checkout.options.environment, + addressDetails: { + name: deliveryAddress.firstName + ' ' + deliveryAddress.lastName, + addressLine1: deliveryAddress.line1, + addressLine2: deliveryAddress.line2, + city: deliveryAddress.town, + stateOrRegion: state, + postalCode: deliveryAddress.postalCode, + countryCode: deliveryAddress.country.isocode, + phoneNumber: deliveryAddress.phone || '0' + }, + region: amazonPayConfiguration.region, + amount: amount, + locale: locale, + configuration: amazonPayConfiguration, + checkoutMode: 'ProcessOrder', + productType: 'PayAndShip', + placement: 'Checkout', + returnUrl: window.location.origin + ACC.config.encodedContextPath + '/checkout/multi/adyen/summary/amazonpay/placeorder', + onClick: (resolve, reject) => { + if (this.isTermsAccepted(label)) { + resolve(); + } else { + reject(); + this.handleResult(ErrorMessages.TermsNotAccepted, true); + } + } + }; + const amazonPayNode = document.getElementById('adyen-component-button-container-' + label); + const adyenComponent = this.checkout.create("amazonpay", componentConfiguration); + try { + adyenComponent.mount(amazonPayNode); + } catch (e) { + console.log('Something went wrong trying to mount the Amazon Pay component: ' + e); + this.handleResult(ErrorMessages.PaymentNotAvailable, true); + } + } + + createMbway(params) { + const {label} = params; + const adyenComponent = new MBWay(this.checkout, this.paymentConfiguration(label)).mount('#adyen-component-container-' + label); + this.helper.configureButton(adyenComponent, false, label); + } + + createBlik(params) { + const {label} = params; + const adyenComponent = new Blik(this.checkout, this.paymentConfiguration(label)).mount('#adyen-component-container-' + label); + this.helper.configureButton(adyenComponent, false, label); + } + + createGiftCard (params) { + const {label} = params; + const adyenComponent = new Giftcard(this.checkout, this.paymentConfiguration(label)).mount('#adyen-component-container-' + label);; + this.helper.configureButton(adyenComponent, false, label); + + } + + createAfterPay(countryCode) { + this.afterPay = this.checkout.create("afterpay_default", { + countryCode: countryCode, + visibility: { // Optional configuration + personalDetails: "editable", + billingAddress: "hidden", + deliveryAddress: "hidden" + } + }); + + try { + this.afterPay.mount('#afterpay-container'); + } catch (e) { + console.log('Something went wrong trying to mount the afterpay component: ' + e); + } + } + + createPix(params) { + const {label, issuers} = params; + $("#generateqr-" + label).click( () => { + this.helper.helper.showSpinner(); + if (!this.helper.helper.isTermsAccepted(label)) { + this.helper.helper.handleResult(ErrorMessages.TermsNotAccepted, true) + } else { + $("#generateqr-" + label).hide(); + $(".checkbox").hide(); + var actionHandler = { + handleAction: (action) => { + this.helper.helper.checkout.createFromAction(action, { //TODO FXIME: check if this is correct + issuers: issuers, + onAdditionalDetails: (state) => { + this.helper.helper.hideSpinner(); + this.helper.helper.submitDetails(state.data, this.helper.helper.handleResult); + } + }).mount('#qrcode-container-' + label); + this.helper.helper.hideSpinner(); + } + }; + this.helper.helper.makePayment({type: "pix"}, actionHandler, this.helper.helper.handleResult, label); + } + }); + } + + createBcmc() { + this.bcmc = this.checkout.create("bcmc", { + hasHolderName: true, + holderNameRequired: true + }); + + try { + this.bcmc.mount('#bcmc-container'); + } catch (e) { + console.log('Something went wrong trying to mount the BCMC component: ' + e); + } + } + + createBcmcMobile(params) { + const {label} = params; + $("#generateqr-" + label).click( () => { + this.helper.showSpinner(); + if (!this.helper.isTermsAccepted(label)) { + this.helper.handleResult(ErrorMessages.TermsNotAccepted, true) + } else { + $("#generateqr-" + label).hide(); + $(".checkbox").hide(); + var actionHandler = { + handleAction: (action) => { + this.helper.checkout.createFromAction(action, { //TODO FXIME: check if this is correct + onAdditionalDetails: (state) => { + this.helper.hideSpinner(); + this.helper.submitDetails(state.data, this.helper.handleResult); + } + }).mount('#qrcode-container-' + label); + this.helper.hideSpinner(); + } + }; + this.helper.makePayment({type: "bcmc_mobile"}, actionHandler, this.helper.handleResult, label); + } + }); + } + + createBizum(params) { + const {label} = params; + + $(document).ready( () => { + $("#placeOrder-" + label).click( () => { + $(this).prop('disabled', true); + + this.helper.showSpinner(); + + let termsCheck = document.getElementById('terms-conditions-check-' + label).checked + + if (termsCheck === false) { + this.helper.handleResult(ErrorMessages.TermsNotAccepted, true); + return; + } + + const placeOrderForm = { + "securityCode": null, + "termsCheck": termsCheck, + }; + + $.ajax({ + url: ACC.config.encodedContextPath + '/checkout/multi/adyen/summary/placeOrder', + type: "POST", + data: placeOrderForm, + success: (data) => { + try { + let response = JSON.parse(data); + + const form = document.createElement('form'); + form.method = 'POST'; + form.action = response.url; + + for (const key in response.data) { + form.innerHTML += ' '; + } + + document.body.appendChild(form); + form.submit(); + } catch (e) { + console.log('Error place order: ' + e); + this.helper.hideSpinner(); + $("#placeOrder-" + label).prop('disabled', false); + this.helper.handleResult(data, true); + } + }, + error: (xmlHttpResponse, exception) => { + console.log(exception); + this.helper.hideSpinner(); + $("#placeOrder-" + label).prop('disabled', false); + this.helper.handleResult(responseMessage, true); + } + }); + }); + }); + } + + createGeneralPayment(params) { + const {label, paymentType} = params; + var paymentNode = document.getElementById('adyen-component-container-' + label); + var adyenComponent = this.checkout.create(paymentType, this.paymentConfiguration); + + try { + adyenComponent.mount(paymentNode); + this.configureButton(adyenComponent, false, label); + } catch (e) { + console.log('Something went wrong trying to mount component: ' + e); + } + } + + + // Redirect payment methods + createIdeal(idealDetails) { + new Redirect(this.checkout, + { + details: idealDetails, + type: 'ideal', + showPayButton: false, + onChange: this.handleOnChange + }) + .mount("#adyen_hpp_ideal_container"); + } + + initiateWalletIN() { + new Redirect(this.checkout, {type: 'wallet_IN', onChange: this.handleOnChange + }).mount('#adyen_hpp_wallet_IN_container'); + } + + initiatePaytm() { + const paytm = new Redirect(this.checkout, {type: 'paytm', onChange: this.handleOnChange}).mount('#adyen_hpp_paytm_container'); + } + + // Helper methods + + handleOnChange(event) { + var issuerIdField = document.getElementById('issuerId'); + var issuerId = event.data.paymentMethod.issuer; + issuerIdField.value = issuerId; + } + + getVisibleLabel() { + if (!(window.getComputedStyle(document.getElementById('adyen-checkout-visible-xs')).display === "none")) { + return 'visible-xs'; + } + if (!(window.getComputedStyle(document.getElementById('adyen-checkout-hidden-xs')).display === "none")) { + return 'hidden-xs'; + } + console.log('Something went wrong while trying to compute current visible label'); + return ''; + } + +} \ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_form_validator.js b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_form_validator.js new file mode 100644 index 000000000..f9c6ec137 --- /dev/null +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen_form_validator.js @@ -0,0 +1,115 @@ +class AdyenFormValidator { + constructor(adyenCheckoutHybris) { + this.adyenCheckoutHybris = adyenCheckoutHybris; + } + + showAlert(message) { + window.alert(message); + } + + isValidCard(card, isDebitCard, isValidBrandType) { + return card.isValid && (!isDebitCard || isValidBrandType); + } + + validateForm() { + const paymentMethod = $('input[type=radio][name=paymentMethod]:checked').val(); + + if (!paymentMethod) { + this.showAlert("Please select a payment method"); + return false; + } + + if (paymentMethod === "adyen_cc") { + if (!this.isValidCard(this.adyenCheckoutHybris.card, this.adyenCheckoutHybris.isDebitCard(), this.adyenCheckoutHybris.isValidBrandType())) { + this.showAlert('Please check your card details.'); + this.adyenCheckoutHybris.card.showValidation(); + document.getElementById("card-div").scrollIntoView(); + return false; + } + this.adyenCheckoutHybris.copyCardData(); + } + + if (paymentMethod.startsWith("adyen_oneclick_")) { + const recurringReference = paymentMethod.slice("adyen_oneclick_".length); + const oneClickCard = this.adyenCheckoutHybris.oneClickCards[recurringReference]; + + if (!(oneClickCard && oneClickCard.isValid)) { + this.showAlert('This credit card is not allowed'); + return false; + } + if (['bcmc', 'maestro'].includes(oneClickCard.props.brand)) { + this.adyenCheckoutHybris.copyOneClickCardBrandData(recurringReference, oneClickCard.props.brand); + } else { + this.adyenCheckoutHybris.copyOneClickCardData(recurringReference, oneClickCard.data.paymentMethod.encryptedSecurityCode, oneClickCard.props.brand); + } + } + $('input[name="txvariant"]').remove(); + + if (['eps', 'ideal', 'onlinebanking_IN', 'onlineBanking_PL'].indexOf(paymentMethod) >= 0) { + var issuerIdField = document.getElementById('issuerId'); + if (issuerIdField.value === "") { + window.alert("Please select an issuer"); + return false; + } + } + + if (paymentMethod === "pos") { + var terminalId = $('#adyen_pos_terminal'); + if (terminalId.val() === "") { + window.alert("Please select a terminal"); + return false; + } + } + + if (paymentMethod === "sepadirectdebit") { + if (!this.adyenCheckoutHybris.sepaDirectDebit.state.isValid) { + window.alert("Invalid SEPA Owner Name and IBAN number"); + return false; + } + } + + if (paymentMethod === "afterpay_default") { + if (!this.adyenCheckoutHybris.afterPay.state.isValid) { + window.alert("Please fill all the details"); + this.adyenCheckoutHybris.afterPay.showValidation(); + document.getElementById("afterpay-container").scrollIntoView(); + return false; + } + var dob = $("input[name=dateOfBirth]").val(); + if (dob) { + $("#dob").val(dob); + } + } + + if (paymentMethod === "paybright") { + var phoneNumber = $("#p_method_adyen_hpp_paybright_telephonenumber").val(); + if (!phoneNumber) { + window.alert("Please fill phone number"); + document.getElementById("p_method_adyen_hpp_paybright_telephonenumber").scrollIntoView(); + return false; + } + } + if (paymentMethod === "giftcard") { + $('input[name="giftCardBrand"]').val($('input[type=radio][name=paymentMethod]:checked').attr('brand')); + } + + if (paymentMethod === "bcmc") { + if (!this.adyenCheckoutHybris.bcmc.state.isValid) { + window.alert("Please fill all the details"); + this.adyenCheckoutHybris.bcmc.showValidation(); + document.getElementById("bcmc-container").scrollIntoView(); + return false; + } + var state = this.adyenCheckoutHybris.bcmc.data.paymentMethod; + $('input[name="encryptedCardNumber"]').val(state.encryptedCardNumber); + $('input[name="encryptedExpiryMonth"]').val(state.encryptedExpiryMonth); + $('input[name="encryptedExpiryYear"]').val(state.encryptedExpiryYear); + $('input[name="cardHolder"]').val(state.holderName); + $('input[name="cardBrand"]').val('bcmc'); + $('input[name="cardType"]').val('debit'); + $('input[name="browserInfo"]').val(JSON.stringify(this.adyenCheckoutHybris.bcmc.data.browserInfo)); + } + + return true; + } +} \ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/project.properties b/adyenv6b2ccheckoutaddon/project.properties index 59711be2c..921818285 100644 --- a/adyenv6b2ccheckoutaddon/project.properties +++ b/adyenv6b2ccheckoutaddon/project.properties @@ -23,7 +23,8 @@ adyenv6b2ccheckoutaddon.application-context=adyenv6b2ccheckoutaddon-spring.xml -adyenv6b2ccheckoutaddon.javascript.paths.responsive=/responsive/common/js/adyen.checkout.js;/responsive/common/js/adyen_billingaddress.js;/responsive/common/js/adyen_deliveryaddress.js;/responsive/common/js/adyen_express_checkout.js +adyenv6b2ccheckoutaddon.javascript.paths.responsive=/responsive/common/js/adyen_component_factory.js;/responsive/common/js/adyen_form_validator.js;/responsive/common/js/adyen.checkout.js;/responsive/common/js/adyen_billingaddress.js;/responsive/common/js/adyen_deliveryaddress.js;/responsive/common/js/adyen_express_checkout.js + adyenv6b2ccheckoutaddon.css.paths.responsive=/responsive/common/css/adyenv6b2ccheckoutaddon.css; csrf.allowed.url.patterns=/[^/]+(/[^?]*)+(sop-response)$,/[^/]+(/[^?]*)+(merchant_callback)$,/[^/]+(/[^?]*)+(hop-response)$,/[^/]+(/[^?]*)+(adyen-response)$,/adyen(/[^?]*)+$ From 207f10be19bc2854401cf31ebe3f3e5e568c7da7 Mon Sep 17 00:00:00 2001 From: kpieloch <113994423+kpieloch@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:18:48 +0200 Subject: [PATCH 2/2] AD-291: tag remove --- .../paymentMethodsConfiguration.tag | 135 ------------------ .../checkout/multi/checkoutSummaryPage.jsp | 1 - 2 files changed, 136 deletions(-) delete mode 100644 adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag deleted file mode 100644 index 2297459d0..000000000 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/tags/responsive/paymentMethodsConfiguration.tag +++ /dev/null @@ -1,135 +0,0 @@ - - - \ No newline at end of file diff --git a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/checkoutSummaryPage.jsp b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/checkoutSummaryPage.jsp index ad9864909..754325e5e 100644 --- a/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/checkoutSummaryPage.jsp +++ b/adyenv6b2ccheckoutaddon/acceleratoraddon/web/webroot/WEB-INF/views/responsive/pages/checkout/multi/checkoutSummaryPage.jsp @@ -132,7 +132,6 @@ } - console.log(paymentMethodConfigs); adyenCheckout.initiateCheckout(initConfig, paymentMethodConfigs);