Search

Are you looking for test card numbers?

Would you like to contact support?

Default icon

iOS Components integration guide

Build your checkout form with our iOS Components.

  Check out Adyen iOS on GitHub.

Components are building blocks that you can use to render UI for individual payment methods: from collecting payment details to handling additional shopper interaction.

We recommend that you integrate Components if you want some degree of customization and flexibility on your payments form.

Supported payment methods

Components are available for cards, wallets, and most local payment methods. For a list of all payment methods with an available component, refer to Supported payment methods.

We're actively building Components for more payment methods. To check the latest on Components, see our release notes.

How it works

On this page we talk about both server-side and client-side integration steps:

  1. From your server, submit a request to get a list of payment methods available to the shopper.
  2. Add Components to your payments form.
  3. From your server, submit a payment request with the data returned by the Component.
  4. Determine from the response if you need to perform additional actions on your client app, such as to redirect the shopper.
  5. From your server, verify the payment result.
  6. Present the payment result to the shopper.

Whenever you want to offer a new payment method, you need to add the specific Component on your checkout page. The steps for integrating are similar regardless of the payment method, but some require additional configuration. For more information, refer to our payment method integration guides.

Before you begin

If you haven't done so already, follow our Get started guide to set up your test account, get your API key, and install a server-side library.

Install the Adyen iOS client-side library

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 version to be at least 3.8.0

To install iOS Components from CocoaPods:

  1. Add pod 'Adyen' to your Podfile.
  2. Run pod install.

To install iOS Components from Carthage:

  1. Add github "adyen/adyen-ios" to your Cartfile.
  2. Run carthage update.
  3. Link the framework with your target as described in Carthage Readme.

Get your client key

You need a client key, a public key linked to your API credential, that the iOS Components use for client-side authentication.

  1. Log in to your Customer Area.
  2. Go to Developers > API credentials, and select the API credential for your integration, for example ws@Company.[YourCompanyAccount].
  3. Under Authentication, select Generate New Client Key.
  4. Select Save.

Step 1: Get available payment methods

When your shopper is ready to pay, get a list of the available payment methods based on their country, device, and the payment amount.

From your server, make a POST /paymentMethods request, providing the following parameters. While most parameters are optional, we recommend that you include them because Adyen uses these to tailor the list of payment methods for your shopper.

We use the optional parameters to tailor the list of available payment methods to your shopper.

Parameter name Required Description
merchantAccount -white_check_mark- Your merchant account name.
amount The currency and value of the payment (in minor units). For more information, see Currency codes.
channel The platform where the payment is taking place. Use iOS. Adyen returns only the payment methods available for iOS.
countryCode The shopper's country code. Adyen returns only the payment methods available in this country.
shopperLocale Language and country code. By default, the shopper locale is set to en-US. If this is provided, the payment method names are translated to the specified language.

Here's an example of how you would get the available payment methods for a shopper in the Netherlands, for a payment of 10 EUR:

curl https://checkout-test.adyen.com/v67/paymentMethods \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{
  "merchantAccount": "YOUR_MERCHANT_ACCOUNT",
  "countryCode": "NL",
  "amount": {
    "currency": "EUR",
    "value": 1000
  },
  "channel": "iOS",
  "shopperLocale": "nl-NL"
}'
require 'adyen-ruby-api-library'

# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.env = :test
adyen.api_key = "YOUR_X-API-KEY"

response = adyen.checkout.payment_methods({
    :countryCode => 'NL',
    :shopperLocale => 'nl-NL',
    :amount => {
        :currency => 'EUR',
        :value => 1000
    },
    :channel => 'iOS',
    :merchantAccount => 'YOUR_MERCHANT_ACCOUNT'
})
// Set your X-API-KEY with the API key from the Customer Area.
String xApiKey = "YOUR_X-API-KEY";
Client client = new Client(xApiKey,Environment.TEST);
Checkout checkout = new Checkout(client);
PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest();
paymentMethodsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
paymentMethodsRequest.setCountryCode("NL");
paymentMethodsRequest.setShopperLocale("nl-NL");
Amount amount = new Amount();
amount.setCurrency("EUR");
amount.setValue(1000L);
paymentMethodsRequest.setAmount(amount);
paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.iOS);
PaymentMethodsResponse paymentMethodsResponse = checkout.paymentMethods(paymentMethodsRequest);
// Pass the response to your front end
// Set your X-API-KEY with the API key from the Customer Area.
$client = new \Adyen\Client();
$client->setEnvironment(\Adyen\Environment::TEST);
$client->setXApiKey("YOUR_X-API-KEY");
$service = new \Adyen\Service\Checkout($client);

