Skip to content

Checkout action callback - #2755

Merged
nauaros merged 34 commits into
developfrom
feature/COSDK-1557_Checkout_action_callback
Sep 30, 2026
Merged

nauaros merged 34 commits into
developfrom
feature/COSDK-1557_Checkout_action_callback

Conversation

@nauaros

@nauaros nauaros commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary [Required]

Introduces onAction(_ actionData: ActionData, actionViewController: UIViewController), which hands the integrator both the action's data and the view controller the SDK built for it, so they decide how the action is presented. It replaces the PresentationDelegate protocol and the presentationDelegate: parameter of Checkout.setup(...). The callback lives on BaseCheckout, so the session, advanced and action-only flows all expose it from one declaration.

Technical Information [Optional]

  • PresentationDelegate became package protocol ActionPresentationDelegate with present(actionData:actionViewController:). All eleven presentation sites supply the matching ActionType.
  • CheckoutCore is now its own presentation delegate. With no handler set it falls back to presenting on the pending payment component; the action-only flow has none, so it asserts.
  • Drop-in presents actions in its own navigation stack and does not fire onAction. Documented on the callback, in README.md, guides/v6/README.md and MIGRATION.md.
  • Removes dead code the refactor exposed: NavigationDelegate/DismissalDelegate, Session.presentationDelegate (stored, never read) and BACSDirectDebitComponent.presentationDelegate (ahead of COSDK-1284).

Testing Instructions [Optional]

  1. Run the BLIK example in the session and advanced flows; the await screen is presented through onAction, wrapped in a navigation controller with a cancel button.
  2. UnitTests and IntegrationTests schemes: 436 and 984 tests, no failures.

Ticket [Optional]

COSDK-1557

Checklist [Required]

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

@nauaros nauaros added the new a pull request that adds a new feature label Sep 29, 2026
@nauaros nauaros self-assigned this Sep 29, 2026

@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 action presentation across the SDK by removing the public PresentationDelegate protocol and the presentationDelegate parameter from Checkout.setup(...) in favor of a new closure-based onAction(_:) callback on all checkout flows. It also introduces ActionData and ActionType to describe the actions being presented. A critical issue was identified in BACSDirectDebitComponent where discarding the confirmation view controller and removing the presentation delegate will prevent the BACS Direct Debit confirmation screen from being presented, which breaks the payment flow.

Comment thread AdyenComponents/BACS Direct Debit/BACSDirectDebitComponent.swift
…_Checkout_action_callback

# Conflicts:
#	MIGRATION.md
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

ℹ️ No baseline data found for 'develop'.

Framework Size
AdyenComponents.framework 2574 KB
AdyenActions.framework 2327 KB
AdyenDropIn.framework 1940 KB
AdyenDelegatedAuthentication.framework 158 KB
AdyenAuthentication.framework 347 KB
AdyenWeChatPay.framework 274 KB
AdyenUI.framework 3404 KB
AdyenCardScanner.framework 689 KB
AdyenEncryption.framework 506 KB
AdyenSession.framework 666 KB
AdyenTwint.framework 302 KB
AdyenWeChatPayInternal.framework 4135 KB
AdyenCheckout.framework 834 KB
AdyenCashAppPay.framework 1764 KB
AdyenCard.framework 1732 KB
TwintSDK.framework 97 KB
Adyen3DS2.framework 919 KB
Adyen.framework 5171 KB
total 27839 KB

Aligns the property name with the ActionPresentationDelegate protocol it
holds, so action-presentation plumbing is distinguishable from other
delegate properties at call sites.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@nauaros nauaros removed the size:huge label Sep 29, 2026

@erenbesel erenbesel 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.

Love to see it! some notes

