# Device Reader SDK Quickstart

This guide shows how to build in-person payment flows on Android using the Finix Device Reader SDK
with the PAX Android based terminals.

## Prerequisites

- Registered as [developer](https://developer.pax.us/) with Pax


## 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 app to a single merchant it is recommended to use `ROLE_MERCHANT` credentials. If you
plan to use your app credentials for multiple devices you should use `ROLE_PARTNER` credentials.

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

- [Split Transactions](/guides/online-payments/payment-features/split-transactions)


### 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.

Example
User - ROLE_MERCHANT

```json User - ROLE_MERCHANT
{
  "id": "USoR21bF52KLZpbQCptrexpH",
  "created_at": "2025-12-08T18:35:51.41Z",
  "updated_at": "2025-12-08T18:35:51.41Z",
  "created_by": "USfdccsr1Z5iVbXDyYt7hjZZ",
  "email": null,
  "enabled": true,
  "first_name": null,
  "identity": "IDjvxGeXBLKH1V9YnWm1CS4n",
  "last_name": null,
  "last_used_date": null,
  "password": "f2fd7118-66c3-495c-8942-8178e0ea9d0c",
  "role": "ROLE_MERCHANT", // [!code highlight]
  "tags": {},
  "_links": {
    "self": {
      "href": "https://finix.sandbox-payments-api.com/users/USoR21bF52KLZpbQCptrexpH"
    },
    "applications": {
      "href": "https://finix.sandbox-payments-api.com/applications"
    },
    "application": {
      "href": "https://finix.sandbox-payments-api.com/applications/APc9vhYcPsRuTSpKD9KpMtPe"
    }
  }
}
```

API Definition
### 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. Use `integration_mode` of
`SDK`. This will designate that this device will be using the Finix Device Reader SDK.

For more details about the payment terminals available, see
our [available devices](/guides/in-person-payments/select-your-device).


```shell 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_A800",
    "name": "PAX_A800 Finix Device Reader SDK",
    "integration_mode": "SDK",
    "serial_number": "19046260947"
    }
  }'
```


```json Response
{
  "id": "DVxcL2fiBdt9frYCKAbZikZK",
  "created_at": "2025-05-21T19:01:32.000581Z",
  "updated_at": "2025-05-21T19:01:32.000581Z",
  "configuration_details": null,
  "description": "Cashier Three",
  "enabled": false,
  "idle_message": null,
  "integration_mode": "SDK",
  "merchant": "MU7noQ1wdgdAeAfymw2rfBMq",
  "model": "PAX_A800",
  "name": "PAX_A800 Finix Device Reader SDK",
  "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"
    }
  }
}
```

## Using the SDK

### Installation

Add dependency in gradle file.
See [Maven Central](https://central.sonatype.com/artifact/com.finix/pax-device-reader-sdk)
or [MVN Repository](https://mvnrepository.com/artifact/com.finix/pax-device-reader-sdk) for the
latest version.


```kotlin
implementation("com.finix:pax-device-reader-sdk:0.1.0")
```

### Initialization

Add permission to AndroidManifest to interact with mPOS device via Bluetooth


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

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


```kotlin 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 = ""
)
)
```

To interact with the device, it first needs to be registered and created.


```kotlin Initialize
VendorBindings.register(driver: VendorTerminalDriver)
FinixTerminalSDK.createDevice(
    activity: Activity,
    merchantData: MerchantData,
    options: TerminalOptions,
)

driver: The type of device (ie. PaxTerminalDriver)
activity: Android activity
merchantData: Merchant data class containing data specific to your merchant
options: Optional data that can affect the transaction processing (no need to set this value for now)


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,

    // Application Id from Finix starting with APxxxx
    val applicationId: String,

    // Sandbox or Production
    val env: Environment = Environment.SB,

    // ROLE_MERCHANT or ROLE_PARTNER UserId
    val userId: String,

    //  ROLE_MERCHANT or ROLE_PARTNER password
    val password: String

    // Operating country of merchant
    val country: Country = Country.USA
)

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

### Start Transaction

To start a transaction, the function `startTransaction()` must be called. This will prep the device
to accept card input (swipe, tap, insert). The resulting TransactionHandle can then be used to listen to updates during the transaction flow or to cancel the pending transaction.


```kotlin Start Transaction
fun startTransaction(
    request: TransactionRequest
): TransactionHandle

data class TransactionRequest(
    val amount: Long,
    val transactionType: TransactionType,
    val splitTransfers: List<SplitTransfer>? = null,
    val tags: Map<String, String>? = null,
    val buyerIdentityId: String? = null,
    val tipAmount: Long = 0L,
    val surchargeAmount: Long = 0L,
    val idempotencyId: String? = null,
    val disabledCardEntryMethods: Set<CardEntryMethod> = emptySet(),
    val timeoutSeconds: Int = 30
)

interface TransactionHandle(
    val id: String
    val updates: Flow<TransactionUpdate>
    suspend fun cancel(): Result<Unit>
)

sealed class TransactionUpdate(
    data class Processing(val step: TransactionStep) : TransactionUpdate()

    data class Success(val result: TransactionResult) : TransactionUpdate()

    data class Error(val result: TransactionResult, val failureType: CardEntryFailureType) :
        TransactionUpdate()

    data class Retry(
        val disabledCardEntryMethods: Set<CardEntryMethod>,
        val failureType: CardEntryFailureType,
        val cardReadMethod: CardReadMethod
    ) : TransactionUpdate()
)

enum class TransactionStep {
    INITIALIZING,
    AWAITING_CARD,
    READING_CARD,
    CARD_READ_COMPLETE,
    AUTHORIZE_CARD,
    PROCESSING,
    SENT_TO_SERVER
}
```

### Signature Upload

When a transaction succeeds, a signature upload can be performed if
`TransactionResult.signaturePending` in `TransactionUpdate.Success` is true.

In this case your app should capture a signature from the user and call `uploadSignature`.


```kotlin Signature Upload
fun uploadSignature(
    // Base64 encoded png of the signature
    pngEncodedBase64: String,
    // traceId of the successful transaction, found in TransactionResult
    traceId: String,
)
```

### Troubleshooting with the Finix Device Reader Sample App

An example sample app to help with your integration can be found
here [sample app](https://github.com/finix-payments/finix-pax-device-reader-android-sdk-demo-app).

If you encounter issues while using the SDK you can reach out to the Finix Support Team
at [support@finix.com](mailto:support@finix.com).

### Remote Key Injection

The Finix Device Reader SDK uses key slots 3 for sandbox and 4 for production. If your app uses
remote key injection you will need to avoid using either of these key slots.

## Registering Devices for Sandbox or Production

Finix will need a list of users that need access to Pax's TMS product. Finix will then invite individuals to be registered for this account. Please reach out to
your Finix contact to initiate this process.

All TMS access is granted by Finix through the sub-reseller structure. If you already have an
existing PAX account (e.g., from a prior relationship), you can maintain that separately, but
Finix-related terminals must be managed exclusively under the Finix sub-reseller account.

## Pax Debug Devices

When developing your own application on Pax devices you'll need to purchase debug devices directly from Pax. Debug devices allow apps to be installed directly from Android studio but cannot be used in production.
You can order debug devices directly through Pax's developer [account](https://developer.pax.us/). Please note that debug devices may have an extended delivery time of 6-8 weeks depending on inventory.