$params = array(
    "countryCode" => "NL",
    "shopperLocale" => "nl-NL",
    "amount" => array(
        "currency" => "EUR",
        "value" => 1000
    ),
    "channel" => "iOS",
    "merchantAccount" => "YOUR_MERCHANT_ACCOUNT"
);
$result = $service->paymentMethods($params);
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen.Adyen()
adyen.payment.client.platform = "test"
adyen.client.xapikey = 'YOUR_X-API-KEY'

request = {
    'countryCode': 'NL',
    'shopperLocale': 'nl-NL',
    'amount': {
        'value': 1000,
        'currency': 'EUR'
    },
    'channel': 'iOS',
    'merchantAccount': 'YOUR_MERCHANT_ACCOUNT'
}
result = adyen.checkout.payment_methods(request)
// Set your X-API-KEY with the API key from the Customer Area.
string apiKey = "YOUR_X-API-KEY";
var client = new Client (apiKey, Environment.Test);
var checkout = new Checkout(client);
var amount = new Adyen.Model.Checkout.Amount("EUR", 1000);
var paymentMethodsRequest = new Adyen.Model.Checkout.PaymentMethodsRequest(merchantAccount: "YOUR_MERCHANT_ACCOUNT")
{ 
    CountryCode = "NL",
    ShopperLocale = "nl-NL",
    Amount = amount,
    Channel = PaymentMethodsRequest.ChannelEnum.iOS
};
var paymentMethodsResponse = checkout.PaymentMethods(paymentMethodsRequest);
const {Client, Config, CheckoutAPI} = require('@adyen/api-library');
const config = new Config();
// Set your X-API-KEY with the API key from the Customer Area.
config.apiKey = '[YOUR_X-API-KEY]';
config.merchantAccount = '[YOUR_MERCHANT_ACCOUNT]';
const client = new Client({ config });
client.setEnvironment("TEST");
const checkout = new CheckoutAPI(client);
const paymentsResponse = checkout.paymentMethods({
    merchantAccount: config.merchantAccount,
    countryCode: "NL",
    shopperLocale: "nl-NL",
    amount: { currency: "EUR", value: 1000, },
    channel: "iOS"
}).then(res => res);
import (
    "github.com/adyen/adyen-go-api-library/v5/src/checkout"
    "github.com/adyen/adyen-go-api-library/v5/src/common"
    "github.com/adyen/adyen-go-api-library/v5/src/adyen"
)
// Set your X-API-KEY with the API key from the Customer Area.
client := adyen.NewClient(&common.Config{
    Environment: common.TestEnv,
    ApiKey:      "[YOUR_X-API-KEY]",
})
res, httpRes, err := client.Checkout.PaymentMethods(&checkout.PaymentMethodsRequest{
    CountryCode: "NL",
    ShopperLocale: "nl-NL",
    Amount: checkout.Amount{
        Value:    1000,
        Currency: "EUR",
    },
    Channel: "iOS",
    MerchantAccount: "[YOUR_MERCHANT_ACCOUNT]",
})

The response includes the list of available paymentMethods:

/paymentMethods response
{
  "paymentMethods":[
    {
      "details":[...],
      "name":"Credit Card",
      "type":"scheme"
      ...
    },
    {
      "details":[...],
      "name":"SEPA Direct Debit",
      "type":"sepadirectdebit"
    },
    ...
  ]
}

Pass the response to your client app. You then use this in the next step to present which payment methods are available to the shopper.

Step 2: Add Components to your payment form

