*New - Android SDK

Introduction

Use the Namipay Merchant App to integrate payment acceptance into merchant workflows. This guide provides step‑by‑step instructions for setup, transaction initiation, and response handling.

Supported Connections

Connection TypeSupportedNotes
TCP/IP (Wi‑Fi)Recommended for stable and fast setup. Uses socket connection with terminal IP + port.
BluetoothRequires pairing the terminal with the POS/mobile device first, then connecting via SDK.
Serial (COM)Not supported on Android SDK. Serial is limited to desktop SDKs (Java, .NET).

Transaction Flow

Set Up Environment → Configure POS → Pack Request → Launch POS App → Send Transaction → Receive Response → Parse Response

Integration Steps

Note: The application requires changes at both the project level and the application (code) level.
Make these updates before you start integration.

Step 1: Set Up Environment

Use these entries to configure your Android project before integrating the Namipay SDK. This ensures the application has the correct permissions, USB host support, and SDK linkage.

Add these entries to AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.usb.host" />
<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
    android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
    android:resource="@xml/usb_device_filter" />

Add these entries to build.gradle:

repositories {
    flatDir { dirs 'libs/aars' }
}
implementation files('libs/NamipaySDK-release.aar')

Step 2: Configure POS Application

Enable ECR Mode on the POS app before integration.

Traditional POS → ECR Mode enabled by default.

SoftPOS → Enable ECR Mode via Merchant Portal custom parameters.

Step 3: Pack ECR Request

Use the SDK to pack transaction requests into byte arrays.

Call the pack method:

byte[] packed = CLibraryLoad.getInstance().getPackData(requestData, transactionType, signature);

Send and receive data:

public String sendReceive() {
    byte[] requestData = CLibraryLoad.getInstance().getPackData(reqData, tranType, szSignature);
    byte[] responseData = inputStream.read();
    return CLibraryLoad.getInstance().getParseData(responseData);
}

Step 4: Provide Function Arguments

Build the request string and compute the signature.

Build request data:

String purchaseReq = date + ";" + purchaseAmount + ";" + printFlag + ";" + ecrReferenceNo + "!";

Compute SHA‑256 signature:

public String computeSha256Hash(String combinedValue) {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    byte[] hashInBytes = md.digest(combinedValue.getBytes());
    StringBuilder sb = new StringBuilder();
    for (byte b : hashInBytes) {
        sb.append(String.format("%02x", b));
    }
    return sb.toString();
}

Step 5: Launch POS App (Intent)

Use an Intent to launch the POS app and send the request packet.

Send request via Intent:

Intent intent = requireActivity().getPackageManager().getLaunchIntentForPackage("com.skyband.pos.app");
intent.putExtra("message", "ecr-txn-event");
intent.putExtra("request", packData);
intent.putExtra("packageName", "com.Namipay.ecr");
startActivity(intent);

Handle response:

byte[] receivedData = getIntent.getByteArrayExtra("app-to-app-response");
if (receivedData != null && receivedData.length > 0) {
    String receivedIntentData = new String(receivedData).replace("�", ";");
    ActiveTxnData.getInstance().setReceivedIntentData(receivedIntentData);
}

Step 6: Launch POS App (Local Host)

Use an Intent to ensure the POS app is running and listening on the local port.

Start POS app in Local Host mode:

Intent intent = requireActivity().getPackageManager().getLaunchIntentForPackage("com.Namipay.pos.app");
intent.putExtra("message", "ecr-local-event");
startActivity(intent);

Step 7: USB Communication Integration

Use USB OTG mode when network connectivity is not available.

Discover devices:

// Discover devices
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();

Filter by VID/PID:

// Select by VID/PID
if (dev.getVendorId() == UN20_VID && dev.getProductId() == UN20_PID) { device = dev; }

Request permission:

usbManager.requestUsbPermission(device);

Initialize connection:

UsbDeviceConnection connection = usbManager.openDevice(device);
connection.claimInterface(cdcControl, true);
connection.claimInterface(cdcData, true);

Send request:

int sent = connection.bulkTransfer(outEndpoint, request, request.length, 30000);

Receive response:

byte[] buffer = new byte[2048];
int read = connection.bulkTransfer(inEndpoint, buffer, buffer.length, 90000);
String response = CLibraryLoad.getInstance().getParseData(buffer);

Step 8: Initiate Payment

Follow these actions to initiate a payment.

Set CRN:

GlobalDataPrefrences.shared.lastCRN = cashRegisterNumberTextfield.getText();

Configure terminal printer:

ECRDataManager.shared.enableTerminalPrinter = 0; // or 1

Compute signature:

String szSignature = ECRSDK.shared.computeSha256Hash(
    ecrTransactionReferenceNumber + GlobalDataPrefrences.shared.lastConnectedTerminalId
);

Generate ECR reference number:

private String getECRTransactionReferenceNumber() {
    String referenceNumber = ECRDataManager.shared.formattedEcrRefNumber();
    return GlobalDataPrefrences.shared.lastCRN + referenceNumber;
}

Get timestamp:

