The classic Checkout SDK integrations are being phased out
This means we are:
- No longer developing the classic Checkout SDK integration.
- Not accepting new classic Checkout SDK integrations.
You have until March 31, 2024 to migrate.
Our Checkout SDK for Android gives you the ability to take advantage of the SDK's payment flow, including the encrypted communication between the SDK and Adyen, but collect and present information using your own UI. There are additional functions that you need to implement to do this, which we explain below. To use the SDK, you'll also need to set up a server that can create a payment session and verify the result of payments.
To accept online payments with the Checkout SDK, you'll need to:
- Install the Android SDK.
- Initialize the SDK.
- Create a payment session from your server.
- Build your payment flow.
- Verify the payment result on your server.
Before accepting live payments, we also recommend that you test your integration.
Step 1: Install SDK
Import the SDK modules into your project:
-
Add the following to your build.gradle file.
final checkoutVersion = "2.x.x" implementation "com.adyen.checkout:core:${checkoutVersion}" implementation "com.adyen.checkout:core-card:${checkoutVersion}" // Optional; Required for processing card payments. implementation "com.adyen.checkout:nfc:${checkoutVersion}" // Optional; Enables reading of card information with the device's NFC chip. implementation "com.adyen.checkout:util:${checkoutVersion}" // Optional; Collection of utility classes.
Step 2: Initialize SDK
-
Call the
startPayment
method of thePaymentController
class. Atoken
will be returned inPaymentSetupParameters
.PaymentController.startPayment(/*Activity*/ this, new PaymentSetupParametersHandler() { @Override public void onRequestPaymentSession(@NonNull PaymentSetupParameters paymentSetupParameters) { // TODO: Forward to your own server and request the payment session from Adyen with the given PaymentSetupParameters. } @Override public void onError(@NonNull CheckoutException checkoutException) { // TODO: Handle error. } });
-
Pass the
token
to your server to create a payment session. -
Handle the
paymentSession
value received by your server withPaymentController
.String encodedPaymentSession = PAYMENTSESSION_VALUE_RECEIVED_BY_YOUR_SERVER; PaymentController.handlePaymentSessionResponse(/*Activity*/ this, encodedPaymentSession, new StartPaymentParametersHandler() { @Override public void onPaymentInitialized(@NonNull StartPaymentParameters startPaymentParameters) { PaymentReference paymentReference = startPaymentParamters.getPaymentReference(); // TODO: Use the PaymentReference to retrieve a PaymentHandler (see the Create Payment Flow section). } @Override public void onError(@NonNull CheckoutException checkoutException) { // TODO: Handle error. } });
Step 3: Create payment session
A payment session is used to securely transmit payment data between the shopper and the Adyen payments platform. Create one from your server by making a POST request to the /paymentSession endpoint.
You can also use our demo server until you have implemented your own:
https://checkoutshopper-test.adyen.com/checkoutshopper/demoserver/
-
In the request, specify:
merchantAccount
: Your merchant account name.channel
: Android.returnUrl
: The URI of your app.amount
.reference
: Your unique reference for this payment.countryCode
: The country code of the shopper.token
: The token generated by the SDK.
curl -H 'content-type: application/json' -H 'x-api-key: ADYEN_API_KEY' -X POST -d '{ "merchantAccount": "YourMerchantAccount", "channel": "Android", "returnUrl": "my-shopping-app://" "amount": { "currency": "EUR", "value": 17408 }, "reference": "Your order number", "countryCode": "NL", "shopperLocale": "nl_NL", "token": "TOKEN_GENERATED_BY_SDK", }' https://checkout-test.adyen.com/v68/paymentSession
Execute this code from your server, not your app. This helps to prevent tampering with transaction data.
-
Use the
paymentSession
you receive in the response to initialize the SDK.
Step 4: Build payment flow
You'll need to create your app's payment flow by building a UI that responds to the SDK's observers and handlers.
-
Use the
PaymentHandler
you retrieved earlier from thePaymentReference
.PaymentReference
is Parcelable, so you can pass it along to anotherActivity
.@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); PaymentReference paymentReference = getIntent().getParcelableExtra(EXTRA_PAYMENT_REFERENCE); mPaymentHandler = paymentReference.getPaymentHandler(/*Activity*/ this);
-
Attach the observers and handlers below in the scope of the current
Activity
. These will be removed automatically when theActivity
is destroyed.
Show progress indicator
- Attach an observer to the
NetworkingStateObservable
. When the networking state changes, this will receive a callback with the latestnetworkingState
. -
When
isExecutingRequests
is true, present a progress indicator to the shopper in your UI.... mPaymentHandler.getNetworkingStateObservable().observe(/*Activity*/ this, new Observer<NetworkingState>() { @Override public void onChanged(@NonNull NetworkingState networkingState) { if (networkingState.isExecutingRequests() == true){ // Display progress screen else { // Remove progress screen } } });
Present available payment methods
To present a list of available payment methods to the shopper:
-
Attach an observer to the
PaymentSessionObservable
. This will be lifecycle aware, and receive callbacks with the latestpaymentSession
. -
From the
paymentSession
, retrieve a list of available payment methods . These are represented in two indexed arrays:-
oneClickPaymentMethods
: One-click enabled payment methods, that the shopper has used previously. -
paymentMethods
: All other payment methods.... PaymentHandler mPaymentHandler = startPaymentParameters.getPaymentReference().getPaymentHandler(MainActivity.this); mPaymentHandler.getPaymentSessionObservable().observe(MainActivity.this, new com.adyen.checkout.core.Observer<PaymentSession>() { @Override public void onChanged(@NonNull PaymentSession paymentSession) { List<PaymentMethod> oneClickPaymentMethods = paymentSession.getOneClickPaymentMethods(); List<PaymentMethod> paymentMethods = paymentSession.getPaymentMethods(); // TODO: Optionally group and show in UI. } }); ...
-
-
Present a list of available payment methods in your UI.
You should also refresh the list of payment methods in your UI whenever the
paymentSession
is updated. -
When the shopper has chosen a payment method, present a form in your UI, and collect the required payment details from the shopper. Use the
type
to determine which payment method input screen to present, and show input fields based on the requiredinputDetails
.For example, if the shopper selected the payment method at index 5:
... PaymentMethod paymentMethod = paymentMethods.get(5); String type = paymentMethod.getType(); List<InputDetail> inputDetails = paymentMethod.getInputDetails(); // TODO: Present UI based on type and inputDetails. ...
Submit payment
Use the shopper's chosen payment method and the payment details that you collected from the shopper to submit the payment:
- In a
paymentMethodDetails
object, provide the required payment details. -
Pass these, together with the
paymentMethod
the shopper selected, to the SDK by callinginitiatePayment
. In the example below we show how you'd do this for an issuer-based payment method such as iDEAL, where:-
The
InputDetail
at index 0 hasIssuerDetails.KEY_ISSUER
askey
. -
The
Item
at index 5 is the shopper's selected issuer.
//InputDetail at index 0 has key IssuerDetails.KEY_ISSUER InputDetail issuersInputDetail = paymentMethod.getInputDetails().get(0); // Item at index 5 was selected by shopper Item issuerItem = issuersInputDetail.getItems().get(5); IssuerDetails issuerDetails = new IssuerDetails.Builder(issuerItem.getId()).build(); mPaymentHandler.initiatePayment(paymentMethod, issuerDetails);
-
Optional: Collect SMS verification
For some payment methods, you'll need to collect SMS verification codes. When required, the onAdditionalDetailsRequired
is called.
-
Use the parameters in
additionalDetails
to present an input field in your UI to collect the SMS verification code from the shopper.... mPaymentHandler.setAdditionalDetailsHandler(/*Activity*/ this, new AdditionalDetailsHandler() { @Override public void onAdditionalDetailsRequired(@NonNull AdditionalDetails additionalDetails) { // TODO: Handle AdditionalDetails. } }); ...
Handle the redirect result
For many local payment methods, such as iDEAL and Sofort, and card payments with 3D Secure verification, you'll need to redirect the shopper to a webpage or app to verify the payment. Once verified, they will be returned to your app. The onRedirectRequired
method is called when a redirect is required.
-
Redirect the shopper to the URI specified in
redirectDetails
.... mPaymentHandler.setRedirectHandler(/*Activity*/ this, new RedirectHandler() { @Override public void onRedirectRequired(@NonNull RedirectDetails redirectDetails) { Uri redirectUri = redirectDetails.getUri(); Intent redirectIntent = new Intent(Intent.ACTION_VIEW, redirectUri); startActivityForResult(redirectIntent, REQUEST_CODE_REDIRECT); } }); ...
-
Once the shopper has completed verification, they'll be redirected to the URI you passed when you created the payment session. Then call
handleRedirectResult
to dispatch the data from theIntent
to thePaymentHandler
.You should declare an
IntentFilter
for theActivity
that handles the redirect to this URI in your AndroidManifest.... @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Uri data = intent.getData(); if (data != null) { mPaymentHandler.handleRedirectResult(data); } } ...
Handle payment result
-
Attach an observer to the
PaymentResultObservable
. This will receive a callback with thePaymentResult
when the payment has been processed.... mPaymentHandler.getPaymentResultObservable().observe(/*Activity*/ this, new Observer<PaymentResult>() { @Override public void onChanged(@NonNull PaymentResult paymentResult) { // TODO: Handle PaymentResult. } }); ...
-
Present the received payment result to the shopper in your calling Activity. For a list of possible payment results and what they mean, refer to Result codes.
-
You'll also receive a
payload
. Send this to your server to verify the result of the payment.
Handle errors
-
Set a handler with
setErrorHandler
. This will receive a callback with aCheckoutException
when an error unrelated to the payment result occurred. -
Use the parameters contained in
CheckoutException
to determine the cause of the error:isFatal
: A fatal exception occurred. This can happen, for example, when the payment session expires. You should create a new payment session to complete the payment.payload
: Get the cause of the error by sending the payload to your server.
... mPaymentHandler.setErrorHandler(/*Activity*/ this, new ErrorHandler() { @Override public void onError(@NonNull CheckoutException error) { // TODO: Handle CheckoutException. } }); ...
-
Present an error message to the shopper in your UI.
Step 5: Verify payment result
Once the payment has been completed, verify its result from your server with a /payments/result request. Include the payload
that was generated by the SDK.
curl \
-H 'content-type: application/json' \
-H 'x-api-key: ADYEN_API_KEY' \
-X POST \
-d '{ "payload": "2he28Ddhwj242he28Ddhwj..." }' \
https://checkout-test.adyen.com/v66/payments/result
If the payment was successful you'll receive an Authorised resultCode
and a pspReference
, which is our unique identifier for the transaction. If you have set up webhooks, you'll also receive a successful AUTHORISATION events.
If you received a different resultCode
, check our result codes documentation for what action you should take.
Testing your integration
Before going live, use our list of test cards and other payment methods to test your integration. 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.
When you have completed testing, there are some additional steps you'll need to complete before you can accept live payments from shoppers. Refer to Getting started with Adyen for more information.