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
startPaymentmethod of thePaymentControllerclass. Atokenwill 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
tokento your server to create a payment session. -
Handle the
paymentSessionvalue 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.
-
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/paymentSessionExecute this code from your server, not your app. This helps to prevent tampering with transaction data.
-
Use the
paymentSessionyou 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
PaymentHandleryou retrieved earlier from thePaymentReference.PaymentReferenceis 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 theActivityis destroyed.
Show progress indicator
- Attach an observer to the
NetworkingStateObservable. When the networking state changes, this will receive a callback with the latestnetworkingState. -
When
isExecutingRequestsis 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
paymentSessionis 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
typeto 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
paymentMethodDetailsobject, provide the required payment details. -
Pass these, together with the
paymentMethodthe 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
InputDetailat index 0 hasIssuerDetails.KEY_ISSUERaskey. -
The
Itemat 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
additionalDetailsto 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
handleRedirectResultto dispatch the data from theIntentto thePaymentHandler.You should declare an
IntentFilterfor theActivitythat 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 thePaymentResultwhen 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 aCheckoutExceptionwhen an error unrelated to the payment result occurred. -
Use the parameters contained in
CheckoutExceptionto 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.