private String getFormattedCurrentDate() {
    SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyHHmmss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    return sdf.format(new Date());
}

Build transaction request:

buildInputRequestData(selectedTransactionType, dateTimeStamp, etpInput, ecrTransactionReferenceNumber);

Execute transaction:

ECRSDK.shared.doTransaction(hexData, selectedTransactionType, szSignature, (status, response) -> {
    handleTransactionResponse(status, response, selectedTransactionType);
});

Transaction Types

Transaction TypeRequired DataElement Description
PurchasedateTimeStamp;amount;etpInput;ecrRefNo!Amount must be converted to 12‑digit string.
Purchase with NaqddateTimeStamp;totalAmount;naqdAmount;etpInput;ecrRefNo!Includes cashback amount.
RefunddateTimeStamp;amount;rrn;etpInput;originalDate;ecrRefNo!Requires refund amount, RRN, and original date.
AuthorizationdateTimeStamp;authAmount;etpInput;ecrRefNo!Authorization‑only transaction.
Auth ExtensiondateTimeStamp;rrn;transactionDate;approvalCode;etpInput;ecrRefNo!Extends authorization validity.
Auth VoiddateTimeStamp;authAmount;rrn;transactionDate;approvalCode;etpInput;ecrRefNo!Voids authorization transaction.
Cash AdvancedateTimeStamp;authAmount;etpInput;ecrRefNo!Cash advance amount.
DuplicatedateTimeStamp;previousECR;ecrRefNo!Previous ECR reference number.
ReversaldateTimeStamp;rrn;etpInput;ecrRefNo!Requires RRN.
ReconciliationdateTimeStamp;etpInput;ecrRefNo!Settlement reconciliation.

Sample Application Flow

Step 1: Add SDK to Project

  • Download the Android SDK package (SkyBandSDK-release.aar).
  • Place the .aar file in your project’s libs folder.
  • Add the dependency in build.gradle:
implementation files('libs/SkyBandSDK-release.aar')
  • Sync the project.

Step 2: Configure Permissions

  • Open AndroidManifest.xml.
  • Add required permissions:
<!-- General -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- Bluetooth -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>

<!-- USB -->
<uses-permission android:name="android.permission.USB_PERMISSION"/>

<!-- Storage -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Note: Permissions vary by connection type. Ensure only relevant permissions are enabled.

Step 3: Establish Connection

  • Ensure the Nami payment terminal is powered on.
  • Select connection method:
    • TCP/IP: Ensure both devices are on the same network. Use terminal IP address.
    • Bluetooth: Pair the terminal with the Android device. Use paired device details.
Connection Type

Connection Type

  • Initialize the SDK and establish connection.

Step 4: Register Terminal

  • Send a Register request with txnType = 17 and your Cash Register Number.
  • Expected Result: Success response confirming registration.

Important: Registration is required only for legacy ECR integrations. Local and Cloud Middleware integrations do not require this step.

Step 5: Start Session

  • Send a Start Session request with txnType = 18.
  • Expected Result: Session start confirmation.

Important: Applies only to legacy ECR integrations. Not required for Local or Cloud Middleware integrations.

Step 6: Perform Transaction

Send a Purchase request::

txnType: 0
amount: "100"   // SAR 1.00 (amount in halalas)
ecrRefNo: "12345678900001"
date: "ddMMyyHHmmss"
  • Note: Transaction amount is in halalas. The amount will display on the terminal.

Step 7: Process Response

  • Receive the response from the terminal.
  • Use SDK utilities to parse the response.
  • Extract:
    • Response code (String)
    • Approval code (String)
    • Receipt data (String/JSON)

Example CSV string:

00,APPROVED,10000,140524193012,TX12345678,RECEIPT123

Parsed Output Mapping:

FieldExample ValueDescription
Response Code00Transaction result (00 = Approved)
Approval CodeAPPROVEDIssuer/host approval code
Amount10000Transaction amount (in minor units)
Timestamp140524193012Date/time in ddMMyyHHmmss format
ECR Reference NoTX12345678Merchant’s transaction reference number
Receipt DataRECEIPT123Printable receipt or structured payload

Parsing Example (Java/Kotlin):*

String response = "00,APPROVED,10000,140524193012,TX12345678,RECEIPT123";
String[] fields = response.split(",");

String responseCode = fields[0];
String approvalCode = fields[1];
String amount = fields[2];
String timestamp = fields[3];
String ecrRefNo = fields[4];
String receiptData = fields[5];

Code Integration Flow

Provide equivalent Java/Kotlin snippets for each step (Add SDK, Configure Permissions, Establish Connection, Register, Start Session, Purchase, Response Parsing).

Notes on Legacy vs Adapter

  • Legacy ECR Integrations: Require Register and Start Session steps.
  • ECR Adapter Integrations: Do not require Register/Session.
  • Documented separately to avoid confusion.

Handle Response

Use the SDK to parse and process the response.

Parse response:

String response = CLibraryLoad.getInstance().getParseData(responseData);

Process response:

  • Convert to JSON.
  • Store in app state.
  • Display in UI.
  • Validate transaction status.
  • Generate receipt if required.