Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/ad 291b #466

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -68,7 +63,7 @@ class Payment extends React.Component<Props, State> {

paymentRef: RefObject<HTMLDivElement>
threeDSRef: RefObject<HTMLDivElement>
dropIn: DropinElement
dropIn: Dropin

constructor(props: Props) {
super(props);
Expand Down Expand Up @@ -105,22 +100,14 @@ class Payment extends React.Component<Props, State> {
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,
Expand All @@ -133,25 +120,39 @@ class Payment extends React.Component<Props, State> {
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(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {PaymentMethod} from "@adyen/adyen-web";

export interface AdyenConfigData {
paymentMethods: PaymentMethodData[];
paymentMethods: PaymentMethod[];
connectedTerminalList: string[];
storedPaymentMethodList: StoredPaymentMethodData[];
issuerLists: Map<string, string>;
Expand Down Expand Up @@ -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<string, string>
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<string, string>;
}

interface ItemData {
id: string;
name: string;
}

interface PaymentMethodGroupData {
name: string;
paymentMethodData: string;
type: string;
}

interface StoredPaymentMethodData {
brand: string;
expiryMonth: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<%@ attribute name="dfUrl" required="false" type="java.lang.String"%>
<%@ attribute name="showDefaultCss" required="false" type="java.lang.Boolean"%>

<c:set var="VERSION" value="5.56.1"/>
<c:set var="VERSION" value="6.1.1"/>
<c:set var="jsHashVersion" value="sha384-ooyykkiG6hsCD+b97FrD/yvSSA4BHJv4I1mvz4KJEaAyJufGfooKzuLVotjKsEpP"/>
<c:set var="cssHashVersion" value="sha384-zgFNrGzbwuX5qJLys75cOUIGru/BoEzhGMyC07I3OSdHqXuhUfoDPVG03G+61oF4"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,22 @@
<json:property name="locale" value="${shopperLocale}"/>
<json:property name="environment" value="${environmentMode}"/>
<json:property name="clientKey" value="${clientKey}"/>
<json:property name="sessionId" value="${sessionData.id}"/>
<json:property name="sessionData" value="${sessionData.sessionData}"/>
<json:property name="countryCode" value="${countryCode}"/>
<json:object name="risk" escapeXml="false">
<json:property name="enabled" value="${false}"/>
</json:object>
</json:object>
</c:set>
<script type="text/javascript">

const { AdyenCheckout, Dropin, Card, PayPal, GooglePay,
ApplePay, CashAppPay, Sepa,Redirect,OnlineBankingIN,
OnlineBankingPL, Ideal, EPS, Pix, WalletIN, AfterPay, Bcmc,
Pos, PayBright, Boleto, SepaDirectDebit, RatePay, Paytm,Giftcard,Blik
} = AdyenWeb;

let checkout;
const handleOnAdditionalDetails = (state) => {
document.getElementById("details").value = JSON.stringify(state.data.details);
Expand Down
Loading