Introduction
The iSale Offline Module is a two-component system that runs on the client's local machine. It enables sales fiscalization via KRA's eTIMS even when internet connectivity is intermittent, while syncing fiscalized records to the central iSale server when online.
| Component | Port | Description |
|---|---|---|
iSale Client Serverisale-jar-*.jar | :9090 | Your POS/ERP talks to this. Handles sales, credit notes, local storage, and sync. |
KRA VSCU JARvscu-v*.jar | :8088 | Fiscalizes transactions with KRA eTIMS. Must run alongside the iSale server. |
Architecture
┌─────────────┐ HTTP :9090 ┌──────────────────┐ HTTP :8088 ┌─────────────┐ ┌─────┐
│ POS / ERP │ ──────────────► │ iSale JAR │ ─────────────► │ VSCU JAR │──►│ KRA │
│ │ /sales │ │ fiscalize │ (local) │ │ │
│ │ /credit │ │ └─────────────┘ └─────┘
└─────────────┘ └────────┬─────────┘
│ when online
▼
┌──────────────────┐
│ iSale Cloud │
│ POST /sync
└──────────────────┘Data flow
- →POS submits a sale to http://localhost:9090/sales
- →iSale JAR fiscalizes via VSCU JAR at http://localhost:8088
- →Fiscalized record is queued for online sync
- →When internet is available, records sync to iSale Cloud automatically
- →On login, the sales invoice counter is synced from the online server
Setup & Requirements
Prerequisites
| Java | Version 17 or higher |
| Operating System | Windows, Linux, or macOS |
| Internet | Required for first login and periodic sync (min. 1 hour per 24 hours) |
1. Verify Java 17+ is installed:
java -version2. Both JAR files must be running before accepting API calls. See Starting the Services.
3. Perform at least one online login to cache credentials and sync the invoice counter before going offline.
Connectivity Rules
| Condition | Behavior |
|---|---|
| Online | Login, sales, credits, and sync all work normally |
| Offline (within 36h) | Sales and credit notes accepted; queued for later sync |
| Offline (beyond 36h) | LOCKED — new sales and credits are rejected |
| Reconnected | Sync runs automatically; lock lifts after successful sync |
Authentication
/auth/loginAuthenticates against the online iSale Admin server. On success, the token is cached locally and the sales invoice counter is synced from the server.
Base URL
http://localhost:9090/auth/loginRequest body
{
"pin": "P051638337P",
"username": "YourUsername",
"password": "yourpassword",
"platform": "web"
}Response
Returns access_token (Bearer JWT). Include in the Authorization header for all subsequent requests.
{
"access_token": "eyJhbGciOiJIUzI1NiJ9...",
"source": "online",
"counterSync": {
"status": true,
"counter": 207782,
"nextInvcNo": 207783
}
}cURL
curl --location 'http://localhost:9090/auth/login' \
--header 'Content-Type: application/json' \
--data '{
"pin": "P051638337P",
"username": "YourUsername",
"password": "yourpassword",
"platform": "web"
}'Sales
/salesSubmits a sale for fiscalization. The record is saved locally and fiscalized via the VSCU JAR. Invoice number is assigned automatically from the local counter (synced on login). If online, the record is queued for sync to iSale Admin.
Headers
| Content-Type | application/json |
| Authorization | Bearer <access_token> |
Key fields
| Field | Description |
|---|---|
| trdInvcNo | Your internal invoice reference (must be unique per business) |
| custTin / custNm | Customer KRA PIN and name |
| salesDt | Sale date — YYYYMMDD |
| cfmDt | Confirmation datetime — YYYYMMDDHHmmss |
| pmtTyCd | Payment type (01 = cash) |
| itemList | Line items — submitted as-is, no local catalog lookup required |
| receipt | Optional receipt block; defaults applied if omitted |
cURL
curl --location 'http://localhost:9090/sales' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your_token>' \
--data '{
"trdInvcNo": "1003u",
"custTin": "P051123223G",
"custNm": "NAIVAS LIMITED",
"custTel": "",
"cfmDt": "20260622103000",
"salesDt": "20260622",
"stockRlsDt": "20260622103000",
"totItemCnt": 1,
"taxblAmtA": 0,
"taxblAmtB": 24137.96,
"taxblAmtC": 0,
"taxblAmtD": 0,
"taxblAmtE": 0,
"taxAmtA": 0,
"taxAmtB": 3862.07,
"taxAmtC": 0,
"taxAmtD": 0,
"taxAmtE": 0,
"taxRtA": 0,
"taxRtB": 16,
"taxRtC": 0,
"taxRtD": 0,
"taxRtE": 0,
"totTaxblAmt": 24137.96,
"totTaxAmt": 3862.07,
"totAmt": 28000.03,
"remark": "Sale",
"prchrAcptcYn": "N",
"pmtTyCd": "01",
"itemList": [
{
"itemSeq": 1,
"itemCd": "KE2NTU0152",
"itemClsCd": "31162800",
"itemNm": "Misc Hardware Stock Clearance - granito floor tiles 500x500",
"qtyUnitCd": "U",
"pkgUnitCd": "NT",
"dcRt": 0,
"dcAmt": 0,
"pkg": "1",
"qty": 14,
"prc": 1724.14,
"splyAmt": 24137.96,
"taxTyCd": "B",
"taxblAmt": 24137.96,
"taxAmt": 3862.07,
"totAmt": 28000.03,
"itemId": 219140
}
],
"receipt": {
"custTin": "P051123223G",
"custMblNo": "",
"custEmail": "",
"rcptPbctDt": "20260622",
"trdeNm": "NAIVAS LIMITED",
"adrs": "",
"topMsg": "iSale POS",
"btmMsg": "Stanbestgroup Ltd",
"prchrAcptcYn": "N"
}
}'Credit Notes
/creditCreates a credit note against an existing fiscalized invoice. Stored locally, fiscalized via VSCU, synced when online.
orgInvcNo referencing the original invoice being credited.Sync & Status
/syncManually triggers sync of all pending fiscalized records to iSale Admin. Also runs automatically every 5 minutes when online.
curl --location --request POST 'http://localhost:9090/sync' \
--header 'Authorization: Bearer <your_token>'/sync/statusReturns transmission lock status and last successful sync timestamp.
curl --location 'http://localhost:9090/sync/status' \
--header 'Authorization: Bearer <your_token>'{
"locked": false,
"lastSuccessfulSyncAt": "2026-06-25T14:30:00Z",
"hoursSinceLastSync": 2
}/healthHealth check — confirms iSale JAR is running.
curl --location 'http://localhost:9090/health'Errors
Transmission lock
Returned when no sync succeeded in over 36 hours:
{
"status": false,
"code": "TRANSMISSION_LOCKED",
"message": "Transmission locked: no successful online sync in the last 36 hours."
}Fix: Restore internet connectivity. The lock lifts automatically after a successful sync.
Common errors
| Code | Meaning | Action |
|---|---|---|
| TRANSMISSION_LOCKED | No sync in 36+ hours | Connect to internet |
| 401 Unauthorized | Missing or expired token | Re-authenticate via /auth/login |
| 924 (KRA) | Invoice number already used | Counter auto-retries; re-login to sync counter |
| VSCU unavailable | VSCU JAR not running | Start VSCU JAR first |
File Directories
| Path | Contents |
|---|---|
| C:\etims\ | iSale JAR, run.bat, run.sh, config, data, logs |
| C:\etims\vscu\ | VSCU JAR, vscu.bat, run.sh |
| C:\etims\data\ | Local H2 database (isale-local.mv.db) |
| C:\etims\logs\ | Application logs (isale-jar.log, sales.log) |
| C:\etims\config\ | application.properties and profile secrets |
Starting the Services
Windows
Step 1 — Start VSCU JAR (port 8088):
cd C:\etims\vscu
vscu.batStep 2 — Start iSale JAR (port 9090):
cd C:\etims
run.batLinux / macOS
cd /opt/etims/vscu
./run.shcd /opt/etims
./run.shVerify both are running
curl --location 'http://localhost:9090/health'
curl --location 'http://localhost:8088/health'