Skip to main content

Upload Shift Information (T163)

Upload shift closing data from Electronic Dispensing Controllers (EDC) to the EFRIS system. This endpoint records start/end volumes, sales amounts, and operational details for specific fuel pumps, nozzles, and tanks at the end of a shift. Request is encrypted; response is unencrypted.


Endpoint Overview

PropertyValue
Interface CodeT163
Request Encrypted✅ Yes
Response Encrypted❌ No
Request Body{ "shiftNo": "...", "startVolume": "...", ... }
Response FormatJSON (Standard Envelope)

Flow Description

  1. Client collects shift data from EDC controller (start/end meter readings, sales totals).
  2. Client submits shift information via T163 with encrypted payload.
  3. Server validates shift data against registered pump/nozzle/tank configurations.
  4. Server records shift data for reconciliation with uploaded invoices (T167).
  5. Client receives confirmation (null content on success).

💡 Tip: Call T163 at the end of each operator shift. Ensure startVolume matches the previous shift's endVolume for continuity. Use T162 to validate fuelType values before submission.


try {
// Call T163: Upload Shift Information
$shiftData = [
'shiftNo' => '20250219-01',
'startVolume' => '851.91',
'endVolume' => '951.91',
'fuelType' => 'Kerosene',
'goodsId' => '12344',
'goodsCode' => 'Kerosene_01',
'invoiceAmount' => '221.31',
'invoiceNumber' => '16',
'nozzleNo' => 'nozzle_01_0001',
'pumpNo' => 'pump_01_0001',
'tankNo' => 'tank_01_0001',
'userName' => 'Kerwin',
'userCode' => 'kerwin0001',
'startTime' => '2025-02-19 10:59:14',
'endTime' => '2025-02-19 18:59:14'
];

$response = $client->uploadShiftInfo($shiftData);

// Response content is typically null/empty on success
echo "✅ Shift information uploaded successfully\n";
echo " Shift No: {$shiftData['shiftNo']}\n";
echo " Fuel Type: {$shiftData['fuelType']}\n";
echo " Volume Sold: " . ($shiftData['endVolume'] - $shiftData['startVolume']) . "\n";

} catch (\UraEfrisSdk\Exceptions\APIException $e) {
echo "❌ Upload failed: " . $e->getMessage() . "\n";
echo " Return Code: " . $e->getReturnCode() . "\n";
}

Request Structure

{
"data": {
"content": "BASE64_ENCRYPTED_PAYLOAD",
"signature": "JKQWJK34K32JJEK2JQWJ5678",
"dataDescription": {
"codeType": "1",
"encryptCode": "2",
"zipCode": "0"
}
},
"globalInfo": {
"interfaceCode": "T163",
"appId": "AP04",
"version": "1.1.20191201",
"tin": "1000029771",
"deviceNo": "TCS9e0df01728335239",
"taxpayerID": "1"
}
}

Request Fields (Encrypted Payload)

FieldRequiredTypeLengthDescription
shiftNo✅ YesString≤20Unique shift identifier (e.g., YYYYMMDD-01)
startVolume✅ YesNumber-Meter reading at shift start (integer ≤12, decimal ≤2)
endVolume✅ YesNumber-Meter reading at shift end (integer ≤12, decimal ≤2)
fuelType✅ YesString≤200Fuel type name (must match T162 fuel types)
goodsId✅ YesString≤18Goods ID linked to fuel type from T130
goodsCode✅ YesString≤50Goods code linked to fuel type from T130
invoiceAmount✅ YesNumber-Total sales amount for the shift (integer ≤12, decimal ≤2)
invoiceNumber✅ YesNumber≤50Count of invoices issued during shift
nozzleNo✅ YesString≤50Nozzle identifier from T169
pumpNo✅ YesString≤50Pump identifier from T169
tankNo✅ YesString≤50Tank identifier from T169
userName✅ YesString≤500Operator name
userCode✅ YesString≤100Operator account code
startTime✅ YesString20Shift start time (yyyy-MM-dd HH:mm:ss)
endTime✅ YesString20Shift end time (yyyy-MM-dd HH:mm:ss)

💡 Tip: Ensure endTime is greater than startTime. Volume calculations (endVolume - startVolume) should match expected sales based on invoiceAmount.