Comment thread Adyen/Actions/ActionType.swift Outdated
Comment thread Adyen/Actions/ActionType.swift Outdated
Comment thread Adyen/Core/Core Protocols/ActionPresentationDelegate.swift Outdated
Comment thread Adyen/Core/Configuration/CheckoutBaseCallbacks.swift Outdated
Comment thread AdyenCheckout/Core/CheckoutCore+Orchestration.swift
Comment thread AdyenCheckout/Core/CheckoutCore.swift
Comment thread Demo/Common/IntegrationExamples/Session/Components/ApplePayComponentExample.swift Outdated
Comment thread Demo/Common/IntegrationExamples/Session/DropIn/DropInExample.swift Outdated
@nauaros nauaros added chore a pull request that has chore changes that shouldn't be in the release notes and removed new a pull request that adds a new feature labels Sep 30, 2026
@nauaros nauaros removed the size:huge label Sep 30, 2026
@nauaros
nauaros marked this pull request as ready for review September 30, 2026 10:29
@nauaros
nauaros requested a review from erenbesel September 30, 2026 10:29
@nauaros
nauaros enabled auto-merge September 30, 2026 13:30
# Summary
Renames the public callback typealiases so they are all prefixed with
`Checkout`, preventing name collisions with integrator types. Also
documents the renames in the migration guide.

## Release Notes
<changed>
- Renamed `SubmitHandler`, `AdditionalDetailsHandler` and
`BeforeSubmitHandler` to `CheckoutSubmitHandler`,
`CheckoutAdditionalDetailsHandler` and `CheckoutBeforeSubmitHandler`.
</changed>

## Technical Information
Handlers already containing `Checkout` (`CheckoutActionHandler`,
`SessionCheckoutCompletionHandler`, `AdvancedCheckoutCompletionHandler`,
`CheckoutFailureHandler`) are unchanged.

## Checklist
- [x] Tested changes locally
- [ ] Added/updated unit tests
- [x] Verified against acceptance criteria
- [ ] Aligned public API changes with other platforms (if applicable)
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ 18 public changes detected ⚠️

Comparing feature/COSDK-1557_Checkout_action_callback to develop
Platform: iOS

❇️7 Additions
🔀7 Modifications
❌4 Removals

Adyen

❇️ Added

public struct ActionData: Swift.Equatable, Swift.Sendable {
  public init(type: Adyen.ActionType)
  public let type: Adyen.ActionType { get }
  public static func ==(
    a: Adyen.ActionData,
    b: Adyen.ActionData
  ) -> Swift.Bool
}
public struct ActionType: Swift.Decodable, Swift.Hashable, Swift.RawRepresentable, Swift.Sendable {
  public init(from decoder: any Swift.Decoder) throws
  public init(rawValue: Swift.String)
  public let rawValue: Swift.String { get }
  public static let await: Adyen.ActionType { get }
  public static let nativeRedirect: Adyen.ActionType { get }
  public static let qrCode: Adyen.ActionType { get }
  public static let redirect: Adyen.ActionType { get }
  public static let sdk: Adyen.ActionType { get }
  public static let threeDS2: Adyen.ActionType { get }
  public static let voucher: Adyen.ActionType { get }
  public typealias RawValue = Swift.String
}
public typealias CheckoutActionHandler = @_Concurrency.MainActor @Sendable (_ actionData: Adyen.ActionData, _ actionViewController: UIKit.UIViewController) -> Swift.Void
public typealias CheckoutAdditionalDetailsHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.ActionComponentData) async -> Adyen.AdditionalDetailsResult
public typealias CheckoutBeforeSubmitHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.BeforeSubmitData) async -> Adyen.BeforeSubmitResult
public typealias CheckoutSubmitHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.PaymentComponentData) async -> Adyen.SubmitResult

❌ Removed

@_Concurrency.MainActor
public protocol PresentationDelegate: AnyObject {
  @_Concurrency.MainActor
  func present(viewController: UIKit.UIViewController) -> Swift.Void
}
public typealias AdditionalDetailsHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.ActionComponentData) async -> Adyen.AdditionalDetailsResult
public typealias BeforeSubmitHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.BeforeSubmitData) async -> Adyen.BeforeSubmitResult
public typealias SubmitHandler = @_Concurrency.MainActor @Sendable (_ data: Adyen.PaymentComponentData) async -> Adyen.SubmitResult

AdyenCheckout

ActionOnlyCheckout

🔀 Modified

// From
@_Concurrency.MainActor
final public func onAdditionalDetails(_ handler: @escaping Adyen.AdditionalDetailsHandler) -> Self

// To
@_Concurrency.MainActor
final public func onAdditionalDetails(_ handler: @escaping Adyen.CheckoutAdditionalDetailsHandler) -> Self

