Skip to main content

Batch Invoice Upload (T129)

Upload multiple invoices in a single request to improve throughput and reduce network overhead. This endpoint wraps multiple T109 Invoice Upload payloads into a single encrypted batch request.


Endpoint Overview

PropertyValue
Interface CodeT129
Request Encrypted✅ Yes
Response Encrypted✅ Yes
Request BodyArray of { invoiceContent, invoiceSignature }
Response FormatArray of { invoiceContent, invoiceReturnCode, invoiceReturnMessage }

Flow Description

  1. Client constructs an array of invoice payloads (same structure as T109).
  2. Client signs each invoice payload individually.
  3. Client wraps payloads into a batch request (invoiceContent + invoiceSignature).
  4. Client sends encrypted batch request to server.
  5. Server processes each invoice independently.
  6. Server returns an array of results, where each item corresponds to the input invoice order.
  7. Client checks invoiceReturnCode for each item to identify successes or failures.

Performance Tip: Use batch upload for high-volume scenarios (e.g., end-of-day reconciliation, bulk imports). However, respect server limits on batch size to avoid timeouts.


try {
// Construct array of invoice payloads (same structure as T109)
$invoices = [
[
'sellerDetails' => [ /* ... */ ],
'basicInformation' => [ /* ... */ ],
'buyerDetails' => [ /* ... */ ],
'goodsDetails' => [ /* ... */ ],
'taxDetails' => [ /* ... */ ],
'summary' => [ /* ... */ ],
'payWay' => [ /* ... */ ]
],
// Add more invoices...
];

// Call T129: Batch Upload
$response = $client->fiscaliseBatchInvoices($invoices);

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

if (is_array($results)) {
foreach ($results as $index => $result) {
$code = $result['invoiceReturnCode'] ?? '99';
$msg = $result['invoiceReturnMessage'] ?? 'Unknown';

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

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

Request Structure

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

Inner Batch Payload (Decrypted)

[
{
"invoiceContent": "{ T109_REQUEST_JSON }",
"invoiceSignature": "SIGNATURE_FOR_INVOICE_1"
},
{
"invoiceContent": "{ T109_REQUEST_JSON }",
"invoiceSignature": "SIGNATURE_FOR_INVOICE_2"
}
]

Request Fields

FieldRequiredTypeDescription
invoiceContent✅ YesStringPlaintext JSON payload of a T109 Invoice Upload request
invoiceSignature✅ YesStringDigital signature for the corresponding invoiceContent

🔐 Note: The SDK handles the inner signing and outer encryption automatically. Users typically pass an array of invoice objects (same as T109) to the fiscaliseBatchInvoices method.


Response Structure

{
"data": {
"content": [
{
"invoiceContent": "{ T109_RESPONSE_JSON }",
"invoiceReturnCode": "00",
"invoiceReturnMessage": "SUCCESS"
},
{
"invoiceContent": "{ T109_RESPONSE_JSON }",
"invoiceReturnCode": "1040",
"invoiceReturnMessage": "Invoice number already exists"
}
]
},
"globalInfo": {
"interfaceCode": "T129",
"returnStateInfo": {
"returnCode": "00",
"returnMessage": "SUCCESS"
}
}
}

Response Fields

FieldRequiredTypeDescription
invoiceContent✅ YesStringPlaintext JSON payload of the T109 response (contains invoiceNo, qrCode, etc.)
invoiceReturnCode✅ YesStringIndividual invoice return code (e.g., 00, 1040, 1316)
invoiceReturnMessage✅ YesStringHuman-readable message for the individual invoice result

Return Codes

Batch-Level Codes (Outer Envelope)

CodeMessageDescription
00SUCCESSBatch request processed successfully
99Unknown errorGeneric server error
1610invoiceContent cannot be empty!One or more batch items missing content
1611invoiceSignature cannot be empty!One or more batch items missing signature
1612Invoice upload quantity cannot be greater than xx!Batch size exceeds server limit
1613Batch upload has problematic invoices...Some invoices failed; check inner invoiceReturnCode

Invoice-Level Codes (Inner invoiceReturnCode)

See T109 Return Codes for detailed invoice-specific errors.

CodeMessageDescription
00SUCCESSIndividual invoice uploaded successfully
1040Invoice number already existsDuplicate invoice number detected
1316goodsDetails-->total:Multiply the quantity...Calculation error in goods details
1342taxDetails-->:'netAmount' plus 'taxAmount'...Tax calculation mismatch
1600Inventory shortageInsufficient stock for goods
2075Invoice amount exceeds the maximum limit!Exceeds maxGrossAmount from T103

💡 Tip: A batch request can return 00 at the envelope level even if individual invoices fail. Always iterate through the response array and check each invoiceReturnCode.


Common Use Cases

  1. High-Volume Retail
    Upload end-of-day sales summaries or bulk transactions from POS systems in a single API call.

  2. Offline Sync
    When reconnecting after offline mode, upload queued invoices in batches to reduce connection overhead.

  3. Data Migration
    Migrate historical invoice data from legacy systems to EFRIS efficiently.

  4. Error Isolation
    Identify specific failed invoices within a batch without halting the entire upload process.


Integration Checklist

✅ Validate each invoice payload (T109 structure) before adding to batch
✅ Ensure batch size does not exceed server limits (check return code 1612)
✅ Iterate through response array to handle partial failures
✅ Log individual invoiceReturnCode for audit trails
✅ Retry failed invoices individually (do not retry entire batch)