---
source: https://carbone.io/examples/edifact-invoice/
title: "Create EDIFACT Invoices from JSON with an EDI API | Carbone"
description: "Create EDI invoices from your ERP or platform data with the Carbone API: a TXT template writes the EDIFACT INVOIC message, totals and segment count included."
generated_at: "2026-11-12"
---

# Create EDIFACT Invoices from JSON with an EDI API

Turn invoice data from your ERP or platform into an EANCOM INVOIC message

[![Create EDIFACT Invoices from JSON with an EDI API](/examples/edifact-invoice/thumb-result.webp)](/examples/edifact-invoice/result.txt)

[Download Template](/examples/edifact-invoice/template.txt)

[Download data sample](/examples/edifact-invoice/data.json)

-   Template type document txt simple
-   Carbone min. v5.0.0+
-   Features loop aggregator alias math
-   Target retail edi invoice

## Generate EDIFACT invoices from your software

Retailers and manufacturers ask their suppliers to invoice by EDI (electronic data interchange), with UN/EDIFACT INVOIC messages. In retail, the version is often EANCOM, the GS1 version of EDIFACT, which identifies companies and products by their barcode numbers. Your ERP or platform sends the invoice to the Carbone API as JSON and gets back the INVOIC message, ready for your EDI provider or AS2 connection. In this example, Fabrikam Cookware invoices four products to the retailer Contoso Hypermarchés in EANCOM INVOIC D96A.

## INVOIC message structure

Each line is a segment: a three-letter tag, then data elements (the values) separated by `+`, then `'`.

| Segments | Role |
| --- | --- |
| `UNA` | The separators of the file |
| `UNB` and `UNZ` | Envelope: sender and receiver GLNs (company barcode numbers), date, reference |
| `UNH` and `UNT` | Start and end of the invoice, with its segment count |
| `BGM`, `DTM`, `RFF` | Invoice number, invoice date, order number |
| `NAD` | Buyer `BY` and supplier `SU`: GLN, name, address |
| `CUX` | Currency |
| `LIN`, `QTY`, `MOA`, `PRI` | One group per product: GTIN (product barcode number), quantity, amount, price |
| `UNS`, `MOA`, `TAX` | Totals: lines, taxable amount, VAT, amount due |

## EDIFACT invoice example

### Template

```text
UNA:+.? '{o.useHighPrecisionArithmetic=true}{#edi($text) = $text:unaccent:replace('?', '??'):replace('+', '?+'):replace(':', '?:'):replace('''', '?''')}
UNB+UNOC:3+{d.supplier.gln}:14+{d.buyer.gln}:14+{d.interchange.date:formatD('YYMMDD:HHmm')}+{d.interchange.ref}'
UNH+1+INVOIC:D:96A:UN:EAN008'
BGM+380+{d.invoice.number}+9'
DTM+137:{d.invoice.date:formatD('YYYYMMDD')}:102'
RFF+ON:{d.invoice.orderNumber}'
NAD+BY+{d.buyer.gln}::9++{$edi(d.buyer.name)}+{$edi(d.buyer.street)}+{$edi(d.buyer.city)}++{d.buyer.postcode}+{d.buyer.country}'
NAD+SU+{d.supplier.gln}::9++{$edi(d.supplier.name)}+{$edi(d.supplier.street)}+{$edi(d.supplier.city)}++{d.supplier.postcode}+{d.supplier.country}'
CUX+2:{d.invoice.currency}:4'
{d.lines[i]}LIN+{d.lines[i].gtin:cumCount}++{d.lines[i].gtin}:EN'
QTY+47:{d.lines[i].qty}'
MOA+203:{d.lines[i].qty:mul(.price):round(2)}'
PRI+AAA:{d.lines[i].price}'
{d.lines[i+1]}UNS+S'
MOA+77:{d.lines[].qty:mul(.price):aggSum:round(2):mul(1 + d.invoice.vatRate / 100):round(2)}'
MOA+79:{d.lines[].qty:mul(.price):aggSum:round(2)}'
MOA+125:{d.lines[].qty:mul(.price):aggSum:round(2)}'
TAX+7+VAT+++:::{d.invoice.vatRate}+S'
MOA+124:{d.lines[].qty:mul(.price):aggSum:round(2):mul(d.invoice.vatRate / 100):round(2)}'
UNT+{d.lines[].gtin:aggCount:mul(4):add(14)}+1'
UNZ+1+{d.interchange.ref}'
```

### JSON data

```json
{
  "interchange": { "ref": "100482", "date": "2026-11-12T09:45:00+01:00" },
  "invoice": { "number": "FA-2026-0412", "date": "2026-11-12", "orderNumber": "PO-77810", "currency": "EUR", "vatRate": 20 },
  "supplier": { "gln": "3015874000008", "name": "Fabrikam Cookware SAS", "street": "14 rue de la Forge", "city": "Lyon", "postcode": "69007", "country": "FR" },
  "buyer": { "gln": "3029461000005", "name": "Contoso Hypermarchés SA", "street": "2 avenue du Port", "city": "Lille", "postcode": "59000", "country": "FR" },
  "lines": [
    { "gtin": "3015874001012", "qty": 24, "price": 18.4 },
    { "gtin": "3015874001180", "qty": 12, "price": 23.95 },
    { "gtin": "3015874001258", "qty": 36, "price": 11.25 },
    { "gtin": "3015874001326", "qty": 48, "price": 3.85 }
  ]
}
```