/**
Changes:
- Modified parameter `_`: Changed type from `@escaping Adyen.AdditionalDetailsHandler` to `@escaping Adyen.CheckoutAdditionalDetailsHandler`
*/

AdvancedCheckout

🔀 Modified

// From
@_Concurrency.MainActor
final public func onAdditionalDetails(_ handler: @escaping Adyen.AdditionalDetailsHandler) -> Self

// To
@_Concurrency.MainActor
final public func onAdditionalDetails(_ handler: @escaping Adyen.CheckoutAdditionalDetailsHandler) -> Self

/**
Changes:
- Modified parameter `_`: Changed type from `@escaping Adyen.AdditionalDetailsHandler` to `@escaping Adyen.CheckoutAdditionalDetailsHandler`
*/
// From
@_Concurrency.MainActor
final public func onSubmit(_ handler: @escaping Adyen.SubmitHandler) -> Self

// To
@_Concurrency.MainActor
final public func onSubmit(_ handler: @escaping Adyen.CheckoutSubmitHandler) -> Self

/**
Changes:
- Modified parameter `_`: Changed type from `@escaping Adyen.SubmitHandler` to `@escaping Adyen.CheckoutSubmitHandler`
*/

BaseCheckout

❇️ Added

@_Concurrency.MainActor
public func onAction(_ handler: @escaping Adyen.CheckoutActionHandler) -> Self

Checkout

🔀 Modified

// From
@_Concurrency.MainActor
public static func setup(
  configuration: AdyenCheckout.CheckoutConfiguration,
  presentationDelegate: (any Adyen.PresentationDelegate)? = nil
) async throws -> AdyenCheckout.ActionOnlyCheckout

// To
@_Concurrency.MainActor
public static func setup(configuration: AdyenCheckout.CheckoutConfiguration) async throws -> AdyenCheckout.ActionOnlyCheckout

/**
Changes:
- Removed parameter `presentationDelegate: (any Adyen.PresentationDelegate)? = nil`
*/
// From
@_Concurrency.MainActor
public static func setup(
  with paymentMethods: Adyen.PaymentMethods,
  configuration: AdyenCheckout.CheckoutConfiguration,
  presentationDelegate: (any Adyen.PresentationDelegate)? = nil
) async throws -> AdyenCheckout.AdvancedCheckout

// To
@_Concurrency.MainActor
public static func setup(
  with paymentMethods: Adyen.PaymentMethods,
  configuration: AdyenCheckout.CheckoutConfiguration
) async throws -> AdyenCheckout.AdvancedCheckout

/**
Changes:
- Removed parameter `presentationDelegate: (any Adyen.PresentationDelegate)? = nil`
*/
// From
@_Concurrency.MainActor
public static func setup(
  with sessionResponse: Adyen.SessionResponse,
  configuration: AdyenCheckout.CheckoutConfiguration,
  presentationDelegate: (any Adyen.PresentationDelegate)? = nil
) async throws -> AdyenCheckout.SessionCheckout

// To
@_Concurrency.MainActor
public static func setup(
  with sessionResponse: Adyen.SessionResponse,
  configuration: AdyenCheckout.CheckoutConfiguration
) async throws -> AdyenCheckout.SessionCheckout

/**
Changes:
- Removed parameter `presentationDelegate: (any Adyen.PresentationDelegate)? = nil`
*/

SessionCheckout

🔀 Modified

// From
@_Concurrency.MainActor
final public func onBeforeSubmit(_ handler: @escaping Adyen.BeforeSubmitHandler) -> Self

// To
@_Concurrency.MainActor
final public func onBeforeSubmit(_ handler: @escaping Adyen.CheckoutBeforeSubmitHandler) -> Self

/**
Changes:
- Modified parameter `_`: Changed type from `@escaping Adyen.BeforeSubmitHandler` to `@escaping Adyen.CheckoutBeforeSubmitHandler`
*/

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

@nauaros
nauaros added this pull request to the merge queue Sep 30, 2026
Merged via the queue into develop with commit a7d4130 Sep 30, 2026
17 checks passed
@nauaros
nauaros deleted the feature/COSDK-1557_Checkout_action_callback branch September 30, 2026 14:17
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:huge size:large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants