Search

Are you looking for test card numbers?

Would you like to contact support?

iOS Drop-in

Accept popular payment methods with a single client-side implementation.

See sample code

  Explore Drop-in for iOS on GitHub.

Drop-in is our all-in-one UI solution that you can use on your checkout page so you can start accepting transactions for key payment methods using a single front-end implementation. To see a complete list of all payment methods supported in Drop-in, see Drop-in payment methods.

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

Drop-in is supported from v49 and later of the of the /paymentMethods, /payments, and /payments/details endpoints.

How Drop-in works

First you have to submit API requests from your server, then pass parts of the responses to your client app. Drop-in takes the responses as input, renders the UI for the corresponding shopper action, and provides the data that you will need to pass on your next API request.

The following general flow applies for each payment method supported in Drop-in:

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. Create an instance of Drop-in.
  3. From your server, submit a payment request with the data returned by Drop-in.
  4. Determine from the response if you need to perform additional actions on your client app.
  5. From your server, submit additional payment details with the data returned by Drop-in.
  6. Present the payment result to the shopper.

When you have completed the integration, proceed to test your integration.

Before you begin

Before you start integrating with our online payments API and Drop-in for iOS, make sure that you have performed the following steps:

  1. Sign up for an Adyen test account at https://www.adyen.com/signup.
  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 Drop-in for iOS.

Installing Drop-in for iOS

Get Drop-in 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

First, you need to get a list of payment methods available to your shopper:

  1. Make a POST /paymentMethods request, 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 countryCode, amount, 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, including the required fields if there are any. If you want to know more about the properties returned in the response, see the response parameters in our API Explorer.

    {
     "paymentMethods":[
      {
        "details":[...],
        "name":"Credit Card",
        "type":"scheme"
        ...
      },
      {
        "details":[...],
        "name":"SEPA Direct Debit",
        "type":"sepadirectdebit"
      },
      ...
      ]
    }
  2. Pass the response to your client app. You will use this in the next step to specify which payment methods are available for the shopper.

Next, initialize Drop-in on your client app.

Step 2: Initialize Drop-in

To use Drop-in on your app, you need to:

  1. Decode the /paymentMethods response with the PaymentMethods structure.

    let paymentMethods = try JSONDecoder().decode(PaymentMethods.self, from: paymentMethodsResponse)
  2. Check specific payment method pages to confirm if you need additional required configuration. For example, to enable the Card, Drop-in needs your public key to use for encryption. Include additional configuration in the an instance of DropInComponent.PaymentmethodsConfiguration:

    let configuration = DropInComponent.PaymentMethodsConfiguration()
    configuration.card.publicKey = "..." // Your public key, retrieved from the Customer Area.
  3. Initialize Drop-in by assigning a delegate. Also use the viewController property to present Drop-in on the screen:

    let dropInComponent = DropInComponent(paymentMethods: paymentMethods,
    paymentMethodsConfiguration: configuration)
    dropInComponent.delegate = self
    dropInComponent.environment = .test
    present(dropInComponent.viewController, animated: true)

    Drop-in will present the available payment methods to the shopper and render the input fields.

  4. After the shopper selects a payment method and provides payment details, the didSubmit method will be invoked. Get the contents of data.paymentMethod and pass this to your server.

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

    In case an error occurs on the app, Drop-in will invoke the didFail method. Dismiss Drop-in's view controller and display an error message.

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

Next, submit a payment request from your server.

For more information on iOS Drop-in classes, see our reference documentation page.

Step 3: Make a payment

