Skip to main content

Overview

NetPOS data models are organized in the com.woleapp.netpos.model package. These classes represent domain objects, API request/response structures, and database entities.

Core Models

User Model

Represents merchant user account with business information.
model/User.kt:5
data class User(
    @SerializedName(value = "agent_id", alternate = ["Merchant_id", "merchant_id"])
    var user_id: Long? = null,
    
    @SerializedName("name")
    var name: String? = null,
    
    @SerializedName("username")
    var email: String? = null,
    
    @SerializedName("mobile_no")
    var phone: String? = null,
    
    @SerializedName("bankAccountNumber")
    var account_number: String? = null,
    
    @SerializedName("bankName")
    var bank: String? = null,
    
    @SerializedName("bvnNumber")
    var bvn: String? = null,
    
    @SerializedName("terminalId")
    var terminal_id: String? = null,
    
    @SerializedName(value = "amount", alternate = ["wallet_amount", "availableBalance"])
    var availableBalance: String? = "0.00",
    
    @SerializedName("ledgerBalance")
    var ledgerBalance: String = "0.00",
    
    @SerializedName("isQRRegistered")
    var qRRegistered: Boolean = false,
    
    @SerializedName("stormId")
    var netplus_id: String? = null,
    
    @SerializedName("businessName")
    var business_name: String? = null,
    
    @SerializedName("business_address")
    var business_address: String? = null,
    
    @SerializedName("phoneNumber")
    var business_phone_number: String? = null,
    
    var mid: String? = null,
    var partnerId: String? = null,
    var merchantId: String? = null,
    var netplusPayMid: String? = null
)
terminal_id
String
Unique terminal identifier assigned to merchant’s POS device
netplus_id
String
Storm ID - unique identifier in NetPlus ecosystem (formerly stormId)
mid
String
Merchant ID for transaction processing
partnerId
String
Partner identifier for white-label configurations
availableBalance
String
Merchant’s available wallet balance (string to preserve decimal precision)
qRRegistered
Boolean
Whether merchant is registered for QR code payments

Authentication Models

AppLoginResponse

model/AppLoginResponse.kt:3
data class AppLoginResponse(
    val data: DataXX,
    val success: Boolean,
    val token: String
)
  • success: Boolean indicating authentication status
  • token: JWT token for authenticated API requests
  • data: Additional user data payload

TokenResp

model/User.kt:52
data class TokenResp(
    val success: Boolean, 
    val token: String
)
Simplified token response for app-level authentication.

Transaction Models

TransactionResponse

Core transaction entity from NIBSS EPMS library:

TransactionType Enum

enum class TransactionType {
    PURCHASE,
    REFUND,
    REVERSAL,
    PRE_AUTHORIZATION,
    PRE_AUTHORIZATION_COMPLETION,
    BALANCE_INQUIRY,
    CASH_ADVANCE
}

IsoAccountType Enum

enum class IsoAccountType {
    DEFAULT_UNSPECIFIED,
    SAVINGS,
    CURRENT,
    CREDIT,
    UNIVERSAL,
    INVESTMENT
}

Payment Models

Pay-by-Transfer Models

data class GetPayByTransferUserAccount(
    val accountName: String?,
    val accountNumber: String?,
    val bankName: String?,
    val terminalId: String?
)

QR Payment Models

model/PayWithQrRequest.kt
data class PayWithQrRequest(
    val qrCode: String,
    val amount: Double,
    val merchantId: String,
    val terminalId: String
)

Checkout Models

data class CheckOutModel(
    val amount: String,
    val merchantId: String,
    val terminalId: String,
    val currency: String = "NGN",
    val customerEmail: String?,
    val customerPhone: String?
)

MQTT Event Models

MqttEvent

Generic event wrapper for MQTT telemetry:
model/MqttEvent.kt:53
data class MqttEvent<T>(
    var storm_id: String? = null,
    var business_name: String? = null,
    var terminalId: String? = null,
    @SerializedName("serial_number") var deviceSerial: String? = null,
    @Ignore var data: T? = null,
    var event: String? = null,
    var status: String? = null,
    var code: String? = null,
    var timestamp: Long? = null,
    var geo: String? = null,
    var transactionType: String? = null
) {
    init {
        val user = Singletons.getCurrentlyLoggedInUser()
        storm_id = user?.netplus_id
        business_name = user?.business_name
        terminalId = NetPosTerminalConfig.getTerminalId()
        deviceSerial = NetPosSdk.getDeviceSerial()
    }
}

MqttEvents Enum

