Vai al contenuto

Fattura elettronica in Java

Questo tutorial crea due semplici applicazioni Java da zero:

  1. Receive: si connette e autentica con l'API Invoicetronic e scarica le nuove fatture passive in arrivo.
  2. Send: si connette e autentica con l'API Invoicetronic e invia una fattura al SDI.

Prima di continuare, assicurati che tutti i prerequisiti siano soddisfatti.

Prerequisiti

Assumiamo che questi prerequisiti siano soddisfatti:

Usiamo Maven per la gestione delle dipendenze, che è lo standard de facto per progetti Java moderni.

Tip

Per un'esperienza Java ottimale, considera l'uso di IntelliJ IDEA o Eclipse come IDE.

Lo sapevi?

L'SDK Java è compatibile con Spring Boot, Jakarta EE e tutte le moderne applicazioni enterprise Java.

Receive

Creare l'applicazione

Il primo passo è creare la directory dell'applicazione:

mkdir receive && cd receive

Configurare Maven

Crea un file pom.xml con la seguente configurazione:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.invoicetronic.example</groupId>
    <artifactId>receive-example</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.invoicetronic</groupId>
            <artifactId>java-sdk</artifactId>
            <version>1.1.7</version>
        </dependency>
    </dependencies>
</project>

Configurare l'SDK

Crea la struttura delle directory e il file principale:

mkdir -p src/main/java/com/invoicetronic/example

Crea il file src/main/java/com/invoicetronic/example/Main.java:

Configurare l'SDK
package com.invoicetronic.example;

import com.invoicetronic.sdk.ApiClient;
import com.invoicetronic.sdk.ApiException;
import com.invoicetronic.sdk.Configuration;
import com.invoicetronic.sdk.auth.HttpBasicAuth;
import com.invoicetronic.sdk.api.ReceiveApi;
import com.invoicetronic.sdk.model.Receive;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Configura l'SDK
        ApiClient defaultClient = Configuration.getDefaultApiClient();
        defaultClient.setBasePath("https://api.invoicetronic.com/v1");

        HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("Basic");
        basicAuth.setUsername("LA TUA CHIAVE API DI TEST (inizia con ik_test_)");
        basicAuth.setPassword("");
    }
}

Come puoi vedere, configuriamo l'SDK impostando il base path e l'autenticazione HTTP Basic con la tua chiave API di test (non quella live). Nota come usiamo setUsername() per la chiave API e setPassword("") vuoto.

Le chiavi API vengono fornite in coppia

Quando crei il tuo account, ottieni una coppia di chiavi API. Una è la chiave di test per l'API Sandbox, e l'altra è quella live. Puoi distinguerle perché la prima inizia con ik_test_, mentre la seconda inizia con ik_live_. In questo tutorial, usa sempre la chiave di test.

Scaricare le fatture

Siamo pronti per effettuare una richiesta. Vogliamo scaricare le nuove fatture passive che potrebbero essere disponibili dall'SDI. Aggiungi questo codice nel metodo main:

Scaricare le fatture non lette
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

// Scarica le fatture non lette
ReceiveApi receiveApi = new ReceiveApi(defaultClient);

try {
    List<Receive> inboundInvoices = receiveApi.receiveGet(
        null,  // companyId
        null,  // identifier
        true,  // unread
        null,  // committente
        null,  // prestatore
        null,  // fileName
        null,  // lastUpdateFrom
        null,  // lastUpdateTo
        null,  // dateSentFrom
        null,  // dateSentTo
        null,  // documentDateFrom
        null,  // documentDateTo
        null,  // documentNumber
        true,  // includePayload
        null,  // page
        null,  // pageSize
        null   // sort
    );

    System.out.println("Ricevute " + inboundInvoices.size() + " fatture");

    for (Receive invoice : inboundInvoices) {
        if (invoice.getEncoding() == Receive.EncodingEnum.XML) {
            try (FileOutputStream fos = new FileOutputStream(invoice.getFileName())) {
                fos.write(invoice.getPayload().getBytes(StandardCharsets.UTF_8));
            }
        } else if (invoice.getEncoding() == Receive.EncodingEnum.BASE64) {
            try (FileOutputStream fos = new FileOutputStream(invoice.getFileName())) {
                fos.write(Base64.getDecoder().decode(invoice.getPayload()));
            }
        }

        System.out.println("Scaricato " + invoice.getFileName() +
            " da un fornitore con Partita IVA " + invoice.getPrestatore());
    }
} catch (ApiException | IOException e) {
    System.err.println("Errore: " + e.getMessage());
    e.printStackTrace();
}

Inclusione del Payload

Impostiamo includePayload a true per recuperare il contenuto effettivo della fattura nella proprietà payload. Senza questo parametro, il campo payload sarebbe null di default, il che migliora le prestazioni e riduce la dimensione della risposta quando hai bisogno solo dei metadati.

Compila ed esegui l'applicazione:

mvn clean compile exec:java -Dexec.mainClass="com.invoicetronic.example.Main"

Dovresti ottenere un output simile a questo:

Ricevute 3 fatture
Scaricato file1.xml da un fornitore con Partita IVA IT06157670966
Scaricato file2.xml.p7m da un fornitore con Partita IVA IT01280270057
Scaricato file3.xml.p7m da un fornitore con Partita IVA IT01280270057

I file sono nella directory corrente, pronti per essere ispezionati.

Non ricevi fatture nell'ambiente live?

