Skip to content

PAX Device Reader SDK Quickstart

Use the Finix Android SDK for PAX Device Readers to integrate PAX Android-based terminals into your app and accept in-person payments. This guide covers SDK installation, initialization, and processing your first transaction.

Prerequisites

Before starting, complete the Integration Prerequisites to set up your PAX developer account, credentials, and a Device resource.

1. SDK setup

Installation

Add the dependency to your Gradle file. See Maven Central or MVN Repository for the latest version.

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

Initialization

Add permissions to the AndroidManifest to interact with the mPOS device via Bluetooth.

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

To interact with the device, initialize the MposFinix class.

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, first register and create it.

Initialize
fun VendorBindings.register(driver: VendorTerminalDriver)

fun FinixTerminalSDK.createDevice(
    activity: Activity,
    merchantData: MerchantData,
    options: TerminalOptions? = null,
)
  • driver: The type of device (e.g., PaxTerminalDriver)
  • activity: Android activity
  • merchantData: Merchant data class containing data specific to your merchant
  • options: Optional data that can affect transaction processing
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 = ""
    )
)

Remote key injection

If your app uses remote key injection, avoid the key slots reserved by the Finix Android SDK for PAX Device Readers. For more information, see App Requirements.

2. Starting a transaction

Call startTransaction() to prompt the device to accept card input (swipe, tap, or insert). Use the returned TransactionHandle to track updates during the transaction or cancel it.

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
}

3. Signature upload

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

Your app should capture a signature from the user and call uploadSignature.

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

Testing your app

To develop and test your app on PAX devices, you will 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 through PAX's developer account. Debug devices may have an extended delivery time of 6-8 weeks depending on inventory.

Finix Device Reader sample app

See the sample app for an example integration.

If you encounter issues while using the SDK, reach out to the Finix Support Team at support@finix.com.

Next steps

When your app is built and tested, deploy it to your production terminals.