Submit a payment request with the data.paymentMethod from Drop-in.

  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.

    • amount
    • reference: Your unique reference for this payment.
    • paymentMethod: The data.paymentMethod from the didSubmit method from your client app.
    • returnUrl: URL to where Drop-in will take your shopper back to after a redirection.
    • merchantAccount: Your merchant account name.

      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": "DROPIN_DATA_PAYMENTMETHOD"
        "returnUrl":"https://your-company.com/checkout/",
        "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 => "https://your-company.com/checkout/",
        :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("https://your-company.com/...");
      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" => "https://your-company.com/checkout/",
        "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': 'https://your-company.com/...',
         '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{DROPIN_DATA_PAYMENTMETHOD};
      var paymentsRequest = new Model.Checkout.PaymentRequest
      {
        Reference = "YOUR_ORDER_NUMBER",
        Amount = amount,
        ReturnUrl = @"https://your-company.com/...",
        MerchantAccount = "YOUR_MERCHANT_ACCOUNT",
        PaymentMethod = details
      };
      
      var paymentResponse = checkout.Payments(paymentsRequest);

    Response

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

    • resultCode: If the payment was succesful, you will get an Authorised result code. For other possible resultCode values and the actions that you need to take, see Result codes.
    • action: If you get this object in the response, this means that you need to perform additional action on your client app to complete the payment. Pass this object to your client app and perform step 4. Drop-in will use the information in this object to continue with the payment flow.
    • pspReference: Our unique identifier for the transaction.
    • refusalReason: Returned with resultCode Error or Refused. See refusal reasons for possible values.

      {
      "resultCode":"IdentifyShopper",
      "action":{
       "paymentMethodType":"scheme",
       "token":"eyJ0aHJlZURTTWV0aG9kTm90aWZpY...",
       "type":"threeDS2Fingerprint"
      },
      "authentication":{
       "threeds2.fingerprintToken":"eyJ0aHJlZURTTWV0aG9kTm90aWZpY..."
      },
      "details":[
       {
         "key":"threeds2.fingerprint",
         "type":"text"
       }
      ],
      "paymentData":"Ab02b4c0!BQABAgCuZFJrQOjSsl\/zt+..."
      }
  2. 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

  1. If your server received an action object in the /paymentMethods response, pass the object to your client app. Make sure that you only pass the action object and not the full response.

    let action = try JSONDecoder().decode(Action.self, from: actionData)
    dropInComponent.handle(action)

    Drop-in will handle additional actions required for the payment method. For example, for the response in step 3, Drop-in will perform device fingerprinting for 3D Secure 2 authentication.

  2. For some payment methods such as iDEAL or for card transactions requiring 3D Secure 1 authentication, the shopper is redirected to an external site or to another application to complete the payment.

    For these cases, you need to inform Drop-in when the 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(from: url)
    
       return true
    }
  3. After Drop-in completes the action, the didProvide method will be invoked. Get the contents of data.details and pass this to your server.

    func didProvide(_ data: ActionComponentData, from component: DropInComponent)

    In case an error occurs on the app, Drop-in will invoke the didFail method. Dismiss Drop-in's view controller and display an error message.

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

Next, pass data.details value to your server.

For more information on iOS Drop-in classes, see our reference documentation page.

Step 5: Submit additional payment details

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

    • 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 'DROPIN_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);

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

    • resultCode: If the payment was succesful, you will get an Authorised result code. For other possible resultCode values and the actions that you need to take, see Result codes.
    • action: If you get this object in the response, this means that you need to perform additional action on your client app to complete the payment. Pass the contents of this object to your client app and perform step 4 again. Drop-in will use the information in this object to continue with the payment flow.
    • pspReference: Our unique identifier for the transaction.
    • refusalReason: Returned with resultCode Error or Refused. See refusal reasons for possible values.

      {
      "pspReference": "88154795347618C",
      "resultCode": "Authorised"
      }
      {
      "pspReference": "89783918347627F",
      "refusalReason": "Not enough balance",
      "resultCode": "Refused"
      }
  2. 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 again.
    • If you did not get an action object, proceed to step 6 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 that the payment has been completed.

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

  • If you get an Authorised result code, inform the shopper that the payment was succesful.
  • 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 to receive payment status updates.

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.

Localization

Our iOS Drop-in 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 will check first the main application bundle for the key 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 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.

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

When you've completed testing, there are some additional steps you need to complete 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'll have to switch from test to our live endpoints. See Live endpoints for more information.

Supported payment methods in Drop-in

The following payment methods are supported in Drop-in. 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-
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-
iDEAL
-white_check_mark-
-white_check_mark-
-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-
WeChat Pay
-white_check_mark-

We're actively adding payment methods to Drop-in. To check the latest on Drop-in and Components, see our release notes.

See also

Next steps