Next, use the Component to collect payment details from your shopper.

  1. Decode the /paymentMethods response with the PaymentMethods structure. Find the payment method object for the Component that you want to instantiate. For example, for a card payment, you need to find the CardPaymentMethod object.

    let paymentMethods = try JSONDecoder().decode(PaymentMethods.self, from: paymentMethodsResponse)
  2. Create an instance of APIContext with the following parameters:

    Parameter name Required Description
    clientKey -white_check_mark- Your client key.
    environment -white_check_mark- Use test. When you're ready to accept live payments, change the value to one of our live environments

    APIContext initialization
    // When you're ready to go live, change environment to Environment.live
    // You can also use other environment values described in https://adyen.github.io/adyen-ios/Docs/Structs/Environment.html
    let apiContext = APIContext(environment: Environment.test, clientKey: clientKey)
  3. Initialize the payment method Component. To do this, you need the decoded payment method object, and any other additional required parameters for the specific payment method.

    The steps for adding Components are the same for each payment method, however, some may require additional configuration. For information on the required configuration, refer to the payment method integration guides.

    For example, to initialize the CardComponent:

    • You need to provide your client key to enable the Card form. iOS Components versions before 3.7.0 use publicKey instead. Find out how to migrate from using publicKey to clientKey.
    • You can show the amount a shopper has to pay on the Pay button. To do this, include additional payment configuration for the Component, passing the currency and the amount that the shopper has to pay.
    // Replace CardComponent with the payment method Component that you want to add.
    // Add additional required parameters if needed and inject the instance of `APIContext`.
    let cardComponent = CardComponent(paymentMethod: cardPaymentMethod, apiContext: apiContext)
    cardComponent.delegate = self
    // Optional. In this example, the Pay button will display 10 EUR.
    cardComponent.payment = Payment(amount: Amount(value: 1000,
                                                currencyCode: "EUR"))
    present(cardComponent.viewController, animated: true)

    After the shopper provides payment details, the Component invokes the didSubmit method from the PaymentComponentDelegate.

  4. Get the contents of data.paymentMethod and pass this to your server. Dismiss the Component immediately, or wait until you have submitted the details to your server.

    func didSubmit(_ data: PaymentComponentData, from component: PaymentComponent)

    In case an error occurs on the app, the Component invokes the didFail method from the PaymentComponentDelegate. Dismiss the Component's view controller and display an error message.

    func didFail(with error: Error, from component: PaymentComponent)

Localization

iOS Components support the languages listed here. However, if you want to customize the localization, you can add new localizable.strings file for the language that you need. You can also override existing entries by using the same keys. Check all available strings here.

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

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

The library first checks the key in the main application bundle and then in the internal bundle.

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

Step 3: Make a payment

After the shopper submits their payment details or chooses to pay with a payment method that requires a redirection, you need to make a payment request to Adyen.

From your server, make a POST /payments request specifying:

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). For more information, see Currency codes.
reference -white_check_mark- Your unique reference for this payment.
paymentMethod -white_check_mark- The data.paymentMethod from the didSubmit method from your client app.
returnUrl -white_check_mark- URL to where the shopper should be taken back to after a redirection. This URL can have a maximum of 1024 characters. For more information on setting a custom URL scheme for your app, read the Apple Developer documentation.
applicationInfo If you're 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.

You need to include additional parameters in your payment request to:

Here's an example of how you would make a payment request for 10 EUR:

curl https://checkout-test.adyen.com/v67/payments \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{
  "amount":{
    "currency":"EUR",
    "value":1000
  },
  "reference":"YOUR_ORDER_NUMBER",
  "paymentMethod":{hint:paymentMethod field of an object passed from the front end or client app}STATE_DATA{/hint},
  "returnUrl":"my-app://",
  "merchantAccount":"YOUR_MERCHANT_ACCOUNT"
}'
require 'adyen-ruby-api-library'

# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.env = :test
adyen.api_key = "YOUR_X-API-KEY"

# STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
paymentMethod = STATE_DATA

response = adyen.checkout.payments({ 
    :paymentMethod => paymentMethod,
    :amount => {
        :currency => 'EUR',
        :value => 1000
    },
    :reference => 'YOUR_ORDER_NUMBER',
    :returnUrl => 'my-app://',
    :merchantAccount => 'YOUR_MERCHANT_ACCOUNT'
})

