Search

Are you looking for test card numbers?

Would you like to contact support?

iOS Components

Build your checkout form with our iOS Components.

We built separate Components per payment method that you can use to render UI and collect your shopper's payment details. For more information on which payment methods have a Component, see list of Components.

If you are new to integrating with Adyen, see our Online payments page for an overview of integration options and available features.

Components is supported from v49 of the /paymentMethods, /payments, and /payments/details endpoints.

See sample code

  Check out Components on GitHub.

Whenever you want to offer a new payment method, you need to add the specific Component on your payments form. The steps for integrating each Component is similar regardless of the payment method.

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.

Before you begin

Before you start integrating with our online payments API, make sure that you have performed the following steps:

  1. Sign up for an Adyen test account
  2. Get your API Key. Save a copy as you need it for API calls you make to the Adyen payments platform.
  3. Install one of our Libraries to connect with the Adyen APIs.
  4. If you're building for multiple merchants, provide some basic information so that we can offer you better support.
  5. Install Components for iOS.

Install iOS Components

Get Components for iOS from CocoaPods or Carthage.

CocoaPods

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

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.

Step 1: Get available payment methods

  1. Make a POST /paymentMethods call, providing:

    • merchantAccount: Your merchant account name. 
    • countryCode: The shopper's country.
    • amount: The currency and value of the payment. 
    • channel: The platform of the shopper's device. Use iOS.

    We use the countryCodeamount, and channel to tailor the list of payment methods to your shopper.

    curl https://checkout-test.adyen.com/v49/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"
    }'
    # Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen::Client.new
    adyen.api_key = "YOUR_X-API-KEY"
    
    response = adyen.checkout.payment_methods({
      :merchantAccount => 'YOUR_MERCHANT_ACCOUNT',
      :countryCode => 'NL',
      :amount => {
        :currency => 'EUR',
        :value => 1000
      },
      :channel => 'iOS'
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Client client = new Client(xApiKey,Environment.TEST);
    
    Checkout checkout = new Checkout(client);
    PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest();
    paymentMethodsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
    paymentMethodsRequest.setCountryCode("NL");
    Amount amount = new Amount();
    amount.setCurrency("EUR");
    amount.setValue(1000L);
    paymentMethodsRequest.setAmount(amount);
    paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.IOS);
    PaymentMethodsResponse response = checkout.paymentMethods(paymentMethodsRequest);
    // Set your X-API-KEY with the API key from the Customer Area.
    $client = new \Adyen\Client();
    $client->setXApiKey("YOUR_X-API-KEY");
    $service = new \Adyen\Service\Checkout($client);
    
    $params = array(
      "merchantAccount" => "YOUR_MERCHANT_ACCOUNT",
      "countryCode" => "NL",
      "amount" => array(
        "currency" => "EUR",
        "value" => 1000
      ),
      "channel" => "iOS"
    );
    $result = $service->paymentMethods($params);
    #Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen.Adyen()
    adyen.client.xapikey = 'YOUR_X-API-KEY'
    
    result = adyen.checkout.payment_methods({
      'merchantAccount': 'YOUR_MERCHANT_ACCOUNT',
      'countryCode': 'NL',
      'amount': {
        'value': 1000,
        'currency': 'EUR'
      },
      'channel': 'iOS',
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    var client = new Client ("YOUR-X-API-KEY", Environment.Test);
    var checkout = new Checkout(client);
    var amount = new Model.Checkout.Amount("EUR", 1000);
    var paymentMethodsRequest = new Model.Checkout.PaymentMethodsRequest(MerchantAccount: "YOUR_MERCHANT_ACCOUNT")
    {
       CountryCode = "NL",
       Amount = amount,
       Channel = "iOS"
    };

    A list of available paymentMethods is returned in the response. Each payment method has a:

    • name: Name of the payment method.
    • type: Unique payment method code.
    {
      "paymentMethods":[
        {
          "details":[...],
          "name":"Credit Card",
          "type":"scheme"
          ...
        },
        {
          "details":[...],
          "name":"SEPA Direct Debit",
          "type":"sepadirectdebit"
        },
        ...
      ]
    }

If you want to know more about the properties returned in the response, see the response parameters on API Explorer.

  1. 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.

Next, initialize a payment method Component on your client app.

Step 2: Initialize Components

Initialize Components to start getting your shopper's payment details on your client app. To do this, you need to:

  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. Check the specific payment method page to confirm if you need to configure additional required parameters. For example, to enable the Card Component, you need to provide your Client Encryption Public Key.

    Next, initialize the Component. Assign a delegate, use the viewController property to present the Component on the screen, pass the payment method object, and set the environment to test. When you're ready to go live, change this to live or to other environment values described in the class reference.

    let cardComponent = CardComponent(paymentMethod: cardPaymentMethod,
    publicKey: "YOUR_PUBLIC_KEY")
    // Replace CardComponent with the payment method Component that you want to add.
    // See list of Supported payment methods at https://docs.adyen.com/checkout/ios/components#supported-payment-methods
    cardComponent.delegate = self
    cardComponent.environment = .test
    present(cardComponent.viewController, animated: true)
  3. After the shopper provides payment details, the Component invokes the didSubmit method from the PaymentComponentDelegate. Get the contents of data.paymentMethod and pass this 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)

Next, submit a payment request from your server.

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

Step 3: Make a payment

Submit a payment request with the data.paymentMethod from the didSubmit method the Component invoked in the previous step.

  1. From your server, make a POST /payments request specifying the parameters described below, along with other parameters that might be required for your integration. For example, you need to include additional fields if you are implementing 3D Secure 2 native or 3D Secure redirect authentication, or if you want to tokenize the shopper's payment details for recurring payments.
  • amount
  • reference: Your unique reference for this payment.
  • paymentMethod: The data.paymentMethod from the didSubmit method from your client app.
  • returnUrl: URL to where the shopper should be taken back to after a redirection. This is used for payment methods that require redirection to issuer's site, such as iDEAL, or in a 3D Secure authentication flow. For more information on setting a custom URL scheme for your app, read the Apple Developer documentation.
  • merchantAccount: Your merchant account name.

The example below shows how you would make a card payment using encrypted values generated by the Card Component.

curl https://checkout-test.adyen.com/v49/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": "COMPONENT_DATA_PAYMENTMETHOD"
  "returnUrl":"my-app://",
  "merchantAccount":"YOUR_MERCHANT_ACCOUNT"
}'
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.api_key = "YOUR_X-API-KEY"
 
response = adyen.checkout.payments({
  :amount => {
    :currency => "EUR",
    :value => 1000
  },
  :reference => "YOUR_ORDER_NUMBER",
  :paymentMethod => "COMPONENT_DATA_PAYMENTMETHOD",
  :returnUrl => "my-app://",
  :merchantAccount => "YOUR_MERCHANT_ACCOUNT"
})
// Set your X-API-KEY with the API key from the Customer Area.
Client client = new Client(xApiKey,Environment.TEST);
 
Checkout checkout = new Checkout(client);
PaymentsRequest paymentsRequest = new PaymentsRequest();
paymentsRequest.setMerchantAccount("YOUR_MERCHANT_ACCOUNT");
Amount amount = new Amount();
amount.setCurrency("EUR");
amount.setValue(15000L);
paymentsRequest.setAmount(amount);
String encryptedCardNumber = "adyenjs_0_1_18$...encryptedCardNumber";
String encryptedExpiryMonth = "adyenjs_0_1_18$...encryptedExpiryMonth";
String encryptedExpiryYear = "adyenjs_0_1_18$...encryptedExpiryYear";
String encryptedSecurityCode = "adyenjs_0_1_18$...encryptedSecurityCode";
paymentsRequest.setReference("Your order number");
paymentsRequest.addEncryptedCardData(encryptedCardNumber,encryptedExpiryMonth, encryptedExpiryYear, encryptedSecurityCode, "John Smith");
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->setXApiKey("YOUR_X-API-KEY");
$service = new \Adyen\Service\Checkout($client);

$params = array(
  "amount" => array(
    "currency" => "EUR",
    "value" => 1000
  ),
  "reference" => "YOUR_ORDER_NUMBER",
  "paymentMethod" => "COMPONENT_DATA_PAYMENTMETHOD",
  "returnUrl" => "my-app://",
  "merchantAccount" => "YOUR_MERCHANT_ACCOUNT"
);
$result = $service->payments($params);
#Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen.Adyen()
adyen.client.xapikey = 'YOUR_X-API-KEY'

result = adyen.checkout.payments({
   'amount': {
      'value': 1000,
      'currency': 'EUR'
   },
   'reference': 'YOUR_ORDER_NUMBER',
   'paymentMethod': 'COMPONENT_DATA_PAYMENTMETHOD',
   'returnUrl': 'my-app://',
   'merchantAccount': 'YOUR_MERCHANT_ACCOUNT'
})
// Set your X-API-KEY with the API key from the Customer Area.
var client = new Client ("YOUR_X-API-KEY", Environment.Test);
var checkout = new Checkout(client);

var amount = new Model.Checkout.Amount("EUR", 1000);
var details = new Model.Checkout.DefaultPaymentMethodDetails{COMPONENT_DATA_PAYMENTMETHOD};
var paymentsRequest = new Model.Checkout.PaymentRequest
{
  Reference = "YOUR_ORDER_NUMBER",
  Amount = amount,
  ReturnUrl = @"my-app://",
  MerchantAccount = "YOUR_MERCHANT_ACCOUNT",
  PaymentMethod = details
};

var paymentResponse = checkout.Payments(paymentsRequest);

Response

Depending on the payment result, you receive a response containing:

  • resultCode: If the payment has been successfully completed, you get an Authorised result code. If you receive an Authorised, Error, or Refused, you can immediately present the payment result to the shopper. For more details on how to handle other resultCode values, see Result codes.
  • pspReference: Our unique identifier for the transaction.
  • refusalReason: Returned with resultCode Error or Refused. See refusal reasons for possible values.
  • action: If you get this object in the response, you need to perform additional action on your client app to complete the payment. Refer to the specific payment method page for the description of each property returned in this object.
  • paymentData: This is returned when you need to perform additional action on your client app to complete the payment. Keep a copy of the paymentData. You need this when you submit additional payment details.

    {
    "pspReference": "88154795347618C",
    "resultCode": "Authorised"
    }
    {
    "resultCode": "RedirectShopper",
    "action": {
      "method": "POST",
      "paymentData": "Ab02b4c0!BQABAgCW5sxB4e/==",
      "paymentMethodType": "scheme",
      "type": "redirect",
      "url": "https://test.adyen.com/hpp/3d/validate.shtml",
      "data": {
        "PaReq": "eNpVUslygkAQ/RXjB8yCgEi1kyJSq..",
        "TermUrl": "https://your-company.com/...",
        "MD": "ejJydDdDeExyVUFrTEFaMTlITCt_..."
      }
    },
    "details": [
    {
      "key": "MD",
      "type": "text"
    },
    {
      "key": "PaRes",
      "type": "text"
    }
    ],
    "paymentData": "Ab02b4c0!BQABAgCW5sxB4e/=="
    }
  1. The next steps depend on if you received an action object in the response.
    • If you received an action object, you need to perform both step 4 and step 5.
    • If you did not get an action object, proceed to step 6 to present the payment result to your shopper.

Step 4: Perform additional actions on your client app

Some payment methods require additional shopper interaction before a payment can be processed. For example, for iDEAL, the shoppers need to complete their payment on the issuer's website or app. For card payments, you might need to perform 3D Secure authentication before a payment can be authorised.

These additional actions that you need to perform on your app is indicated in the action object that you receive in the API response.

  1. Pass the action object from the response and use the Action class to determine the type of action that you should take. Make sure that you only pass the action object and not the full response.

    let action = try JSONDecoder().decode(Action.self, from: actionResponse)

    This class returns any of the following actions:

    • .redirect: Redirect the shopper to a site or to another app to proceed with the payment as in the case of iDEAL or 3D Secure 1 authentication. You can either use the Redirect Component or handle the redirect on your own.
    • .threeDS2Fingerprint: Perform 3D Secure 2 device fingerprinting using the 3D Secure 2 Component.
    • .threeDS2Challenge: Present the 3D Secure 2 challenge to the shopper using the 3D Secure 2 Component.

Step 5: Submit additional payment details

  1. From your server, make a POST /payments/details request.

    • details: This is the data.details from the didProvide method from your client app.
    curl https://checkout-test.adyen.com/v49/payments/details \
    -H "x-API-key: YOUR_X-API-KEY" \
    -H "content-type: application/json" \
    -d 'COMPONENT_DATA_DETAILS'
    # Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen::Client.new
    adyen.api_key = "YOUR_X-API-KEY"
    
    response = adyen.checkout.payments.details({
      :details => {
        :payload => "sdfsdfsdf..."
      }
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    Client client = new Client(xApiKey,Environment.TEST);
    
    Checkout checkout = new Checkout(client);
    PaymentDetailsRequest paymentDetailsRequest = new PaymentDetailsRequest();
    HashMap<String, String> details = new HashMap<>();
    details.put("payload", "sdfsdfsdf...");
    paymentsDetailsRequest.setDetails(details);
    PaymentsResponse paymentsResponse = checkout.paymentDetails(PaymentDetailsRequest);
    // Set your X-API-KEY with the API key from the Customer Area.
    $client = new \Adyen\Client();
    $client->setXApiKey("YOUR_X-API-KEY");
    $service = new \Adyen\Service\Checkout($client);
    
    $params = array(
      "details" => array(
        "payload" => "sdfsdfsdf..."
      )
    );
    $result = $service->paymentDetails($params);
    #Set your X-API-KEY with the API key from the Customer Area.
    adyen = Adyen.Adyen()
    adyen.client.xapikey = 'YOUR_X-API-KEY'
    
    result = adyen.checkout.payments_details({
       'details': {
          'payload': 'sdfsdfsdf...'
       }
    })
    // Set your X-API-KEY with the API key from the Customer Area.
    var client = new Client ("YOUR_X-API-KEY", Environment.Test);
    var checkout = new Checkout(client);
    
    var details = new Dictionary<string, string>
    {
      { "payload", "Ab02b4c0..." }
    };
    var paymentsDetailsRequest = new Model.Checkout.PaymentsDetailsRequest(Details: details);
    var paymentResponse = checkout.PaymentDetails(paymentsDetailsRequest);

    If the payment was successful you receive:

    • pspReference: Our unique identifier for the transaction.
    • resultCode: Authorised.
  2. The next steps depend on if you received an action object in the response.

    • If you received an action object, perform step 4 and step 5 again.
      • If you did not get an action object, proceed to the next step to present the payment result to your shopper.

Step 6: Present the payment result

If you do not receive an action object from your last API request, this means the payment has been completed.

Use the resultCode from the response to present the payment result to your shopper. For example:

  • If you get an Authorised result code, inform the shopper that the payment has been successfully completed.
  • If you get an Error or Refused result code, inform the shopper that the payment failed.
  • If you get a Pending or Received resultCode, inform the shopper that you've received their order, and are waiting for the payment to be processed. To receive payment status updates, set up your notification webhooks.

Check out your specific payment method page for the possible result codes that you might receive, or see this list of Result codes for recommended messages that you can present to your shopper.

Action Components

You can use the following Action Components to help you perform additional required actions as described in step 4:

  • Redirect Component: Handles redirecting your shopper to another app or to a website to complete the payment. The Component also returns the information that you need to submit in your next API request.
  • 3D Secure 2 Component: Handles 3D Secure 2 device fingerprinting and 3D Secure 2 challenge flow. The Component also returns the information that you need to submit in your next API request.

Using the Redirect Component

  1. If the Action type is .redirect, initialize the Redirect Component.

    let redirectComponent = RedirectComponent(action: redirectAction)

    You also need to inform the Component when shopper returns to your app. Implement the following in your UIApplicationDelegate to do this:

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
     RedirectComponent.applicationDidOpen(url)
    
     return true
    }
  2. After the Redirect Component completes the additional action, the Component invokes the didProvide method from the ActionComponentDelegate. Get the contents of data.details and pass this 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)

Next, pass data.details value to your server and perform step 5.

Using the 3D Secure 2 Component

  1. If the Action type is .threeDS2Fingerprint, initialize the 3D Secure 2 Component.

    let threeDS2Component = ThreeDS2Component()
    threeDS2Component.delegate = self
    self.threeDS2Component = threeDS2Component
    
    threeDS2Component.handle(action)
  2. After the Component completes the 3D Secure 2 device fingerprinting, the Component invokes the didProvide method from the ActionComponentDelegate. Get the contents of data.details and pass this 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)

    Next, pass data.details value to your server and perform step 5.

  3. If the issuer requires further shopper interaction in a challenge flow, you might still get an action object in the /payments/details response be indicated by a .threeDS2Challenge action type. To handle the challenge flow, pass the action to the Component.

    threeDS2Component.handle(action)
  4. After the Component completes the 3D Secure 2 challenge flow, the Component invokes the didProvide method from the ActionComponentDelegate. Get the contents of data.details and pass this 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)

    Next, pass data.details value to your server and perform step 5 again.

