Integration Guide

Use the Nami ECR App to integrate payment functionality into iOS and iPadOS applications. The SDK supports native Swift and Objective‑C.
Follow the steps in this guide to initialize the SDK, connect to a terminal, perform transactions, and handle responses.

For environment setup and SDK details, refer to iOS ECR SDK Library.

Supported Connections (iOS SDK)

PlatformConnection TypesNotes
iOSTCP/IP (Wi‑Fi / LAN)Stable network integration using IP + Port
iOSScan & Auto‑ConnectRequires ECR Adapter 2.4 service on POS terminal

Transaction Flow (iOS SDK)

Initialize SDK → Configure POS terminal → Connect Device (TCP/IP or Scan) → Register (txnType 17) → Start Session (txnType 18) → Execute Transaction → Receive Response → Parse Response → Disconnect

iOS SDK Integration

Step 1: Initialize SDK

  • Ensure Xcode 14+, Swift 5.7+, and iOS 13.0 or later.
  • Connect the Nami terminal to Wi‑Fi.
  • Use the following code to initiate SDK:
import NamiECRSDK

Step 2: Choose Connection Method

The SDK supports two connection methods:

  • Direct TCP connection using terminal IP address and port
  • Automatic discovery by scanning available terminals

Option A: Direct TCP Connection

Call connectTCP() with the terminal IP address and port.

  • Handle success by showing connection status.
  • Handle failure by enabling scan and stop buttons.
ECRSDK.shared.connectTCP(ip: ip, port: port) { status, result in
    DispatchQueue.main.async {
        if status {
            let statusVC = self.storyboard?.instantiateViewController(
                identifier: "ConnectionStatusViewController"
            ) as! ConnectionStatusViewController
            NamiECRNavigationManager.shared.pushViewController(destinationVC: statusVC)
        } else {
            self.scanButton.isEnabled = true
            self.stopButton.isEnabled = true
            self.showToast(message: String(data: result ?? Data(), encoding: .utf8) ?? "No data")
        }
    }
}

Option B: Scan and Auto Connect

Scan available terminals and select a device from the list.

  • Once the device is selected, the SDK automatically establishes the connection.
  • No additional connectTCP() call is required.

Note: Scan and auto‑connect functionality requires the ECR Adapter 2.4 service to be available on the POS terminal.

Step 3: Scan Device

  • Start scanning for available terminals:
class  ConnectionsSettingViewController:ServiceDiscoveryDelegate{
ECRSDK.shared.scanDevice(delegate: self)
}

Step 4: Scan Complete

  • Handle scan completion.
  • Select the device from the list.
  • Push connection status view on success.
  • Show error toast on failure.

Use the following code to complete scanning.

class ConnectionsSettingViewController:ServiceDiscoveryDelegate{
func onScanCompleted(services: [String]) {
    showAlertWithList(devices: services) { device in
        ECRSDK.shared.onSelectDevice(deviceName: device, port: UInt16(self.portNumberTextField.text!)!) { status, result in
            self.handleConnectionResponse(status: status, result: result)
        }
    } onCancel: { isCancelled in }
}
}

Step 5: Select Device

Use the following code to select a device and connect to the terminal.

ECRSDK.shared.onSelectDevice(deviceName: device, port: UInt16(self.portNumberTextField.text!)!) { status, result in
    DispatchQueue.main.async {
        if status {
            let statusVC = self.storyboard?.instantiateViewController(
                identifier: "ConnectionStatusViewController"
            ) as! ConnectionStatusViewController
            NamiECRNavigationManager.shared.pushViewController(destinationVC: statusVC)
        } else {
            self.scanButton.isEnabled = true
            self.stopButton.isEnabled = true
            self.showToast(message: String(data: result ?? Data(), encoding: .utf8) ?? "No data")
        }
    }
}

Step 6: Stop and Disconnect

  • Stop scanning:
