From d76b798e6763b889ea499cf38ec55980e8d193e8 Mon Sep 17 00:00:00 2001 From: PJaneta Date: Tue, 17 Sep 2024 12:38:32 +0200 Subject: [PATCH] AD-247 Implement Conditional Region/State Field in Shipping Address for Checkout Process --- .../api/AdyenConfigurationController.java | 24 +++++++++++++- .../response/ConfigurationResponse.java | 11 +++++++ .../commerce/response/RegionResponse.java | 33 +++++++++++++++++++ .../src/components/common/AddressForm.tsx | 31 ++++++++++++++++- .../src/components/common/AddressSection.tsx | 2 ++ .../src/components/payment/Payment.tsx | 6 ++++ .../shipping-address/AddressBookSelector.tsx | 2 +- .../shipping-address/ShippingAddress.tsx | 3 ++ .../src/const/translationConst.ts | 5 ++- .../src/reducers/addressConfigReducer.ts | 4 ++- .../src/reducers/billingAddressReducer.ts | 13 +++++++- .../src/reducers/shippingAddressReducer.ts | 15 ++++++++- .../js/adyen-checkout/src/reducers/types.ts | 7 ++++ .../src/service/addressService.ts | 27 ++++++++++++--- .../src/service/paymentService.ts | 1 + .../adyen-checkout/src/types/addressData.ts | 2 +- .../validators/PaymentRequestValidator.java | 15 +++++++++ 17 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/RegionResponse.java diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenConfigurationController.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenConfigurationController.java index 1b61b55d3..3f9532942 100644 --- a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenConfigurationController.java +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/controllers/api/AdyenConfigurationController.java @@ -1,8 +1,11 @@ package com.adyen.commerce.controllers.api; import com.adyen.commerce.response.ConfigurationResponse; +import com.adyen.commerce.response.RegionResponse; +import de.hybris.platform.commercefacades.i18n.I18NFacade; import de.hybris.platform.commercefacades.order.CheckoutFacade; import de.hybris.platform.commercefacades.user.UserFacade; +import de.hybris.platform.commercefacades.user.data.RegionData; import de.hybris.platform.commerceservices.enums.CountryType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; @@ -10,6 +13,10 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + @Controller @RequestMapping(value = "/api/configuration") public class AdyenConfigurationController { @@ -20,15 +27,30 @@ public class AdyenConfigurationController { @Autowired private UserFacade userFacade; + @Autowired + private I18NFacade i18NFacade; + @GetMapping("/shipping-address") - public ResponseEntity getConfiguration() { + public ResponseEntity getConfiguration(Map map) { ConfigurationResponse configurationResponse = new ConfigurationResponse(); configurationResponse.setCountries(checkoutFacade.getCountries(CountryType.SHIPPING)); configurationResponse.setTitles(userFacade.getTitles()); configurationResponse.setAnonymous(userFacade.isAnonymousUser()); + configurationResponse.setRegions(mapRegions(i18NFacade.getRegionsForAllCountries())); return ResponseEntity.ok(configurationResponse); } + private List mapRegions(final Map> regions) { + List result = new ArrayList<>(); + + regions.forEach((k, v) -> { + RegionResponse regionResponse = new RegionResponse(k, v); + result.add(regionResponse); + }); + + return result; + } + } diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/ConfigurationResponse.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/ConfigurationResponse.java index 6f71982df..a804b2acd 100644 --- a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/ConfigurationResponse.java +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/ConfigurationResponse.java @@ -1,14 +1,17 @@ package com.adyen.commerce.response; import de.hybris.platform.commercefacades.user.data.CountryData; +import de.hybris.platform.commercefacades.user.data.RegionData; import de.hybris.platform.commercefacades.user.data.TitleData; import java.util.List; +import java.util.Map; public class ConfigurationResponse { private boolean isAnonymous; private List countries; private List titles; + private List regions; public boolean isAnonymous() { return isAnonymous; @@ -33,4 +36,12 @@ public List getTitles() { public void setTitles(List titles) { this.titles = titles; } + + public List getRegions() { + return regions; + } + + public void setRegions(List regions) { + this.regions = regions; + } } diff --git a/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/RegionResponse.java b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/RegionResponse.java new file mode 100644 index 000000000..dfbc7ada5 --- /dev/null +++ b/adyencheckoutaddonapi/acceleratoraddon/web/src/com/adyen/commerce/response/RegionResponse.java @@ -0,0 +1,33 @@ +package com.adyen.commerce.response; + +import de.hybris.platform.commercefacades.user.data.RegionData; + +import java.util.List; + +public class RegionResponse { + String countryCode; + List regionData; + + public RegionResponse(){} + + public RegionResponse(String countryCode, List regionData) { + this.countryCode = countryCode; + this.regionData = regionData; + } + + public String getCountryCode() { + return countryCode; + } + + public void setCountryCode(String countryCode) { + this.countryCode = countryCode; + } + + public List getRegionData() { + return regionData; + } + + public void setRegionData(List regionData) { + this.regionData = regionData; + } +} diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressForm.tsx b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressForm.tsx index d376e4c08..2cb853c39 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressForm.tsx +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressForm.tsx @@ -2,7 +2,7 @@ import {InputDropdown} from "../controls/InputDropdown"; import {InputText} from "../controls/InputText"; import React from "react"; import {AddressConfigModel} from "../../reducers/addressConfigReducer"; -import {AddressModel} from "../../reducers/types"; +import {AddressModel, CodeValueItem} from "../../reducers/types"; import {translationsStore} from "../../store/translationsStore"; interface Props { @@ -11,6 +11,7 @@ interface Props { errorFieldCodes: string[] errorFieldCodePrefix: string onCountryCodeChange: (countryCode: string) => void, + onRegionCodeChange: (regionCode: string) => void, onTitleCodeChange: (titleCode: string) => void, onFirstNameChange: (firstName: string) => void, onLastNameChange: (lastName: string) => void, @@ -23,6 +24,33 @@ interface Props { export class AddressForm extends React.Component { + private renderRegions() { + let regions = this.getRegionsByCountryCode(this.props.address.countryCode) + + if (regions.length > 0) { + return this.props.onRegionCodeChange(regionCode)} + selectedValue={this.props.address.regionCode} + placeholderText={translationsStore.get("address.selectState")} + placeholderDisabled={true} + fieldErrorId={this.props.errorFieldCodePrefix + "regionIso"} + fieldErrorTextCode="address.regionIso.invalid" + fieldErrors={this.props.errorFieldCodes}/> + } + + return <> + } + + private getRegionsByCountryCode(countryCode: string): CodeValueItem[] { + let region = this.props.addressConfig.regions.find((region) => region.countryCode === countryCode); + if (region) { + return region.regions + } + return [] + } + render() { return <> { fieldErrorId={this.props.errorFieldCodePrefix + "townCity"} fieldErrorTextCode="address.townCity.invalid" fieldErrors={this.props.errorFieldCodes}/> + {this.renderRegions()} this.props.onPostCodeChange(postCode)} diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressSection.tsx b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressSection.tsx index ef4ce2c23..fb90516fb 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressSection.tsx +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/common/AddressSection.tsx @@ -25,6 +25,7 @@ interface ComponentProps { onSelectAddress: (address: AddressModel) => void onCountryCodeChange: (countryCode: string) => void, + onRegionCodeChange: (regionCode: string) => void, onTitleCodeChange: (titleCode: string) => void, onFirstNameChange: (firstName: string) => void, onLastNameChange: (lastName: string) => void, @@ -99,6 +100,7 @@ class AddressSection extends React.Component {
this.props.onCountryCodeChange(countryCode)} + onRegionCodeChange={(regionCode) => this.props.onRegionCodeChange(regionCode)} address={this.props.address} errorFieldCodes={this.props.errorFieldCodes} errorFieldCodePrefix={this.props.errorFieldCodePrefix} 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 8caf482b2..b6c154b86 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 @@ -52,6 +52,7 @@ interface DispatchProps { setFirstName: (firstName: string) => void setLastName: (lastName: string) => void setCountryCode: (countryCode: string) => void + setRegionCode: (countryCode: string) => void setTitleCode: (titleCode: string) => void setLine1: (line1: string) => void setLine2: (line2: string) => void @@ -225,6 +226,7 @@ class Payment extends React.Component { errorFieldCodes={this.state.errorFieldCodes} errorFieldCodePrefix={"billingAddress."} onCountryCodeChange={(countryCode) => this.props.setCountryCode(countryCode)} + onRegionCodeChange={(regionCode) => this.props.setRegionCode(regionCode)} onTitleCodeChange={(titleCode) => this.props.setTitleCode(titleCode)} onFirstNameChange={(firstName) => this.props.setFirstName(firstName)} onLastNameChange={(lastName) => this.props.setLastName(lastName)} @@ -304,6 +306,10 @@ function mapDispatchToProps(dispatch: StoreDispatch): DispatchProps { type: "billingAddress/setCountryCode", payload: country }), + setRegionCode: (country: string) => dispatch({ + type: "billingAddress/setRegionCode", + payload: country + }), setTitleCode: (title: string) => dispatch({type: "billingAddress/setTitleCode", payload: title}), setLine1: (line1: string) => dispatch({type: "billingAddress/setLine1", payload: line1}), setLine2: (line2: string) => dispatch({type: "billingAddress/setLine2", payload: line2}), diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/AddressBookSelector.tsx b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/AddressBookSelector.tsx index 8d88a0822..47b15a9b1 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/AddressBookSelector.tsx +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/AddressBookSelector.tsx @@ -39,7 +39,7 @@ class AddressBookSelector extends React.Component {address.line1} {address.line2}
- {address.city} + {address.city}{isNotEmpty(address.region)? '\xa0' + address.region : ''}
{address.country} {address.postalCode}
diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/ShippingAddress.tsx b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/ShippingAddress.tsx index 3672fea24..7c94252e3 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/ShippingAddress.tsx +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/components/shipping-address/ShippingAddress.tsx @@ -19,6 +19,7 @@ interface DispatchProps { setFirstName: (firstName: string) => void setLastName: (lastName: string) => void setCountryCode: (countryCode: string) => void + setRegionCode: (regionCode: string) => void setTitleCode: (titleCode: string) => void setLine1: (line1: string) => void setLine2: (line2: string) => void @@ -89,6 +90,7 @@ class ShippingAddress extends React.Component this.props.setCountryCode(countryCode)} + onRegionCodeChange={(regionCode) => this.props.setRegionCode(regionCode)} onTitleCodeChange={(titleCode) => this.props.setTitleCode(titleCode)} onFirstNameChange={(firstName) => this.props.setFirstName(firstName)} onLastNameChange={(lastName) => this.props.setLastName(lastName)} @@ -118,6 +120,7 @@ const mapDispatchToProps = (dispatch: StoreDispatch): DispatchProps => ({ setFirstName: (firstName: string) => dispatch({type: "shippingAddress/setFirstName", payload: firstName}), setLastName: (lastName: string) => dispatch({type: "shippingAddress/setLastName", payload: lastName}), setCountryCode: (country: string) => dispatch({type: "shippingAddress/setCountryCode", payload: country}), + setRegionCode: (regionCode: string) => dispatch({type: "shippingAddress/setRegionCode", payload: regionCode}), setTitleCode: (title: string) => dispatch({type: "shippingAddress/setTitleCode", payload: title}), setLine1: (line1: string) => dispatch({type: "shippingAddress/setLine1", payload: line1}), setLine2: (line2: string) => dispatch({type: "shippingAddress/setLine2", payload: line2}), diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/const/translationConst.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/const/translationConst.ts index 738532cac..50d20b028 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/const/translationConst.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/const/translationConst.ts @@ -24,6 +24,8 @@ export const translationKeys: string[] = [ "address.selectCountry", "address.title.none", "address.country", + "address.state", + "address.selectState", "address.title", "address.firstName", "address.surname", @@ -82,5 +84,6 @@ export const translationKeys: string[] = [ "address.line1.invalid", "address.line2.invalid", "address.townCity.invalid", - "address.postcode.invalid" + "address.postcode.invalid", + "address.regionIso.invalid" ] \ No newline at end of file diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/addressConfigReducer.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/addressConfigReducer.ts index af9089cd1..3416a16d4 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/addressConfigReducer.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/addressConfigReducer.ts @@ -1,9 +1,10 @@ import {PayloadAction, RootAction} from "./rootReducer"; -import {CodeValueItem} from "./types"; +import {CodeValueItem, RegionModel} from "./types"; export const addressConfigInitialState: AddressConfigModel = { titles: [], countries: [], + regions: [], anonymousUser: false } @@ -28,6 +29,7 @@ export function addressConfigReducer(addressConfigState: AddressConfigModel, act export interface AddressConfigModel { titles: CodeValueItem[] countries: CodeValueItem[] + regions: RegionModel[] anonymousUser: boolean } diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/billingAddressReducer.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/billingAddressReducer.ts index 4bf249259..b96deca18 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/billingAddressReducer.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/billingAddressReducer.ts @@ -19,7 +19,14 @@ export function billingAddressReducer(addressState: AddressModel, action: RootAc case "billingAddress/setCountryCode": return { ...addressState, - countryCode: action.payload + countryCode: action.payload, + regionCode: null + } + + case "billingAddress/setRegionCode": + return { + ...addressState, + regionCode: action.payload } case "billingAddress/setTitleCode": @@ -76,6 +83,9 @@ interface SetBALastNameAction extends PayloadAction<"billingAddress/setLastName" interface SetBACountryCodeAction extends PayloadAction<"billingAddress/setCountryCode"> { } +interface SetBARegionCodeAction extends PayloadAction<"billingAddress/setRegionCode"> { +} + interface SetBATitleCodeAction extends PayloadAction<"billingAddress/setTitleCode"> { } @@ -102,6 +112,7 @@ export type BillingAddressAction = SetBAFirstNameAction | SetBALastNameAction | SetBACountryCodeAction + | SetBARegionCodeAction | SetBATitleCodeAction | SetBALine1Action | SetBALine2Action diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/shippingAddressReducer.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/shippingAddressReducer.ts index 49e283e65..37579ec77 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/shippingAddressReducer.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/shippingAddressReducer.ts @@ -10,6 +10,8 @@ export const addressInitialState: AddressModel = { city: "", country: "", countryCode: "", + regionCode: null, + region: "", lastName: "", phoneNumber: "", postalCode: "", @@ -34,7 +36,14 @@ export function shippingAddressReducer(addressState: AddressModel, action: RootA case "shippingAddress/setCountryCode": return { ...addressState, - countryCode: action.payload + countryCode: action.payload, + regionCode: null + } + + case "shippingAddress/setRegionCode": + return { + ...addressState, + regionCode: action.payload } case "shippingAddress/setTitleCode": @@ -91,6 +100,9 @@ interface SetSALastNameAction extends PayloadAction<"shippingAddress/setLastName interface SetSACountryCodeAction extends PayloadAction<"shippingAddress/setCountryCode"> { } +interface SetSARegionCodeAction extends PayloadAction<"shippingAddress/setRegionCode"> { +} + interface SetSATitleCodeAction extends PayloadAction<"shippingAddress/setTitleCode"> { } @@ -117,6 +129,7 @@ export type ShippingAddressAction = SetSAFirstNameAction | SetSALastNameAction | SetSACountryCodeAction + | SetSARegionCodeAction | SetSATitleCodeAction | SetSALine1Action | SetSALine2Action diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/types.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/types.ts index 50c8c1c9e..fcb017ac9 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/types.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/reducers/types.ts @@ -5,6 +5,8 @@ export interface AddressModel { id: string country: string countryCode: string + region: string + regionCode: string title: string titleCode: string firstName: string @@ -16,6 +18,11 @@ export interface AddressModel { phoneNumber: string } +export interface RegionModel { + countryCode: string + regions: CodeValueItem[] +} + export interface ShippingMethodState { selectedShippingMethodCode: string, shippingMethods: ShippingMethodModel[] diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/addressService.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/addressService.ts index 607f9b35e..e22fd53e4 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/addressService.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/service/addressService.ts @@ -1,12 +1,13 @@ import {AxiosError} from "axios"; import {CSRFToken, urlContextPath} from "../util/baseUrlUtil"; -import {AddressModel} from "../reducers/types"; +import {AddressModel, RegionModel} from "../reducers/types"; import {store} from "../store/store"; import {isNotEmpty} from "../util/stringUtil"; import {AddressConfigModel} from "../reducers/addressConfigReducer"; -import {AddressData} from "../types/addressData"; +import {AddressData, RegionData} from "../types/addressData"; import {ErrorResponse} from "../types/errorResponse"; import {adyenAxios} from "../axios/AdyenAxios"; +import {companyDetailsValidationRules} from "@adyen/adyen-web/dist/types/components/internal/CompanyDetails/validate"; interface AddDeliveryAddressResponse { success: boolean, @@ -94,6 +95,8 @@ export class AddressService { title: responseData.title, countryCode: responseData.country.isocode, country: responseData.country.name, + regionCode: responseData.region ? responseData.region.isocode : null, + region: responseData.region ? responseData.region.name : null, line1: responseData.line1, line2: responseData.line2, city: responseData.town, @@ -112,7 +115,7 @@ export class AddressService { line1: addressModel.line1, line2: addressModel.line2, townCity: addressModel.city, - regionIso: null, + regionIso: addressModel.regionCode, postcode: addressModel.postalCode, countryIso: addressModel.countryCode, saveInAddressBook: saveInAddressBook, @@ -133,9 +136,19 @@ export class AddressService { return {code: country.isocode, value: country.name} }); + let regions: RegionModel[] = response.regions.map(region => { + return { + countryCode: region.countryCode, + regions: region.regionData.map(r => { + return {code: r.isocode, value: r.name} + }) + } + }) + return { anonymousUser: response.anonymous, titles: titles, + regions: regions, countries: countries, } } @@ -170,8 +183,14 @@ interface TitleData { name: string } +export interface Region { + countryCode: string, + regionData: RegionData[] +} + interface AddressConfigResponse { anonymous: boolean, countries: CountryData[], - titles: TitleData[] + titles: TitleData[], + regions: Region[] } 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 3dca059e6..2a75d3912 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 @@ -87,6 +87,7 @@ export class PaymentService { return { addressId: address.id, countryIso: address.countryCode, + regionIso: address.regionCode, firstName: address.firstName, lastName: address.lastName, line1: address.line1, diff --git a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/addressData.ts b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/addressData.ts index f42081798..611512d87 100644 --- a/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/addressData.ts +++ b/adyencheckoutaddonspa/acceleratoraddon/web/webroot/_ui/responsive/common/js/adyen-checkout/src/types/addressData.ts @@ -28,7 +28,7 @@ export interface AddressData { fullnameWithTitle: string } -interface RegionData { +export interface RegionData { isocode: string; isocodeShort: string; countryIso: string; diff --git a/adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java b/adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java index e5f7d6de9..b9fd11651 100644 --- a/adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java +++ b/adyenwebcommons/src/com/adyen/commerce/validators/PaymentRequestValidator.java @@ -77,7 +77,22 @@ public void validate(Object o, Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "billingAddress.townCity", "address.townCity.invalid"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "billingAddress.postcode", "address.postcode.invalid"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "billingAddress.countryIso", "address.country.invalid"); + + validateCountrySpecificFields(errors); } } + + protected void validateCountrySpecificFields(Errors errors) { + String countryIso = (String) errors.getFieldValue("billingAddress.countryIso"); + if (countryIso != null) { + switch (countryIso){ + case "US", "CA", "JP", "CN": + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "billingAddress.regionIso","address.regionIso.invalid"); + break; + default: + break; + } + } + } }