# Check if further action is needed.
if response.body.has_key(:action)
   # Pass the action object to your front end
   # response.body[:action]
else
   # No further action needed, pass the resultCode object to your front end
   # response.body[:resultCode]
// Set your X-API-KEY with the API key from the Customer Area.
String xApiKey = "YOUR_X-API-KEY";
Client client = new Client(xApiKey,Environment.TEST);
Checkout checkout = new Checkout(client);
PaymentsRequest paymentsRequest = new PaymentsRequest();
paymentsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
// STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
paymentsRequest.setPaymentMethod(STATE_DATA)
Amount amount = new Amount();
amount.setCurrency("EUR");
amount.setValue(1000L);
paymentsRequest.setAmount(amount);
paymentsRequest.setReference("YOUR_ORDER_NUMBER");
paymentsRequest.setReturnUrl("my-app://");
PaymentsResponse paymentsResponse = checkout.payments(paymentsRequest);
// Set your X-API-KEY with the API key from the Customer Area.
$client = new \Adyen\Client();
$client->setEnvironment(\Adyen\Environment::TEST);
$client->setXApiKey("YOUR_X-API-KEY");
$service = new \Adyen\Service\Checkout($client);

// STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
$paymentMethod = STATE_DATA;;

$params = array(
    "paymentMethod" => $paymentMethod,
    "amount" => array(
        "currency" => "EUR",
        "value" => 1000
    ),
    "reference" => "YOUR_ORDER_NUMBER",
    "returnUrl" => "my-app://",
    "merchantAccount" => "YOUR_MERCHANT_ACCOUNT"
);
$result = $service->payments($params);

// Check if further action is needed
if (array_key_exists("action", $result)){
   // Pass the action object to your front end
   // $result["action"]
}
else {
   // No further action needed, pass the resultCode to your front end
   // $result['resultCode']
}
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen.Adyen()
adyen.payment.client.platform = "test"
adyen.client.xapikey = 'YOUR_X-API-KEY'

# STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
paymentMethod = STATE_DATA

result = adyen.checkout.payments({
    'paymentMethod': paymentMethod,
    'amount': {
        'value': 1000,
        'currency': 'EUR'
    },
    'reference': 'YOUR_ORDER_NUMBER',
    'returnUrl': 'my-app://',
    'merchantAccount': 'YOUR_MERCHANT_ACCOUNT'
})

# Check if further action is needed
if 'action' in result.message:
   # Pass the action object to your front end
   # result.message['action']
else:
   # No further action needed, pass the resultCode to your front end
   # result.message['resultCode']
// Set your X-API-KEY with the API key from the Customer Area.
string apiKey = "YOUR_X-API-KEY";
var client = new Client (apiKey, Environment.Test);
var checkout = new Checkout(client);
var amount = new Adyen.Model.Checkout.Amount("EUR", 1000);
var paymentRequest = new Adyen.Model.Checkout.PaymentRequest
{ 
// STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
    PaymentMethod = STATE_DATA,
    Amount = amount,
    Reference = "YOUR_ORDER_NUMBER",
    ReturnUrl = @"my-app://",
};
var paymentResponse = checkout.Payment(paymentRequest);
const {Client, Config, CheckoutAPI} = require('@adyen/api-library');
const config = new Config();
// Set your X-API-KEY with the API key from the Customer Area.
config.apiKey = '[YOUR_X-API-KEY]';
config.merchantAccount = '[YOUR_MERCHANT_ACCOUNT]';
const client = new Client({ config });
client.setEnvironment("TEST");
const checkout = new CheckoutAPI(client);
checkout.payments({
    merchantAccount: config.merchantAccount,
// STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
    paymentMethod: STATE_DATA,
    amount: { currency: "EUR", value: 1000, },
    reference: "YOUR_ORDER_NUMBER",
    returnUrl: "my-app://"
}).then(res => res);
import (
    "github.com/adyen/adyen-go-api-library/v5/src/checkout"
    "github.com/adyen/adyen-go-api-library/v5/src/common"
    "github.com/adyen/adyen-go-api-library/v5/src/adyen"
)
// Set your X-API-KEY with the API key from the Customer Area.
client := adyen.NewClient(&common.Config{
    Environment: common.TestEnv,
    ApiKey:      "[YOUR_X-API-KEY]",
})
// STATE_DATA is the paymentMethod field of an object passed from the front end or client app, deserialized from JSON to a data structure.
paymentMethod := STATE_DATA
res, httpRes, err := client.Checkout.Payments(&checkout.PaymentRequest{
    PaymentMethod: paymentMethod,
    Amount: checkout.Amount{
        Value:    1000,
        Currency: "EUR",
    },
    Reference: "YOUR_ORDER_NUMBER",
    ReturnUrl: "my-app://",
    MerchantAccount: "[YOUR_MERCHANT_ACCOUNT]",
})

