ADYEN-Android Payment Gateway Integration

Adyen is a global leader in the online payments industry which has worked on connecting multiple countries and multiple currencies by linking up with local payment gateways. Adyen in some countries and regions has connected directly with banks to provide a seamless experience in the payments sector. This has created a unique advantage for the company, where it can charge a very less transaction fee for its customers.

We can experience Adyen in many of our day to day applications or websites like Uber, Grab, Booking.com, Spotify, LinkedIn, Evernote, Microsoft, etc

Adyen supports multiple payment methods and internationally popular wallets like Amazon, PayPal, Alipay, WeChat, GooglePay

In this article, we would take step by step procedure of integrating the Adyen payment gateway with Android, where we are trying to deploy the in-app checkout with a Drop-in based option. Drop-in handles all shopper interactions for popular payment methods. Recommended if you want a quick way to start accepting payments, with little to no customization.

The Flow of the integration would be

Adyen Drop-in Payment Flow

To explain the integration process, we can split them into two.

The server side consists of importing the Adyen packages into it. This phase consists of 3 files. The merchant Key is used in all the backend API files to authenticate the calls. I have implemented it with PHP as my backend, so the files would be

This API would return the user with the payment options available. Say if we are making an API call with the information like Merchant Name, Currency Code, Amount, Country Code, and Channel, it would return the available payment options related to the region.

$params = array(
“merchantAccount” => “Merchant Name”,
“countryCode” => “IN”,
“amount” => array(
“currency” => “INR”,
“value” => 200
),
“channel” => “Android”
);

Say if the call is made from India, it would return payment options and wallets associated with India like GooglePay, Credit Cards, etc. If the call is made from China, it would return the payment options associated with China like Alipay, WeChat pay, etc. If the call is made from Europe, it would show options like SEPA, Klarna, etc

Sample Response for India would be,

{“groups”:[{“name”:”Credit Card”,”types”:[“visa”,”mc”,”maestro”,”amex”,”diners”,”discover”]}],”paymentMethods”:[{“brands”:[“visa”,”mc”,”maestro”,”amex”,”diners”,”discover”],”details”:[{“key”:”encryptedCardNumber”,”type”:”cardToken”},{“key”:”encryptedSecurityCode”,”type”:”cardToken”},{“key”:”encryptedExpiryMonth”,”type”:”cardToken”},{“key”:”encryptedExpiryYear”,”type”:”cardToken”},{“key”:”holderName”,”optional”:true,”type”:”text”}],”name”:”Credit Card”,”type”:”scheme”},{“details”:[{“key”:”paywithgoogle.token”,”type”:”payWithGoogleToken”}],”name”:”Google Pay”,”supportsRecurring”:true,”type”:”paywithgoogle”}]

This is an important API where the actual processing of the payment takes place.

This API requires important declarations to be made like

$browserInf =’{
“userAgent”:”Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008052912 Firefox/3.0",
“acceptHeader”:”text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}’;
$browserInfo = json_decode($browserInf, true);
$add =’{
“allow3DS2” : true
}’;
$additionalData = json_decode($add, true);

This component ensures that 3DS2 authorization is enabled in the API call so that the call is secured.

$params = array(
“amount” => array(
“currency” =>”INR”,
“value” => 200
),
“reference” => “10001”,
“paymentMethod” => $paymentMethod,
“returnUrl” => “adyencheckout://com.sivakumar.adyen”, //com.sivakumar.adyen is the package name used in android
“merchantAccount” => “merchant_name”,
“browserInfo” => $browserInfo,
“shopperInteraction” => “Ecommerce”,
“channel” => “Android”,
“countryCode” => “IN”
);

This component ensured the addition of Reference ID, Shoppers Interaction type, return URL.

Sample response is

{ “resultCode”:”IdentifyShopper”,“action”:{“paymentData”:”Ab02b4c0!BQABAgCuZFJrQOjSsl\/zt+…”,“paymentMethodType”:”scheme”,“token”:”eyJ0aHJlZURTTWV0aG9kTm90aWZpY…”,“type”:”threeDS2Fingerprint” }, “authentication”:{“threeds2.fingerprintToken”:”eyJ0aHJlZURTTWV0aG9kTm90aWZpY…”}}

This API returns the status of the transaction, where this could be one of the following — Authorise, Refused, Pending, Error, Received.

Sample response of this API would be

{“pspReference”:”883616401509140G”,”resultCode”:”Authorised”,”merchantReference”:”10002"}
com.sivakumar.adyen D/OkHttp: ← END HTTP (89-byte body)
{“pspReference”: “883616401509140G”,”resultCode”: “Authorised”,”merchantReference”: “10002” }

In your Android Studio, create a new Project, and add the following,

a) In your app.gradle, add the following dependencies

implementation “com.adyen.checkout:drop-in:3.5.1”
implementation “com.adyen.checkout:card-ui:3.5.1”

b) In your manifest file, add the following service

