DEVELOPER
Products

PAX Mobile SDK Integration Guide


How To Start


PlatformRequirements
iOSiOS 13.0 or later, Xcode 14.0 or later
AndroidAndroid 8.0 (API 26) or later, Android Studio
HardwarePAX D135 Bluetooth card reader

  1. Sign up for a free North Developer account.
  2. Contact us for credentials. You will receive your EPX ID (four-part key) and EPX Key for authentication. Once credentials are provisioned, they can be referenced when logged in by selecting the User profile icon in the top right corner of the screen, selecting View Dashboard, then Credentials.
  3. Apply for a Merchant Processing Account. Once approved, a Merchant ID (MID) will be provided to you.
  4. Download the PAX Mobile SDK framework for your platform from the Resources page and follow the integration steps below.
    When logged in, you can use the Integration Tracker to view the status of your integration, notes from meetings with Integration Engineers, resources related to your solution, and more.
  5. When development is complete, contact us and once we ensure things are working properly, Production credentials will be provided to you.





iOS Integration


Step 1: Add the PaxSDK Framework

  1. Create a new folder called Libraries in your Xcode project's root directory using File > New > Folder.

  2. Drag the PaxSDK.xcframework file from the downloaded SDK package into your project's Libraries folder. Select "Copy items if needed" before clicking Finish.

  3. Go to your target's General settings and verify that the PaxSDK.xcframework is listed under the Frameworks, Libraries and Embedded Content section. If not, click the "+" icon and add it manually.


Step 2: Configure Bluetooth Permissions

Add the following keys to your Info.plist to enable Bluetooth communication with the PAX D135 reader:


Step 3: Initialize the SDK (iOS)

The PaxSDK class requires seven parameters for initialization:

ParameterDescription
epxIdThe ID given by EPX to identify your application (four-part key)
epxKeyAuthentication key for the JSON API, provided by EPX
environmentSwitch between .Uap (sandbox/certification) and .Production
merchantNameThe name or DBA of the merchant (not sent to EPX)
terminalNumberIdentifies the particular reader and device combination (not sent to EPX)
maxRetriesNumber of failed chip reads before the reader/code goes to the swipe fallback scenario
traceEnable to log raw request/response data for debugging

Step 4: Connect to the PAX D135 Reader (iOS)

Connect to the Bluetooth device using the BLEViewController:





Android Integration


Step 1: Add the SDK Dependency

Add the PAX SDK to your Android project by including the AAR file in your libs folder and adding the following to your build.gradle:


Step 2: Configure Bluetooth Permissions

Add the following permissions to your AndroidManifest.xml:


Step 3: Initialize the SDK (Android)

ParameterDescription
easyLinkInstance of EasyLinkSdkManager (singleton)
epxIdThe four-part key provided by EPX (used as the EPI-Id header)
epxKeyThe HMAC key used to generate the EPI-Signature

Step 4: Connect to the PAX D135 Reader (Android)

First, discover devices using the EasyLink SDK Manager:

Once you have a device, connect to it:





Transaction Workflow

All card-present transactions follow this general flow:

  1. Initiate Transaction using runTxn() (Android) or transaction methods like sale(), refund(), etc. (iOS). This opens the reader to accept a chip dip, tap, or card swipe.
  2. Device reads card via chip, tap, or swipe.
  3. Transaction is sent to EPX and a response is returned.

Listener Methods (Android)

The PaxNabEventListener interface provides the following callback methods:

MethodDescription
transactionResponse(PaxNabTxnResponse)Called when the transaction completes. Contains the transaction result with Success status, Message, and nested EpxResponse object containing the actual EPX host response.
showMessage(String)Called with display messages for the customer (e.g., "PRESENT CARD", "REMOVE CARD", "PROCESSING..."). Display these messages to the user in your UI.
debugMessage(String)Called with debug log messages. Use this for troubleshooting and logging SDK activity.



Transaction Types


Sale

The sale transaction is an authorization and capture within the same transaction. The authorization is immediately captured, and the transaction will settle during the next batch close time.

Required fields: amount, transaction, batchID, industryType

iOS:

Android:


Authorization Only

An authorization only transaction holds funds on a cardholder's account without capturing. A subsequent capture transaction is required for settlement.

iOS:

Android:


Capture

The capture transaction captures a previous authorization to allow settlement. The capture amount can be equal to or less than the original authorization.

Required fields: amount, batchID, transaction, bric

iOS:

Android:


Refund (Card Present)

The refund transaction returns funds to an account previously acted upon by a settled sale or capture. Multiple partial refunds can be performed up to the original transaction amount.