Your next steps depend on whether the /payments response contains an action object:

Description Next steps
No action object No additional steps are needed to complete the payment. Use the resultCode to present the payment result to your shopper.
With action object The shopper needs to do additional actions to complete the payment. 1. Pass the action object to your client app. Make sure that you only pass the action object and not the full response.
2. Proceed to step 4.

The following example shows a /payments response with action.type: threeDS2:

/payments response body
{
  "resultCode" : "IdentifyShopper",
  "action" : {
    "token" : "eyJkaXJl...",
    "paymentMethodType" : "scheme",
    "paymentData" : "Ab02b4c0...",
    "type" : "threeDS2",
    "authorisationToken" : "BQABAQ...",
    "subtype" : "fingerprint"
  }
}

The following example shows a /payments response with action.type: threeDS2Fingerprint:

/payments response body
{
  "resultCode":"IdentifyShopper",
  "action":{
    "paymentData":"Ab02b4c0!BQABAgCuZFJrQOjSsl\/zt+...",
    "paymentMethodType":"scheme",
    "token":"eyJ0aHJlZURTTWV0aG9kTm90aWZpY...",
    "type":"threeDS2Fingerprint"
  },
  "authentication":{
    "threeds2.fingerprintToken":"eyJ0aHJlZURTTWV0aG9kTm90aWZpY..."
  },
  "details":[
    {
      "key":"threeds2.fingerprint",
      "type":"text"
    }
  ],
  ...
}

Step 4: Perform additional client-side actions

Some payment methods require additional action from the shopper such as: to authenticate a payment with 3D Secure, or to switch to another app to complete the payment.

