Skip to content

Align BillingAddressMode configuration for CardComponent#2590

Draft
robertdalmeida wants to merge 6 commits into
developfrom
chore/billing-address-mode-configuration
Draft

Align BillingAddressMode configuration for CardComponent#2590
robertdalmeida wants to merge 6 commits into
developfrom
chore/billing-address-mode-configuration

Conversation

@robertdalmeida

Copy link
Copy Markdown
Contributor

Summary [Required]

Changed the way the Billing Address Configuration is done as per the alignment PR.

Next

  • I think we don't need the logic to make the field optional, maybe we should remove it.
  • The Analytic payload has been changed due to this. Added a todo for this. We need to know what we need to send for this.

Ticket [Optional]

COSDK-1206

Checklist [Required]

  • Tested changes locally
  • Added/updated unit tests
  • Verified against acceptance criteria
  • Aligned public API changes with other platforms (if applicable)

@robertdalmeida robertdalmeida self-assigned this Jun 11, 2026
@robertdalmeida robertdalmeida added the chore a pull request that has chore changes that shouldn't be in the release notes label Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

ℹ️ No baseline data found for 'develop'.

Framework Size
AdyenComponents.framework 2509 KB
AdyenActions.framework 2364 KB
AdyenDropIn.framework 1390 KB
AdyenDelegatedAuthentication.framework 158 KB
AdyenAuthentication.framework 347 KB
AdyenWeChatPay.framework 274 KB
AdyenUI.framework 3272 KB
AdyenCardScanner.framework 689 KB
AdyenEncryption.framework 506 KB
AdyenSession.framework 674 KB
AdyenTwint.framework 263 KB
AdyenWeChatPayInternal.framework 4135 KB
AdyenCheckout.framework 2393 KB
AdyenCashAppPay.framework 1764 KB
AdyenCard.framework 1677 KB
TwintSDK.framework 97 KB
Adyen3DS2.framework 919 KB
Adyen.framework 5169 KB
total 28600 KB

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the billing address configuration by replacing the BillingAddressConfiguration struct with parameters directly on the BillingAddressMode enum cases, allowing the billing address fields to be hidden based on card types. Feedback on these changes highlights a missing supportedCountryCodes parameter in the .lookup case, which breaks country filtering during address lookup. Additionally, the reviewer recommends cleaning up unused methods like updateOptionalStatus and resolving outstanding TODOs regarding backend analytics compatibility and test events before merging.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 47 to 51
case lookup(
onAddressLookup: (String) async -> [AddressLookupResult],
onAddressSelected: ((AddressLookupResult) async throws -> PostalAddress)? = nil
onAddressSelected: ((AddressLookupResult) async throws -> PostalAddress)? = nil,
hideForCardTypes: Set<CardType> = []
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The .lookup case is missing the supportedCountryCodes parameter. Previously, merchants could configure supported country codes independently of the mode, and these were passed to the address lookup view model. With this change, supportedCountryCodes is only available for the .full case, meaning country filtering is no longer possible when using address lookup. Consider adding supportedCountryCodes: [String] = [] to the .lookup case as well.

    case lookup(
        supportedCountryCodes: [String] = [],
        onAddressLookup: (String) async -> [AddressLookupResult],
        onAddressSelected: ((AddressLookupResult) async throws -> PostalAddress)? = nil,
        hideForCardTypes: Set<CardType> = []
    )

Comment on lines +56 to 63
internal var supportedCountryCodes: [String]? {
switch self {
case let .full(supportedCountryCodes, _):
return supportedCountryCodes.isEmpty ? nil : supportedCountryCodes
case .none, .postalCode, .lookup:
return nil
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Update the supportedCountryCodes helper property to also extract and return the supported country codes for the .lookup case.

Suggested change
internal var supportedCountryCodes: [String]? {
switch self {
case let .full(supportedCountryCodes, _):
return supportedCountryCodes.isEmpty ? nil : supportedCountryCodes
case .none, .postalCode, .lookup:
return nil
}
}
internal var supportedCountryCodes: [String]? {
switch self {
case let .full(supportedCountryCodes, _),
let .lookup(supportedCountryCodes, _, _, _):
return supportedCountryCodes.isEmpty ? nil : supportedCountryCodes
case .none, .postalCode:
return nil
}
}

internal lazy var billingAddressPickerItem: FormAddressPickerItem? = {
switch addressMode {
case let .lookup(onLookup, onAddressSelected):
case let .lookup(onLookup, onAddressSelected, _):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If supportedCountryCodes is added to the .lookup case, make sure to update the pattern matching here to account for the new parameter.

Suggested change
case let .lookup(onLookup, onAddressSelected, _):
case let .lookup(_, onLookup, onAddressSelected, _):

Comment on lines +88 to 91
// TODO: Robert: BillingAddressModeConfiguration: I don't think this is needed anymore.
package func updateOptionalStatus(isOptional: Bool) {
context.isOptional = isOptional
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since the billing address optional status is no longer used (replaced by hiding the field entirely), this method and the associated TODO comment can be safely removed to keep the codebase clean.

} else {
self.billingAddressRequired = false
}
// TODO: Robert: BillingAddressMode: What should we send to the backend for billingAddressRequired?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Unresolved TODO: Please resolve what should be sent to the backend for billingAddressRequired before merging. Removing this field entirely might break backend analytics or compatibility if the backend expects this key.

XCTAssertEqual(configDataDict["socialSecurityNumberVisibility"], "auto")
XCTAssertEqual(configDataDict["hasInstallmentOptions"], "false")
XCTAssertEqual(configDataDict["billingAddressRequired"], "true")
// TODO: Robert: billingAddressRequired removed in favor of hideForCardTypes. What should be the alternate way to receive this event?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Unresolved TODO: Please resolve how this event should be handled or what alternative event/parameter should be verified in the test before merging.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ 4 public changes detected ⚠️

Comparing chore/billing-address-mode-configuration to develop
Platform: iOS

🔀3 Modifications
1 Removal

AdyenCard

BillingAddressMode

🔀 Modified

// From
case full

// To
case full(
  supportedCountryCodes: [Swift.String] = [],
  hideForCardTypes: Swift.Set<Adyen.CardType> = []
)

/**
Changes:
- Added parameter `hideForCardTypes: Swift.Set<Adyen.CardType> = []`
- Added parameter `supportedCountryCodes: [Swift.String] = []`
*/
// From
case lookup(
  onAddressLookup: (Swift.String) async -> [Adyen.AddressLookupResult],
  onAddressSelected: ((Adyen.AddressLookupResult) async throws -> Adyen.PostalAddress)? = nil
)

// To
case lookup(
  onAddressLookup: (Swift.String) async -> [Adyen.AddressLookupResult],
  onAddressSelected: ((Adyen.AddressLookupResult) async throws -> Adyen.PostalAddress)? = nil,
  hideForCardTypes: Swift.Set<Adyen.CardType> = []
)

/**
Changes:
- Added parameter `hideForCardTypes: Swift.Set<Adyen.CardType> = []`
*/
// From
case postalCode

// To
case postalCode(hideForCardTypes: Swift.Set<Adyen.CardType> = [])

/**
Changes:
- Added parameter `hideForCardTypes: Swift.Set<Adyen.CardType> = []`
*/

CardConfiguration

❌ Removed

public func billingAddressCountryCodes(_ countryCodes: [Swift.String]) -> AdyenCard.CardConfiguration

Analyzed targets: Adyen, AdyenActions, AdyenCard, AdyenCardScanner, AdyenCashAppPay, AdyenCheckout, AdyenComponents, AdyenDelegatedAuthentication, AdyenDropIn, AdyenEncryption, AdyenSession, AdyenSwiftUI, AdyenTwint, AdyenUI, AdyenWeChatPay

/// - hideForCardTypes: Card types for which the address form should be hidden
/// when detected via BIN lookup.
case full(
supportedCountryCodes: [String] = [],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@erenbesel @nauaros
I find this part strange, when we provide nil then all countries are available.
I would have preferred to have an enum something like below. WDYT?

CountryCode {
case all
case countries([String])
}

/// When empty, all countries are available.
/// - hideForCardTypes: Card types for which the address form should be hidden
/// when detected via BIN lookup.
case full(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@nauaros @erenbesel
I'm not sure what full means here. I personally think that either .form or .manual better describes the option where the user has to manually fill up the address without the search functioality.
Is this something that warrants a change? WDYT?

…nd refactor tests to match optional address policy behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore a pull request that has chore changes that shouldn't be in the release notes size:medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant