Documentation Index
Fetch the complete documentation index at: https://mintlify.com/netplusTeam/NetPOS/llms.txt
Use this file to discover all available pages before exploring further.
The NetPOS REST API provides HTTP endpoints for user authentication, transaction management, terminal configuration, and data retrieval.
Base URLs
NetPOS uses multiple API base URLs for different services:
| Service | Base URL | Description |
|---|
| Main API | https://netpos.netpluspay.com/ | Core POS operations |
| Bills/Storm | https://storm.netpluspay.com/ | Bill payments and Storm services |
| Cash Service | https://netpos.netpluspay.com/api/cash/ | Cash transaction tracking |
| Zenith PBT | https://api.zenith-pbt.netpluspay.com/ | Zenith Pay-by-Transfer |
| QR Payments | https://masterpassqr.netpluspay.com/api/v1/ | QR payment processing |
| SMS Service | https://sms.netpluspay.com | SMS notifications |
Authentication
App Token
Obtain application-level authentication token:
import com.google.gson.JsonObject
import com.woleapp.netpos.network.StormApiClient
val credentials = JsonObject().apply {
addProperty("client_id", "your_client_id")
addProperty("client_secret", "your_client_secret")
}
StormApiClient.getBillsInstance()
.appToken(credentials)
.subscribe { response, error ->
response?.let {
val token = it.token
// Store token for subsequent requests
}
}
Endpoint: POST /api/token
Request Body:
Application client secret
Response:
Token expiration time in seconds
User Authentication
Authenticate a user and obtain user token:
val credentials = JsonObject().apply {
addProperty("username", "user@example.com")
addProperty("password", "password123")
addProperty("terminal_id", "2058XU23")
}
StormApiClient.getBillsInstance()
.userToken(credentials)
.subscribe { response, error ->
response?.let {
val userToken = it.token
val user = it.user
// Store user session
}
}
Endpoint: POST /api/auth
Request Body:
Terminal ID for this session
Response:
User profile data including terminal_id, business_name, netplus_id
Transactions
Log Transaction (Before NIBSS)
Log transaction details before connecting to NIBSS:
val transactionData = TransactionToLogBeforeConnectingToNibbs(
terminalId = "2058XU23",
amount = "500000", // Amount in kobo
stan = "000123",
rrn = "202112011234567",
cardPan = "506066******1234",
cardExpiry = "12/25",
timestamp = System.currentTimeMillis()
)
StormApiClient.getStormApiLoginInstance()
.logTransactionBeforeConnectingToNibss(transactionData)
.subscribe { response, error ->
response?.let {
val transactionId = it.id
}
}
Endpoint: POST /pos_transaction
Headers:
Bearer token from user authentication
Request Body:
Transaction amount in kobo (minor units)
System Trace Audit Number
Retrieval Reference Number
Update Transaction (After NIBSS)
Update transaction with response from NIBSS:
val rrn = "202112011234567"
val updateData = DataToLogAfterConnectingToNibss(
responseCode = "00",
responseMessage = "Approved",
authCode = "123456",
isoString = "0200...",
responseTime = System.currentTimeMillis()
)
StormApiClient.getStormApiLoginInstance()
.updateLogAfterConnectingToNibss(rrn, updateData)
.subscribe { response, error ->
response?.let {
// Transaction updated
}
}
Endpoint: PUT /pos_transaction/{rrn}
Path Parameters:
Retrieval Reference Number from initial transaction log
Request Body:
ISO 8583 response code (“00” for approved)
Human-readable response message
Authorization code from issuer
Full ISO 8583 message for audit
Get Transactions
Retrieve transactions by terminal and date range:
val terminalId = "2058XU23"
val from = "2021-12-01 00:00:00"
val to = "2021-12-31 23:59:59"
val page = 1
val pageSize = 50
StormApiClient.getStormApiLoginInstance()
.getTransactionsFromNewService(terminalId, from, to, page, pageSize)
.subscribe { response, error ->
response?.let {
val transactions = it.data
val totalPages = it.totalPages
}
}
Endpoint: GET /pos_transactions/terminal/{terminalId}/btw/{from}/{to}/{page}/{pageSize}
Path Parameters:
Start date (format: YYYY-MM-DD HH:mm:ss)
End date (format: YYYY-MM-DD HH:mm:ss)
Number of records per page
Response:
Array of transaction objects
Agent Management
Get Agent Details
val stormId = "AGT123456"
StormApiClient.getInstance()
.getAgentDetails(stormId)
.subscribe { user, error ->
user?.let {
val terminalId = it.terminal_id
val businessName = it.business_name
}
}
Endpoint: GET /api/agents/{stormId}
Path Parameters:
Response:
NIP (Bank Transfer)
Get NIP Notifications
Retrieve NIP transfer notifications:
val terminalId = "2058XU23"
val from = "2021-12-01"
val to = "2021-12-31"
val clientId = "85522f45-e459-4548-8b20-3a922196c515"
val accessCode = "a14014e18e2cffc4d74e150ed68a472bd94189db82d374306d5b307dc7620f20"
StormApiClient.getInstance()
.getNotifications(terminalId, from, to, clientId, accessCode)
.subscribe { notifications, error ->
notifications?.let {
it.forEach { notification ->
val amount = notification.amount
val reference = notification.referenceNo
}
}
}
Endpoint: GET /api/nip-notifications
Headers:
Query Parameters:
Specific transaction reference (alternative to date range)
Get Session Code
Generate session code for NIP transfers:
StormApiClient.getNipInstance()
.getSessionCode()
.subscribe { sessionCode, error ->
sessionCode?.let {
val code = it.code
val expiresAt = it.expiresAt
}
}
Endpoint: GET /api/sessionCode
Response:
Cash Transactions
Add Cash Transaction
val cashTransaction = JsonObject().apply {
addProperty("terminalId", "2058XU23")
addProperty("amount", 50000) // In kobo
addProperty("type", "CASH_IN")
addProperty("reference", "CASH202112011234")
addProperty("timestamp", System.currentTimeMillis())
}
StormApiClient.getCashInstance()
.addCashTransaction(cashTransaction)
.subscribe { response, error ->
response?.let {
// Cash transaction logged
}
}
Endpoint: POST /addTransactions
Request Body:
Transaction type: CASH_IN or CASH_OUT
Unique transaction reference
QR Payments
Pay with QR
val qrPaymentRequest = PayWithQrRequest(
qrData = "scanned_qr_code_data",
amount = 500000, // In kobo
terminalId = "2058XU23"
)
val qrService = Retrofit.Builder()
.baseUrl("https://masterpassqr.netpluspay.com/api/v1/")
.build()
.create(QrPaymentService::class.java)
qrService.payWithQr(qrPaymentRequest)
.subscribe { response, error ->
response?.let {
if (it.isSuccessful) {
// Payment successful
}
}
}
Endpoint: POST /contactlessQr
Request Body:
Password Management
Reset Password
val resetPayload = JsonObject().apply {
addProperty("email", "user@example.com")
addProperty("terminal_id", "2058XU23")
}
StormApiClient.getBillsInstance()
.passwordReset(resetPayload)
.subscribe { response, error ->
response?.let {
// Password reset email sent
}
}
Endpoint: POST /api/passwordReset
Request Body:
API Client Configuration
NetPOS uses Retrofit with custom interceptors:
private fun getOkHttpClient() =
OkHttpClient.Builder()
.addInterceptor(TokenInterceptor())
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.connectTimeout(120, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build()
class TokenInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val headersInReq = request.headers
if (headersInReq["Authorization"].isNullOrEmpty()) {
Prefs.getString(PREF_USER_TOKEN, null)?.let {
request = request.newBuilder()
.addHeader("Authorization", "Bearer $it")
.build()
}
}
return chain.proceed(request)
}
}
Error Handling
API errors follow standard HTTP status codes:
| Status Code | Meaning |
|---|
| 200 | Success |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or expired token |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Resource doesn’t exist |
| 500 | Internal Server Error |
Next Steps
Webhooks
Set up webhook notifications for real-time events