Required fields: amount, batchID, transaction

iOS:

Android:


Linked Refund (Card Not Present)

A linked refund can be performed without the card present by including the BRIC of the original sale or capture:

iOS:

Android:


Reverse

Voids and reverses an unsettled Sale or Auth Only transaction.

iOS:

Android:


Void

Voids a Capture or Refund before settlement.

Android:


Incremental Authorization

Increases a prior authorization amount. Requires the BRIC from the original authorization.

Android:


Batch Close

Marks transactions for settlement.

Android:


Transaction Lookup

Query a transaction using its BRIC.

Android:


Batch Totals

Retrieve batch totals using batchID.

Android:





Additional Transaction Fields

Beyond the required fields, you can include additional parameters in your transaction requests:

Field NameEPX FieldDescription
invoiceNumberINVOICE_NBRInvoice number for the transaction
orderNumberORDER_NBROrder number for the transaction
tipAmountTIP_AMTTip amount (decimal)
taxAmountTAX_AMTTax amount (decimal)
taxExemptTAX_EXEMPTTax exempt flag
emailAddressEMAILCustomer email address
address.addressADDRESSStreet address for AVS verification
address.zipCodeZIP_CODEZIP code for AVS verification
address.firstNameFIRST_NAMECustomer first name
address.lastNameLAST_NAMECustomer last name
address.stateSTATEState for AVS verification
softDescriptorSOFT_DESCRIPTORSoft descriptor for statement

Example with additional fields (iOS):





Response Handling

Android:

Displaying Messages to User:

Use the PaxNabEventListener methods to surface status or instructions:





Support

For further assistance with your integration, please contact our support team or visit the Resources page for additional documentation and downloads.



Top of Page
// PaxController.swift
// This example demonstrates how to initialize the PAX SDK
// and process a sale transaction on iOS

import UIKit
import PaxSDK
import CoreBluetooth

class PaxController: UIViewController, UITextFieldDelegate, UIActionSheetDelegate, PaxSDKEvent, TxnTypeListEvent, AppListEvent {
    
    var sdk: PaxSDK = PaxSDK(epxId: "9001-901029-1-3", epxKey: "F9269E0641E507D4E0533213180ADBC8", environment: .Uap, merchantName: "TestMerchant1", terminalNumber: "TestTerminal1", maxRetries: 2, trace: true)
    
    sdk = PaxSDK(epxId: self.epxId, epxKey: self.epxKey, environment: self.epxEnv, merchantName: self.merchantName, terminalNumber: self.terminalNumber, maxRetries: maxRetries, trace: true)
    sdk.delegate = self
    
    @objc func connect() {
        let list = BLEViewController(sdk: sdk)
        self.navigationController?.pushViewController(list, animated: true)
    }
    
    public func runTxn(amount: Double, BatchId: Int, transactionNum: Int) {
        var txnData = [
            "amount": amount,
            "transaction": transactionNum,
            "batchId": BatchId
        ] as [String: Any]
        
        sdk.sale(txnData: txnData)
    }
    
    public func onTransactionComplete(_ response: EPXResponse) {
        let jsonEncoder = JSONEncoder()
        
        do {
            let jsonData = try jsonEncoder.encode(response)
            let jsonString = String(data: jsonData, encoding: .utf8)
            
            appendToDisplayText("\n\nTransaction Complete!  Response:\n" + jsonString!)
            
            let message = response.errors != nil ? "Error: " + (response.errors?.joined(separator: ", "))! : response.data!["text"] ?? response.data!["authorization"]
            
            self.messageBox(messageTitle: "Status", messageAlert: message!, messageBoxStyle: .alert, alertActionStyle: .default) {}
        } catch {}
    }
    
    func onTransactionError(_ reason: NABPAXFailureReason, description: String) {
        let fullMessage = "\n\nTransaction Error!  Message:\n" + reason.rawValue + " " + description
        print(fullMessage)
        appendToDisplayText(fullMessage)
        
        self.messageBox(messageTitle: "Error", messageAlert: fullMessage, messageBoxStyle: .alert, alertActionStyle: .default) {}
    }
}
©2026 North is a registered DBA of NorthAB, LLC. All rights reserved. North is a registered ISO of BMO Harris Bank N.A., Chicago, IL, Citizens Bank N.A., Providence, RI, The Bancorp Bank, Philadelphia, PA, FFB Bank, Fresno, CA, Wells Fargo Bank, N.A., Concord, CA, and PNC Bank, N.A.