### Generated INVOIC message

```text
UNA:+.? '
UNB+UNOC:3+3015874000008:14+3029461000005:14+261112:0945+100482'
UNH+1+INVOIC:D:96A:UN:EAN008'
BGM+380+FA-2026-0412+9'
DTM+137:20261112:102'
RFF+ON:PO-77810'
NAD+BY+3029461000005::9++Contoso Hypermarches SA+2 avenue du Port+Lille++59000+FR'
NAD+SU+3015874000008::9++Fabrikam Cookware SAS+14 rue de la Forge+Lyon++69007+FR'
CUX+2:EUR:4'
LIN+1++3015874001012:EN'
QTY+47:24'
MOA+203:441.6'
PRI+AAA:18.4'
LIN+2++3015874001180:EN'
QTY+47:12'
MOA+203:287.4'
PRI+AAA:23.95'
LIN+3++3015874001258:EN'
QTY+47:36'
MOA+203:405'
PRI+AAA:11.25'
LIN+4++3015874001326:EN'
QTY+47:48'
MOA+203:184.8'
PRI+AAA:3.85'
UNS+S'
MOA+77:1582.56'
MOA+79:1318.8'
MOA+125:1318.8'
TAX+7+VAT+++:::20+S'
MOA+124:263.76'
UNT+30+1'
UNZ+1+100482'
```

## How to create an EDIFACT invoice

### 1\. Write the segments

Write each segment on its own line, with the fixed codes as they are and a tag where a value changes: `BGM+380+{d.invoice.number}+9'` prints `BGM+380+FA-2026-0412+9'`. If your trading partner wants a single line, write the template on one line.

### 2\. Release the special characters

`+`, `:`, `'` and `?` are reserved. In names and addresses, the release character `?` goes before them: `Fabrikam's` becomes `Fabrikam?'s`. The alias on the first line does it, and `{$edi(d.buyer.name)}` applies it:

```text
{#edi($text) = $text:unaccent:replace('?', '??'):replace('+', '?+'):replace(':', '?:'):replace('''', '?''')}
```

`?` is replaced first, so the next replacements are not doubled. In a formatter argument, `''''` is one single quote. `:unaccent` keeps the text in ASCII for the `UNOC` character set. Learn more about [parametrized aliases](/documentation/design/substitutions/aliases.md#parametrized-alias).

### 3\. Repeat the lines and compute the totals

`{d.lines[i]}` repeats the `LIN`, `QTY`, `MOA` and `PRI` segments for each product, as a [loop](/documentation/design/template-formats/txt.md#loops), and `:cumCount` numbers them. Carbone computes every amount:

-   `MOA+203`, the line amount: `{d.lines[i].qty:mul(.price):round(2)}`. 24 items at 18.40 give `441.6`.
-   `MOA+79` and `MOA+125`, the sum of the lines: `{d.lines[].qty:mul(.price):aggSum:round(2)}`.
-   `MOA+124`, the VAT: the taxable amount times `d.invoice.vatRate / 100`. 20% of 1318.8 gives `263.76`.
-   `MOA+77`, the amount due: the taxable amount plus the VAT.

`{o.useHighPrecisionArithmetic=true}` keeps the totals exact to the cent. See [aggregators](/documentation/design/computation/aggregation.md) and [formulas](/documentation/design/computation/simple-mathematics.md#mathematical-formula).

### 4\. Count the segments

`UNT` gives the number of segments from `UNH` to `UNT`: 14 fixed ones, plus 4 per product. `{d.lines[].gtin:aggCount:mul(4):add(14)}` prints 30 for four products and stays right for any number of lines. When you add a segment to the template, change `:add(14)`, or `:mul(4)` for a segment inside the loop.

## Related Examples

[![Invoice Automation / Factur-X](/examples/factur-x/thumb-result.webp)](/examples/factur-x/index.md) [![NACHA File Generator: Create ACH Files from JSON](/examples/nacha-ach-file/thumb-result.webp)](/examples/nacha-ach-file/index.md)

## Trusted by 800+ paid customers in 40+ countries

Industries: Finance, Healthcare, Insurance, Legal, Public, Retail, Energy, Software, Telecom.

Customers include Dior, Thales, Younited, Danfoss, CMA CGM, Illumina, KparK, Scalingo, French Ministry of the Armed Forces, BMW, Telus, Bestseller, Flagship Biosciences, Insly, Ninox, Sodexo.

## Related topics

- [Transport ticket](/examples/ticket/index.md)
- [Summary](/examples/summary/index.md)
- [Stock inventory spreadsheet](/examples/stock-inventory-spreadsheet/index.md)
- [Store Inventory](/examples/shoes/index.md)
- [Sensor readings](/examples/sensor-readings/index.md)
- [Real estate property document](/examples/real-estate-property-description/index.md)