<service
android:name=”.YourDropInService”
android:permission=”android.permission.BIND_JOB_SERVICE”/>

c) In your MainActivity, create an event listener say a button Onclick, and call the PaymentMethod API with the required arguments. This will return the available payment options associated with the user’s location.

d) Then Initialize the Drop-in by using the following code,

val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(jsonObject)

val googlePayConfig = GooglePayConfiguration.Builder(this@MainActivity, “merchant_name” ).build()

val cardConfiguration = CardConfiguration.Builder(this@MainActivity, public_key).setHolderNameRequire(true).setShopperReference(“shopper_reference”).build()

val bcmcConfiguration = BcmcConfiguration.Builder(this@MainActivity, public_key).build()

val dotpayConfiguration = DotpayConfiguration.Builder(Locale.getDefault(),resources.displayMetrics, Environment.TEST).build()

val openBankingConfiguration = OpenBankingConfiguration.Builder(Locale.getDefault(),resources.displayMetrics, Environment.TEST).build()

val sepaConfiguration = SepaConfiguration.Builder(Locale.getDefault(), Environment.TEST).build()

val idealConfiguration = IdealConfiguration.Builder(this@MainActivity).build()

val resultIntent = Intent(this@MainActivity, MainActivity::class.java)

resultIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP

// When you’re ready to accept live payments, change the value to one of our live environments.
val dropInConfiguration = DropInConfiguration.Builder(this@MainActivity, resultIntent, YourDropInService::class.java).setEnvironment(Environment.TEST)
.addCardConfiguration(cardConfiguration)
.addBcmcConfiguration(bcmcConfiguration)
.addGooglePayConfiguration(googlePayConfig)
.addIdealConfiguration(idealConfiguration)
.addDotpayConfiguration(dotpayConfiguration)
.addOpenBankingConfiguration(openBankingConfiguration)
.addSepaConfiguration(sepaConfiguration)

DropIn.startPayment(this@MainActivity, paymentMethodsApiResponse, dropInConfiguration.build())

e) Once you select the payment option and initiate the payment, this will call the Payments API with the payments component data(payment information like merchantAccount, returnURL, paymentMethod, etc.

f) As we worked with 3DS2 secure authentication, we are supposed to use a different set of test cards listed by Adyen

https://docs.adyen.com/development-resources/test-cards/test-card-numbers#test-3d-secure-2-authentication

3DS2 Authentication Test Cards

g) /payments API will read the “action” object of the response and fetch the token, payment data, and type. Then it validates this transaction and calls the /result API

h) The result API will update the user on the status of the transaction.

i) The /payments and /result APIs are called through CallResult class. The CallResult contains the result of the API calls from our server. Drop-in uses the CallResult to determine if you must take additional action to complete the payment, such as redirecting the shopper to another site or performing 3D Secure authentication.

That’s it! Now you have integrated the Adyen payment gateway in your android application.

Credits to Adyen for images and continuous support in the process.

Thank you for your time and attention, and I would certainly love to have your appreciations in form of 👏 !

Senior Android Developer | AR Developer @ a popular Automotive Company | Prev. Android Application Developer @tinysurprise | IIM Trichy Alumini