Checkout icon

Sessions flow integration guide

Start accepting payments on your website or app.

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

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
5.3.1

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 Components integration, you must implement the following parts:

  • Your payment server: sends the API request to create a payment session.
  • Your client app: shows the Redirect UI where the shopper makes the payment. The Component 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. The shopper goes to the checkout page.

  2. Your server uses the shopper's country or region and currency information from your client to create a payment session.

  3. Your client creates an instance of Redirect using the session data from the server.

  4. The Component collects the shopper's payment details, handles additional actions, and presents the payment result to the shopper.

  5. Your webhook server receives the event containing the payment outcome.

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

Create a payment session

Payment server

A payment session is a resource with information about a payment flow initiated by the shopper. This resource has all the information required to handle all the stages of a payment flow. You can configure this resource with information like available payment methods, payment amount, or line items.

To create a payment session, make a /sessions 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. This is used to filter the list of available payment methods to your shopper.
returnUrl -white_check_mark- URL to where the shopper should be taken back to after a redirection. The URL can contain a maximum of 1024 characters and should include the protocol: http:// or https://. You can also include your own additional query parameters, for example, shopper ID or order reference number. Get this URL from the RedirectComponent.getReturnUrl(context).
If the URL to return to includes non-ASCII characters, like spaces or special letters, URL encode the value.
The URL must not include personally identifiable information (PII), for example name or email address.
reference -white_check_mark- Your unique reference for the payment. Minimum length: three characters.
expiresAt The session expiry date in ISO8601 format, for example 2023-11-23T12:25:28Z, or 2023-05-27T20:25:28+08:00. When not specified, the expiry date is set to 1 hour after session creation. You cannot set the session expiry to more than 24 hours after session creation.
countryCode The shopper's country/region. This is used to filter the list of available payment methods to your shopper.
Format: the two-letter ISO-3166-1 alpha-2 country code. Exception: QZ (Kosovo).
channel The platform where the payment is taking place. Use Android. Strongly recommended because this field is used for 3D Secure.
shopperLocale The language that the payment methods will appear in. Set it to the shopper's language and country code. The default is en-US. The client app. also uses this locale if it is available.
shopperEmail The shopper's email address. Strongly recommended because this field is used in a number of risk checks, and for 3D Secure.
shopperReference Your reference to uniquely identify this shopper. Strongly recommended because this field is used in a number of risk checks.
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 more information, refer to Building Adyen solutions.

Here is an example of how to create a session 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/sessions \
-H 'x-api-key: ADYEN_API_KEY' \
-H "idempotency-key: YOUR_IDEMPOTENCY_KEY" \
-H 'content-type: application/json' \
-d '{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"amount": {
"value": 1000,
"currency": "EUR"
},
"returnUrl": "adyencheckout://your.package.name",
"reference": "YOUR_PAYMENT_REFERENCE",
"countryCode": "NL"
}'

The response contains:

  • sessionData: the payment session data you need to pass to your client app.
  • id: a unique identifier for the session data.
  • The request body.
HTTP 201 /sessions response body
Expand view
Copy link to code block
Copy code
Copy code
{
"amount": {
"currency": "EUR",
"value": 1000
},
"countryCode": "NL",
"expiresAt": "2021-08-24T13:35:16+02:00",
"id": "CSD9CAC34EBAE225DD",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YOUR_PAYMENT_REFERENCE",
"returnUrl": "adyencheckout://your.package.name",
"sessionData": "Ab02b4c.."
}

You must pass the response to your client app to create the checkout session.

API error handling

If you do not get an HTTP 201 response, use the errorCode field and the list of API error codes to troubleshoot.

Set up Components

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. For example, to import the Card Component:

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

You can find the module to import for each payment method on the corresponding payment method page.

