Checkout icon

Sessions flow integration guide

Start accepting payments on your website or app.

Web
iOS
Android
React Native
Flutter
Use our pre-built UI for accepting payments
Use our customizable UI components
/user/pages/filters/advanced-flow-integration/ios/components/visual/ios-components.svg

iOS Components

Render individual payment methods anywhere in your app.

Supported payment methods

Cards, buy now pay later, wallets, and many more.

See all supported payment methods

Features

  • Low development time to integrate each payment method component
  • UI styling customization for each payment method
  • Flexibility to add payment method components with configuration for each
  • 3D Secure 2 support using the 3D Secure 2 Component

Start integrating with iOS Components

Choose your version
5.1.0

Requirements

Before you begin to integrate, make sure you have followed the Get started with Adyen guide to:

  • Get an overview of the steps needed to accept live payments.
  • Create your test account.

After you have created your test account:

How it works

For a Components integration, you must implement the following parts:

  • Your payment server: sends the API request to create a payment session.
  • Your client app: shows the the Component UI where the shopper makes the payment. The Component uses the data from the API responses to handle the payment flow and additional actions on your client app.
  • Your webhook server: receives webhooks that include the outcome of each payment.

The parts of your integration work together to complete the payment flow:

  1. The shopper goes to the checkout page.

  2. Your server uses the shopper's country and currency information from your client to create a payment session.

  3. Your client creates an instance of the Component using the session data from the server.

  4. The Component collects the shopper's payment details, handles additional actions, and presents the payment result to the shopper.

  5. Your webhook server receives the notification containing the payment outcome.

If you are integrating these parts separately, you can start at the corresponding part of this integration guide:

Install an API library

Payment server

We provide server-side API libraries for several programming languages, available through common package managers, like Gradle and npm, for easier installation and version management. Our API libraries will save you development time, because they:

  • Use an API version that is up to date.
  • Have generated models to help you construct requests.
  • Send the request to Adyen using their built-in HTTP client, so you do not have to create your own.
Try our example integration

Requirements

  • Java 11 or later.

Installation

You can use Maven, adding this dependency to your project's POM.

Add the API library
Expand view
Copy link to code block
Copy code
Copy code
<dependency>
<groupId>com.adyen</groupId>
<artifactId>adyen-java-api-library</artifactId>
<version>LATEST_VERSION</version>
</dependency>

You can find the latest version on GitHub. Alternatively, you can download the release on GitHub.

Setting up the client

Create a singleton resource that you use for the API requests to Adyen:

Set up your client
Expand view
Copy link to code block
Copy code
Copy code
// Import the required classes.
package com.adyen.service;
import com.adyen.Client;
import com.adyen.service.checkout.PaymentsApi;
import com.adyen.model.checkout.Amount;
import com.adyen.model.checkout.CreateCheckoutSessionRequest;
import com.adyen.model.checkout.CreateCheckoutSessionResponse;
import com.adyen.enums.Environment;
import com.adyen.service.exception.ApiException;
import java.io.IOException;
public class Snippet {
public Snippet() throws IOException, ApiException {
// Set up the client and service.
Client client = new Client("ADYEN_API_KEY", Environment.TEST);
}
}

Create a payment session

Payment server

A payment session is a resource with information about a payment flow initiated by the shopper. This resource has all the information required to handle all the stages of a payment flow. You can configure this resource with information like available payment methods, payment amount, or line items.

To create a payment session, make a /sessions request, including:

Parameter name Required Description
merchantAccount -white_check_mark- Your merchant account name.
amount -white_check_mark- The currency and value of the payment, in minor units. This is used to filter the list of available payment methods to your shopper.
returnUrl -white_check_mark- The URL the shopper should be taken back to after a redirection. Use the custom URL for your app, for example, my-app://adyen, to take the shopper back to your app after they complete the payment outside of your app. For more information on setting a custom URL scheme, read the Apple Developer documentation. The URL can contain a maximum of 1024 characters. You can also include your own additional query parameters, for example, shopper ID or order reference number.
If the URL to return to includes non-ASCII characters, like spaces or special letters, URL encode the value.
The URL must not include personally identifiable information (PII), for example name or email address.
reference -white_check_mark- Your unique reference for the payment. Minimum length: three characters.
expiresAt The session expiry date in ISO8601 format, for example 2023-11-23T12:25:28Z, or 2023-05-27T20:25:28+08:00. When not specified, the expiry date is set to 1 hour after session creation. You cannot set the session expiry to more than 24 hours after session creation.
countryCode The shopper's country/region. This is used to filter the list of available payment methods to your shopper.
Format: the two-letter ISO-3166-1 alpha-2 country code. Exception: QZ (Kosovo).
channel The platform where the payment is taking place. Use iOS. Strongly recommended because this field is used for 3D Secure.
shopperLocale The language that the payment methods will appear in. Set it to the shopper's language and country code. The default is en-US. The client app. also uses this locale if it is available.
shopperEmail The shopper's email address. Strongly recommended because this field is used in a number of risk checks, and for 3D Secure.
shopperReference Your reference to uniquely identify this shopper. Minimum length: three characters. Do not include personally identifiable information, for example name or email address. Strongly recommended because this field is used in a number of risk checks.
applicationInfo If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support. For more information, refer to Building Adyen solutions.