To handle these additional client app actions, the Component uses the action object from the previous step. You should also use the action.type to determine your next steps.

  1. Use AdyenActionComponent to perform any actions.
    Create and persist instance of AdyenActionComponent:

    internal lazy var actionComponent: AdyenActionComponent = {
    let component = AdyenActionComponent(apiContext: apiContext)
    component.delegate = self
    component.presentationDelegate = self
    return component
    }()

    Then use it to handle the action:

    let action = try JSONDecoder().decode(Action.self, from: actionData)
    actionComponent.handle(action)
  2. AdyenActionComponent performs additional client app actions depending on the action.type. Your next steps depend on the type of action that it performs.

    action.type Description Next steps
    redirect AdyenActionComponent redirects the shopper to another website or app to complete the payment.

    When the shopper is redirected back to your app, AdyenActionComponent calls the delegate's didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. When the shopper returns to your app, handle the redirect result.
    3. Proceed to step 5 to check the payment result.
    threeDS2 The payment qualifies for 3D Secure 2, and will go through either the frictionless or the challenge flow.

    AdyenActionComponent performs the authentication flow, and calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    sdk AdyenActionComponent triggers the app switch from your app to the payment method's app, if installed in the shopper's device.

    When the shopper is redirected back to your app, AdyenActionComponent calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to check the payment result.
    voucher AdyenActionComponent uses presentationDelegate to present UI for voucher. The shopper expected to shared, save voucher as image or, in some cases, add voucher to AppleWallet.

    When shopper finishes the flow, AdyenActionComponent calls didComplete
    Dismiss current component immediately. Payment flow is completed.
    await AdyenActionComponent uses presentationDelegate to present await UI. The shopper expected to continue payment process outside of the merchant's app.

    AdyenActionComponent will poll payment status and, if completed, calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    qrcode AdyenActionComponent uses presentationDelegate to present UI for QR code payment. The shopper expected to continue payment process outside of the merchant's app.

    AdyenActionComponent will poll payment status and, if completed, calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    action.type Description Next steps
    redirect AdyenActionComponent redirects the shopper to another website or app to complete the payment.

    When the shopper is redirected back to your app, AdyenActionComponent calls the delegate's didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. When the shopper returns to your app, handle the redirect result.
    3. Proceed to step 5 to check the payment result.
    threeDS2Fingerprint The payment qualifies for 3D Secure 2, and will go through either the frictionless or the challenge flow.

    AdyenActionComponent performs the authentication flow, and calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    threeDS2Challenge The payment qualifies for 3D Secure 2, and the issuer is initiating a challenge flow.

    AdyenActionComponent performs the authentication flow, and calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    sdk AdyenActionComponent triggers the app switch from your app to the payment method's app, if installed in the shopper's device.

    When the shopper is redirected back to your app, AdyenActionComponent calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to check the payment result.
    voucher AdyenActionComponent uses presentationDelegate to present UI for voucher. The shopper expected to shared, save voucher as image or, in some cases, add voucher to AppleWallet.

    When shopper finishes the flow, AdyenActionComponent calls didComplete
    Dismiss current component immediately. Payment flow is completed.
    await AdyenActionComponent uses presentationDelegate to present await UI. The shopper expected to continue payment process outside of the merchant's app.

    AdyenActionComponent will poll payment status and, if completed, calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.
    qrcode AdyenActionComponent uses presentationDelegate to present UI for QR code payment. The shopper expected to continue payment process outside of the merchant's app.

    AdyenActionComponent will poll payment status and, if completed, calls the didProvide method.
    1. Get the data from the didProvide method and pass it to your server. Dismiss current component immediately, or wait until you have submitted the details to your server.
    2. Proceed to step 5 to submit additional payment details.

Redirect Component

If the action class is .redirect, initialize the Redirect Component.

  1. Make sure that you inform the AdyenActionComponent when the shopper returns to your app. To do this, implement the following in your UIApplicationDelegate:

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
    RedirectComponent.applicationDidOpen(from: url)
    return true
    }
  2. After the Redirect Component under the hood of AdyenActionComponent completes the additional action, the Component invokes the didProvide method from the ActionComponentDelegate. Get the contents of data and pass this to your server. Dismiss the Component immediately, or wait until you have submitted the details to your server.

    func didSubmit(_ data: ActionComponentData, from component: ActionComponent)

    In case an error occurs on the app, the Component invokes the didFail method from the ActionComponentDelegate. Dismiss the Component's view controller and display an error message.

    func didFail(with error: Error, from component: ActionComponent)

Step 5: Submit additional payment details

If the shopper performed additional action to complete the payment, you need to make another request to Adyen to either submit the additional payment details or to check the payment result.

From your server, make a POST /payments/details request with the data from the didProvide method from your client app:

curl https://checkout-test.adyen.com/v67/payments/details \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{hint:object passed from the front end or client app}STATE_DATA{/hint}'
require 'adyen-ruby-api-library'

# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.env = :test
adyen.api_key = "YOUR_X-API-KEY"

# STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
request = STATE_DATA 
response = adyen.checkout.payments.details(request)  

# Check if further action is needed.
if response.body.has_key(:action)
   # Pass the action object to your frontend
   puts response.body[:action]
else
   # No further action needed, pass the resultCode to your frontend
   puts response.body[:resultCode]
