Install and integrate the Android library

This guide will help you integrate your existing POS system, which runs on Android, with the Adyen payments platform. If you have any question after completing this tutorial, contact the Support Team.

To proceed with this tutorial you should sign up for a test account. If you haven't done so yet, submit your details on this page.

Add the Adyen library module as a dependency to your app module

  1. Import the new Adyen Android Library module.
    1. Go to File > Project Structure in Android Studio.
    2. Press the + button on the upper-left corner of the Project Structure window to add a new module. 
    3. In the Create new module screen: 
      1. Select Import .JAR/.AAR Package and click Next.
      2. In the file selector, browse to the unzipped adyen-android-library-{version}.aar file.
  2. Add a dependency in the app module to the Adyen library module.

    1. Go to File > Project structure in Android Studio.

    2. Select the app module in the Modules list on the left.

    3. Select the Dependencies tab. 

    4. Add dependency on the + button on the lower left corner. 
    5. Select 3.Module dependency in the drop down menu. 

    6. Select the Adyen library module you have previously added in step 3.

  3.  Add dependency for appcompat-v7.

    1. Go to File > Project Structure in Android Studio.

    2. Select the app module in the Modules list on the left.

    3. Select the Dependencies tab. 

    4. Click the + button on the lower left to add the dependency.

    5. Select 1. Library dependency in the drop down menu.

    6. From the Choose Library Dependency screen choose the com.android.support:appcompat-v7:{version}.

    7. Click OK.

  4. Sync project with gradle files.

You can now use the Adyen library in your Android application. 

Register your app module 

  • Register your app module with the Adyen library module.

    public class App extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            try {
                LibraryReal.registerLib(getApplicationContext(), getString(R.string.app_name));
            } catch (final AlreadyRegisteredException e) {
                // Do nothing.
            }
        }
    }

    app_name -

    Format this value like so: Cash register company and product /  Cash register product version / Adyen integration name / Adyen integration version. For example,  Acme Corp POS / 1.2.1 / Acme Adyen connector / 0.1 

Get an instance of the Adyen library

  • Once the Adyen library is registered, you can use functionality from the Adyen library instance.

    @Nullable
    public AdyenLibraryInterface getAdyenLibrary() {
        if (mAdyenLibrary == null) {
            try {
                mAdyenLibrary = LibraryReal.getLib();
            } catch (NotYetRegisteredException e) {
                Log.e(TAG, "Failed to get AdyenLibraryInterface, the library must be registered first", e);
            }
        }
    
        return mAdyenLibrary;
    }