Customizing the UI for 3D Secure 2

The Component inherits your app's theme to ensure the UI of the challenge flow fits your app's look and feel. If you require further UI customizations, use the customization options provided in the appearanceConfiguration property.

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

Localization

Our iOS Components supports 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.

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.

Check all available strings on GitHub.

Notification webhooks

Although in most cases the resultCode you received from the /payments or /payments/details endpoints already indicate the payment result, notifications are the only way to know about the outcome of a payment in cases where:

  • The resultCode is Pending or Received.
  • The shopper completed the payment but failed to return to your website or app.

Make sure that you set up your notification webhooks so you can receive payment status updates.

After we know the outcome of a payment, we will send you a notification containing:

  • eventCode: AUTHORISATION
  • success: Indicates the outcome of the payment. Possible values:

    • true: The payment was successful.
    • false: The payment failed.

Refer to Notification request item to see all the information returned in a notification.

Testing and going 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.

When you've completed testing, you need to complete some additional steps before you can accept live payments from shoppers. Refer to Getting started with Adyen for more information. 

When you're ready to move to production, you should switch from test to our live endpoints. See Live endpoints for more information.

Supported payment methods

We have Components for the following payment methods. If you have questions about payment methods not on the list below or those that do not have linked pages, contact Support Team.

Payment method Web iOS Android
AfterPay -white_check_mark-
Apple Pay -white_check_mark- -white_check_mark-
BCMC Mobile -white_check_mark-
Cards, including 3D Secure 1 and 3D Secure 2
authentication
-white_check_mark- -white_check_mark- -white_check_mark-
Stored card details -white_check_mark- -white_check_mark-
Dragonpay -white_check_mark-
Dotpay -white_check_mark- -white_check_mark- -white_check_mark-
Entercash -white_check_mark- -white_check_mark- -white_check_mark-
EPS -white_check_mark- -white_check_mark- -white_check_mark-
giropay -white_check_mark-
Google Pay -white_check_mark- -white_check_mark-
iDEAL -white_check_mark- -white_check_mark- -white_check_mark-
Japanese convenience stores (Konbini)/
7-Eleven Japan
-white_check_mark-
MOLPay -white_check_mark- -white_check_mark- -white_check_mark-
Open banking -white_check_mark- -white_check_mark- -white_check_mark-
QiwiWallet -white_check_mark-
Redirect payment methods
(For example, UnionPay)
-white_check_mark- -white_check_mark- -white_check_mark-
SEPA Direct Debit -white_check_mark- -white_check_mark- -white_check_mark-
WeChat Pay -white_check_mark-

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

See also

Next steps