end
// Set your X-API-KEY with the API key from the Customer Area.
String xApiKey = "YOUR_X-API-KEY";
Client client = new Client(xApiKey,Environment.TEST);
Checkout checkout = new Checkout(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
PaymentsDetailsRequest paymentsDetailsRequest = STATE_DATA;
PaymentsResponse paymentsDetailsResponse = checkout.paymentsDetails(paymentsDetailsRequest);
// Set your X-API-KEY with the API key from the Customer Area.
$client = new \Adyen\Client();
$client->setEnvironment(\Adyen\Environment::TEST);
$client->setXApiKey("YOUR_X-API-KEY");
$service = new \Adyen\Service\Checkout($client);

// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
$params = STATE_DATA;
$result = $service->paymentsDetails($params);

// Check if further action is needed
if (array_key_exists("action", $result)){
   // Pass the action object to your frontend.
   // $result["action"]
}
else {
   // No further action needed, pass the resultCode to your front end
   // $result['resultCode']
}
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen.Adyen()
adyen.payment.client.platform = "test"
adyen.client.xapikey = 'YOUR_X-API-KEY'

# STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
request = STATE_DATA
result = adyen.checkout.payments_details(request)

# Check if further action is needed.
if 'action' in result.message:
   # Pass the action object to your front end
   # result.message['action']
else:
   # No further action needed, pass the resultCode to your front end
   # result.message['resultCode']
// Set your X-API-KEY with the API key from the Customer Area.
string apiKey = "YOUR_X-API-KEY";
var client = new Client (apiKey, Environment.Test);
var checkout = new Checkout(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
var paymentsDetailsRequest = STATE_DATA;
var paymentsDetailsResponse = checkout.PaymentsDetails(paymentsDetailsRequest);
const {Client, Config, CheckoutAPI} = require('@adyen/api-library');
const config = new Config();
// Set your X-API-KEY with the API key from the Customer Area.
config.apiKey = '[YOUR_X-API-KEY]';
const client = new Client({ config });
client.setEnvironment("TEST");
const checkout = new CheckoutAPI(client);
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
checkout.paymentsDetails(STATE_DATA).then(res => res);
import (
    "github.com/adyen/adyen-go-api-library/v5/src/checkout"
    "github.com/adyen/adyen-go-api-library/v5/src/common"
    "github.com/adyen/adyen-go-api-library/v5/src/adyen"
)
// Set your X-API-KEY with the API key from the Customer Area.
client := adyen.NewClient(&common.Config{
    Environment: common.TestEnv,
    ApiKey:      "[YOUR_X-API-KEY]",
})
// STATE_DATA is an object passed from the front end or client app, deserialized from JSON to a data structure.
req := STATE_DATA;
res, httpRes, err := client.Checkout.PaymentsDetails(&req)

Your next steps depend on whether the /payments/details response contains an action object:

Description Next steps
no action object No additional steps are needed to complete the payment.
This is always the case for Checkout v67 and above.
Use the resultCode to present the payment result to your shopper.
action object The shopper needs to do additional actions to complete the payment. 1. Pass the action object to your client app.
3. Perform step 4 again.
Successful payment response
 {
   "pspReference": "88154795347618C",
   "resultCode": "Authorised"
 }
Refused response
 {
   "pspReference": "89783918347627F",
   "refusalReason": "Not enough balance",
   "resultCode": "Refused"
 }

Step 6: Present the payment result

After the shopper completes the payment and no more further actions are required on the client app, use the resultCode to inform the shopper of the payment status.

resultCode Description Action to take
Authorised The payment was successful. Inform the shopper that the payment was successful.
Error Inform the shopper that there was an error processing their payment. You'll receive a refusalReason in the same response, indicating the cause of the error.
Pending The shopper has completed the payment but the final result is not yet known. Inform the shopper that you've received their order, and are waiting for the payment to be completed.
You will receive the final result of the payment in an AUTHORISATION notification.
Refused The payment was refused. Inform the shopper that the payment was refused. Ask the shopper to try the payment again using a different payment method or card.
Received For some payment methods, it can take some time before the final status of the payment is known. Inform the shopper that you've received their order, and are waiting for the payment to clear.
You will receive the final result of the payment in an AUTHORISATION notification.

For other possible resultCode values and recommended messages that you can present to your shopper, see Result codes.

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 Transactions > Payments.

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

  1. Apply for a live account.  
  2. Assess your PCI DSS compliance, and submit the Self-Assessment Questionnaire-A.
  3. Configure your live account.
  4. Switch from test to our live endpoints.
  5. Load the Components from one of our live environments closest to where your shoppers are. Set the Component's environment to any of the following values:

    • Europe: liveEurope
    • Australia: liveAustralia
    • US: liveUnitedStates

    Make sure environment matches the region of the live endpoints you're connecting to.

See also

Next steps