Android Components
Render individual payment methods anywhere in your app.
Supported payment methods
Cards, buy now pay later, wallets, and many more.
See all supported payment methods
Features
- Low development time to integrate each payment method component
- UI styling customization for each payment method
- Flexibility to add payment method components with configuration for each
- 3D Secure 2 support using the 3D Secure 2 Component
Start integrating with Android Components
Choose your version
Adyen Android on GitHub
View the Adyen Android repository
View our example integration
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:
- Get your API key.
- Get your client key.
- Set up webhooks to know the payment outcome.
How it works
For a Components integration, you must implement the following parts:
The parts of your integration work together to complete the payment flow:
- From your server, submit a request to get a list of payment methods available to the shopper.
- Configure and launch the Component to collect the shopper's details.
- From your server, make a payment request with data that you receive from the Component.
- Handle additional client-side actions, if required.
- From your server, send additional payment details that you receive from the Component, if required.
- 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
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.
<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:
// 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.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
When the 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, 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 |
![]() |
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 Checkout configuration. |
For example, to get available payment methods for a shopper in the Netherlands, for a payment of 10 EUR:
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":[ { "details":[...], "name":"Cards", "type":"scheme" ... }, { "details":[...], "name":"SEPA Direct Debit", "type":"sepadirectdebit" }, ... ] }
You must pass the response to your client app to launch and show Components.
Set up Components
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. For example, to import the Card Component:
implementation "com.adyen.checkout:card:YOUR_VERSION" implementation "com.adyen.checkout:components-compose:YOUR_VERSION"
2. Configure components
- Create a configuration object, setting the following properties:
Property | Required | Description |
---|---|---|
shopperLocale |
![]() |
The shopper's locale. To use the device's default locale, replace this with your context. |
environment |
![]() |
Use Environment.TEST for testing. When going live, use one of our live environments. |
clientKey |
![]() |
Your client key. |
-
Include other optional configurations for the Component and call the
build
function.For example:
Create the configuration objectExpand viewCopy link to code blockCopy code// Create a configuration object. For example, for the card Component. val cardConfiguration = cardConfiguration.Builder( shopperLocale, // Use your context instead to use the device's default locale. environment, clientKey ) // Set additional configuration. .setHolderNameRequired(true) // Optional property to show the cardholder name input field. .setSubmitButtonVisible(false) // Optional property to hide the Pay button. .build()
2: Create the configuration object
-
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. shopperLocale
The shopper's locale. To use the device's default locale, replace this with your context. environment
Use Environment.TEST
for testing. When going live, use one of our live environments.clientKey
Your client key. -
Call the
build
function.
For example, to configure the card Component:
// Create the amount object. val amount = Amount( currency = "EUR", value = 1000, ) // Create a configuration object. val cardConfiguration = CardConfiguration.Builder( shopperLocale, // Use your context instead to use the device's default locale. environment, clientKey ) // Set the amount in the configuration object. .setAmount(amount) // Optional to show the amount on the Pay button. .setHolderNameRequired(true) // Optional configuration property to show the cardholder name input field. .build()
-
Implement methods in
ComponentCallback
to pass data between your client app and your server.Method Description onSubmit
Make a /payments request. onAdditionalDetails
Make a /payments/details request. onError
Handle an error if the Component encounters one.
For example, for the card Component:
// Handler to make a /payments request. override fun onSubmit(state: CardComponentState) { val paymentComponentJson = PaymentComponentData.SERIALIZER.serialize(state.data) // Your server makes /payments request, including paymentComponentJson. // This is used in Step 4: Make a payment. // If additional action is required, handle the action. val action = Action.SERIALIZER.deserialize(actionJSONObject) cardComponent.handleAction(action, activity) } // 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. } // The Component encounters an error. override fun onError(componentError: ComponentError) { // Handle the error. }
4: Launch and show the Component
-
Implement the
SessionComponentCallback
class to handle additional actions and receive the result of the session.Add handlersExpand viewCopy link to code blockCopy codeoverride fun onFinished(result: SessionPaymentResult) { // The payment finishes with a result. } override fun onAction(action: Action) { // An additional action needs to be handled. Forward the action to the Component. cardComponent.handleAction(action, activity) } override fun onError(componentError: ComponentError) { // The Component encounters an error. } -
Create the Component and attach it to a view. For example:
Create the ComponentExpand viewCopy link to code blockCopy codeimport com.adyen.checkout.components.compose.get // Get the payment method. val paymentMethod = checkoutSession.getPaymentMethod(PaymentMethodTypes.SCHEME) @Composable private fun ComposableCardComponent() { // Keep a reference to this Component in case you need to access it later. val cardComponent = CardComponent.PROVIDER.get( checkoutSession = checkoutSession, paymentMethod = paymentMethod, configuration = configuration, componentCallback = callback, // This key is required to ensure a new Component gets created for each different screen or payment session. // Generate a new value for this key every time you need to reset the Component. key = "YOUR_UNIQUE_KEY_FOR_THIS_COMPONENT", ) // This is your composable, a wrapper around our xml view. AdyenComponent( component = cardComponent, modifier = YOUR_MODIFIER, ) }
Your app shows the Component, and the Component handles the whole payment flow.
Make a payment
When the shopper enters their payment details and selects the Pay button, the onSubmit
method in your ComponentCallback
class is called, passing the paymentComponentJson
object.
-
Pass the
paymentComponentJson
object to your server. -
From your server, make a POST /payments request, including:
Parameter name Required Description merchantAccount
Your merchant account name. amount
The currency
andvalue
of the payment, in minor units.reference
Your unique reference for this payment. paymentMethod
The paymentComponentData.paymentMethod
from your client app.returnUrl
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 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. For the following cases, you must include additional parameters in your request:
- Integrating some payment methods. For more information, refer to our payment method integration guides.
- Using of our risk management features. For more information, see Required risk fields.
- Native 3D Secure 2 authentication.
- Tokenizing your shopper's payment details or making recurring payments.
-
Your next steps depend on if the /payments response contains an
action
object:Description Next steps No action
objectNo additional steps are needed to complete the payment. 1. Pass the resultCode
from your server to your client app.
2. Get the payment outcome.With action
objectThe shopper needs to do additional actions to complete the payment. 1. Pass the action
object from your server to your client app.
2. CallhandleAction
from your Component, passing theaction
object and youractivity
.
3. Send additional payment details.The following example shows a /payments response with
action.type
: threeDS2 that you need to handle:/payments responseExpand viewCopy link to code blockCopy code{ "resultCode" : "IdentifyShopper", "action" : { "token" : "eyJkaXJl...", "paymentMethodType" : "scheme", "paymentData" : "Ab02b4c0...", "type" : "threeDS2", "authorisationToken" : "BQABAQ...", "subtype" : "fingerprint" } }
For example, to make a payment request for EUR 10:
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" }'
Error handling
If the /payments request fails, show the error to the shopper in your client UI.
Handle the additional action
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 | Action handling |
---|---|---|
voucher | The Component shows the voucher that the shopper uses to complete the payment. | Handle the action without a redirect. |
qrCode | The Component shows the QR code that the shopper uses to complete the payment. | Handle the action without a redirect. |
await | The Component shows the waiting screen while the shopper completes the payment. | Handle the action without a redirect. |
sdk | The Component presents the specific payment method's UI as an overlay. | Handle the action without a redirect. |
threeDS2 | The payment qualifies for 3D Secure 2, and goes through either frictionless or challenge flow. | Handle the action without a redirect. |
redirect | The Component redirects the shopper to another website or app to complete the payment. | Handle the redirect. |
Handle the additional action without a redirect
To handle an action.type
without a redirect:
- Pass the complete
action
object from your server to the Component. - The Component calls the
onAdditionalDetails
method in yourComponentCallback
class. - From
onAdditionalDetails
, get theactionComponentJson
object. - Pass the
actionComponentJson
object from your client app to your server. - Send additional payment details.
Handle the redirect
To handle action.type
: redirect:
-
Add an
IntentFilter
to yourActivity
that handles redirects.Add handling for redirectsExpand viewCopy link to code blockCopy code<activity android:name="YOUR_ACTIVITY" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:host="YOUR_APPLICATION_ID" android:scheme="adyencheckout"/> </intent-filter> </activity> The
android:host
value is your package name at build time. This must match thereturnUrl
from the /payments request.
To get yourreturnUrl
from the Component, you can use theRedirectComponent.getReturnUrl(context)
function. -
Pass the complete
action
object from your server to the Component. -
The Component redirects the shopper to another website or app.
-
The shopper gets redirected back to your client app.
-
From your
Activity
, get the result of the redirect. -
Pass the
Intent
to the the Component. Depending on your activity's launch mode, you get the intent in eitheronCreate
oronNewIntent
.Handle the intentExpand viewCopy link to code blockCopy codeprivate fun handleIntent(intent: Intent?) { if (intent.data?.toString().orEmpty().startsWith(RedirectComponent.REDIRECT_RESULT_SCHEME)) { cardComponent?.handleIntent(intent) } } -
The Component notifies you through the
ComponentCallback.onAdditionalDetails
method with theactionComponentData
object fromintent.data
. -
Pass the
actionComponentData
object from your client app to your server.
Send additional payment details
If you handled an additional action, you must send additional payment details (actionComponentJson
) to Adyen.
-
From your server, make a POST /payments/details request, including
actionComponentJson
object:Expand viewCopy link to code blockCopy codecurl 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' -
Pass the /payments/details response from your server to your client app.
Get the payment outcome
After the Component finishes the payment flow, you can show the shopper the current payment status. Adyen sends a webhook with the outcome of the payment.
Inform the shopper
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
You get the outcome of each payment asynchronously, in an AUTHORISATION webhook. Use the merchantReference
from the webhook to match it to your order reference.
For a successful payment, the event contains success
: true.
{ "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.
{ "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 Transactions > Payments.
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:
- Apply for a live account. Review the process to start accepting payments on Get started with Adyen.
- Assess your PCI DSS compliance by submitting the Self-Assessment Questionnaire-A.
- Configure your live account.
- Submit a request to add payment methods in your live Customer Area .
- Switch from test to our live endpoints.
-
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











