Crear factura electrónica de AFIP en Java

Con pocas líneas de código


Crear factura electrónica de AFIP en Java

El primer paso para crear una factura electrónica de AFIP es obtener el Código de Autorización Electrónico o CAE.

Esto lo vamos a hacer utilizando Afip SDK que nos permite conectarnos a los web services de AFIP sin complicarnos con el uso de SOAP y la autenticación.

Vamos a user Gson para trabajar con JSON.

Añadimos la dependencia de Maven:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
</dependency>

Obtener la autorización

Lo primero que tenemos hacer es obtener el “Token authorization”, que seria la autorización en AFIP.

Para usar los web services de AFIP necesitamos un certificado y key pero Afip SDK nos deja utilizar el CUIT 20409378472 en modo testing para integrarnos rápidamente.

Debemos ejecutar una solicitud POST al endpoint

https://app.afipsdk.com/api/v1/afip/auth
package com.example;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        try {
            // Paso 1: Obtener el Token Authorization
            HttpClient client = HttpClient.newBuilder()
                    .connectTimeout(Duration.ofSeconds(15))
                    .build();

            // Crear JSON para el request usando GSON
            Map<String, String> authRequestMap = new HashMap<>();
            authRequestMap.put("environment", "dev");
            authRequestMap.put("tax_id", "20409378472");
            authRequestMap.put("wsid", "wsfe");

            Gson gson = new Gson();
            String authRequestBody = gson.toJson(authRequestMap);

            HttpRequest authRequest = HttpRequest.newBuilder()
                    .uri(new URI("https://app.afipsdk.com/api/v1/afip/auth"))
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(authRequestBody))
                    .build();

            HttpResponse<String> authResponse = client.send(authRequest, HttpResponse.BodyHandlers.ofString());

            if (authResponse.statusCode() >= 400) {
                System.out.println("Error in auth request: " + authResponse.body());
                return;
            }

            // Parsear respuesta para extraer el sign y token usando GSON
            Type mapType = new TypeToken<Map<String, String>>() {}.getType();
            Map<String, String> authData = gson.fromJson(authResponse.body(), mapType);

            String token = authData.get("token");
            String sign = authData.get("sign");

            System.out.println("Token: " + token);
            System.out.println("Sign: " + sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

En la pestaña “API” de la documentacion podes consultar todos los parametros del endpoint.

Ahora tenemos token y sign que nos dio AFIP para usar el web service. No es necesario que lo guardemos, Afip SDK se encarga de esto por nosotros, debemos solicitarlo antes de cada llamada a los métodos del web service.

Crear la factura

Vamos a crear una Factura B por un importe de $121. En el main de nuestra clase añadimos el siguiente codigo:

Debemos ejecutar una solicitud POST al endpoint

https://app.afipsdk.com/api/v1/afip/requests
// Obtener la fecha actual en formato yyyyMMdd
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
String fechaActual = formatter.format(new Date());

Map<String, Object> payload = new LinkedHashMap<>();
payload.put("environment", "dev");
payload.put("method", "FECAESolicitar");
payload.put("wsid", "wsfe");

Map<String, Object> auth = new LinkedHashMap<>();
auth.put("Token", token); // Replace with the actual token
auth.put("Sign", sign);   // Replace with the actual sign
auth.put("Cuit", "20409378472");

Map<String, Object> feCabReq = new LinkedHashMap<>();
feCabReq.put("CantReg", 1);
feCabReq.put("PtoVta", 1);
feCabReq.put("CbteTipo", 6);

Map<String, Object> detRequest = new LinkedHashMap<>();
detRequest.put("Concepto", 1);
detRequest.put("DocTipo", 99);
detRequest.put("DocNro", 0);
detRequest.put("CbteDesde", 1);
detRequest.put("CbteHasta", 1);
detRequest.put("CbteFch", fechaActual);
detRequest.put("ImpTotal", 121);
detRequest.put("ImpTotConc", 0);
detRequest.put("ImpNeto", 100);
detRequest.put("ImpOpEx", 0);
detRequest.put("ImpIVA", 21);
detRequest.put("ImpTrib", 0);
detRequest.put("MonId", "PES");
detRequest.put("MonCotiz", 1);

Map<String, Object> iva = new LinkedHashMap<>();
iva.put("Id", 5);
iva.put("BaseImp", 100);
iva.put("Importe", 21);

detRequest.put("Iva", Map.of("AlicIva", List.of(iva)));

Map<String, Object> feDetReq = new LinkedHashMap<>();
feDetReq.put("FECAEDetRequest", List.of(detRequest));

Map<String, Object> feCAEReq = new LinkedHashMap<>();
feCAEReq.put("FeCabReq", feCabReq);
feCAEReq.put("FeDetReq", feDetReq);

Map<String, Object> params = new LinkedHashMap<>();
params.put("Auth", auth);
params.put("FeCAEReq", feCAEReq);

payload.put("params", params);

String invoiceRequestBody = gson.toJson(payload);

HttpRequest invoiceRequest = HttpRequest.newBuilder()
        .uri(new URI("https://app.afipsdk.com/api/v1/afip/requests"))
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(invoiceRequestBody))
        .build();

HttpResponse<String> invoiceResponse = client.send(invoiceRequest, HttpResponse.BodyHandlers.ofString());

if (invoiceResponse.statusCode() >= 400) {
    System.out.println("Error in invoice request: " + invoiceResponse.body());
    return;
}

System.out.println("Invoice Response: " + invoiceResponse.body());

En la pestaña “API” de la documentacion podes consultar todos los parametros del endpoint.

En invoiceData tenemos el CAE y vencimiento correspondientes a la factura que acabamos de crear.

{
...
  "CAE": "12345678987654",
  "CAEFchVto": "20240327"
...
}

Con la autorizacion creada ya podemos proceder a crear el PDF para presentarle a nuestro cliente. Podes usar como base esta factura o ticket de ejemplo.

Luego, lo único que nos queda es pasar a modo producción, para más información de cómo hacerlo pueden dirigirse a la documentación de la librería https://docs.afipsdk.com/

Conectate a AFIP sin vueltas

Certificados, codigo, tutoriales, soporte, todo lo que necesitas para usar los web services de AFIP en un solo lugar.