Response Structure

{
"globalInfo": {
"interfaceCode": "T163",
"returnStateInfo": {
"returnCode": "00",
"returnMessage": "SUCCESS"
}
}
}

📋 Note: On success, the data.content is typically null or empty. Validation results are returned via globalInfo.returnStateInfo.


Response Fields

Global Info

FieldRequiredTypeDescription
interfaceCode✅ YesString (5)Echoes T163
returnStateInfo✅ YesObjectContains returnCode and returnMessage

Return State Info

FieldRequiredTypeDescription
returnCode✅ YesString00 = Success, otherwise error code
returnMessage✅ YesStringHuman-readable status message

Return Codes

CodeMessageDescription
00SUCCESSShift information uploaded successfully
99Unknown errorGeneric server error
400Device does not existdeviceNo not registered for this TIN
402Device key expiredDevice credentials expired; re-run T102
403Device status is abnormalDevice blocked or suspended
2933shiftNo: cannot be empty!Missing shift number
2934shiftNo: Byte length cannot be greater than 20!Shift number exceeds length limit
2935startVolume: cannot be empty!Missing start volume
2936startVolume: The integer character length cannot exceed 12, and the decimal character length cannot exceed 2!Start volume format error
2940endVolume: cannot be empty!Missing end volume
2941endVolume: The integer character length cannot exceed 12, and the decimal character length cannot exceed 2!End volume format error
2945fuelType: cannot be empty!Missing fuel type
2946fuelType: Byte length cannot be greater than 200!Fuel type name exceeds limit
2947goodsId: cannot be empty!Missing goods ID
2948goodsId: Byte length cannot be greater than 18!Goods ID exceeds limit
2949goodsCode: cannot be empty!Missing goods code
2950goodsCode: Byte length cannot be greater than 50!Goods code exceeds limit
2951invoiceNumber: cannot be empty!Missing invoice count
2956nozzleNo: cannot be empty!Missing nozzle number
2958pumpNo: cannot be empty!Missing pump number
2960tankNo: cannot be empty!Missing tank number
2962userName: cannot be empty!Missing user name
2964userCode: cannot be empty!Missing user code
2966startTime: cannot be empty!Missing start time
2967startTime: The time format must be yyyy-MM-dd HH:mm:ssInvalid start time format
2968endTime: cannot be empty!Missing end time
2969endTime: The time format must be yyyy-MM-dd HH:mm:ssInvalid end time format
2974edcDetails-->nozzleNo: NozzleNo errorNozzle not registered/invalid
2975edcDetails-->tankNo: Does not match 'nozzleNo'Tank/nozzle mismatch
2976edcDetails-->pumpNo: Does not match 'nozzleNo'Pump/nozzle mismatch

💡 Tip: Errors 2974-2976 indicate configuration mismatches. Use T169 to verify pump/nozzle/tank relationships before uploading shift data.


Common Use Cases

  1. Shift Closing Operations
    Submit meter readings and sales totals at the end of each operator shift for reconciliation.

  2. EDC Sales Reconciliation
    Compare shift volume data with uploaded invoices (T167) to identify discrepancies or potential leakage.

  3. Operator Performance Tracking
    Track sales performance by userCode and userName across different shifts.

  4. Fuel Inventory Management
    Use startVolume/endVolume data to calculate fuel dispensed and update tank inventory levels.

  5. Audit Trail Maintenance
    Maintain historical records of shift operations for tax audits and compliance verification.

  6. Multi-Pump Station Management
    Upload shift data for multiple pumps/nozzles simultaneously (separate T163 calls per nozzle/pump combination).


Integration Checklist

✅ Validate fuelType against T162 query results before submission
✅ Ensure goodsId and goodsCode match registered fuel products from T130
✅ Verify pump/nozzle/tank relationships via T169 before uploading shift data
✅ Ensure endTime is greater than startTime to avoid validation errors
✅ Validate volume calculations (endVolumestartVolume) before submission
✅ Handle null/empty response content gracefully on success
✅ Log shift submissions for audit trails and discrepancy investigation
✅ Implement retry logic for network failures during shift closing
✅ Ensure shiftNo is unique per pump/nozzle per day
✅ Cross-reference invoiceAmount with actual invoices issued during shift