Skip to content

    SDK integration

    Overview

    In addition to the backend B2B API integration, the App2App SDK provides the client-side component necessary to complete the enrollment and payment flows from within the merchant’s mobile application. Acting as a bridge between the merchant app and the Nexi POS app (SoftPOS or mPOS), the SDK ensures a seamless and secure user experience by handling device-level interactions and deeplinks during key operations like enrollment, payment, reversal, account closure and get last transaction.

    The SDK relies on the App2AppIPC class, which must be instantiated in the merchant application and configured with core parameters such as appId, merchantUsername, redirectUri, and deviceId. A key element of this setup is the onGetRequestUri callback, which connects the SDK to the previously described PAR B2B API call, allowing the app to request a request_uri from the backend. This request_uri, once returned via callback, is injected into the SDK to complete the device enrollment process in a secure and standardized way.

    Once enrollment is complete, the SDK can execute operations such as payment, reversal, and get last transaction, each of which triggers the Nexi POS app via inter-process communication (IPC). Results are returned to the merchant app via deeplinks using a predefined scheme (e.g., demonexi://) and include full transaction details.

    The SDK design is fully asynchronous and coroutine-compatible, ensuring smooth integration with Kotlin and proper support for Java applications. Developers must handle thread management and UI updates carefully to avoid exceptions during background-to-main thread transitions.

    By combining the B2B API layer with the client-side SDK, the App2App solution provides a robust, end-to-end integration path for managing secure payment workflows between the merchant backend, frontend, and Nexi's payment infrastructure.

    Scope

    The technical interaction between App2App SDK and Merchant App involves the exchange of data through defined operations. In this context:

    • Incoming data: refers to data that App2App SDK receives from Merchant App during various operations.

    • Outgoing data: represents the data that App2App SDK sends back to Merchant App as a result of the operations.

    The scope of the interaction between the app (merchant application) and the App2App SDK is primarily related to facilitating secure and seamless payment transactions.

    The SDK likely serves as a bridge between the merchant's application and Nexi POS application, enabling the app to initiate, authorize, and handle payments.

    Operations flow

    To perform any operation, the app is required to instance the App2AppIPC class, needed to send developer data and then, setup the connection to Nexi POS app.

    App2AppIPC

    class App2AppIPC( 
    internal val activity: Activity,     internal val appData: AppData,     
    internal val onGetRequestUri: (    
           deviceId: String,

    The App2App IPC (Inter-Process Communication) class is responsible for setting up and handling the interaction with the App2App SDK. Hence, an instance of this class is needed before starting any operation. The class requires the following parameters:

    1. activity, current active activity.

    2. appData, data representing the app created by developer on web portal. AppData contains:

    • appId, the id of the app. (ID CLIENT on the web portal)

    • redirectUri, the URI chosen during app creation. (once created the App, save this info, cannot be retrieved if lost, and a new app logic Is required)

    • merchantUsername, the merchant username with which any operation will be run. ( If the email is not handled, please follow this setting: noreply@(companyname).com noreply2@(companyname).com noreplyn@(companyname).com)

    • merchantId, the merchant id corresponding to the account assigned on the portal. (ID AMMINISTRATORE on the web portal)

    • deeplinkScheme, the scheme used to get back to the caller app. “demonexi” as default.

    • domain, desired service domain among INTEGRATION, STAGING, PRODUCTION.

    1. onGetRequestUri (deviceId, onSuccess, onError), the callback through which it will be possible to enroll the current device during the enrollment phase.

    2. onConnectionEvent (ConnectionEvent): After having created an App2AppIPC instance, the connection must be opened by calling the connectToRemoteService method. This callback will notify any connection event, allowing the caller app to continue with any operation (pay, reversal,..)

    The App2AppIPC instance should be created ahead (ex: Activity/Fragment onCreate) and kept in memory, since it works with remote time sync to ensure secure network calls.

    Connection Event

    After having called the connectToRemoteService method, the SDK will search for one of the following apps in your device:

    code

    -Nexi POS – package it.nexi.mpos
      -Nexi POS debug – package it.nexi.mpos.debug

    Aiming to connect the caller app with ONE instance of the Nexi POS application. The outcome of the search will be notified using the ConnectionEvent.

    Let’s explore all the possible outcomes:

    • One app is found, and the connection is secured, event type will be CONNECTED. After having received this specific event, the caller can interact with the SDK.

    • No app is found, the event type will be ERROR_APP_NOT_INSTALLED, and a service message is filled within the object. The Nexi POS app should be installed.

    • Both apps are found, the event type will be ERROR_MULTIPLE_APPS_INSTALLED, and a service message is filled within the object. One app should be removed.

    Throughout the caller app lifecycle, it could be useful receiving the DISCONNECTED event. This one can occur whether the Nexi App is closed or in case of OS memory cleaning.
    Having received a disconnection, it will be possible to call connectToRemoteService again to fix it up.

    To recap, the callback will make sure that the caller app is kept updated about the connection status.

    SDK APIs

    The caller app can run the following operations:

    • Payment, using the pay method.
    • Revert a transaction, using the revert method.
    • Close MPOS account, using the closeAccount method.
    • Retrieve the last transaction, using lastTransaction method.

    When calling any of them, the SDK will check if the device is enrolled, which implies a group of security checks have been executed on the device. The enrollment involves SDK internal calls, requesting the merchant application to provide the requestUri parameter.

    By passing the onGetRequestUri callback, the merchant app can prepare a specific flow to use the device id and produce the requestUri. The latter must be passed to the SDK, using the onSuccess callback, to allow the SDK to perform the enrollment

    SDK outcome and App outcome

    All methods will return an outcome via operationListener, which is not the real outcome of the operation (payment, reversal, close account), but the outcome of the SDK task. In case of failure, for example, the listener will tell why the SDK operation has failed. In case of success, instead, the SDK will notify about having completed its task and the Nexi POS app will be opened to finalize the operation.

    Happy flow:

    1. App calls pay method
    2. OperationListener notifies a success (could be used for tracking or logging events)
    3. The Nexi POS app is opened for running the payment through mPOS or SoftPOS
    4. After having completed the payment, the result is sent back via deeplink, using given deeplinkScheme and an operation-based authority (in this case payment)

    Unhappy flow:

    1. App calls pay method
    2. OperationListener notifies a failure, which can be used to show an error
    3. The Nexi POS is not opened

    Outcome and threads

    The operationListener will return the outcome in a background thread, so any operation inside success and failure callback should be a legit background operation.

    For example, to show a Toast, the app will have to wrap the logic inside a runOnUiThread scope.

    In the same way, a LiveData implementation should handle the result using the postValue method, instead of the classic value setter method.

    Any violation of background thread rules will result into an exception.

    Enrollment

    During payment or any App2App operation, the enrollment could be requested. In case of need, the onGetRequestUri callback will be called from the SDK and the application should gather necessary params to send a network request and get a request URI from our side.

    Request

    This is used to request a specific URI from the App2App service. It takes the following parameters:

    Name parameter Description Type Mandatory
    thirdAppUserna meMerchant Represents the username associated with the third-party application or merchant making the request. String yes
    thirdAppDeviceId Represents the unique identifier associated with the device of the third-party application or merchant. String yes
    appId Represents the application identifier associated with the third-party application. String yes
    merchantId Represents the merchant identifier associated with the third-party application. String yes
    terminalIds Represents a list of terminal identifiers associated with the thirdparty application or merchant. String yes

    Enrollment Constraints

    Keep in mind that:

    • After having enrolled a merchantUsername, any previous enrollment linked to the same username will be disabled.
    • After having enrolled a merchantUsername with a specific terminal ID, any previous enrollment linked to the same terminal ID will be disabled.

    This implies that a merchantUsername or a single terminal ID cannot be used on two devices at the same time. Therefore, in case of active enrollment on device A and a successful enrollment on device B:

    • The device B will have an active session
    • The device A will keep the previous one. In case of transaction on device A, it will receive a server error, easily solvable by calling the enrollment again. The session of device B will be invalidated.

    Was this helpful?

    What was your feeling about it?