superius / ubl-invoice
Superius UBL Invoice Package for Laravel
Requires
- php: ^8.2
- ext-dom: *
- eclipxe/xmlschemavalidator: ^3.0
- illuminate/contracts: ^10.0||^11.0||^12.0
- spatie/array-to-xml: ^3.4
- spatie/laravel-data: ^4.15
- superius/app-common: ^0.5
Requires (Dev)
- barryvdh/laravel-ide-helper: ^3.1
- fakerphp/faker: ^1.23
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.17
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.0.0||^8.22.0
- pestphp/pest: ^3.7
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-drift: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/phpstan-strict-rules: ^1.6
- thecodingmachine/phpstan-safe-rule: ^1.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v1.8.0
- v1.7.9
- v1.7.8
- v1.7.7
- v1.7.6
- v1.7.5
- v1.7.4
- v1.7.3
- v1.7.2
- v1.7.1
- v1.7.0
- v1.6.9
- v1.6.8
- v1.6.7
- v1.6.6
- v1.6.5
- v1.6.4
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.2
- v1.5.1
- v1.5.0
- v1.4.9
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- 1.4.0
- v1.3.8
- v1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.9
- v1.2.8
- v1.2.7
- v1.2.6
- v1.2.5
- v1.2.4
- v1.2.3
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.21
- v1.1.20
- v1.1.19
- v1.1.18
- v1.1.17
- v1.1.16
- v1.1.15
- v1.1.14
- v1.1.13
- v1.1.12
- v1.1.11
- v1.1.10
- v1.1.9
- v1.1.8
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.0
- dev-feature/OBL-7353-uskladi-limite-znakova-sa-schematronom
This package is auto-updated.
Last update: 2026-09-04 10:53:05 UTC
README
A Laravel package for validating UBL (Universal Business Language) invoices against XML schemas, including support for Croatian e-invoicing standards (FISK 2.0).
Duljine polja (OBL-7353)
Izvor istine za duljine je hrvatski Schematron (HR-CIUS-EXT-EN16931-UBL.sch,
porezna.gov.hr dok. 197). On propisuje točno četiri duljinska pravila:
| Pravilo | Polje | Limit |
|---|---|---|
| HR-BR-42 | BT-23 ProfileID | ≤ 200 (kod nas enum, strukturno zadovoljeno) |
| HR-BR-43 | BT-12 contract_reference_id | ≤ 1024 |
| HR-BR-46 | BT-153 item_name | ≤ 1024 |
| HR-BR-47 | BT-154 item_description | ≤ 4096 |
Za sva ostala polja država duljinu ne propisuje. Vlastiti limit niži od toga odbija račun koji je po specifikaciji ispravan — a upravo su takvi limiti (100 znakova na nazivima, adresama i referencama) rušili evidentiranje ulaznih računa.
Zato vrijedi: svako tekstualno polje, ime, adresa, referenca ili identifikator ima
limit 1024 znaka, osim polja čiju duljinu fiksira kodna lista ili vanjski standard
(šifre, postal_zone, customization_id URN, IBAN, BIC, PAN kartice). Popis iznimaka
i provjera koja sprječava povratak preuskih limita žive u
tests/DTO/FieldLengthLimitsTest.php.
Napomena za potrošače paketa: podizanje ovih limita znači da kroz DTO sada prolaze
duže vrijednosti nego prije, pa stupci u koje se te vrijednosti spremaju moraju biti
dovoljno široki (npr. document_xmls.document_number, supplier_name,
supplier_endpoint_id, customer_endpoint_id u masterappu).
Recent Fixes
Fix #2: High Precision Decimal Numbers (MultiplierFactorNumeric)
Problem
XML schema validation was failing with high precision decimal numbers:
Element '{urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2}MultiplierFactorNumeric':
'23.8938053097345132743362831858407079646' is not a valid value
of the atomic type 'xs:decimal'.
Root Cause
The issue occurred due to precision limitations in libxml2's xs:decimal type:
High Precision Decimals: Discount/charge multiplier calculations can produce decimal numbers with 30+ decimal places (e.g., when calculating exact percentages).
libxml2 Decimal Limitation: While
xs:decimaltheoretically supports arbitrary precision, libxml2's implementation has practical limits on the number of significant digits it can validate.Schema Definition: The UBL schema defines
MultiplierFactorNumericTypeextendingNumericType, which usesbase="xsd:decimal", triggering validation errors for high-precision values.
Solution
Modified MultiplierFactorNumericType to use TextType instead of NumericType:
File: src/Services/XmlSchemaValidator/XmlSchemas/ubl/common/UBL-CommonBasicComponents-2.1.xsd
<!-- Before -->
<xsd:complexType name="MultiplierFactorNumericType">
<xsd:simpleContent>
<xsd:extension base="udt:NumericType"/>
</xsd:simpleContent>
</xsd:complexType>
<!-- After -->
<xsd:complexType name="MultiplierFactorNumericType">
<xsd:simpleContent>
<xsd:extension base="udt:TextType"/>
</xsd:simpleContent>
</xsd:complexType>
Why This Fix Works
Targeted Fix: Only affects
MultiplierFactorNumericfields, preserving strict numeric validation for other numeric types.Unlimited Precision: Text-based validation removes artificial precision limits while maintaining the value as-is.
Semantic Correctness: Multiplier factors are stored and transmitted as strings in XML. The text type accurately represents this while allowing arbitrary precision.
Backward Compatibility: All valid decimal numbers are also valid text strings, so existing documents continue to validate correctly.
Testing
Added specific test for high-precision decimals in tests/Services/XmlSchemaValidatorTest.php:
vendor/bin/pest tests/Services/XmlSchemaValidatorTest.php
The test validates that MultiplierFactorNumeric with 38 decimal places passes validation.
Fix #1: X.509 Certificate Serial Number Validation
Problem
XML schema validation was failing with the following error:
Element '{http://www.w3.org/2000/09/xmldsig#}X509SerialNumber':
'110746456427574609188109388963935261765' is not a valid value
of the atomic type 'xs:integer'.
Root Cause
The issue occurred due to a limitation in libxml2 (the underlying XML parsing library used by PHP):
X.509 Serial Numbers: Certificate serial numbers can be arbitrarily large integers. The serial number
110746456427574609188109388963935261765is a 130-bit number (39 decimal digits).libxml2 Integer Limitation: While XML Schema's
xs:integertype theoretically supports unbounded integers, libxml2 validates integers using system-dependent integer types, typically with a maximum value of 2^63-1 on 64-bit systems.Schema Definition: The W3C XML Digital Signature schema (
xmldsig-core-schema.xsd) definesX509SerialNumberastype="integer", which triggers this validation error for large certificate serial numbers.
Solution
Modified the XML Digital Signature schema to use string instead of integer for the X509SerialNumber element:
File: src/Services/XmlSchemaValidator/XmlSchemas/ubl/common/xmldsig-core-schema.xsd
<!-- Before -->
<complexType name="X509IssuerSerialType">
<sequence>
<element name="X509IssuerName" type="string"/>
<element name="X509SerialNumber" type="integer"/>
</sequence>
</complexType>
<!-- After -->
<complexType name="X509IssuerSerialType">
<sequence>
<element name="X509IssuerName" type="string"/>
<element name="X509SerialNumber" type="string"/>
</sequence>
</complexType>
Why This Fix Works
Semantic Correctness: Certificate serial numbers are identifiers, not numeric values used for arithmetic operations. Using
stringtype is semantically appropriate.Industry Practice: This is a well-known workaround in XML signature validation implementations. Many production systems use
stringtype forX509SerialNumberto avoid this limitation.Specification Compliance: The fix maintains compatibility with X.509 certificates while working around libxml2's implementation constraints.
Testing
The fix was validated using the test suite:
vendor/bin/pest tests/Services/XmlSchemaValidatorTest.php
The test validates:
- Correct XML documents pass validation
- Invalid XML documents are properly rejected with appropriate exceptions
Related Standards
- UBL 2.1: Universal Business Language standard for electronic documents
- XML Digital Signature: W3C recommendation for XML-based digital signatures
- Croatian e-Invoicing: Ministry of Finance FISK 2.0 requirements (urn:mfin.gov.hr:cius-2025:1.0)
License
Proprietary - Superius Internal