model/MqttEvent.kt:11
enum class MqttEvents(val event: String?) {
    AUTHENTICATION("AUTHENTICATION"),
    TERMINAL_CONFIGURATION("TERMINAL_CONFIGURATION"),
    TRANSACTIONS("TRANSACTION"),
    PRINTING_RECEIPT("PRINTING_RECEIPT"),
    NIP_PULL("BANK_TRANSFER"),
    NIP_NEW("GENERATE_SESSION_CODE"),
    NIP_SEARCH("VERIFY_SESSION_CODE"),
    CARD_READER_EVENTS("CARD_READER_EVENTS"),
    POWER_EVENTS("POWER_EVENTS"),
    BATTERY_EVENTS("BATTERY_EVENTS"),
    SMS_EVENTS("SMS_EVENTS")
}

Event Data Models

data class AuthenticationEventData(
    val business_name: String,
    val storm_id: String,
    @SerializedName("serial_number") val deviceSerial: String
)

data class PrinterEventData(
    val transactionRef: String, 
    val printerCode: String
)

data class BatteryEvents(
    val battery_percentage: Int, 
    val status: String
)

data class CardReaderMqttEvent(
    val cardExpiry: String? = null,
    val cardHolder: String? = null,
    val maskedPan: String? = null,
    val readerError: String? = null
)

data class SMSEvent(
    val to: String, 
    val status: String, 
    var serverResponse: String
)

Notification Models

NipNotification

NIBSS Instant Payment (NIP) notification:
data class NipNotification(
    val referenceNo: String,
    val sessionCode: String?,
    val amount: Double,
    val senderName: String?,
    val senderAccount: String?,
    val narration: String?,
    val timestamp: String?
)

PayWithCardNotificationModelResponse

Card payment notification from gateway:
data class PayWithCardNotificationModelResponse(
    val transactionRef: String,
    val amount: String,
    val responseCode: String,
    val responseMessage: String,
    val timestamp: String
)

End-of-Day Models

model/GetEndOfDayModelFromNewServer.kt
data class GetEndOfDayModelFromNewServer(
    val transactions: List<GetEodFromNewServiceModel>,
    val totalPages: Int,
    val currentPage: Int,
    val totalRecords: Int
)

data class GetEodFromNewServiceModel(
    val terminalId: String,
    val from: String,
    val to: String,
    val page: Int,
    val pageSize: Int
)

QR Code Models

Zenith QR Models

data class ZenithQr(
    val qrCode: String,
    val message: String?
)

NIBSS QR Models

model/NibssQRResponse.kt
data class NibssQRResponse(
    val returnCode: String?,
    val codeUrl: String?,
    val orderNo: String?
)

Merchant Models

MerchantDetailsResponse

model/MerchantDetailsResponse.kt
data class MerchantDetailsResponse(
    val merchantId: String,
    val merchantName: String,
    val merchantAddress: String?,
    val merchantPhone: String?,
    val merchantEmail: String?,
    val accountNumber: String?,
    val bankName: String?
)

MerchantCategory

data class MerchantCategory(
    val merchantCategoryCode: String,
    val merchantCategoryDescription: String
)

Logging Models

Transaction Logging

data class TransactionToLogBeforeConnectingToNibbs(
    val terminalId: String,
    val amount: Long,
    val transactionType: String,
    val timestamp: Long
)

Feedback Models

model/FeedbackRequest.kt
data class FeedbackRequest(
    val terminalId: String,
    val subject: String,
    val message: String,
    val category: String,
    val userId: String
)

Constants

model/AppConstants.kt:3
object AppConstants {
    const val BASE_URL_FOR_LOGGING_TO_BACKEND = "https://device.netpluspay.com/"
    const val APP_DB_NAME = "netpos-db"
    const val ISW_TOKEN = "TokenForIsw"
    const val FIREBASE_TOPIC_UPDATE = "UpdateYourApp"
    const val PAYMENT_WITH_QR_STRING = "Payment_with_qr_string"
}

Model Validation

// Email validation
if (!Patterns.EMAIL_ADDRESS.matcher(username).matches()) {
    throw ValidationException("Invalid email")
}

// BVN validation
if (payload.bvn.isNullOrEmpty() || payload.bvn!!.length < 11) {
    throw ValidationException("Invalid BVN")
}

// Amount validation
if (amount <= 0.0) {
    throw ValidationException("Amount must be greater than zero")
}

Serialization Notes

All models use Gson for JSON serialization with these annotations:
  • @SerializedName: Map JSON field names
  • @Ignore: Exclude fields from serialization
  • @Expose: Explicitly include fields (when using excludeFieldsWithoutExposeAnnotation())

Best Practices

Use data classes

Kotlin data classes provide automatic equals(), hashCode(), and toString()

Nullable safety

Use nullable types (String?) for optional API fields

Default values

Provide sensible defaults for optional fields (e.g., availableBalance = "0.00")

Immutability

Prefer val over var for immutable fields

Database Schema

See how models are persisted

Services

API services using these models

ViewModels

Business logic with models

Build docs developers (and LLMs) love