Skip to content

Build out your in-person payments integration using Finix's mobile SDK.

The Pax D135 Android SDK is currently in pilot

The SDK is available to customers that wish to join the pilot program. Because functionality is still in pilot there may be degraded acceptance rates and overall issues with the feature. We will be partnering with those in pilot to help resolve issues as part of our overall product roadmap.

PAX D135 Integration Overview

The PAX D135 is an ultra-portable and cost-effective mobile device that can serve a wide range of uses.

Important Pre-Requisites

Device Designation

A D135 device can be designated to be used for either Sandbox development or Production transaction processing but not both. We recommend requesting enough devices to utilize in both your Sandbox development and Production testing.

  • To designate a device for use in the Sandbox or Production environment please reach out to your Finix point of contact or support team and provide the serial number of the device and the environment you wish to use it in. Finix will then notify you once the device is ready to be used to process transactions.

  • Version 3.0.0 is a major update. Devices that are currently in use and upgraded to this version will not be compatible with earlier versions (2.x.x or below). If you are currently using D135 readers in Production on a 2.0.0 or above version please reach out to Finix before updating. We will guide you through the rollout process and help facilitate additional devices for ease of rollout.

  • The minimum Android version supported is Android Version 26.


Determine Which Type of Integration You Prefer

The SDK supports the use of either ROLE_PARTNER or ROLE_MERCHANT credentials. If you would like to scope your device to a single merchant it is recommended to use ROLE_MERCHANT credentials. If you plan to use the device across multiple merchants you should use ROLE_PARTNER credentials.

Note that the following functionality requires the use of ROLE_PARTNER credentials.

How to Create ROLE_MERCHANT Credentials

The following outlines how to create ROLE_MERCHANT credentials. Once created, you can use these credentials across multiple devices as long as the devices are associated to the same Merchant.

Create Role Merchant Credentials Request
curl https://finix.sandbox-payments-api.com/identities/IDuWtgdP9VERb4FiLeYatWy/users \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u "USjHFGYvecE4LBitYG8KDE2g:b698f403-d9b7-4157-82d8-162cea8c8cc3" \
    -d '{}'
Create Role Merchant Credentials Response
{
    "id": "USxxxxxxxxxxxxxxxxxxxxxx",
    "created_at": "2022-10-10T06:05:08.11Z",
    "updated_at": "2022-10-10T06:05:08.11Z",
    "enabled": true,
    "identity": "IDxxxxxxxxxxxxxxxxxxxxxx",
    "password": "xxxxxxxxxxxxxxxxxxxxxx",
    "role": "ROLE_MERCHANT",
    "tags": {},
    "_links": {
        "self": {
            "href": "https://finix.sandbox-payments-api.com/users/USgymgj1dSkCNxYmZKd9GxQN"
        },
        "applications": {
            "href": "https://finix.sandbox-payments-api.com/applications"
        },
        "application": {
            "href": "https://finix.sandbox-payments-api.com/applications/APeUbTUjvYb1CdPXvNcwW1wP"
        }
    }
}

How to Create ROLE_PARTNER Credentials

The following explains how to create a new set of ROLE_PARTNER api credentials.

  1. Login to the Finix dashboard.
  2. Select the environment for which you would like to create the api credentials (Sandbox or Live)
  3. In the bottom left hand corner select the Developer section
  4. In the Api Keys section. Select Create Api Key
Create API Key

Creating a Device Resource

Creating a device resource can be done either via the Finix dashboard or via api. Below are the steps for creating a device via API.

Step 1: Create a Device

Create a Device under the Merchant provisioned to process In-Person Payments. Include the Device.model of the payment terminal you'll be using to process cards.

For more details about the payment terminals available, see our available devices.

Request
curl -i -X POST \
  -u USfdccsr1Z5iVbXDyYt7hjZZ:313636f3-fac2-45a7-bff7-a334b93e7bda \
  https://finix.sandbox-payments-api.com/merchants/MUwfZPNW3r4EqLMzwgr6txw4/devices \
  -H 'Accept: application/hal+json' \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "Cashier Three",
    "model": "PAX_D135",
    "name": "My PAX_D135 Finix Device",
    "serial_number": "19046260947"
    }
  }'