Register the merchant credentials with the Adyen library

  1. Register merchant credentials (merchant, username, password) with the Adyen library, and set the desired ServerMode [DEV/TEST/BETA/LIVE].

    AdyenLibraryInterface adyenLibrary = getAdyenLibrary();
    adyenLibrary.setServerMode(ServerMode.TEST);
    try {
        adyenLibrary.registerApp(merchant, username, password, createRegistrationCompleteListener());
    } catch (AppAlreadyRegisteredException e) {
        e.printStackTrace();
    } catch (AlreadyRegisteringAppException e) {
        e.printStackTrace();
    } catch (InvalidRequestException e) {
        e.printStackTrace();
  2. Implement the RegistrationCompleteListener to handle the response from registration of merchant credentials.

    private RegistrationCompleteListener createRegistrationCompleteListener() {
        return (statusCode, appInfo, statusMessage) -> {
            Log.i(TAG, "statusCode: " + statusCode + ", statusMessage: " + statusMessage);
    
            switch (statusCode) {
                case OK:
                    // Redirect from the LoginActivity to your HomeActivity
                    Intent intent = HomeActivity.getIntent(LoginActivity.this);
                    startActivity(intent);
                    finish();
                    break;
                case ERROR_NONETWORK:
    				// Failed to register the app, network issues.
                    break;
                case ERROR_BADCREDENTIALS:
    				// Failed to register the app, bad merchant credentials.
                    break;
                case ERROR_NOROUTE:
    				// Failed to register the app, network issues.
    				// The phone cannot connect to the Adyen backend (even if there is internet connection)
                case ERROR:
    				// Failed to register the app, general error look at the statusMessage.
                default:
                    Log.e(TAG, "statusCode: " + statusCode + ", statusMessage: " + statusMessage);
                    break;
            }
        };
    }

Register a payment terminal

  1. Create a new DeviceInfo instance:
    WiFi devices:

    DeviceInfo deviceInfo = new DeviceInfo();
    deviceInfo.setConnectionType(DeviceInfo.TYPE_WIFI);
    deviceInfo.setDeviceId(mDeviceIpAddressEditText.getText().toString());
    deviceInfo.setFriendlyName("Cash register 1");
    onAddDevice(deviceInfo);

    Bluetooth devices:

    DeviceInfo deviceInfo = new DeviceInfo();
    deviceInfo.setConnectionType(DeviceInfo.TYPE_BT);
    deviceInfo.setFriendlyName(device.getName());
    deviceInfo.setDeviceId(device.getAddress());
    onAddDevice(deviceInfo);
  2. Add the device to the Adyen library:

    private void addDevice(@NonNull DeviceInfo deviceInfo) {
        Log.d(TAG, "addDevice() called with: deviceInfo = [" + deviceInfo + "]");
    
        try {
            getAdyenLibrary().addDevice(createAddDeviceListener(), deviceInfo);
        } catch (DeviceAlreadyAddedException e) {
            e.printStackTrace();
        } catch (AlreadyAddingDeviceException e) {
            e.printStackTrace();
        } catch (AppNotRegisteredException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  3. Implement the AddDeviceListener to handle adding devices to the Adyen library:

    private AddDeviceListener createAddDeviceListener() {
        return new AddDeviceListener() {
            @Override
            public void onAddDeviceComplete(CompletedStatus completedStatus, String statusMessage, DeviceData deviceData) {
                Log.d(TAG, "onAddDeviceComplete() called with: completedStatus = [" + completedStatus + "], statusMessage = [" + statusMessage + "], deviceData = [" + deviceData + "]");
    
                switch (completedStatus) {
                    case OK:
                        // Boarding the device succeeded
                        break;
    
                    case TIMEOUT:
                        // Failed to board the device, connection timeout.
                        break;
    
                    case ERROR:
                        // Failed to board the device, general error look at the status message.
                        break;
    
                    case ERROR_SYNCACTION:
                        // Failed to board the device, ???
                        break;
    
                    case ERROR_VERIFY:
                        // Failed to board the device, couldn't verify ???
                        break;
    
                    case ERROR_NOROUTE:
                        // Failed to board the device, 
                        // The phone cannot connect to the Adyen backend (even if there is internet connection)
                        break;
    
                    case ERROR_IDENTIFY:
                        // Failed to board the device, couldn't identify terminal device with Adyen backend.
                        break;
    
                    case ERROR_REGISTER:
                        // Failed to board the device, couldn't register the teminal device with Adyen backend.
                        break;
    
                    case ERROR_NONETWORK:
                        // Failed to board the device, network issues.
    					break;
    
                    case ERROR_SYNCDEVICE:
                        // Failed to board the device. failed to sync device with Adyen backend.
    					break;
    
                    case ERROR_CONFLICTING_SERVER_MODE:
                        // Failed to board the device, due to server mode try to register the Adyen library with a different server mode.
    					break;
                }
            }
    
            @Override
            public void onProgress(ProcessStatus processStatus, String message) {
                Log.d(TAG, "onProgress() called with: processStatus = [" + processStatus + "], message = [" + message + "]");
    
                switch (processStatus) {
                    case PREPARING:
                        break;
                    case IDENTIFY:
                        break;
                    case REGISTER:
                        break;
                    case SYNCACTION:
                        break;
                    case SYNCDEVICE:
                        break;
                    case VERIFY:
                        break;
                    case RUNNING_TRANSACTION:
                        break;
                    case STEP_4_OK:
                        break;
                    case NONETWORK:
                        break;
                    case NOROUTE:
                        break;
                }
    
                if (!TextUtils.isEmpty(message)) {
                    // Notify the user with the progress status message.
                    mStatusTextView.setText(message);
                }
            }
        };
    }

Connect to the registered payment terminal

  • Once the payment terminal is added, you can connect it by using the connectDevice method:

    private void connectDevice(@NonNull DeviceInfo deviceInfo) {
        try {
            getAdyenLibrary().connectDevice(deviceInfo, true, true);
            getAdyenLibrary().setDefaultDeviceInfo(deviceInfo);
        } catch (UnknownDeviceIdException e) {
            Log.e(TAG, "Failed to connect to device, first add the device to the Adyen library: ", e);
        } catch (IOException e) {
            Log.e(TAG, "Failed to connect to device, network issues: ", e);
        }
    } 

Accept payments

 Once the terminal device is added and connected to the Adyen library. You can start making payment requests:

  1. Create new TransactionRequest instance (This is the most basic transaction request):

    transactionRequest = new TransactionRequest();
    transactionRequest.setValue(value);
    transactionRequest.setCurrencyCode(currency);
    transactionRequest.setVendorDescription(description);
    transactionRequest.setTransactionType(transactionType);
    transactionRequest.setShopperLocale(Locale.getDefault().toString());
    
    ArrayList<TenderOptions> tenderOptions = new ArrayList<>();
    transactionRequest.setTenderOptions(tenderOptions);
  2. Initiate a transaction with the previously created TransactionRequest instance.

     private void initiateTransaction(@NonNull TransactionRequest transactionRequest) {
        try {
            getAdyenLibrary().initiateTransaction(transactionRequest, createTransactionListener());
        } catch (InvalidTransactionRequestException e) {
            Log.e(TAG, "Invalid transaction request: ", e);
        } catch (AlreadyProcessingTransactionException e) {
            Log.e(TAG, "Transaction failed, that transaction already processed: ", e);
        } catch (NoDefaultDeviceException e) {
            Log.e(TAG, "Transaction failed, first set default terminal device, then try again: ", e);
        } catch (IOException e) {
            Log.e(TAG, "Transaction failed, network issues: ", e);
        }
    }
  3. Implement a TransactionListener to handle transaction responses as follows:

     private TransactionListener createTransactionListener() {
        return new TransactionListener() {
            @Override
            public void onTransactionComplete(CompletedStatus completedStatus, String statusMessage, Integer code, Map<String, String> additionalData) {
                Log.d(TAG, "onTransactionComplete() called with: completedStatus = [" + completedStatus + "], statusMessage = [" + statusMessage + "], code = [" + code + "], additionalData = [" + additionalData + "]");
    
                switch (completedStatus) {
                    case APPROVED:
                        // Transaction succeeded.
                        break;
                    case DECLINED:
                        // Declined because:
                        // The amount too low or other card reasons.
                        // Transaction was canceled by getAdyenLibrary().cancelTransaction().
                        // etc.
                        break;
                    case CANCELLED:
                        // Transaction was cancel:
                        // By the merchant from the Android app.
                        // By the shopper from the Terminal device.
                        break;
                    case ERROR:
                        // My be because network issues, communication is lost.
                        break;
                }
            }
    
            @Override
            public void onProgress(ProcessStatus processStatus, String message) {
                Log.d(TAG, "onProgress() called with: processStatus = [" + processStatus + "], message = [" + message + "]");
    
                switch (processStatus) {
                    case CONNECTING:
                        // App is connecting to the terminal - just starts a connection
                        break;
                    case IDENTIFYING:
                        // Identifying the terminal - the connection was established and now the terminal is been identified
                        break;
                    case PROCESSING:
                        // The terminal is processing the payment
                        break;
                    case NONETWORK:
                        // The phone doesn't have internet connection
                        break;
                    case NOROUTE:
                        // The phone cannot connect to the Adyen backend (even if there is internet connection)
                        break;
                    case CANCELLING:
                        // The merchant or the shopper cancelled the transaction
                        break;
                }
            }
    
            @Override
            public void onStateChanged(TenderStates tenderStates, String s, Map<String, String> map) {
                Log.d(TAG, "onStateChanged() called with: tenderStates = [" + tenderStates + "], s = [" + s + "], map = [" + map + "]");
    
                switch (tenderStates) {
                    case PIN_DIGIT_ENTERED:
                        // pin digits was entered in the terminal device
                        break;
                    case INITIAL:
                        // transaction was initiated
                        break;
                    case TENDER_CREATED:
                        // a new tender was created
                        break;
                    case CARD_INSERTED:
                        // the card was inserted
                        break;
                    case CARD_SWIPED:
                        // the card was swiped
                        break;
                    case WAIT_FOR_APP_SELECTION:
                        // waiting for some input from the customer on the terminal
                        break;
                    case APPLICATION_SELECTED:
                        // the customer selected something from the previous step
                        break;
                    case WAIT_FOR_AMOUNT_ADJUSTMENT:
                        // waiting for an amount to be adjusted based on the gratuity
                        break;
                    case ASK_GRATUITY:
                        // gratuity option was selected in tender options and the shuttle requests for it
                        break;
                    case GRATUITY_ENTERED:
                        // gratuity amount was entered
                        break;
                    case ASK_DCC:
                        // dynamic currency conversion was selected in tender options
                        break;
                    case DCC_ACCEPTED:
                        // the conversion amount was accepted
                        break;
                    case DCC_REJECTED:
                        // the conversion amount was rejected
                        break;
                    case PROCESSING_TENDER:
                        // the payment is being processed (on the terminal you can see the progress bar)
                        break;
                    case WAIT_FOR_PIN:
                        // pin is being requested on the terminal
                        break;
                    case PIN_ENTERED:
                        // the user accepted the pin
                        break;
                    case PROVIDE_CARD_DETAILS:
                        // for MKE the card details are requested
                        break;
                    case CARD_DETAILS_PROVIDED:
                        // for MKE the card details were provided
                        break;
                    case PRINT_RECEIPT:
                        // starting printing the receipt (receipt generation)
                        break;
                    case RECEIPT_PRINTED:
                        // the receipt printing was finished
                        break;
                    case REFERRAL:
                        // the acquirer sends a referral status
                        break;
                    case REFERRAL_CHECKED:
                        // the referral code was checked
                        break;
                    case CHECK_SIGNATURE:
                        // after the user has entered the signature, there's a check between the signature on the card and the one on the screen/receipt
                        break;
                    case SIGNATURE_CHECKED:
                        // the signature matched the one on the card
                        break;
                    case ADDITIONAL_DATA_AVAILABLE:
                        // additional data (like currency conversion rate, adjusted amount for gratuity and others) are available
                        break;
                    case ERROR:
                        // final states of a transaction
                        break;
                    case APPROVED:
                        // transaction was approved
                        break;
                    case DECLINED:
                        // transaction was declined
                        break;
                    case CANCELLED:
                        // transaction was cancelled
                        break;
                    case UNKNOWN:
                        break;
                    case ACKNOWLEDGED:
                        break;
                }
            }
        };
    }