Skip to main content

Invoice Upload (T109)

Upload fiscal documents (Invoices, Receipts, Debit Notes, Credit Memos) to the EFRIS server. This is the core endpoint for issuing tax-compliant documents. Requires encrypted request and response.


Endpoint Overview

PropertyValue
Interface CodeT109
Request Encrypted✅ Yes
Response Encrypted✅ Yes
Request BodyFull invoice structure
Response FormatJSON (with server-generated fields)

Flow Description

  1. Client constructs invoice payload (Seller, Buyer, Goods, Tax, Summary).
  2. Client calculates totals (Net, Tax, Gross) ensuring mathematical consistency.
  3. Client sends encrypted request via T109.
  4. Server validates TINs, commodity codes, tax calculations, and stock availability.
  5. Server returns signed invoice with invoiceNo, antifakeCode, and qrCode.
  6. Client stores response for records and prints QR code on receipt.

⚠️ Critical: Ensure summary totals match the sum of taxDetails, and taxDetails match the sum of goodsDetails. Mismatches will result in rejection.


try {
// Construct invoice payload
$invoiceData = [
'sellerDetails' => [
'tin' => $config['tin'],
'legalName' => 'Your Company Ltd',
'businessName' => 'Your Brand',
'address' => 'Plot 123, Kampala',
'mobilePhone' => '0772140000',
'emailAddress' => 'accounts@yourcompany.com',
'placeOfBusiness' => 'Kampala',
'referenceNo' => 'REF-' . time(),
'isCheckReferenceNo' => '0'
],
'basicInformation' => [
'deviceNo' => $config['device_no'],
'issuedDate' => date('Y-m-d H:i:s'),
'operator' => 'Cashier 01',
'currency' => 'UGX',
'invoiceType' => '1', // 1=Invoice, 2=Credit Note, 4=Debit Note
'invoiceKind' => '1', // 1=Invoice, 2=Receipt
'dataSource' => '103', // 103=WebService API
'invoiceIndustryCode' => '101' // 101=General Industry
],
'buyerDetails' => [
'buyerTin' => '1000029771',
'buyerLegalName' => 'Customer Name',
'buyerBusinessName' => 'Customer Biz',
'buyerAddress' => 'Customer Address',
'buyerEmail' => 'customer@example.com',
'buyerMobilePhone' => '0772999999',
'buyerType' => '0', // 0=B2B, 1=B2C, 2=Foreigner
'buyerCitizenship' => 'UG-Uganda',
'buyerSector' => 'Private'
],
'goodsDetails' => [
[
'item' => 'Test Product',
'itemCode' => 'ITEM001',
'qty' => '1',
'unitOfMeasure' => '101', // From T115
'unitPrice' => '1000.00',
'total' => '1000.00',
'taxRate' => '0.18',
'tax' => '180.00',
'goodsCategoryId' => '100000000',
'vatApplicableFlag' => '1',
'discountFlag' => '2', // 2=Non-discount
'deemedFlag' => '2',
'exciseFlag' => '2'
]
],
'taxDetails' => [
[
'taxCategoryCode' => '01', // 01=Standard 18%
'netAmount' => '1000.00',
'taxRate' => '0.18',
'taxAmount' => '180.00',
'grossAmount' => '1180.00',
'taxRateName' => 'Standard'
]
],
'summary' => [
'netAmount' => '1000.00',
'taxAmount' => '180.00',
'grossAmount' => '1180.00',
'itemCount' => 1,
'modeCode' => '1', // 1=Online, 0=Offline
'remarks' => 'Test invoice'
],
'payWay' => [
[
'paymentMode' => '102', // 102=Cash
'paymentAmount' => '1180.00',
'orderNumber' => 'a'
]
]
];

// Call T109: Upload Invoice
$response = $client->fiscaliseInvoice($invoiceData);

$content = $response['data']['content'] ?? $response;
$invoiceNo = $content['basicInformation']['invoiceNo'] ?? null;

if ($invoiceNo) {
echo "✅ Invoice Uploaded: {$invoiceNo}\n";
echo " QR Code: {$content['summary']['qrCode']}\n";
echo " AntiFake: {$content['basicInformation']['antifakeCode']}\n";
} else {
echo "⚠️ Upload failed or missing invoice number\n";
}

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

Request Structure

{
"sellerDetails": {
"tin": "1000029771",
"legalName": "Your Company Ltd",
"businessName": "Your Brand",
"address": "Plot 123",
"mobilePhone": "0772140000",
"emailAddress": "accounts@yourcompany.com",
"placeOfBusiness": "Kampala",
"referenceNo": "REF-123456",
"isCheckReferenceNo": "0"
},
"basicInformation": {
"deviceNo": "TCS9e0df01728335239",
"issuedDate": "2025-02-19 10:00:00",
"operator": "Cashier 01",
"currency": "UGX",
"invoiceType": "1",
"invoiceKind": "1",
"dataSource": "103",
"invoiceIndustryCode": "101"
},
"buyerDetails": {
"buyerTin": "1000029771",
"buyerLegalName": "Customer Name",
"buyerBusinessName": "Customer Biz",
"buyerAddress": "Customer Address",
"buyerEmail": "customer@example.com",
"buyerMobilePhone": "0772999999",
"buyerType": "0",
"buyerCitizenship": "UG-Uganda",
"buyerSector": "Private"
},
"goodsDetails": [
{
"item": "Test Product",
"itemCode": "ITEM001",
"qty": "1",
"unitOfMeasure": "101",
"unitPrice": "1000.00",
"total": "1000.00",
"taxRate": "0.18",
"tax": "180.00",
"goodsCategoryId": "100000000",
"vatApplicableFlag": "1",
"discountFlag": "2",
"deemedFlag": "2",
"exciseFlag": "2"
}
],
"taxDetails": [
{
"taxCategoryCode": "01",
"netAmount": "1000.00",
"taxRate": "0.18",
"taxAmount": "180.00",
"grossAmount": "1180.00",
"taxRateName": "Standard"
}
],
"summary": {
"netAmount": "1000.00",
"taxAmount": "180.00",
"grossAmount": "1180.00",
"itemCount": 1,
"modeCode": "1",
"remarks": "Test invoice"
},
"payWay": [
{
"paymentMode": "102",
"paymentAmount": "1180.00",
"orderNumber": "a"
}
]
}

Response Structure

{
"basicInformation": {
"invoiceId": "1000002",
"invoiceNo": "00000000001",
"antifakeCode": "201905081711",
"deviceNo": "TCS9e0df01728335239",
"issuedDate": "19/02/2025 10:00:00",
"operator": "Cashier 01",
"currency": "UGX",
"invoiceType": "1",
"invoiceKind": "1",
"dataSource": "103"
},
"summary": {
"netAmount": "1000.00",
"taxAmount": "180.00",
"grossAmount": "1180.00",
"itemCount": 1,
"modeCode": "1",
"qrCode": "02000000416B9C322000150744000016E3600000037DCD..."
},
"sellerDetails": {
"branchName": "Head Office",
"branchCode": "01"
}
}

Field Descriptions

Seller Details

FieldRequiredTypeDescription
tin✅ YesString (10-20)Seller's TIN (must match globalInfo)
legalName✅ YesString (256)Registered legal name
businessName❌ NoString (256)Trading name
mobilePhone❌ NoString (30)Contact phone
emailAddress✅ YesString (50)Valid email format
referenceNo✅ YesString (50)Unique transaction reference
isCheckReferenceNo❌ NoString (1)0=No (default), 1=Yes (enforce uniqueness)

Basic Information

FieldRequiredTypeDescription
deviceNo✅ YesString (20)Registered device serial number
issuedDate✅ YesDateyyyy-MM-dd HH:mm:ss
operator✅ YesString (150)Cashier/operator name
currency✅ YesString (10)UGX or from T115 dictionary
invoiceType✅ YesString (1)1=Invoice/Receipt, 2=Credit Note, 4=Debit Note, 5=Credit Memo
invoiceKind✅ YesString (1)1=Invoice, 2=Receipt
dataSource✅ YesString (3)103=WebService API
modeCode✅ YesString (1)1=Online, 0=Offline (requires QR code generation client-side)

Buyer Details

FieldRequiredTypeDescription
buyerTin❌ NoString (10-20)Mandatory for B2B (buyerType=0) or B2G (buyerType=3)
buyerLegalName❌ NoString (256)Mandatory for B2B
buyerType✅ YesString (1)0=B2B, 1=B2C, 2=Foreigner, 3=B2G
buyerCitizenship❌ NoString (128)Required for Foreigner (buyerType=2)
buyerMobilePhone❌ NoString (30)Contact number

Goods Details (Array)

FieldRequiredTypeDescription
item✅ YesString (200)Product name
itemCode✅ YesString (50)Must match registered goods code
qty✅ YesNumberQuantity (must be positive for invoices)
unitPrice✅ YesNumberUnit price (excl. tax)
total✅ YesNumberqty * unitPrice (max 2 decimals)
taxRate✅ YesNumbere.g., 0.18 for 18%
tax✅ YesNumberCalculated tax amount
goodsCategoryId✅ YesString (18)From T115/T123 dictionary
vatApplicableFlag❌ NoString (1)1=Applicable, 0=Not Applicable
discountFlag✅ YesString (1)0=Discount Amount, 1=Discount Item, 2=Non-discount
exciseFlag✅ YesString (1)1=Excise, 2=Not Excise

Tax Details (Array)

FieldRequiredTypeDescription
taxCategoryCode✅ YesString (2)01=Standard, 02=Zero, 03=Exempt, 05=Excise
netAmount✅ YesNumberSum of net amounts for this tax category
taxAmount✅ YesNumberSum of tax amounts for this category
grossAmount✅ YesNumbernetAmount + taxAmount
taxRate✅ YesNumbere.g., 0.18

Summary

FieldRequiredTypeDescription
netAmount✅ YesNumberTotal net amount (must match taxDetails sum)
taxAmount✅ YesNumberTotal tax amount (must match taxDetails sum)
grossAmount✅ YesNumberTotal gross amount (must match taxDetails sum)
itemCount✅ YesNumberCount of goods lines (excluding discount lines)
modeCode✅ YesString (1)1=Online, 0=Offline
qrCode❌ NoString (500)Required if modeCode=0 (Offline)

Payment Way (Array)

FieldRequiredTypeDescription
paymentMode✅ YesString101=Credit, 102=Cash, 105=Mobile Money, etc.
paymentAmount✅ YesNumberAmount paid via this mode
orderNumber✅ YesStringSort order (e.g., 'a', 'b', 'c')

Return Codes (T109 Specific)

CodeMessageDescription
00SUCCESSInvoice uploaded successfully
1040Invoice number already existsDuplicate invoice number detected
1100sellerDetails-->tin:cannot be empty!Missing seller TIN
1102sellerDetails-->tin:The inner tin must be the same as the tin in the outer packet!TIN mismatch
1316goodsDetails-->total:Multiply the quantity by the product of the unit price...Calculation error (total != qty * price)
1342taxDetails-->:'netAmount' plus 'taxAmount' must equal 'grossAmount'!Tax calculation mismatch
1344summary-->taxAmount:Must be equal to the sum of all taxAmount's in taxDetails!Summary mismatch
1600Inventory shortageInsufficient stock for goods (if stock management enabled)
2075Invoice amount exceeds the maximum limit!Exceeds maxGrossAmount from T103
2786You cannot issue offline invoices!Offline mode disabled for this taxpayer
2821buyerDetails-->buyerTin: you don't have permission to issue deemed invoices!Missing deemed invoice permission
3088Device has been blockedContact URA

💡 Tip: Always validate calculations client-side before sending. The server strictly enforces net + tax = gross consistency across goodsDetails, taxDetails, and summary.


Common Use Cases

  1. Standard B2B Invoice
    Set buyerType=0, provide buyerTin, buyerLegalName. Use invoiceType=1, invoiceKind=1.

  2. Simplified Receipt (B2C)
    Set buyerType=1, buyerTin optional. Use invoiceKind=2 for receipt.

  3. Debit Note
    Set invoiceType=4, provide oriInvoiceId (original invoice ID). Adjust amounts positively.

  4. Offline Mode
    Set modeCode=0. Generate QR code client-side using URA algorithm. Upload later when online.

  5. Export Invoice
    Set invoiceIndustryCode=102. Provide buyerPassportNum, buyerCitizenship. Zero-rated tax.