Response
{
  "id": "DVxcL2fiBdt9frYCKAbZikZK",
  "created_at": "2025-05-21T19:01:32.000581Z",
  "updated_at": "2025-05-21T19:01:32.000581Z",
  "configuration_details": {
    "allow_debit": true,
    "check_for_duplicate_transactions": true,
    "prompt_amount_confirmation": true,
    "prompt_manual_entry": false,
    "signature_threshold_amount": 10000,
    "bypass_device_on_capture": true,
    "prompt_receipt_confirmation": true,
    "display_tip_on_receipt": false,
    "prompt_tip_on_screen": false,
    "allow_standalone_authorizations": false,
    "allow_standalone_sales": false,
    "allow_standalone_refunds": false,
    "tipping_details": {
      "percent_tipping_threshold": 0,
      "percent_options": [
        18,
        20,
        22
      ],
      "fixed_options": [
        100,
        150,
        200
      ]
    },
    "idle_message": null,
    "idle_image_file_id": null,
    "automatic_receipt_delivery_methods": null,
    "available_receipt_methods": null,
    "prompt_for_signature": "NEVER",
    "surcharge_basis_points": null
  },
  "description": "Cashier Three",
  "enabled": false,
  "idle_message": null,
  "merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
  "model": "PAX_D135",
  "name": "My PAX_D135 Finix Device",
  "serial_number": "19046260947",
  "tags": {},
  "_links": {
    "self": {
      "href": "https://finix.sandbox-payments-api.com/devices/DVxcL2fiBdt9frYCKAbZikZK"
    },
    "merchant": {
      "href": "https://finix.sandbox-payments-api.com/merchants/MU7noQ1wdgdAeAfymw2rfBMq"
    },
    "transfers": {
      "href": "https://finix.sandbox-payments-api.com/transfers"
    },
    "authorizations": {
      "href": "https://finix.sandbox-payments-api.com/authorizations"
    }
  }
}

Step 2: Activate the Payment Terminal

Once the Device is created and the serial_number is set, you can link the Device resource with the payment terminal you'll use by sending an activation request to the payment terminal. A successful request returns Device.enabled: true. The device must be online and connected to the network with the app in the front in order for the request to succeed.

Activate Device
curl -i -X PUT \
    -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    https://finix.sandbox-payments-api.com/devices/DVxcL2fiBdt9frYCKAbZikZK \
    -H 'Accept: application/hal+json' \
    -H 'Content-Type: application/json' \
    -H 'Finix-Version: 2022-02-01' \
    -d '{
        "action": "ACTIVATE"
    }'

Using the SDK

Installation

Add dependency in gradle file. See Maven Central or MVN Repository for the latest version.

implementation("com.finix:pax-mpos-sdk-android:3.3.1")

Initialization

Add permission to AndroidManifest to interact with mPOS device via Bluetooth

<!-- For network communication -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- For bluetooth communication -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!-- TargetSdkVersion greater than or equal to 31 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

To interact with the MPOS device, it first needs to be initialized. This can be done by initializing the class mposFinix.

Initialize
class mposFinix(private val context: Context, private val merchantData: MerchantData)

context: Android application context
merchantData: Specific values which help identify the merchant

class MerchantData (
    // Merchant Id from Finix starting with MUxxxx
    val merchantId: String,
    
    // Finix mid (GUID representation)
    val mid: String,
    
    // Device ID - device registers with Finix, starting with DVxxxx
    val deviceId: String,
    
    val currency: Currency = Currency.USD,
    
    // Sandbox or Production
    val env: EnvEnum = EnvEnum.SB,
    
    // ROLE_MERCHANT or ROLE_PARTNER UserId
    val userId : String,
    
    //  ROLE_MERCHANT or ROLE_PARTNER password
    val password: String
)

Example : val mpos = mposFinix(
    context,
    MerchantData(
        merchantId = "MUxxxxxx",
        mid = "",
        deviceId = "DVxxxxx",
        env = EnvEnum.SB,
        userId = "USxxxxxxxxx",
        password = ""
  )
)

Once initialized, connect to the device. When the device is ready for pairing, it will show an orange light and green light. Once connected, the orange light will disappear and only the green light will stay on.

First Time Device Configuration

When first pairing a Pax D135 the initial configuration may take a few minutes to complete. We recommended that the user experience you build factors in the configuration time to ensure that the user knows the device configuration is in progress.

Connect
fun connect(deviceName: String, deviceAddress: String, callback: MPOSConnectionCallback)

deviceName : bluetooth name of the device
deviceAddress : bluetooth address of the device
callback: exposes functions which are invoked to propagate success, error, progress