The following example shows how to create a session for a payment of 10 EUR:

Expand view
Copy link to code block
Copy code
Copy code
curl https://checkout-test.adyen.com/checkout/v70/sessions \
-H 'x-api-key: ADYEN_API_KEY' \
-H 'content-type: application/json' \
-d '{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"amount": {
"value": 1000,
"currency": "EUR"
},
"returnUrl": "my-app://adyen",
"reference": "YOUR_PAYMENT_REFERENCE",
"countryCode": "NL"
}'

The response contains:

  • sessionData: the payment session data you need to pass to your client app.
  • id: a unique identifier for the session data.
  • The request body.
HTTP 201 /sessions response body
Expand view
Copy link to code block
Copy code
Copy code
{
"amount": {
"currency": "EUR",
"value": 1000
},
"countryCode": "NL",
"expiresAt": "2021-08-24T13:35:16+02:00",
"id": "CSD9CAC34EBAE225DD",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YOUR_PAYMENT_REFERENCE",
"returnUrl": "my-app://adyen",
"sessionData": "Ab02b4c.."
}

API error handling

If you do not get an HTTP 201 response, use the errorCode field and the list of API error codes to troubleshoot.

Set up Components

Client app

1. Get Adyen iOS

Choose how you want to install the Adyen iOS client-side library:

To install iOS Components using Swift Package Manager, follow the Apple guide and specify:

  • The repository URL as https://github.com/Adyen/adyen-ios.
  • The Adyen iOS client-side library version to be at least 5.0.0.

2. Create the context

First, create an instance of APIContext that contains:

Then, create an instance of AdyenContext that contains:

  • The instance of APIContext.
  • Payment information.
Create the context
Expand view
Copy link to code block
Copy code
Copy code
// Set the client key and environment in an instance of APIContext.
let apiContext = APIContext(clientKey: clientKey, environment: Environment.test) // Set the environment to a live one when going live.
// Create the amount with the value in minor units and the currency code.
let amount = Amount(value: 1000, currencyCode: "EUR")
// Create the payment object with the amount and country code.
let payment = Payment(amount: amount, countryCode: "NL")
// Create an instance of AdyenContext, passing the instance of APIContext, and payment object.
let adyenContext = AdyenContext(apiContext: apiContext, payment:payment)

3. Create a configuration object

Use the fields from the /sessions response to configure and create an instance of AdyenSession:

Create a configuration object
Expand view
Copy link to code block
Copy code
Copy code
let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId, // The id from the API response.
initialSessionData: data, // The sessionData from the API response.)

4. Initialize AdyenSession

Call the static initialize function of the AdyenSession, setting:

  • configuration: the configuration object you created in the previous step.
  • delegate: your delegate object. For example, self.
  • presentationDelegate: your delegate object. For example, self.

This asynchronously creates and returns an instance of the session.

Initialize AdyenSession
Expand view
Copy link to code block
Copy code
Copy code
AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
switch result {
case let .success(session):
//Store the session object.
self?.session = session
case let .failure(error):
//Handle the error.
}
}

5. Configure the Component

The Component shows the UI elements such as the payment form and pay button.

Create and set the following:

  • a configuration object for the payment method. For example, cardComponentConfiguration for the Card Component. Initialize it with CardComponent.Configuration().
    • optionally, custom localization parameters.
    • optionally, payment method specific parameters. For example, showsHolderNameField for the Card Component.
  • other optional configuration.
Configure the Component
Expand view
Copy link to code block
Copy code
Copy code
var cardComponentConfiguration = CardComponent.Configuration()
cardComponentConfiguration.localizationParameters = // Optional custom localization parameters.
cardComponentConfiguration.showsHolderNameField = true // Optional configuration for Card Component.
... // Other required or optional payment method configuration.

6. Initialize the Component

When the shopper selects a payment method, initialize the matching payment method Component.

  1. Create the Component, passing the following configurations:

    • paymentMethod: the payment method object that you created.
    • context: the AdyenContext that you created.
    • configuration: the configuration object that you created.
  2. Set the instance of AdyenSession you created in the previous step as the delegate.

    The following example shows how to create the Card Component and set the instance of AdyenSession you created as the delegate:

    Create the Card Component
    Expand view
    Copy link to code block
    Copy code
    Copy code
    // Check that the payment method is supported before showing the Component.
    guard let paymentMethods = self.session?.sessionContext.paymentMethods,
    let paymentMethod = paymentMethods.paymentMethod(ofType: CardPaymentMethod.self) else { return nil }
    let cardComponent = CardComponent(paymentMethod: paymentMethod,
    context: adyenContext,
    configuration: cardComponentConfiguration)
    // Set the session as the delegate.
    cardComponent.delegate = session

