Skip to main content

Goods Upload (T130)

Register or modify goods and services in the EFRIS system. This endpoint allows taxpayers to maintain their product catalog, including pricing, tax categories, excise duty details, and units of measure. Requires encrypted request and response.


Endpoint Overview

PropertyValue
Interface CodeT130
Request Encrypted✅ Yes
Response Encrypted✅ Yes
Request BodyArray of goods objects
Response FormatArray of goods objects with status

Flow Description

  1. Client constructs an array of goods items to add or modify.
  2. Client specifies operationType (101=Add, 102=Modify).
  3. Client sends encrypted request to server.
  4. Server validates commodity categories, excise codes, and units of measure against system dictionary (T115).
  5. Server returns an array of results. Successful items may return empty messages; failed items return returnCode and returnMessage.

📦 Note: Goods must be registered before they can be included in invoices (T109) or stock operations (T131). Ensure commodityCategoryId and measureUnit match the system dictionary.


try {
// Construct goods payload
$goodsData = [
[
'operationType' => '101', // 101=Add, 102=Modify
'goodsName' => 'Test Product',
'goodsCode' => 'ITEM001',
'measureUnit' => '101', // From T115 rateUnit
'unitPrice' => '1000.00',
'currency' => '101', // From T115 currencyType
'commodityCategoryId' => '10111301',
'haveExciseTax' => '102', // 101=Yes, 102=No
'description' => 'Test product for integration',
'stockPrewarning' => '10',
'havePieceUnit' => '102', // 101=Yes, 102=No
'haveOtherUnit' => '102', // 101=Yes, 102=No
'goodsTypeCode' => '101', // 101=Goods, 102=Fuel
'haveCustomsUnit' => '102' // 101=Yes, 102=No
]
];

// Call T130: Upload Goods
$response = $client->uploadGoods($goodsData);

$results = $response['data']['content'] ?? $response;

if (is_array($results)) {
foreach ($results as $index => $result) {
$code = $result['returnCode'] ?? '00';
$msg = $result['returnMessage'] ?? 'SUCCESS';

if ($code === '00' || empty($code)) {
echo "✅ Goods #{$index} uploaded successfully\n";
} else {
echo "❌ Goods #{$index} failed: {$code} - {$msg}\n";
}
}
}

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

Request Structure

[
{
"operationType": "101",
"goodsName": "Test Product",
"goodsCode": "ITEM001",
"measureUnit": "101",
"unitPrice": "1000.00",
"currency": "101",
"commodityCategoryId": "10111301",
"haveExciseTax": "102",
"description": "Test product",
"stockPrewarning": "10",
"havePieceUnit": "102",
"pieceMeasureUnit": "",
"pieceUnitPrice": "",
"packageScaledValue": "",
"pieceScaledValue": "",
"exciseDutyCode": "",
"haveOtherUnit": "102",
"goodsTypeCode": "101",
"haveCustomsUnit": "102",
"commodityGoodsExtendEntity": {
"customsMeasureUnit": "",
"customsUnitPrice": "",
"packageScaledValueCustoms": "",
"customsScaledValue": ""
},
"customsUnitList": [],
"goodsOtherUnits": []
}
]

Response Structure

[
{
"operationType": "101",
"goodsName": "Test Product",
"goodsCode": "ITEM001",
"measureUnit": "101",
"unitPrice": "1000.00",
"currency": "101",
"commodityCategoryId": "10111301",
"haveExciseTax": "102",
"description": "Test product",
"stockPrewarning": "10",
"havePieceUnit": "102",
"haveOtherUnit": "102",
"goodsTypeCode": "101",
"haveCustomsUnit": "102",
"returnCode": "00",
"returnMessage": "SUCCESS"
}
]

Field Descriptions

Basic Goods Information

FieldRequiredTypeDescription
operationType❌ NoString (3)101=Add goods (default), 102=Modify product
goodsName✅ YesString (200)Product name. Cannot be empty.
goodsCode✅ YesString (50)Product code. Cannot be empty. Must be unique.
measureUnit✅ YesString (3)Unit of measure from T115 rateUnit (e.g., 101=per stick)
unitPrice✅ YesNumberUnit price. Integer ≤12 digits, Decimal ≤8 digits. Can be empty for services.
currency✅ YesString (3)Currency from T115 currencyType (e.g., 101=UGX)
commodityCategoryId✅ YesString (18)Commodity category ID from T115/T123. Must be a leaf node.
haveExciseTax✅ YesString (3)101=Yes, 102=No
description❌ NoString (1024)Product description
stockPrewarning✅ YesNumberStock warning threshold. Integer ≤12 digits. Can be zero. Empty for services.
goodsTypeCode❌ NoString (3)101=Goods (default), 102=Fuel

Piece Unit Configuration (If havePieceUnit = 101)

FieldRequiredTypeDescription
havePieceUnit✅ YesString (3)101=Yes, 102=No. If haveExciseTax=101 and excise has unit, must be 101.
pieceMeasureUnit⚠️ ConditionalString (3)Required if havePieceUnit=101. From T115 rateUnit.
pieceUnitPrice⚠️ ConditionalNumberRequired if havePieceUnit=101. Integer ≤12, Decimal ≤8.
packageScaledValue⚠️ ConditionalNumberRequired if havePieceUnit=101. If measureUnit = excise unit, must be 1.
pieceScaledValue⚠️ ConditionalNumberRequired if havePieceUnit=101. If measureUnit = excise unit, must be 1.

Excise Duty Configuration (If haveExciseTax = 101)

FieldRequiredTypeDescription
exciseDutyCode⚠️ ConditionalString (20)Required if haveExciseTax=101. Must be valid leaf node from T125.

Other Unit Configuration (If haveOtherUnit = 101)

FieldRequiredTypeDescription
haveOtherUnit❌ NoString (3)101=Yes, 102=No. If havePieceUnit=102, must be 102.
goodsOtherUnits⚠️ ConditionalArrayRequired if haveOtherUnit=101. Cannot contain duplicate units.

goodsOtherUnits Array Fields

FieldRequiredTypeDescription
otherUnit✅ YesString (3)From T115 rateUnit. Cannot equal measureUnit or pieceMeasureUnit.
otherPrice❌ NoNumberPrice for this unit.
otherScaled✅ YesNumberConversion scale. Integer ≤12, Decimal ≤8.
packageScaled✅ YesNumberPackage scale. Integer ≤12, Decimal ≤8.

Customs Unit Configuration (If haveCustomsUnit = 101)

FieldRequiredTypeDescription
haveCustomsUnit✅ YesString (3)101=Yes, 102=No
commodityGoodsExtendEntity⚠️ ConditionalObjectRequired if haveCustomsUnit=101.
customsUnitList⚠️ ConditionalArrayRequired if haveCustomsUnit=101.

commodityGoodsExtendEntity Fields

FieldRequiredTypeDescription
customsMeasureUnit✅ YesString (3)From T115 exportRateUnit.
customsUnitPrice✅ YesNumberInteger ≤12, Decimal ≤8.
packageScaledValueCustoms✅ YesNumberInteger ≤12, Decimal ≤8.
customsScaledValue✅ YesNumberInteger ≤12, Decimal ≤8.

Return Codes (T130 Specific)

CodeMessageDescription
00SUCCESSGoods uploaded successfully
99Unknown errorGeneric server error
600GoodsCode cannot be emptyMissing goods code
601GoodsCode cannot be greater than 50!Goods code too long
602goodsCode already existsDuplicate goods code (for Add operation)
603GoodsName cannot be emptyMissing goods name
605Measureunit cannot be emptyMissing unit of measure
606measureUnit:Invalid field valueUnit not found in dictionary
614commodityCategoryId:Cannot be empty!Missing category ID
617commodityCategoryId: commodity category has been deleted!Invalid category
619commodityCategoryId: commodity category is not a leaf node!Must select lowest level category
620haveExciseTax:Cannot be emptyMissing excise flag
670haveExciseTax is '102', exciseDutyCode must be empty!Conflict between flags
671exciseDutyCode: haveExciseTax is '101', exciseDutyCode cannot be empty!Missing excise code
682This product is a 'service' product, cannot operate inventory!Service items cannot have stock
684product does not exist!Product not found (for Modify operation)
3341If 'haveCustomsUnit' is '101', commodityGoodsExtendEntity... cannot be empty!Missing customs entity
3342If 'haveCustomsUnit' is '101', please use the measurement unit accepted by customs...Invalid customs unit

💡 Tip: Always fetch the latest system dictionary (T115) before uploading goods to ensure measureUnit, currency, and commodityCategoryId values are valid.


Common Use Cases

  1. Product Catalog Setup
    Register all sellable items before issuing invoices. Required for stock-managed goods.

  2. Excise Duty Configuration
    Configure excisable products (e.g., alcohol, fuel) with correct duty codes and units.

  3. Multi-Unit Pricing
    Define secondary units (e.g., sell by piece vs. by box) using goodsOtherUnits.

  4. Export Goods Setup
    Configure customs units of measure for export invoices using haveCustomsUnit.

  5. Price Updates
    Use operationType=102 to modify unit prices or stock warnings for existing goods.