E-Invoice XML customization
While creating an e-invoice you could need to have more control over the XML that is generated through our APIs. On this page, we'll explain how to set up the e-invoice advanced attributes.
📜 The Official XML Structure
The Official e-invoice XML structure is directly defined by the Italian Public Administration, and can be found here. This structure is subject to changes over time, and that's why we decided to manage some of these fields in a different way.
If you want to know which additional attributes we support you can also read this page. The Fatture in Cloud Web App lets you define these fields through dedicated components, so you can also check it to discover which attributes we support; we'll show you how to do it in the following sections.
🍡 The ei_raw flavours
If you already are familiar with creating e-invoices from our Web App, you already know that you can set advanced attributes in three different entities:
- E-invoice body
- Items list
- Payments list
While using our Create Issued Document and Modify Issued Document API methods, the fields provided by our model don't let you define all the fields available through our Web App: these advanced fields can instead be managed using the ei_raw params.
Keep in mind that every field in ei_raw is always managed as a String! This means, for example, that even numbers must be inserted in String format (eg. "NumItem": "5")
📃 E-invoice body
In our Web Interface, you can add your custom XML fields here:
In our API, that section corresponds to the data.ei_raw field. Let's try to set up one of these attributes.
For this example, we'll suppose to need to manage the NumItem field (2.1.5.4).
This is the structure declared by the Official Structure:
XML Tag Name | XML Tag ID | Occurrences |
---|---|---|
FatturaElettronicaBody | 2 | root |
DatiGenerali | 2.1 | <1,1> |
DatiRicezione | 2.1.5 | <0,N> |
NumItem | 2.1.5.4 | <0,1> |
This is the final XML that we want to obtain:
<FatturaElettronicaBody>
<DatiGenerali>
<DatiRicezione>
<NumItem>5</NumItem>
</DatiRicezione>
</DatiGenerali>
</FatturaElettronicaBody>
The ei_raw field uses JSON instead of XML but uses a similar structure.
While mapping the XML structure to our JSON, you have to keep in mind a few things:
- The FatturaElettronicaBody tag is the root of our ei_raw field, and we accept only one instance of that in our e-invoices
- For the root subfields, you need to check if the field is mandatory and its occurrences (check the Obbligatorietà e occorrenze field in the official structure); if the field can have more than one occurrence then it must be represented as a JSON list. For example, DatiRicezione is <0, N>: it means that it isn't mandatory and that it must be represented as a JSON list.
Mapping the XML shown above to our ei_raw JSON format we will obtain the following result:
- ei_raw only
- complete example
"ei_raw": {
"FatturaElettronicaBody": {
"DatiGenerali": {
"DatiRicezione": [
{
"NumItem": "5"
}
]
}
}
}
{
"data": {
"type": "invoice",
"entity": {
"name": "Mario Rossi"
},
"date": "2022-01-20",
"e_invoice": true,
"items_list": [
{
"product_id": 4,
"code": "TV3",
"name": "Tavolo in legno",
"net_price": 100,
"category": "cucina",
"discount": 0,
"qty": 1,
"vat": {
"id": 0
}
}
],
"payment_method": {
"id": 386683
},
"payments_list": [
{
"amount": 122,
"due_date": "2022-01-23",
"paid_date": "2022-01-22",
"status": "paid",
"payment_account": {
"id": 110
}
}
],
"ei_raw": {
"FatturaElettronicaBody": {
"DatiGenerali": {
"DatiRicezione": [
{
"NumItem": "5"
}
]
}
}
}
}
}
And here you can see how to set the ei_raw field with our SDKs:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
IssuedDocument invoice = new IssuedDocument(
type: IssuedDocumentType.Invoice,
eiRaw: new {
FatturaElettronicaBody = new {
DatiGenerali = new {
DatiRicezione = new [] {
new {
NumItem = "5"
}
}
}
}
}
);
invoice := *fattureincloud.NewIssuedDocument().
SetType(fattureincloud.IssuedDocumentTypes.INVOICE).
SetEiRaw(map[string]interface{}{
"FatturaElettronicaBody": map[string]interface{}{
"DatiGenerali": map[string]interface{}{
"DatiRicezione": []interface{}{
map[string]interface{}{
"NumItem": "5",
},
},
},
},
},
)
Map<String, Map<String, Map<String, List<Map<String, String>>>>> eiRaw = Map.of(
"FatturaElettronicaBody", Map.of(
"DatiGenerali", Map.of(
"DatiRicezione",
Arrays.asList(
Map.of(
"NumItem", "5"
)
)
)
)
);
IssuedDocument invoice = new IssuedDocument()
.type(IssuedDocumentType.INVOICE)
.eiRaw(eiRaw);
let invoice = new fattureInCloudSdk.IssuedDocument();
invoice.type = new fattureInCloudSdk.IssuedDocumentType().invoice;
invoice.ei_raw = {
FatturaElettronicaBody: {
DatiGenerali: {
DatiRicezione: [
{
NumItem: "5",
},
],
},
},
};
$invoice = new IssuedDocument();
$invoice
->setType(IssuedDocumentType::INVOICE);
->setEiRaw(
[
"FatturaElettronicaBody" => [
"DatiGenerali" => [
"DatiRicezione" => [
["NumItem" => "5"]
]
]
]
]
);
invoice = IssuedDocument(
type = IssuedDocumentType("invoice"),
ei_raw ={
"FatturaElettronicaBody": {
"DatiGenerali": {
"DatiRicezione": [
{
"NumItem": "5"
}
]
}
}
}
)
invoice = FattureInCloud_Ruby_Sdk::IssuedDocument.new(
type: FattureInCloud_Ruby_Sdk::IssuedDocumentType::INVOICE,
ei_raw: {
FatturaElettronicaBody: {
DatiGenerali: {
DatiRicezione: [
{
NumItem: "5"
}
]
}
}
}
)
let invoice: IssuedDocument = {
type: IssuedDocumentType.Invoice,
ei_raw: {
FatturaElettronicaBody: {
DatiGenerali: {
DatiRicezione: [
{
NumItem: "5",
},
],
},
},
},
};
🍜 Items list
In our web interface, you can define advanced attributes for each of the inserted items:
This section is mapped in our API methods in the data.items_list.ei_raw field. This field's behavior is similar to what was explained in the previous section, but in this case, the root tag is DettaglioLinee (2.2.1); this means that this is the first tag that we must represent in the item (you must ignore the parent nodes) and that there can be only one root tag per item.
In the following example, we suppose that we need to set the TipoDato field (2.2.1.16.2); the following table contains the Official XML Structure for the field:
XML Tag Name | XML Tag ID | Occurrences |
---|---|---|
FatturaElettronicaBody | 2 | |
DatiBeniServizi | 2.2 | |
DettaglioLinee | 2.2.1 | root |
AltriDatiGestionali | 2.2.1.16 | <0,N> |
TipoDato | 2.2.1.16.2 | <1,1> |
This is the final XML that we want to obtain:
<FatturaElettronicaBody>
<DatiBeniServizi>
<DettaglioLinee>
<AltriDatiGestionali>
<TipoDato>TIPO_DATO</TipoDato>
</AltriDatiGestionali>
</DettaglioLinee>
</DatiBeniServizi>
</FatturaElettronicaBody>
While mapping this XML to our JSON, we have to keep in mind two things:
- The root is the DettaglioLinee tag, so its parents must be omitted;
- As explained before, AltriDatiGestionali can appear more than once, so it must be represented as a JSON list.
The resulting JSON will be the following one:
- ei_raw only
- complete example
"ei_raw": {
"DettaglioLinee": {
"AltriDatiGestionali": [
{
"TipoDato": "TIPO_DATO"
}
]
}
}
{
"data": {
"type": "invoice",
"entity": {
"name": "Mario Rossi"
},
"date": "2022-01-20",
"e_invoice": true,
"items_list": [
{
"product_id": 4,
"code": "TV3",
"name": "Tavolo in legno",
"net_price": 100,
"category": "cucina",
"discount": 0,
"qty": 1,
"vat": {
"id": 0
},
"ei_raw": {
"DettaglioLinee": {
"AltriDatiGestionali": [
{
"TipoDato": "TIPO_DATO"
}
]
}
}
}
],
"payment_method": {
"id": 386683
},
"payments_list": [
{
"amount": 122,
"due_date": "2022-01-23",
"paid_date": "2022-01-22",
"status": "paid",
"payment_account": {
"id": 110
}
}
],
"ei_raw": {
"FatturaElettronicaBody": {
"DatiGenerali": {
"DatiRicezione": [
{
"NumItem": "5"
}
]
}
}
}
}
}
And here you can see how to set the ei_raw field with our SDKs:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
IssuedDocument invoice = new IssuedDocument(
itemsList: new List < IssuedDocumentItemsListItem > {
new IssuedDocumentItemsListItem(
productId: 4,
eiRaw: new {
DettaglioLinee = new {
AltriDatiGestionali = new [] {
new {
TipoDato = "TIPO DATO"
}
}
}
}
)
}
);
invoice := *fattureincloud.NewIssuedDocument().
SetType(fattureincloud.IssuedDocumentTypes.INVOICE).
SetEiRaw(map[string]interface{}{
"ei_raw": map[string]interface{}{
"DettaglioLinee": map[string]interface{}{
"AltriDatiGestionali": []interface{}{
map[string]interface{}{
"TipoDato": "TIPO_DATO",
},
},
},
},
},
)
Map<String, Map<String, List<Map<String, String>>>> eiRaw = Map.of(
"DettaglioLinee", Map.of(
"AltriDatiGestionali",
Arrays.asList(
Map.of(
"TipoDato", "TIPO DATO"
)
)
)
);
IssuedDocument invoice = new IssuedDocument()
.addItemsListItem(
new IssuedDocumentItemsListItem()
.productId(4)
.eiRaw(eiRaw)
);
let invoice = new fattureInCloudSdk.IssuedDocument();
invoice.items_list = [
{
product_id: 4,
ei_raw: {
DettaglioLinee: {
AltriDatiGestionali: [
{
TipoDato: "TIPO_DATO",
},
],
},
},
},
];
$invoice = new IssuedDocument();
$invoice->setItemsList(
[
new IssuedDocumentItemsListItem(
[
"product_id" => 4,
"ei_raw" => [
"DettaglioLinee" => [
"AltriDatiGestionali" => [
[
"TipoDato" => "TIPO_DATO"
]
]
]
]
]
)
]
);
invoice = IssuedDocument(
items_list = [
IssuedDocumentItemsListItem(
product_id=4,
ei_raw={
"DettaglioLinee": {
"AltriDatiGestionali": [
{
"TipoDato": "TIPO_DATO"
}
]
}
}
)
]
)
invoice = FattureInCloud_Ruby_Sdk::IssuedDocument.new(
items_list: Array(
FattureInCloud_Ruby_Sdk::IssuedDocumentItemsListItem.new(
product_id: 4,
ei_raw: {
DettaglioLinee: {
AltriDatiGestionali: [
{
NumItem: "5"
}
]
}
}
)
)
)
let invoice: IssuedDocument = {
items_list: [
{
product_id: 4,
ei_raw: {
DettaglioLinee: {
AltriDatiGestionali: [
{
TipoDato: "TIPO_DATO",
},
],
},
},
},
],
};
💸 Payments list
In our web interface, you can define advanced attributes for each of the inserted payments:
This section is mapped in our API methods in the data.payments_list.ei_raw field. This field's behavior is similar to what was explained in the previous section, but in this case, the root tag is DettaglioPagamento (2.4.2); this means that this is the first tag that we must represent in the item (you must ignore the parent nodes) and that there can be only one root tag per item.
In the following example, we suppose that we need to set the CAB field (2.4.2.15); the following table contains the Official XML Structure for the field:
XML Tag Name | XML Tag ID | Occurrences |
---|---|---|
FatturaElettronicaBody | 2 | |
DatiPagamento | 2.4 | |
DettaglioPagamento | 2.4.2 | root |
CAB | 2.4.2.15 | <0,1> |
This is the final XML that we want to obtain:
<FatturaElettronicaBody>
<DatiPagamento>
<DettaglioPagamento>
<CAB>CAB</CAB>
</DettaglioPagamento>
</DatiPagamento>
</FatturaElettronicaBody>
While mapping this XML to our JSON, we have to omit the root's parent tags, as already explained above.
The resulting JSON will be the following one:
- ei_raw only
- complete example
"ei_raw": {
"DettaglioPagamento": {
"CAB": "CAB"
}
}
{
"data": {
"type": "invoice",
"entity": {
"name": "Mario Rossi"
},
"date": "2022-01-20",
"e_invoice": true,
"items_list": [
{
"product_id": 4,
"code": "TV3",
"name": "Tavolo in legno",
"net_price": 100,
"category": "cucina",
"discount": 0,
"qty": 1,
"vat": {
"id": 0
},
"ei_raw": {
"DettaglioLinee": {
"AltriDatiGestionali": [
{
"TipoDato": "TIPO_DATO"
}
]
}
}
}
],
"payment_method": {
"id": 386683
},
"payments_list": [
{
"amount": 122,
"due_date": "2022-01-23",
"paid_date": "2022-01-22",
"status": "paid",
"payment_account": {
"id": 110
},
"ei_raw": {
"DettaglioPagamento": {
"CAB": "CAB"
}
}
}
],
"ei_raw": {
"FatturaElettronicaBody": {
"DatiGenerali": {
"DatiRicezione": [
{
"NumItem": "5"
}
]
}
}
}
}
}
And here you can see how to set the ei_raw field with our SDKs:
- C#
- Go
- Java
- JavaScript
- PHP
- Python
- Ruby
- TypeScript
IssuedDocument invoice = new IssuedDocument(
paymentsList: new List < IssuedDocumentPaymentsListItem > {
new IssuedDocumentPaymentsListItem(
amount: 122,
eiRaw: new {
DettaglioPagamento = new {
CAB = "CAB"
}
}
)
}
);
invoice := *fattureincloud.NewIssuedDocument().
SetType(fattureincloud.IssuedDocumentTypes.INVOICE).
SetEiRaw(map[string]interface{}{
"DettaglioPagamento": map[string]interface{}{
"CAB": "CAB",
},
},
)
Map<String, Map<String, String>> eiRaw = Map.of(
"DettaglioPagamento", Map.of(
"CAB", "CAB"
)
);
IssuedDocument invoice = new IssuedDocument()
.addPaymentsListItem(
new IssuedDocumentPaymentsListItem()
.amount(BigDecimal.valueOf(122))
.eiRaw(eiRaw)
);
let invoice = new fattureInCloudSdk.IssuedDocument();
invoice.payments_list = [
{
amount: 122,
ei_raw: {
DettaglioPagamento: {
CAB: "CAB",
},
},
},
];
$invoice = new IssuedDocument();
$invoice->setPaymentsList(
[
new IssuedDocumentPaymentsListItem(
[
"amount" => 122,
"ei_raw" => [
"DettaglioPagamento" => [
"CAB" => "CAB"
]
]
]
)
]
);
invoice = IssuedDocument(
payments_list = [
IssuedDocumentPaymentsListItem(
amount=122,
ei_raw={
"DettaglioPagamento": {
"CAB": "CAB"
}
}
)
]
)
invoice = FattureInCloud_Ruby_Sdk::IssuedDocument.new(
payments_list: Array(
FattureInCloud_Ruby_Sdk::IssuedDocumentPaymentsListItem.new(
amount: 122,
ei_raw: {
DettaglioPagamento: {
CAB: "CAB"
}
}
)
)
)
let invoice: IssuedDocument = {
payments_list: [
{
amount: 122,
ei_raw: {
DettaglioPagamento: {
CAB: "CAB",
},
},
},
],
};