Skip to content

Commit

Permalink
Merge pull request #466 from Adyen/feature/AD-291b
Browse files Browse the repository at this point in the history
Feature/ad 291b
  • Loading branch information
kpieloch authored Oct 22, 2024
2 parents 1f01785 + 7a4d801 commit 4fe5ae6
Show file tree
Hide file tree
Showing 13 changed files with 1,161 additions and 1,308 deletions.
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

0 comments on commit 4fe5ae6

Please sign in to comment.