Assicurati di esserti registrato con l'Agenzia delle Entrate, che è un requisito per l'ambiente live.

Cosa abbiamo imparato

In questo esempio, abbiamo imparato diverse cose.

  1. Dobbiamo configurare l'SDK ottenendo il client di default con Configuration.getDefaultApiClient(), impostando il base path e configurando l'autenticazione HTTP Basic con username (chiave API) e password vuota.

  2. Dobbiamo istanziare una classe che rappresenta l'endpoint con cui vogliamo lavorare. In questo caso, utilizziamo ReceiveApi per scaricare le fatture in arrivo, passando il client configurato.

  3. Le classi endpoint come ReceiveApi offrono metodi per interagire con la loro entità target. Chiamiamo receiveGet() per recuperare le fatture. Poiché vogliamo solo fatture nuove e non lette, passiamo true per il parametro unread. Passiamo anche true per includePayload per recuperare il contenuto effettivo della fattura.

  4. Gli oggetti fattura espongono metodi come getEncoding(), getFileName() e getPayload(). L'ultimo contiene il contenuto della fattura, come testo semplice o codificato in Base64, come descritto da getEncoding() che restituisce un enum Receive.EncodingEnum.

Codice sorgente su GitHub

Il codice sorgente per questo Quickstart è disponibile anche su GitHub.

Send

Creare l'applicazione

Il primo passo è creare la directory dell'applicazione:

mkdir send && cd send

Configurare Maven

Crea un file pom.xml con la seguente configurazione:

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.invoicetronic.example</groupId>
    <artifactId>send-example</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.invoicetronic</groupId>
            <artifactId>java-sdk</artifactId>
            <version>1.1.7</version>
        </dependency>
    </dependencies>
</project>

Configurare l'SDK

Crea la struttura delle directory e il file principale:

mkdir -p src/main/java/com/invoicetronic/example

Crea il file src/main/java/com/invoicetronic/example/Main.java:

Configurare l'SDK
package com.invoicetronic.example;

import com.invoicetronic.sdk.ApiClient;
import com.invoicetronic.sdk.ApiException;
import com.invoicetronic.sdk.Configuration;
import com.invoicetronic.sdk.auth.HttpBasicAuth;
import com.invoicetronic.sdk.api.SendApi;
import com.invoicetronic.sdk.model.Send;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        // Configura l'SDK
        ApiClient defaultClient = Configuration.getDefaultApiClient();
        defaultClient.setBasePath("https://api.invoicetronic.com/v1");

        HttpBasicAuth basicAuth = (HttpBasicAuth) defaultClient.getAuthentication("Basic");
        basicAuth.setUsername("LA TUA CHIAVE API DI TEST (inizia con ik_test_)");
        basicAuth.setPassword("");
    }
}

Come puoi vedere, configuriamo l'SDK impostando il base path e l'autenticazione HTTP Basic con la tua chiave API di test (non quella live).

Le chiavi API vengono fornite in coppia

Quando crei il tuo account, ottieni una coppia di chiavi API. Una è la chiave di test per l'API Sandbox, e l'altra è quella live. Puoi distinguerle perché la prima inizia con ik_test_, mentre la seconda inizia con ik_live_. In questo tutorial, usa sempre la chiave di test.

Inviare una fattura

Siamo pronti per effettuare una richiesta. Vogliamo inviare una fattura all'SDI. Aggiungi questo codice nel metodo main:

Inviare una fattura
// Invia una fattura
String filePath = "/qualche/percorso/file/nomefile.xml";

Map<String, String> metaData = new HashMap<>();
metaData.put("internal_id", "123");
metaData.put("created_with", "myapp");
metaData.put("some_other_custom_data", "value");

SendApi sendApi = new SendApi(defaultClient);

try {
    String payload = new String(Files.readAllBytes(Paths.get(filePath)));

    Send sendData = new Send();
    sendData.setFileName(Paths.get(filePath).getFileName().toString());
    sendData.setPayload(payload);
    sendData.setMetaData(metaData);

    Send sentInvoice = sendApi.sendPost(sendData, null, null);

    System.out.println("La fattura è stata inviata con successo, ora ha l'Id univoco " +
        sentInvoice.getId() + ".");

} catch (ApiException | IOException e) {
    System.err.println("Errore: " + e.getMessage());
    e.printStackTrace();
}

Compila ed esegui l'applicazione:

mvn clean compile exec:java -Dexec.mainClass="com.invoicetronic.example.Main"

Dovresti ottenere un output simile a questo:

La fattura è stata inviata con successo, ora ha l'Id univoco 123.

Cosa abbiamo imparato

In questo esempio, abbiamo imparato diverse cose.

  1. Dobbiamo configurare l'SDK ottenendo il client di default con Configuration.getDefaultApiClient(), impostando il base path e configurando l'autenticazione HTTP Basic.

  2. Dobbiamo istanziare una classe che rappresenta l'endpoint con cui vogliamo lavorare. In questo caso, utilizziamo SendApi per inviare fatture. Le classi endpoint come SendApi offrono metodi per interagire con la loro entità target. Chiamiamo sendPost() per inviare una fattura.

  3. Il modello Send espone metodi come setFileName(), setMetaData() e setPayload(). L'ultimo contiene il contenuto della fattura, mentre setMetaData() è opzionale e lega dati personalizzati al documento.

Codice sorgente su GitHub

Il codice sorgente per questo Quickstart è disponibile anche su GitHub.