7. Show the Component in your app

Call the present method, passing the configured viewController.

The following example shows how to present the Card Component:

Present the Card Component
Expand view
Copy link to code block
Copy code
Copy code
present(cardComponent.viewController)

Some payment methods require additional action from the shopper such as authenticating a payment with 3D Secure, or to switch to another app to complete the payment. Your instance of AdyenSession handles the actions to complete the payment.

If the action type is redirect, you need to handle the redirect result.

8. Handle the redirect

If the action field returns redirect, the shopper is redirected to an external site or to another application to complete the payment. You then need to inform the Component when the shopper returns to your app.

The way to handle the redirect depends on if you use Custom or Universal URLs and the way you manage your app’s lifecycle events:

If you use a Custom URL scheme, implement the following in your UIApplicationDelegate :

Handle the redirect for Custom URLs
Expand view
Copy link to code block
Copy code
Copy code
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return RedirectComponent.applicationDidOpen(from: url)
}

If you use a Universal URL, implement the following in your UIApplicationDelegate instead:

Handle the redirect for Universal URLs
Expand view
Copy link to code block
Copy code
Copy code
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let incomingURL = userActivity.webpageURL else { return false }
return RedirectComponent.applicationDidOpen(from: incomingURL)
}

9. Handle the result

The Component handles a result code or an error object.

Result code

When the payment flow is finished, your instance of AdyenSession calls the didComplete method.

Implement the following Component configuration object.

Implement didComplete in Component configuration
Expand view
Copy link to code block
Copy code
Copy code
func didComplete(with resultCode: SessionPaymentResultCode, // The result code with the current payment status from the API response.
component: Component, // Your instance of Component.
session: AdyenSession) // Your instance of AdyenSession.

Use the resultCode to inform your shopper about the current payment status. Possible values:

resultCode Description Action to take
authorised The payment was successfully authorised. Inform the shopper that the payment was successful.
refused The payment was refused.
The response also contains a refusal reason that indicates why it was refused.
Inform the shopper that the payment was refused.
pending The final status of the payment isn't available yet. This is common for payments with an asynchronous flow, such as Boleto or iDEAL. Inform the shopper that you have received their order, and are waiting for them to complete the payment.
When the shopper completes the payment, you get a webhook with the updated payment status.
cancelled The payment was cancelled (by either the shopper or your system) before processing was completed. Inform the shopper that the payment was cancelled.
error An error occurred during payment processing.
The response also contains an error code that gives more details about the error.
Inform the shopper that an error occurred during payment processing.
received The payment request was received, but the final status of the payment isn't available yet. Some payments, like SEPA Direct Debit, take time to process. Inform the shopper that you have received their order, and are waiting for the final payment status.

When the updated payment status is available, you get a webhook.
presentToShopper Show the voucher or QR code to the shopper. Inform the shopper that you have received their order, and are waiting for them to complete the payment.
When the shopper completes the payment, you get a webhook with the updated payment status.

Error

If an error occurs during the payment flow, your instance of AdyenSession calls the didFail method containing the error.

Implement the following in your Component configuration object.

Implement didFail in Component configuration
Expand view
Copy link to code block
Copy code
Copy code
func didFail(with error: Error, // The error object.
from component: Component, // Your instance of the Component.
session: AdyenSession) // Your instance of AdyenSession.

The error tells you the type of error and contains a message with details. Use the information to tell the shopper what happened and use the message to troubleshoot the error.

Get the payment outcome

After the Component finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment.

Inform the shopper

Client app

From the didComplete method, you can get the resultCode to inform the shopper about the current payment status.

Payment server

You can also get the result of the payment session on your server.

  1. Get the id from the /sessions response.
  2. Get sessionResult from the onPaymentCompleted event.
  3. Make a GET /sessions/{id}?sessionResult={sessionResult} request including the id and sessionResult. For example:

    Request for result of payment session
    Expand view
    Copy link to code block
    Copy code
    Copy code
    curl -X GET https://checkout-test.adyen.com/checkout/v71/sessions/CS12345678?sessionResult=SOME_DATA

    The response includes the result of the payment session (status). For example:

    Response with result of the payment session
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {
    "id": "CS12345678",
    "status": "completed"
    }

    Possible statuses:

    status Description
    completed The shopper completed the payment. This means that the payment was authorized.
    paymentPending The shopper is in the process of making the payment. This applies to payment methods with an asynchronous flow.
    canceled The shopper canceled the payment.
    expired The session expired (default: 1 hour after session creation). Shoppers can no longer complete the payment with this sessionId.