2: Create the checkout session

  1. Deserialize the /sessions response to a SessionsModel object:

    Deserialize the API response
    Expand view
    Copy link to code block
    Copy code
    Copy code
    val sessionModel = SessionModel.SERIALIZER.deserialize(sessionsResponseJSON)
  2. Call the CheckoutSessionProvider.createSession suspending function, passing:

    Parameter Required Description
    sessionModel -white_check_mark- The deserialized SessionsModel object.
    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.

    For example:

    Create the checkout session
    Expand view
    Copy link to code block
    Copy code
    Copy code
    // Create an object for the checkout session.
    val result = CheckoutSessionProvider.createSession(sessionModel, environment, clientKey)
    // If the payment session is successful, handle the result.
    // If the payment session encounters an error, handle the error.
    when (result) {
    is CheckoutSessionResult.Success -> handleCheckoutSession(result.checkoutSession)
    is CheckoutSessionResult.Error -> handleError(result.exception)
    }

Create a configuration object, setting the following properties:

Property Required Description
environment -white_check_mark- The same environment that you set when you created the session.
clientKey -white_check_mark- The same clientKey that you set when you created the session.
shopperLocale The shopper's locale. By default, this matches the shopperLocale you included in the /sessions request.
Optionally create a configuration object
Expand view
Copy link to code block
Copy code
Copy code
// Create a configuration object.
val checkoutConfiguration = CheckoutConfiguration(
environment = environment,
clientKey = clientKey,
shopperLocale = shopperLocale, // Optional
) {
// Optional: add Drop-in configuration.
dropIn {
setEnableRemovingStoredPaymentMethods(true)
}
// Optional: add or change default configuration for the card payment method.
card {
setHolderNameRequired(true)
setShopperReference("...")
}
// Optional: change configuration for 3D Secure 2.
adyen3DS2 {
setThreeDSRequestorAppURL("...")
}
}

4: Launch and show the Component

  1. Implement the SessionComponentCallback class to handle additional actions and receive the result of the session.

    Add handlers
    Expand view
    Copy link to code block
    Copy code
    Copy code
    override 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.
    }
  2. Create the Component and attach it to a view. For example:

    Create the Component
    Expand view
    Copy link to code block
    Copy code
    Copy code
    import 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 = checkoutConfiguration, //Optional: pass this if you added a configuration object in the previous step.
    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.

Handle a redirect

If the shopper was redirected to another website or app, handle when the shopper is redirected back to your app:

  1. Add an IntentFilter to your Activity that handles redirects. The
Add handling for redirects
Expand view
Copy link to code block
Copy code
Copy 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 the returnUrl from the /sessions request. To get your returnUrl, you can use the RedirectComponent.getReturnUrl(context) function.

  1. Get the result of the redirect from your Activity. Pass the Intent to the Component. Depending on your activity's launch mode, you get the intent in either onCreate or onNewIntent.
Handle the intent
Expand view
Copy link to code block
Copy code
Copy code
private fun handleIntent(intent: Intent?) {
if (intent.data?.toString().orEmpty().startsWith(RedirectComponent.REDIRECT_RESULT_SCHEME)) {
cardComponent?.handleIntent(intent)
}
}

Get the payment outcome

After Redirect 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

From the onFinished function, you can get the resultCode to inform the shopper about the current payment status.

Payment server

You can also get the result of the payment session on your server.

  1. Get the id from the /sessions response.
  2. Get sessionResult from the onFinished function.
  3. Make a GET /sessions/{id}?sessionResult={sessionResult} request including the id and sessionResult. For example:

    Request for result of payment session
    Expand view
    Copy link to code block
    Copy code
    Copy code
    curl -X GET https://checkout-test.adyen.com/checkout/v70/sessions/CS12345678?sessionResult=SOME_DATA

    The response includes the result of the payment session (status). For example:

    Response with result of the payment session
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {
    "id": "CS12345678",
    "status": "completed"
    }

    Possible statuses:

    status Description
    completed The shopper completed the payment. This means that the payment was authorized.
    paymentPending The shopper is in the process of making the payment. This applies to payment methods with an asynchronous flow.
    canceled The shopper canceled the payment.
    expired The session expired (default: 1 hour after session creation). Shoppers can no longer complete the payment with this sessionId.

The status included in the response doesn't get updated. Do not make the request again to check for payment status updates. Instead, check webhooks or the Transactions list in your Customer Area.

Update your order management system

Webhook server

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.

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",
"checkoutSessionId":"CSF46729982237A879"
},
"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",
"checkoutSessionId":"861631540104159H"
},
"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