interface MPOSConnectionCallback {
    fun onSuccess() // Called if the connection is successfully established
    fun onError(errorMessage: String) // Called if the connection fails for some reason
    fun onProcessing(currentStepMessage: String) // Provides status messages of what's currently happening
}

Start Transaction

To start a transaction, the function startTransaction() must be called. This will prep the mPOS device to accept card input (swipe, tap, insert). A blue status light will be shown. Once any action is performed with the card the device would show a red light to indicate, the card has been read and to remove it.

Start Transaction
fun startTransaction(
        amount: Long,
        transactionType: TransactionType
        transactionCallback: MPOSTransactionCallback,
        configureEMVResponseCallback: MPOSEMVProcessingCallback,
        splitTransfers: List<SplitTransfer>? = null,
        tags: Map<String, String>? = null
    )

amount : amount in cents for \$10.10 this value would be 1010
transactionType : TransactionType enum with support for only Sale, Refund and Authorization
transactionCallback : Exposes functions which are invoked with status of the transaction or the Transaction Result
configureEMVResponseCallback: Exposes functions which are invoked to with status of authorizing a card insert
splitTransfers: Optional list of split transfer request data
tags: Optional map of key/value strings to be provided in the request

interface MPOSTransactionCallback {
    fun onSuccess(result: TransactionResult?) // Called if the transaction is successfully processed
    fun onError(errorMessage: String) // Called if the transaction fails for any reason
    fun onProcessing(currentStepMessage: String) // Provides status messages of what's currently happening
}

interface MPOSEMVProcessingCallback {
    fun onError(errorMessage: String) // Called if the authorization of chip insert fails for any reason
    fun onProcessing(currentStepMessage: String) // Provides status messages of what's currently happening
}

Referenced Refund

A referenced refund, refunds the amount specified (refund amount) of a particular transaction (transaction id) to the card on file

Referenced Refund
fun startRefund(
    transactionId: String,
    refundAmount: Long,
    refundCallback: MPOSRefundCallback
    tags: Map<String, String>? = null
)

transactionId : The transaction id specified correlating to a previous transaction. The ID is returned as part of the TransactionResult
in the above start transaction
refundAmount : amount in cents for \$10.10 this value would be 1010
refundCallback : Exposes functions which are invoked with status of the refund or the Refund Result

Proguard Rules

If you're using proguard please add the following to your proguard rules.

#Retrofit
 -dontwarn retrofit.**
 -keep class retrofit.** { *; }
 -keepattributes Signature
 -keepattributes Exceptions
 -keepattributes RuntimeVisibleAnnotations
 -keepattributes RuntimeInvisibleAnnotations
 -keepattributes RuntimeVisibleParameterAnnotations
 -keepattributes RuntimeInvisibleParameterAnnotations

#OkHttp3
 -keepattributes Signature
 -keepattributes *Annotation*
 -keep class okhttp3.** { *; }
 -keep interface okhttp3.** { *; }
 -dontwarn okhttp3.**
 -dontwarn java.nio.file.*
 -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

#Gson
  -keep class com.google.gson.stream.** { *; }

#Finix
 -dontwarn com.finix.mpos.sdk.**
 -keep class com.finix.mpos.sdk.** { *; }
 -keep class com.finix.mpos.models.** { *; }
 -dontwarn java.lang.invoke.StringConcatFactory

Troubleshooting with the Finix D135 Sample App

If you encounter issues with a Pax D135 while using the SDK you can reach out to the Finix Support Team at support@finix.com. Before reaching out to support, please follow the steps below to provide the necessary information to help us troubleshoot the issue.

A sample app showing how to integrate the Android D135 SDK can be found here.

Step 1: Launch the Finix D135 Sample App

Step 2: Connect to the Pax D135

Step 3: Click Send Debug Data

Troubleshooting Devices in the Field via Your Android Application

If you encounter issues with a Pax D135 that is in the field with a customer you can reach out to the Finix Support Team at support@finix.com.

We strongly recommend that you build in the function below to collect the necessary information from the device that will be used to troubleshoot the issue. Not doing so may delay the resolution of the issue.

Send Report
fun sendDebugReport(sendReportCallback: MPOSSendReportCallback)

interface MPOSSendReportCallback {
    fun onError(errorMessage: String?)
    fun onSuccess(result: LogsResponse?)
}