The status included in the response doesn't get updated. Do not make the request again to check for payment status updates. Instead, check webhooks or the Transactions list in your Customer Area.

Update your order management system

Webhook server

You get the outcome of each payment asynchronously, in an AUTHORISATION webhook. Use the merchantReference from the webhook to match it to your order reference.
For a successful payment, the event contains success: true.

Example webhook for a successful payment
Expand view
Copy link to code block
Copy code
Copy code
{
"live": "false",
"notificationItems":[
{
"NotificationRequestItem":{
"eventCode":"AUTHORISATION",
"merchantAccountCode":"YOUR_MERCHANT_ACCOUNT",
"reason":"033899:1111:03/2030",
"amount":{
"currency":"EUR",
"value":2500
},
"operations":["CANCEL","CAPTURE","REFUND"],
"success":"true",
"paymentMethod":"mc",
"additionalData":{
"expiryDate":"03/2030",
"authCode":"033899",
"cardBin":"411111",
"cardSummary":"1111",
"checkoutSessionId":"CSF46729982237A879"
},
"merchantReference":"YOUR_REFERENCE",
"pspReference":"NC6HT9CRT65ZGN82",
"eventDate":"2021-09-13T14:10:22+02:00"
}
}
]
}

For an unsuccessful payment, you get success: false, and the reason field has details about why the payment was unsuccessful.

Example webhook for an unsuccessful payment
Expand view
Copy link to code block
Copy code
Copy code
{
"live": "false",
"notificationItems":[
{
"NotificationRequestItem":{
"eventCode":"AUTHORISATION",
"merchantAccountCode":"YOUR_MERCHANT_ACCOUNT",
"reason":"validation 101 Invalid card number",
"amount":{
"currency":"EUR",
"value":2500
},
"success":"false",
"paymentMethod":"unknowncard",
"additionalData":{
"expiryDate":"03/2030",
"cardBin":"411111",
"cardSummary":"1112",
"checkoutSessionId":"861631540104159H"
},
"merchantReference":"YOUR_REFERENCE",
"pspReference":"KHQC5N7G84BLNK43",
"eventDate":"2021-09-13T14:14:05+02:00"
}
}
]
}

Test and go live

Before going live, use our list of test cards and other payment methods to test your integration. We recommend testing each payment method that you intend to offer to your shoppers.

You can check the status of a test payment in your Customer Area, under TransactionsPayments.

To debug or troubleshoot test payments, you can also use API logs in your test environment.

When you are ready to go live, you need to:

  1. Apply for a live account. Review the process to start accepting payments on Get started with Adyen.
  2. Assess your PCI DSS compliance by submitting the Self-Assessment Questionnaire-A.
  3. Configure your live account
  4. Submit a request to add payment methods in your live Customer Area .
  5. Switch from test to our live endpoints.
  6. Load Components from one of our live environments and set the environment to match your live endpoints:

    Endpoint region Value
    Europe (EU) live liveEurope
    United States (US) live liveUnitedStates
    Australia (AU) live liveAustralia
    Asia Pacific & Southeast (APSE) live liveApse
    India (IN) live liveIndia

Optional configuration

You can set additional configuration on the Component configuration.

Parameter name Description
shopperInformation Prefilled shopper information.
localizationParameters Localization parameters, like custom placeholders in other languages.
style Custom styling of the UI.

The following example shows how to set optional configuration parameters on the Card Component.

Set optional configuration parameters
Expand view
Copy link to code block
Copy code
Copy code
// Create a configuration object for the Component.
let cardComponentConfiguration = CardComponent.Configuration()
// Optional: create a configuration object for styling.
let style = FormComponentStyle()
// Set the background color.
style.backgroundColor = .darkGray
// Set the style on the configuration object.
cardComponentConfiguration.style = style

iOS Components support the languages listed here.

To customize a localization, add a new localizable.strings file for the language that you need. You can also override existing strings by using the same keys.

For example, to override the cardholder name field title, set the following on your localizable.strings file:

Copy code
"adyen.card.nameItem.title" = "Your cardholder name";

For more information on iOS Components classes, see our reference documentation page.

To find localized strings, the library first checks your custom localizable.strings file, and then the default Adyen file.

You can use LocalizationParameters to customize the localization file name, bundle, or the separator for translation strings.

For example, if you store translations in MyLocalizable.strings files in the shared bundle CommonBundle:

Copy code
let localizationParameters = LocalizationParameters(bundle: commonBundle, tableName: "MyLocalizable")
cardComponentConfiguration.localizationParameters = localizationParameters