Adyen Components for Android allows you to accept in-app payments by providing you with the building blocks you need to create a checkout experience.
For an overview of how you can integrate with Adyen on Android check out the Documentation Website
If you have a feature request, or spotted a bug or a technical problem, create a GitHub issue. For other questions, contact our support team.
The Components are available through Maven Central, you only need to add the Gradle dependency.
If you are upgrading from 3.x.x to a current release, check out our migration guide.
Import the Component module for the Payment Method you want to use by adding it to your build.gradle
file.
For example, for the Drop-in solution you should add:
implementation "com.adyen.checkout:drop-in:4.13.2"
For a Credit Card component you should add:
implementation "com.adyen.checkout:card:4.13.2"
Drop-in and Components require a client key, that should be provided in the Configuration.Builder
constructors.
The Drop-in is the implementation that handles the presentation of all available payment methods and the subsequent entry of a customer's payment details. It is initialized with the response of /paymentMethods
, and provides everything you need to make an API call to /payments
and /payments/details
.
The Drop-in requires the response of the /paymentMethods
endpoint to be initialized. To pass the response to Drop-in, decode the response to the PaymentMethodsApiResponse
class.
You can provide the raw JSONObject to the SERIALIZER
object to deserialize the data.
val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(jsonObject)
The Drop-in relies on you to implement the calls to your server.
When calling /payments
or /payments/details
is required, it will trigger an intent to the DropInService
which you need to extend.
The data comes as a JSONObject
that you can use to compose your final /payments
call on your back end.
After the call, you return a DropInServiceResult
with a certain type, each type expects different parameters.
DropInServiceResult.Action
- If the result contains anaction
object, return it in theactionJSON
param to continue the payment flow.DropInServiceResult.Finished
- If there is noaction
the payment flow is finished, theresult
will be passed along.DropInServiceResult.Error
- If an error happened during the connection.
class YourDropInService : DropInService() {
// Submitting a payment request
override fun makePaymentsCall(paymentComponentJson: JSONObject): DropInServiceResult {
// Your server should make a /payments call containing the `paymentComponentJson`
// Create the `DropInServiceResult` based on the /payments response
return DropInServiceResult.Action("action JSON object")
}
// Submitting additional payment details
override fun makeDetailsCall(actionComponentJson: JSONObject): DropInServiceResult {
// Your server should make a /payments/details call containing the `actionComponentJson`
// Create the `DropInServiceResult` based on the /payments/details response
return DropInServiceResult.Finished("Authorised")
}
}
Don't forget to also add the service your manifest.
<service android:name=".YourDropInService"/>
Configure Drop-in:
// Optional, if you want to display the amount and currency. In this example, the Pay button will display 10 EUR.
val amount = Amount().apply {
currency = "EUR"
value = 10_00
}
val dropInConfiguration = DropInConfiguration.Builder(YourContext, YourDropInService::class.java, "YOUR_CLIENT_KEY")
.setAmount(amount)
.setShopperLocale(shopperLocale)
.build()
Optional - Configure specific payment methods:
val cardConfiguration = CardConfiguration.Builder(YourContext, "YOUR_CLIENT_KEY")
.build()
val dropInConfiguration = DropInConfiguration.Builder(YourContext, YourDropInService::class.java, "YOUR_CLIENT_KEY")
// ...
.addCardConfiguration(cardConfiguration)
.build()
You can find an example on how to create the cardConfiguration
in the Components section.
After serializing the payment methods and creating the configuration, the Drop-in is ready to be initialized. Just call the DropIn.startPayment()
method. Optionally, you can pass a resultIntent
to be launched after Drop-in finishes (for example, a ResultActivity
).
//Optional. In this example, ResultActivity will be launched after Drop-in finishes
val resultIntent = Intent(YourContext, ResultActivity::class.java)
DropIn.startPayment(YourContext, paymentMethodsApiResponse, dropInConfiguration, resultIntent)
To handle the Drop-in result, call DropIn.handleActivityResult
inside onActivityResult
within the activity that initiated the payment (DropIn.startPayment
). The result is obtained in the DropInResult
wrapper class:
class CheckoutActivity : Activity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val dropInResult = DropIn.handleActivityResult(requestCode, resultCode, data) ?: return
when (dropInResult) {
is DropInResult.Finished -> handleFinished(dropInResult.result) // will not be called if a resultIntent was passed to DropIn.startPayment
is DropInResult.Error -> handleError(dropInResult.reason)
is DropInResult.CancelledByUser -> handleCancelled()
}
}
}
Additionally, if you specified a resultIntent
when calling DropIn.startPayment
, simply call DropIn.getDropInResultFromIntent
inside onCreate
within the newly launched activity:
class ResultActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val result = DropIn.getDropInResultFromIntent(intent)
}
}
In order to have more flexibility over the checkout flow, you can use our Components to present each payment method individually in your own Activity.
To do that you need the data of that specific payment method parsed to the PaymentMethod
class, and to create the configuration object (check out the docs for a more detailed guide on how to initialize the CardConfiguration.Builder
).
val cardConfiguration = CardConfiguration.Builder(context, "YOUR_CLIENT_KEY") .build()
val cardComponent = CardComponent.PROVIDER.get(this@YourActivity, paymentMethod, cardConfiguration)
Then you need to add the Component View to your layout.
<com.adyen.checkout.card.CardView
android:id="@+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Then, after the component is initialized, you can attach it to the view to start getting user data.
cardView.attach(cardComponent, this@YourActivity)
From this moment you will start receiving updates when the user inputs data. When the data is valid, you can send it to the /payments
endpoint.
cardComponent.observe(this) { paymentComponentState ->
if (paymentComponentState?.isValid == true) {
// When the shopper proceeds to pay, pass the `paymentComponentState.data` to your server to send a /payments request
sendPayment(paymentComponentState.data)
}
}
If you use ProGuard or R8, you do not need to manually add any rules, as they are automatically embedded in the artifacts. Please let us know if you find any issues.
This repository is open source and available under the MIT license. For more information, see the LICENSE file.