Checkout icon

Advanced flow integration guide

Accept payments using the Advanced flow.

Web
iOS
Android
React Native
Flutter
Use our pre-built UI for accepting payments
Use our customizable UI components
Use Adyen APIs and your own UI
/user/pages/filters/sessions-flow-integration/android/dropin/visual/android-dropin.svg

Android Drop-in

Render a list of available payment methods anywhere in your app.

Supported payment methods

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

See all supported payment methods

Features

  • Lowest development time to integrate payment methods
  • UI styling customization for the list of payment methods
  • Adding payment methods to the list requires no extra development time
  • 3D Secure 2 support built in

Start integrating with Android Drop-in

Choose your version
5.8.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 Drop-in integration, you must implement the following parts:

  • Your payment server: sends the API requests to get available payment methods, make a payment, and send additional payment details.
  • Your client app: shows the Drop-in UI where the shopper makes the payment. Drop-in 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. From your server, submit a request to get a list of payment methods available to the shopper.
    2. Configure and launch Drop-in to collect the shopper's details.
    3. From your server, make a payment request with data that you receive from Drop-in.
    4. Handle additional client-side actions, if required.
    5. From your server, send additional payment details with data you receive from Drop-in, if required.
    6. Get the payment outcome to inform the shopper and update your order management system.

    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);
    }
    }

    Get available payment methods

    Payment server

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

    1. From your server, make a POST /paymentMethods request, including:

      We recommend that you include all the optional parameters to get the most accurate list of available payment methods.

      Parameter name Required Description
      merchantAccount -white_check_mark- Your merchant account name.
      amount The currency and value of the payment, in minor units.
      channel Use Android. Adyen returns only the payment methods available for Android.
      countryCode The shopper's country/region. Adyen returns only the payment methods available in this country.
      Format: the two-letter ISO-3166-1 alpha-2 country code. Exception: QZ (Kosovo).
      shopperLocale By default, the shopperlocale is set to en-US. To change the language, set this to the shopper's language and country code. You also need to set the same ShopperLocale within your Drop-in configuration.

      For example, to get available payment methods for a shopper in the Netherlands, 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/paymentMethods \
      -H 'x-api-key: ADYEN_API_KEY' \
      -H 'content-type: application/json' \
      -d '{
      "merchantAccount": "ADYEN_MERCHANT_ACCOUNT",
      "countryCode": "NL",
      "amount": {
      "currency": "EUR",
      "value": 1000
      },
      "channel": "Android",
      "shopperLocale": "nl-NL"
      }'

      The response includes the list of available paymentMethods:

      /paymentMethods response
      Expand view
      Copy link to code block
      Copy code
      Copy code
      {
      "paymentMethods":[
      {
      "details":[...],
      "name":"Cards",
      "type":"scheme"
      ...
      },
      {
      "details":[...],
      "name":"SEPA Direct Debit",
      "type":"sepadirectdebit"
      },
      ...
      ]
      }
    2. Deserialize the response to a PaymentMethodsApiResponse:

    Deserialize the response
    Expand view
    Copy link to code block
    Copy code
    Copy code
    val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(paymentMethodsResponse)
    1. Pass the PaymentMethodsApiResponse object to your client app to launch and show Drop-in.

    Set up Drop-in

    Client app

    1: Import the library

    The default implementation is with Jetpack Compose, but you can import the library without Jetpack Compose instead.

    Import the compatibility module in your build.gradle file:

    Import the module with Compose
    Expand view
    Copy link to code block
    Copy code
    Copy code
    implementation "com.adyen.checkout:drop-in-compose:YOUR_VERSION"

    2: Create the configuration object

    Create the configuration object to pass when you launch and show Drop-in.

    1. Set the following properties in the configuration object:

      Property Required Description
      amount If you want to show the amount on the Pay button. The currency and value of the payment amount shown on the Pay button.
      environment -white_check_mark- Use Environment.TEST for testing. When going live, use one of our live environments.
      clientKey -white_check_mark- Your client key.
      shopperLocale The shopper's locale. By default, this is the device's locale.
    2. Add additional configuration to this object. Some payment methods require additional configuration, and you can add optional configuration for Drop-in.

      For example, to configure for a payment of 10 EUR:

      Example configuration
      Expand view
      Copy link to code block
      Copy code
      Copy code
      // Create the amount object.
      val amount = Amount(
      currency = "EUR",
      value = 1000, // Value in minor units.
      )
      // Create a configuration object
      val checkoutConfiguration = CheckoutConfiguration(
      environment = environment,
      clientKey = clientKey,
      shopperLocale = shopperLocale, // Optional
      amount = amount, // Optional: set this to show the amount on the Pay button.
      ) {
      // Optional: add Drop-in configuration.
      dropIn {
      setEnableRemovingStoredPaymentMethods(true)
      }
      // Optional: add or change default configuration for the card payment method.
      card {
      setHolderNameRequired(true)
      setShopperReference("...")
      }
      // Optional: add or change default configuration for 3D Secure 2.
      adyen3DS2 {
      setThreeDSRequestorAppURL("...")
      }
      }
    3. Extend the DropInService class so that you can interact with Drop-in.

    4. Implement methods to pass data between your client app and your server. You must also handle the DropInServiceResult which includes the result of the API requests from your server.

      For example:

      Example DropInService implementation
      Expand view
      Copy link to code block
      Copy code
      Copy code
      class YourDropInService : DropInService() {
      // The handler to make a /payments request.
      override fun onSubmit(state: PaymentComponentState<*>) {
      val paymentComponentJson = PaymentComponentData.SERIALIZER.serialize(state.data)
      // Your server makes a /payments request, including `paymentComponentJson`.
      // This is used in 4: Make a payment.
      // Create the `DropInServiceResult` based on the /payments response.
      // You must switch to a background thread before making an API request. For example, `launch(Dispatchers.IO)` if using coroutines.
      // If the payment finished, handle the result.
      sendResult(DropInServiceResult.Finished("YOUR_RESULT"))
      // If additional action is needed, handle the action.
      val action = Action.SERIALIZER.deserialize(actionJSONObject)
      sendResult(DropInServiceResult.Action(action))
      }
      // Handler to make a /payments/details request to send additional payment details.
      override fun onAdditionalDetails(actionComponentData: ActionComponentData) {
      val actionComponentJson = ActionComponentData.SERIALIZER.serialize(actionComponentData)
      // Your server makes a /payments/details request, including `actionComponentJson`.
      // This is used in Step 5: Submit additional payment details.
      // Create the `DropInServiceResult` based on the /payments/details response.
      sendResult(DropInServiceResult.Finished("YOUR_RESULT"))
      }
      }

      Drop-in uses the DropInServiceResult to complete or dismiss the payment and determine if you need to handle additional actions. Additional actions include redirecting the shopper to another app or performing 3D Secure 2 authentication.

    5. Add your DropInService to your manifest file.

      For example:

      Copy code
      <service
      android:name=".YourDropInService"
      android:exported="false" />

    Launch and show Drop-in

    1. Implement DropInCallback to get the final result.

      Implement DropInCallback
      Expand view
      Copy link to code block
      Copy code
      Copy code
      override fun onDropInResult(dropInResult: DropInResult?) {
      when (dropInResult) {
      // The payment finishes with a result.
      is DropInResult.Finished -> handleResult(dropInResult.result)
      // The shopper dismisses Drop-in.
      is DropInResult.CancelledByUser ->
      // Drop-in encounters an error.
      is DropInResult.Error -> handleError(dropInResult.reason)
      // Drop-in encounters an unexpected state.
      null ->
      }
      }
    2. Create the Drop-in launcher and call DropIn.startPayment, passing:

      Parameter Description
      dropInLauncher The Drop-in launcher you created.
      paymentMethodsApiResponse The /paymentMethods response that you deserialized.
      checkoutConfiguration The Drop-in configuration that you created.
      YourDropInService::class.java (Example) The DropInService that you created.

      For example:

      Start Drop-in
      Expand view
      Copy link to code block
      Copy code
      Copy code
      import com.adyen.checkout.dropin.compose.startPayment
      import com.adyen.checkout.dropin.compose.rememberLauncherForDropInResult
      @Composable
      private fun ComposableDropIn() {
      val dropInLauncher = rememberLauncherForDropInResult(dropInCallback)
      DropIn.startPayment(dropInLauncher, paymentMethodsApiResponse, checkoutConfiguration, YourDropInService::class.java)
      }

    Your app shows Drop-in, and your shopper can choose a payment method.

    Make a payment

    Payment server

    When the shopper enters their payment details and selects the Pay button, the onSubmit method in your DropInService class is called, passing the paymentComponentJson object.

    1. Pass the paymentComponentJson object to your server.

    2. From your server, make a POST /payments 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.
    reference -white_check_mark- Your unique reference for this payment.
    paymentMethod -white_check_mark- The paymentComponentData.paymentMethod from your client app.
    returnUrl -white_check_mark- In case of a redirection, this is the URL to where your shopper is redirected after they complete the payment. Maximum length: 1024 characters. Get this URL from Drop-in in the RedirectComponent.getReturnUrl(context).
    applicationInfo If you are building an Adyen solution for multiple merchants, include some basic identifying information, so that we can offer you better support.

    You must include additional parameters in your payment request to:

    For example, to make a payment request for EUR 10:

    Expand view
    Copy link to code block
    Copy code
    Copy code
    curl https://checkout-test.adyen.com/checkout/v70/payments \
    -H 'x-api-key: ADYEN_API_KEY' \
    -H 'content-type: application/json' \
    -d '{
    "amount":{
    "currency":"EUR",
    "value":1000
    },
    "reference":"YOUR_ORDER_NUMBER",
    "paymentMethod":STATE_DATApaymentMethod field of an object passed from your client app,
    "returnUrl":"adyencheckout://your.package.name",
    "merchantAccount":"ADYEN_MERCHANT_ACCOUNT"
    }'
    1. Your next steps depend on if the /payments response contains an action object:
    Description Next steps
    No action object No additional steps are needed to complete the payment. 1. Return DropInServiceResult.Finished to your client app, including the resultCode from the response.
    2. Get the payment outcome.
    With action object The shopper needs to do additional actions to complete the payment. 1. Return DropInServiceResult.Action to your client app, including the action object.
    2. Send additional payment details.

    The following example shows a /payments response with action.type: threeDS2 that you need to handle:

    /payments response
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {
    "resultCode" : "IdentifyShopper",
    "action" : {
    "token" : "eyJkaXJl...",
    "paymentMethodType" : "scheme",
    "paymentData" : "Ab02b4c0...",
    "type" : "threeDS2",
    "authorisationToken" : "BQABAQ...",
    "subtype" : "fingerprint"
    }
    }

    Error handling

    If the /payments request fails, return DropInServiceResult.Error to your client app, including the action object.

    Handle the additional action

    Client app

    Some payment methods require you to handle an additional action in your client app. For example, you must handle the action to authenticate a payment with 3D Secure 2 or to redirect the shopper to another app.

    Implement your server logic to handle all of the following action types, so that you can add payment methods that require additional actions.

    You can receive different action types in the /payments response:

    action.type Description
    voucher Drop-in shows the voucher that the shopper uses to complete the payment.
    qrCode Drop-in shows the QR code that the shopper uses to complete the payment.
    await Drop-in shows the waiting screen while the shopper completes the payment.
    sdk Drop-in presents the specific payment method's UI as an overlay.
    threeDS2 The payment qualifies for 3D Secure 2, and goes through either frictionless or challenge flow.
    redirect Drop-in redirects the shopper to another website or app to complete the payment.

    To handle an action:

    1. Pass the complete action object from your server to Drop-in.
    2. Use ActionResponse.SERIALIZER to deserialize the action object.
    3. Return it as DropInServiceResult.Action to Drop-in.
    4. Drop-in calls the onAdditionalDetails method in your DropInService class.
    5. From onAdditionalDetails, get the actionComponentJson object.
    6. Pass the actionComponentJson object from your client app to your server.
    7. Send additional payment details.

    Send additional payment details

    Payment server

    If you handled an additional action, you must send additional payment details (actionComponentJson) to Adyen.

    1. From your server, make a POST /payments/details request, including actionComponentJson object:

      Expand view
      Copy link to code block
      Copy code
      Copy code
      curl https://checkout-test.adyen.com/checkout/v70/payments/details \
      -H 'x-api-key: ADYEN_API_KEY' \
      -H 'content-type: application/json' \
      -d 'STATE_DATAobject passed from your client app'
    2. Pass the /payments/details response from your server to your client app.

    Get the payment outcome

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

    Use the resultCode to show the shopper the current payment status. This synchronous response doesn't give you the final outcome of the payment. You get the final payment status in a webhook that you use to update your order management system.

    Update your order management system

    Webhook server

    You get the outcome of each payment asynchronously, in a webhook with eventCode: AUTHORISATION. Use this to update your order management system.
    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"
    },
    "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"
    },
    "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. Use the Adyen Android test cards app to access, copy, and autofill card details from within your Android device. 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 from one of our live environments and set the environment to match your live endpoints:

      Endpoint region Value
      Europe (EU) live EUROPE
      United States (US) live UNITED_STATES
      Australia (AU) live AUSTRALIA
      Asia Pacific & Southeast (APSE) live APSE
      India (IN) live INDIA