Classic-integration icon

Build your own UI

Integrate our Checkout iOS SDK with your own UI.

The classic Checkout SDK integrations are being phased out
This means we are:

  • No longer developing the classic Checkout SDK integration.
  • Not accepting new classic Checkout SDK integrations.

You have until March 31, 2024 to migrate.

Our Checkout SDK for iOS gives you the ability to take advantage of the SDK's payment flow, including the communication between the SDK and Adyen, yet still collect and present information using your own UI. There are additional functions that you need to implement to do this, which we explain below. 

This guide expects you to have followed the Checkout iOS SDK integration guide. The integration steps are similar, but when you build your own UI integration, you'll need to use the PaymentControllerDelegate and PaymentControllernot the CheckoutControllerDelegate and CheckoutController referred to in the guide.

To start the payment, initiate and start a PaymentController

var paymentController: PaymentController?

func startPayment() {
    paymentController = PaymentController(delegate: self)
    paymentController?.start()
}

Create payment session

The steps for generating a paymentSession value with the client side requestPaymentSession and /paymentSession API call are identical to those described in the integration guide. Instead, you'll need to implement them against the PaymentControllerDelegate.

Present payment methods

The PaymentControllerDelegate will call the selectPaymentMethod method to provide a list of available payment methods. You will need to provide your own UI to collect the shopper's chosen payment method and any required details.

func selectPaymentMethod(from paymentMethods: SectionedPaymentMethods, for paymentController: PaymentController, selectionHandler: @escaping (PaymentMethod) -> Void)

The paymentMethods object has two properties:

  • preferred: contains an array of one-click enabled payment methods, that the shopper has used previously.
  • other: contains an array of all other payment methods.

Display a list of payment methods to the shopper. We recommend presenting the preferred methods at the top of the list. Then, collect their chosen payment method by passing the corresponding payment method object from paymentMethods.

func selectPaymentMethod(from paymentMethods: SectionedPaymentMethods, for paymentController: PaymentController, selectionHandler: @escaping (PaymentMethod) -> Void) {
    // Present paymentMethods to the shopper
    var paymentMethod = ... // A payment method selected by the shopper.
    selectionHandler(paymentMethod)
}

Collect payment details

For most payment methods, you'll need to collect additional details from the shopper. You can find a list of these inside the details array in the PaymentMethod. Once you've collected these details from the shopper, provide the values back in the details object of the paymentMethod. Then, pass this to the SDK via the selectionHandler.

The example below shows how you'd collect the payment method details for a SEPA Direct Debit payment.

func selectPaymentMethod(from paymentMethods: SectionedPaymentMethods, for paymentController: PaymentController, selectionHandler: @escaping (PaymentMethod) -> Void) {
    // Present View Controller with the list of paymentMethods
    var paymentMethod = ... // A payment method selected by the shopper.

    // For SEPA Direct Debit:
    paymentMethod.details.sepaName?.value = "J. Snow"
    paymentMethod.details.sepaIBAN?.value = "NL13TEST0123456789"

    selectionHandler(paymentMethod)
}

Handle the redirect result

For many local payment methods, such as iDEAL or card payments with 3D Secure, you'll need to redirect the shopper to a webpage or app to verify the payment. In this case, the redirect method from PaymentControllerDelegate is invoked.

func redirect(to url: URL, for paymentController: PaymentController)

Load the URL for the shopper with, for example, the SFSafariViewController.

func redirect(to url: URL, for paymentController: PaymentController) {
    let safariViewController = SFSafariViewController(url: url)
    present(safariViewController, animated: true)
}

When the shopper has completed verification, handle their return to your app by implementing the following in your UIApplicationDelegate.

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
    let adyenHandled = Adyen.applicationDidOpen(url)
    if !adyenHandled {
        //Adyen did not handle the url
        //Provide additional url handling logic for your app if needed
    }
    return true
}

Handle payment result

After the payment has been processed, get the result by implementing the didFinish method of the PaymentControllerDelegate protocol. Present this to the shopper in your app. You'll also receive a payload. Use this to verify the outcome of the payment with your server.

func didFinish(with result: Result<PaymentResult>, for paymentController: PaymentController) {
    // Handle the result.
}

Next steps