ECRSDK.shared.stopScan()
  • Disconnect terminal:
ECRSDK.shared.disconnectTCP()

Step 7: Initiate Payment

Follow these steps to initiate a payment.

A) Set CRN

Set the Cash Register Number (CRN, 8-digit numeric).

Swift

ECRSDK.shared.cashRegisterNumber = cashRegisterNumberTextfield.text

B) Configure Terminal Printer

Configure the terminal printing preference.

  • true = Enable terminal printing
  • false = Disable terminal printing

Swift

ECRSDK.shared.enableTerminalPrinter = true // or false

C) Create Transaction Request

Create a transaction request object for the required transaction type.

For example, to perform a purchase transaction:

Swift

let transactionRequest = PurchaseRequest(amount: amount)

D) Execute Transaction

Pass the request object to the SDK using doTransaction().

Swift

        ECRSDK.shared.doTransaction(request: transactionRequest){ status, response in

            DispatchQueue.main.async {

                self.hideLoaderWithAnimatedImageView()

                self.handleTransactionResponse(status: status, response: response, selectedTransactionType: selectedTransactionType)

            }

        }

Supported Transaction Request Objects

Use the appropriate request object based on the transaction type.

TransactionRequest Object
PurchasePurchaseRequest(amount: amount)
Purchase with NaqdPurchaseWithNaqdRequest(amount: amount, naqdAmount: naqdAmount)
RefundRefundRequest(amount: refundAmount, rrn: originalRRN, originalDate: originalDate)
AuthorizationAuthorizationRequest(authAmount: authAmount)
AdviceAdviseRequest(amount: authAmount, rrn: rrn, transactionDate: transactionDate, approvalCode: approvalCode, partialCompletion: "1" or "0")
Auth ExtensionAuthExtensionRequest(rrn: rrn, transactionDate: transactionDate, approvalCode: approvalCode)
Auth VoidAuthVoidRequest(authAmount: authAmount, rrn: rrn, transactionDate: transactionDate, approvalCode: approvalCode)
Cash AdvanceCashAdvanceRequest(authAmount: authAmount)
DuplicateDuplicateRequest(previousEcr: prevECR)
ReversalReversalRequest(rrn: rrn)
ReconciliationReconcilationRequest()

Note

When specifying transaction amounts, convert the amount to a 12-digit numeric string.

Example:

10.25000000001025

Handle Response

The transaction response is returned through the completion handler of the doTransaction() method.

The SDK returns the transaction result directly as a response string. Handle unsuccessful transactions before processing the response.

Swift

private func handleTransactionResponse(    status: Bool,    response: String,    selectedTransactionType: SupportedTransactions) {    SampleAppLogger.log("transaction status: \(status)", ofType: .debug)    guard status else {        if !ECRSDK.shared.isDeviceConnected() {            updateConnectivityStatus()        }        showAlert(            message: "Transaction failed: \(String(data: response ?? Data(), encoding: .utf8) ?? "Failed to print response Error")"        )        return    }    let components = transactionResponse.responseBody.components(separatedBy: ";")    if transactionResponse.responseBody.caseInsensitiveCompare("Transaction Not Allowed") == .orderedSame {        displayResponseReceived(            for: selectedTransactionType,            with: [transactionResponse.responseBody]        )    } else if components.count > 2 {        let trimmed = Array(components.dropFirst().dropLast())        displayResponseReceived(            for: selectedTransactionType,            with: trimmed        )    } else {        displayResponseReceived(            for: selectedTransactionType,            with: [transactionResponse.responseBody]        )    }}

Response Processing

The SDK processes the transaction response and returns the transaction details through the completion handler.

  • Verify the transaction status.
  • Check the terminal connection status if the transaction fails.
  • Parse the response fields separated by semicolons (;).
  • Display the parsed response in the response screen.
  • Handle special responses such as Transaction Not Allowed separately.

Error Handling


Did this page help you?