Skip to content

Conversation

@M-Izadmehr
Copy link

@M-Izadmehr M-Izadmehr commented Mar 20, 2025

Summary

Adyen-web drop-in can get specifications which can provide address specifications. This can be used to specifically determine for each country, which billing address fields are needed, and what are specific details needed for each field (label/placeholder/optional/etc).

However, in the code, the specifications is not actively used, and finally, when rendering the Credit Card Address component, the main criteria depend on billingAddressMode only. And the specifications are ignored.

Here is a summary of the data flow:

  1. In the Credit Card components in CardInput.tsx (github). While the specifications are used they are not passed to FieldsToRendered
<FieldsToRender
   {...restOfProps}
    partialAddressSchema={partialAddressSchema}
/>
  1. in case FieldsToRender uses CardFieldsWrapper:
    CardFieldsWrapper will use the partialAddressSchema as specifications and completely ignores specifications you pass in (github)
            {billingAddressRequired && (
                <Address
                    ...rest
                    specifications={partialAddressSchema}
                />
            )}

so it either uses the hardcoded partial form (meaning only postal code) or null.

This MR will ensure that if address specifications are passed, they are preferred over default specifications.

This means if you pass specifications to credit card config when initializing the drop-in like this:

const config = {
  paymentMethodsConfiguration: {
    card: {
          specifications: {
            NL: {
              optionalFields: ["houseNumberOrName"],
              labels: {
                [HOUSE_NUMBER_OR_NAME]: "customHouseNumberLabel",
              },
              placeholders: {
                ["houseNumberOrName"]: "Unit 451",
              },
            },
          },
    }
  }

}

image

Tested scenarios

Fixed issue:

@changeset-bot
Copy link

changeset-bot bot commented Mar 20, 2025

🦋 Changeset detected

Latest commit: 3cd1f02

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@adyen/adyen-web Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

const showBillingAddress = props.billingAddressMode !== AddressModeOptions.none && props.billingAddressRequired;

const partialAddressSchema = handlePartialAddressMode(props.billingAddressMode);
const partialAddressSchema = handlePartialAddressMode(props.billingAddressMode, specifications.getSpecifications());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will allow us to use the custom specifications properly

showStoreDetailsCheckbox?: boolean;
showWarnings?: boolean;
specifications?: Specifications;
specifications?: AddressSpecifications;
Copy link
Author

@M-Izadmehr M-Izadmehr Mar 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed the type here, the value of specifications coming from props is not the class rather its the AddressSpecifications object. This was not caught by TS since in specifications.ts class we have the following logic:

class Specifications {
    private specifications: AddressSpecifications;

    constructor(specifications?) {
        this.specifications = { ...ADDRESS_SPECIFICATIONS, ...specifications };
    }

here using specifications? in the constructor, assumes specifications to be type any


export const handlePartialAddressMode = (addressMode: AddressModeOptions): AddressSpecifications | null => {
export const handlePartialAddressMode = (addressMode: AddressModeOptions, specifications: AddressSpecifications): AddressSpecifications | null => {
if (specifications) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the main addition to this MR, in case we get specifications, we can prefer it over addressMode


class Specifications {
private specifications: AddressSpecifications;
private readonly specifications: AddressSpecifications;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added for safety

constructor(specifications?) {
this.specifications = { ...ADDRESS_SPECIFICATIONS, ...specifications };
constructor(specifications?: AddressSpecifications) {
if (specifications && typeof specifications === 'object') {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a small check here to make sure the input type is correct

* Returns the specifications object.
* @returns specifications - returns combines specifications
*/
getSpecifications(): AddressSpecifications {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added this new getter to give the merged specification

@M-Izadmehr
Copy link
Author

Can you please guide me to find what is the best approach here to add this change to both V5 and V6?

@m1aw
Copy link
Contributor

m1aw commented Mar 21, 2025

Hey @M-Izadmehr

If I understand correctly the objective of the PR is to allow passing specification property to the card component so you can customise the billing address form?

@M-Izadmehr
Copy link
Author

If I understand correctly the objective of the PR is to allow passing specification property to the card component so you can customise the billing address form?

Hey @m1aw, exactly.

In our case, we noticed our users from some countries are not used to having some of the fields. In this case for example for NL we want to have houseNumber as required, however for TW to keep it as optional and change its label

specification seemed to support this use case very well

@m1aw
Copy link
Contributor

m1aw commented Mar 26, 2025

@M-Izadmehr thank you for the PR.

We agree that this is a feature we want to expose, we aren't certain if this is something we want to expose in it's current form. We had some changes to address component in the pipeline, we want to ensure this feature is compatible with this.

So for now we are parking this change. We will try to revisit ASAP.

@M-Izadmehr
Copy link
Author

Hi @m1aw,
do we have any sample or docs on how it's planned to expose this? I'd be more than happy to adjust it to be consistent with it.
Currently lack of customization on the form is proving to be a blocker for us, so I'd like to help finding a solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants