Terminal-2 icon

Android Payments app

Use our Payments app to enable Tap to Pay on your Android mobile devices without integrating our POS Mobile SDK.

If you want to accept Tap to Pay payments on your Android mobile device but do not want to integrate our POS Mobile SDK, you can download the Adyen Payments app from the Google Play store. You can then use the Payments app to connect your own POS app to the Adyen payments platform and authenticate payment requests in a compliant way.

This page explains how to build the Payments app solution. Before you begin, see Build your solution to help you decide if the Payments app is the right solution for your situation.

Requirements

Before you begin, take into account the following requirements, limitations, and preparations.

Requirement Description
Integration type Your POS app must be integrated with Terminal API.
API credentials An API key specifically for the Adyen Payments app, with a client key and the Adyen Payments app role.
Hardware An Android commercial off-the-shelf (COTS) mobile device with an integrated NFC reader. Must not be a payment terminal. See Android system requirements for the full hardware and software requirements.
Limitations See the countries/regions, payment methods, and functionality that we support.
Setup steps Before you begin:

How it works

To build an Android Payments app solution for Tap to Pay:

  1. Build the boarding flow. The Payments app must be boarded on every Android mobile device where the app is installed.
  2. Build the payment flow.
  3. Implement an API request to revoke an app instance for cases when the mobile device is defective, stolen, or no longer needed for payments.

1. Board the app

After you download the Payments app from the Google Play store to a mobile device, you need to board the Payments app on that device. Boarding is a three-step process:

  1. Check the boarding status.
    From your POS app, you call a deep link to check if the Payments app is boarded. If the Payments app is not boarded, you receive a "boarding request token".

  2. Authenticate the app instance.
    From your back-end, you send an API request that includes the boarding request token. In the response, you receive a one-time boarding token that is unique for the combination of Payments app instance and device.

  3. Finish boarding the app.
    From your POS app, you call a deep link that includes the boarding token. The response confirms that the Payments app is now boarded, and includes an installation ID that you need to pass in your transaction requests.

1.1 Check the boarding status

To start the boarding flow, you call a deep link from your POS app to check if the Adyen Payments app is already boarded.

  1. From your POS app, call a deep link that consists of:

    • Base URL: adyenpayments-test://boarded.
    • returnUrl: the URL-encoded base URL where you want to receive the response. We will call your return URL with Action type Intent.ACTION_VIEW.

    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    adyenpayments-test://boarded?returnUrl=your_scheme%3A%2F%2Fyour_company.example.com
  2. Check the response and decide what to do next:

    • If boarded is true: save the installationId, which you will need in your payment requests. You do not need to continue with the boarding process and you are ready to make a payment.
    • If boarded is false: pass the installationId and boardingRequestToken to your back-end and go to step 2 of the boarding process.

    The response consists of the following parameters:

    Parameter Required Type Description
    Base URL -white_check_mark- URL The URL-encoded base URL where you want to receive the response. This is the returnUrl you specified in the request.
    boarded -white_check_mark- Boolean Indicates if the app is boarded or not.
    installationId -white_check_mark- String The unique identifier of the Payments app instance on the specific device.
    When creating Terminal API requests on your back-end, use this as the POIID in the MessageHeader of the request.
    boardingRequestToken String The app token used to request the boardingToken from Adyen.
    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {YOUR_SCHEME}://company.example.com?boarded=false&installationId=<INSTALLATION_ID>&boardingRequestToken=<BOARDING_REQUEST_TOKEN>

1.2. Authenticate the app instance

If you determined in step 1 of the boarding process that the Payments app is not boarded yet, you send a Payments app API request from your back-end to authenticate your app installation. In the response you receive a boardingToken. You only need to authenticate the app instance once.

To authenticate the app:

  1. Depending on whether you want to accept payments using your merchant account or a store, make a POST request to either /merchants/merchantId/generatePaymentsAppBoardingToken or /merchants/merchantId/stores/storeId/generatePaymentsAppBoardingToken, specifying:

    • Path parameters:

      Parameters Required Description
      merchantId -white_check_mark- The unique identifier of the merchant account.
      storeId The unique identifier of the store.
      The storeId is not the same as store reference. If you only know the reference, you can use it to get the storeId with an API call.
    • Request parameters:

      Parameters Required Description
      boardingRequestToken -white_check_mark- The app token used to request a boardingToken from Adyen. You received the boarding request token in step 1 of the boarding process.
    Create boarding token request
    Expand view
    Copy link to code block
    Copy code
    Copy code
    curl https://management-test.adyen.com/v1/merchants/{merchantId}/generatePaymentsAppBoardingToken \
    -H 'x-API-key: ADYEN_API_KEY' \
    -H 'content-type: application/json' \
    -X POST \
    -d '{
    "boardingRequestToken": "BOARDING_REQUEST_TOKEN"
    }'
  2. From the response, save the boardingToken, which you will need in the last step of the boarding process.
    The response consists of the following parameters:

    Parameter Type Description
    installationId String The unique identifier of the Payments app instance on the specific device.
    boardingToken String The one-time token used to authenticate the app installation. Valid for one hour.
    Create boarding token response
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {
    "installationId": "INSTALLATION_ID",
    "boardingToken": "BOARDING_TOKEN"
    }

1.3. Finish boarding the app

When you have received the boardingToken from Adyen, you need to send it to the Payments app to finish boarding the app and prepare for making payments.

  1. From your POS app, call a deep link that contains:

    • Base URL: adyenpayments-test://board.
    • boardingToken: the token generated for this installationId in step 2 of the boarding process. This token must be Base64URL-encoded.
    • returnUrl: a URL-encoded base URL where you want to receive the response. We will call your return URL with Action type Intent.ACTION_VIEW.

    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    adyenpayments-test://board?boardingToken=APP_BOARDING_TOKEN&returnUrl=YOUR_SCHEME%3A%2F%2Fyour_company.example.com
  2. Check the response and decide what to do next:

    • If boarded is true: save the installationId. You need this when you make a payment. You do not need board the app again.
    • If boarded is false: check the error and try again.

    The response consist of the returnUrl you specified in the deep link, and the following parameters:

    Parameter Type Description
    Base URL URL The URL-encoded base URL where you want to receive the response. This is the returnUrl you specified in the request.
    boarded Boolean Indicates if the app is boarded or not.
    installationId String The unique identifier of the Payments app instance on the specific device.
    When creating Terminal API requests on your back-end, use this as the POIID in the MessageHeader of the request.
    error String Additional information in case an error occurred and boarded is false.
    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {YOUR_SCHEME}://your_company.example.com?boarded=true&installationId=APP_INSTALLATION_ID

2. Make a transaction

After the Payments app is boarded, you are ready to make transactions. To do this you need to create a Terminal API request in Base64URL format as a deep link and call it from your POS app. The boarded Payments app then communicates with Adyen, receives the response and returns it in Base64 format as part of a deep link to your POS app.

To start a transaction from your POS app:

  1. Create a Terminal API request with the POIID value set to the installationId value of the boarded Payments app.

  2. Encrypt the Terminal API request as described for a local Terminal API integration.

  3. Encode the payment request to Base64URL.

  4. Call the deep link from your POS app. The deep link contains:

    • Base URL: adyenpayments-test://nexo.
    • request: Base64URL-encoded Terminal API payment request.
    • returnUrl: a URL-encoded base URL where you want to receive the response. We will call your return URL with Action type Intent.ACTION_VIEW.

    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    adyenpayments-test://nexo?request=<ewogICAgIlNhb...CAgfQp9>&returnUrl=your_scheme%3A%2F%2Fyour_company.example.com

    A Tap to Pay screen appears on the mobile device.

    If the shopper does not present their payment method within 30 seconds, the payment request times out. If that happens, you need to make another payment request.

  5. Use the response to show the payment result in your POS app. The response consist of the returnUrl you specified in the deep link, and the following parameters:

    Parameter Type Description
    Base URL URL Your returnUrl.
    response String Base64URL-encoded and encrypted Terminal API payment response.
    error String Additional information in case an error occurs.
    Deep link example
    Expand view
    Copy link to code block
    Copy code
    Copy code
    {YOUR_SCHEME}://your_company.example.com?response=PAYMENT_RESPONSE

3. Revoke app instance

If your Android mobile device is defective, stolen, or you do not need it anymore for payments processing, you can stop the Payments app from processing transactions with Adyen. To do this, you make an API call to Adyen to revoke the specified installationId.

To revoke a boarding token:

  1. Optionally, make either a GET /merchants/merchantId/paymentsApps or /merchants/merchantId/stores/storeId/paymentsApps request to retrieve the list of Payments app instances for a merchant account or a store. You can then use the installationId to revoke boarding tokens.

  2. Make a POST /merchants/merchantId/paymentsApps/installationId/revoke request specifying:

    • As path parameters:
    Parameters Required Description
    installationId -white_check_mark- The unique identifier of the Payments app instance on the specific device.
    merchantId -white_check_mark- The unique identifier of the merchant account.
    Revoke Payments app instance authentication
    Expand view
    Copy link to code block
    Copy code
    Copy code
    curl https://management-test.adyen.com/v1/merchants/{merchantId}/paymentsApps/{installationId}/revoke \
    -H 'x-API-key: ADYEN_API_KEY' \
    -H 'content-type: application/json' \
    -X POST \
  3. If successful, the response returns 200 OK.

Test your solution

To make test transactions:

  1. Make sure you are using the test version of the Payments app.

  2. Initiate a test transaction using the following Adyen point-of-sale test cards to complete the payment:

    The instructions are the same for both cards; see either of the pages mentioned above.

Go live

When you have finished testing your integration and are ready to go live:

  1. If new to Adyen, get a live account. You need to have access to your organization's live Customer Area to generate an API credentials for the live environment.
  2. In your live Customer Area generate a new API key with the Adyen Payments app role for use with the Adyen Payments app.
  3. Download the Adyen Payments app from the Google Play store.
  4. Contact us to enable Tap to Pay on Android, and optionally also enable unreferenced refunds.
  5. Update your code to use the live base URLs for deep links:
    • adyenpayments://boarded
    • adyenpayments://board
    • adyenpayments://nexo
  6. Update your code to use the live Management API endpoints:
    • https://management-live.adyen.com

Verify app instance

Adyen continuously checks if the app instance on your Android mobile device is authentic. This is to protect your integration against man-in-the-middle attacks, eavesdropping, and tampering. You can also check this yourself manually using a different device and your email address.

To verify the app instance, in the Payments app:

  1. Go to Settings and tap Verify app.
  2. Enter your email address and tap Send email.
  3. Check your email on another device. You should have received an email with a 5-character code.
  4. In the Payments app, if you received the email, tap Continue. If you did not receive the email, check the email address you entered, and tap Resend email and go back to step 2.
  5. Under Verify app, check that the 5-character code on the screen matches the code you received in the email.

If the app instance verification is successful, you can continue making payments with the Payments app. If the verification fails, Adyen automatically revokes the app instance. In this case, you need to board the app again on that Android mobile device.

Next steps