<!-- Fuente: https://docs.matias-api.com/docs/use-cases/simple-invoice -->
# Guía: Factura Electrónica Simple

## Introducción

Esta guía te mostrará cómo emitir tu primera factura electrónica usando la API de MATIAS. Es perfecta si acabas de empezar y tienes un caso de uso simple: vender un producto o servicio a un cliente empresario.

## ¿Cuándo usar esta guía?

✅ Tu primer documento electrónico
✅ Venta sin descuentos
✅ Cliente empresario identificado
✅ Pago único (no a plazo)
✅ No necesitas casos especiales

:::tip
Si tu caso es más complejo (exportación, múltiples monedas, descuentos), consulta las otras guías.
:::

## Requisitos Previos

Antes de empezar, asegúrate de tener:

- ✅ Usuario y contraseña en MATIAS API
- ✅ Token OAuth2 obtenido
- ✅ Resolución de facturación de DIAN
- ✅ Certificado digital vigente
- ✅ Datos de tu empresa

## Paso 1: Obtener el Token de Autenticación

Primero, necesitas autenticarte en la API:

### Solicitud

```bash
curl -X POST {{url}}/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "tu-email@empresa.com",
    "password": "tu-contraseña",
    "remember_me": 0
  }'
```

### Respuesta

```json
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjM...",
  "user": {
    "id": 1,
    "email": "tu-email@empresa.com",
    "name": "TU EMPRESA S.A.S."
  },
  "expires_at": "2026-05-06 14:30:00",
  "message": "Bienvenido a Matias. Su sesión ha sido iniciada con éxito.",
  "success": true
}
```

:::info
Guarda este `access_token`, lo usarás en todos los próximos pasos.
:::

:::tip Alternativa: Personal Access Tokens
En v3.0.0 puedes crear **Personal Access Tokens** directamente desde tu cuenta sin hacer login cada vez:

```bash
# 1. Primero haz login para obtener un token temporal
# 2. Luego crea un PAT que dure más tiempo (1-365 días; 90 por defecto)
curl -X POST {{url}}/tokens \
  -H "Authorization: Bearer {token_temporal}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Token Produccion",
    "expires_in_days": 60
  }'
```

[📖 Ver guía completa de Personal Access Tokens](https://docs.matias-api.com/docs/endpoints/intro-auth#personal-access-tokens)
:::

## Paso 2: Preparar los Datos de la Factura

Reúne la información necesaria:

### 📝 Información del Documento

```json
{
  "resolution_number": "18764074347312",
  "prefix": "LZT",
  "document_number": "2002",
  "date": "2024-10-17",
  "time": "14:30:00"
}
```

### 📝 Información del Cliente (Comprador)

```json
{
  "country_id": "45",
  "city_id": "836",
  "identity_document_id": "1",
  "type_organization_id": 2,
  "tax_regime_id": 2,
  "tax_level_id": 5,
  "company_name": "LOPEZ GOMEZ LEWIS OSWALDO",
  "dni": "1063279307",
  "email": "cliente4@ejemplo.com",
  "address": "Calle 64 #1823",
  "postal_code": "661002"
}
```

:::info
**Nota Importante:** El emisor (tu empresa) NO se envía en el JSON. La API identifica al emisor por el **token de autenticación**. Solo debes enviar información del cliente (comprador).
:::

## Paso 3: Crear la Estructura JSON de la Factura

Monta el JSON completo usando la estructura real del API:

```json
{
  "resolution_number": "18764074347312",
  "prefix": "LZT",
  "notes": "Nota del documento",
  "document_number": "2002",
  "graphic_representation": 0,
  "send_email": 1,
  "operation_type_id": 1,
  "type_document_id": 7,
  
  "payments": [
    {
      "payment_method_id": 1,
      "means_payment_id": 10,
      "value_paid": "224.00"
    }
  ],
  
  "customer": {
    "country_id": "45",
    "city_id": "836",
    "identity_document_id": "1",
    "type_organization_id": 2,
    "tax_regime_id": 2,
    "tax_level_id": 5,
    "company_name": "LOPEZ GOMEZ LEWIS OSWALDO",
    "dni": "1063279307",
    "mobile": "3108435423",
    "email": "cliente4@ejemplo.com",
    "address": "Calle 64 #1823",
    "postal_code": "661002"
  },
  
  "lines": [
    {
      "invoiced_quantity": "2",
      "quantity_units_id": "1093",
      "line_extension_amount": "100.00",
      "free_of_charge_indicator": false,
      "description": "TIJERA NECROPSIA AVES",
      "code": "HMT83",
      "type_item_identifications_id": "4",
      "reference_price_id": "1",
      "price_amount": "50",
      "base_quantity": "2",
      "tax_totals": [
        {
          "tax_id": "1",
          "tax_amount": 19,
          "taxable_amount": 100,
          "percent": 19
        }
      ]
    }
  ],
  
  "legal_monetary_totals": {
    "line_extension_amount": "100.00",
    "tax_exclusive_amount": "100.00",
    "tax_inclusive_amount": "119.00",
    "payable_amount": 119.00
  },
  
  "tax_totals": [
    {
      "tax_id": "1",
      "tax_amount": 19,
      "taxable_amount": 100,
      "percent": 19
    }
  ]
}
```

:::warning
**Puntos Importantes:**
- `type_document_id: 7` → Factura de venta
- `operation_type_id: 1` → Estándar
- `line_extension_amount` = `invoiced_quantity` × `price_amount`
- `tax_inclusive_amount` = `tax_exclusive_amount` + suma de `tax_totals.tax_amount`
- El `customer.dni` NO incluye dígito verificador en este caso
:::

## Paso 4: Validar la Factura Localmente

Antes de enviarla a la API, verifica:

✅ **Identificación**
- `resolution_number: "18764074347312"` (válida)
- `prefix: "LZT"` (registrada en DIAN)
- `document_number: "2002"` (no duplicado)
- `type_document_id: 7` (Factura de venta)
- `operation_type_id: 1` (Operación estándar)

✅ **Cliente**
- `dni: "1063279307"` (válido con dígito verificador)
- `company_name: "LOPEZ GOMEZ LEWIS OSWALDO"` (no vacío)
- `email: "cliente4@ejemplo.com"` (formato correcto)
- `country_id: "45"` (Colombia)

✅ **Líneas**
- `invoiced_quantity: "2"` > 0
- `price_amount: "50"` > 0
- `line_extension_amount: "100.00"` = 2 × 50 ✓
- `tax_totals` con cálculo: 100 × 0.19 = 19 ✓

✅ **Totales**
- `tax_exclusive_amount: "100.00"` = suma de líneas
- `tax_inclusive_amount: "119.00"` = 100 + 19 ✓
- `payable_amount: 119.00` = `tax_inclusive_amount` ✓

✅ **Pagos**
- `value_paid: "224.00"` = `payable_amount` ✓
- `payment_method_id: 1` (válido)
- `means_payment_id: 10` (válido)

## Paso 5: Enviar la Factura a la API

Una vez validada localmente, envía la factura:

```bash
curl -X POST "{{url}}/invoice" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "resolution_number": "18764074347312",
  "prefix": "LZT",
  "notes": "Nota del documento",
  "document_number": "2002",
  "type_document_id": 7,
  "operation_type_id": 1,
  "graphic_representation": 0,
  "send_email": 1,
  "customer": {
    "country_id": "45",
    "city_id": "836",
    "identity_document_id": "1",
    "type_organization_id": 2,
    "tax_regime_id": 2,
    "tax_level_id": 5,
    "company_name": "LOPEZ GOMEZ LEWIS OSWALDO",
    "dni": "1063279307",
    "mobile": "3108435423",
    "email": "cliente4@ejemplo.com",
    "address": "Calle 64 #1823",
    "postal_code": "661002"
  },
  "lines": [
    {
      "invoiced_quantity": "2",
      "quantity_units_id": "1093",
      "line_extension_amount": "100.00",
      "free_of_charge_indicator": false,
      "description": "TIJERA NECROPSIA AVES",
      "code": "HMT83",
      "type_item_identifications_id": "4",
      "reference_price_id": "1",
      "price_amount": "50",
      "base_quantity": "2",
      "tax_totals": [
        {
          "tax_id": "1",
          "tax_amount": 19,
          "taxable_amount": 100,
          "percent": 19
        }
      ]
    }
  ],
  "legal_monetary_totals": {
    "line_extension_amount": "100.00",
    "tax_exclusive_amount": "100.00",
    "tax_inclusive_amount": "119.00",
    "payable_amount": 119.00
  },
  "tax_totals": [
    {
      "tax_id": "1",
      "tax_amount": 19,
      "taxable_amount": 100,
      "percent": 19
    }
  ],
  "payments": [
    {
      "payment_method_id": 1,
      "means_payment_id": 10,
      "value_paid": "119.00"
    }
  ]
}'
```

### Respuesta Exitosa

```json
{
  "message": "El documento ha sido procesado por la DIAN.",
  "send_to_queue": 0,
  "XmlDocumentKey": "d45f3b2ed042ce0e075891591c3b3a7ae3a9c176ca191dab1bd23e5cdd3b48b8c548a088dfcbe20ee7baa2bed2dccd48",
  "response": {
    "ErrorMessage": {
      "string": []
    },
    "IsValid": "true",
    "StatusCode": "00",
    "StatusDescription": "Procesado Correctamente.",
    "StatusMessage": "La Factura electrónica LZT2002, ha sido autorizada.",
    "XmlBase64Bytes": "",
    "XmlBytes": {
      "_attributes": {
        "nil": "true"
      }
    },
    "XmlDocumentKey": "d45f3b2ed042ce0e075891591c3b3a7ae3a9c176ca191dab1bd23e5cdd3b48b8c548a088dfcbe20ee7baa2bed2dccd48",
    "XmlFileName": "fv09010914030002500000095"
  },
  "XmlBase64Bytes": "",
  "AttachedDocument": {
    "pathZip": "1/ad/z09010914030002500000042.zip",
    "path": "1/ad/ad09010914030002500000041.xml",
    "url": "https://sandbox-api.matias-api.com/attachments/1/ad/ad09010914030002500000041.xml",
    "data": ""
  },
  "qr": {
    "qrDian": "",
    "url": "",
    "path": "1/fv09010914030002500000095.png",
    "data": ""
  },
  "pdf": {
    "path": "1/fv09010914030002500000095.pdf",
    "url": "https://sandbox-api.matias-api.com/pdf/1/fv09010914030002500000095.pdf",
    "data": ""
  },
  "success": true
}
```

:::info
**Campos Clave en la Respuesta:**
- `message`: Mensaje genérico del API
- `XmlDocumentKey` (CUFE): Identificador único del documento en DIAN
- `response.IsValid`: "true" = documento válido
- `response.StatusCode`: "00" = procesado correctamente
- `response.StatusMessage`: Confirmación de autorización
- `XmlFileName`: Nombre del documento en portal DIAN
- `success`: true = operación exitosa
- `pdf.url`: Enlace para descargar el PDF
- `AttachedDocument.url`: Enlace del XML
:::

### Si Hay Errores

Si el número ya fue validado ante la DIAN, la API responde **HTTP 400** con el registro del envío existente en `data` (ver [Respuestas de la API](https://docs.matias-api.com/docs/response-json.md)):

```json
{
  "message": "El documento (Factura electrónica) con numero LZT2002 ya se encuentra validado.",
  "data": {
    "uuid": "dde72910-eb42-11ef-9b27-f02f74cac485",
    "document_number": "LZT2002",
    "XmlDocumentKey": "cf9864294501e8a9578235dd2ab3c4fd...",
    "is_valid": 1
  },
  "success": false
}
```

:::warning
**Códigos de Error Comunes:**
- Documento duplicado
- Datos de cliente inválidos
- Cálculos de totales incorrectos
- NIT sin dígito verificador o incorrecto
- Resolución no válida o vencida
:::

## Paso 6: Consultar Detalles del Documento

Para obtener los detalles completos de tu factura después de haberla creado:

```bash
curl -X GET "{{url}}/status?number=LZT2002&type_document_id=7" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

### Respuesta

```json
{
  "message": "El documento ha sido procesado por la DIAN.",
  "send_to_queue": 0,
  "XmlDocumentKey": "d45f3b2ed042ce0e075891591c3b3a7ae3a9c176ca191dab1bd23e5cdd3b48b8c548a088dfcbe20ee7baa2bed2dccd48",
  "response": {
    "ErrorMessage": {
      "string": []
    },
    "IsValid": "true",
    "StatusCode": "00",
    "StatusDescription": "Procesado Correctamente.",
    "StatusMessage": "La Factura electrónica LZT2002, ha sido autorizada.",
    "XmlBase64Bytes": "",
    "XmlBytes": {
      "_attributes": {
        "nil": "true"
      }
    },
    "XmlDocumentKey": "d45f3b2ed042ce0e075891591c3b3a7ae3a9c176ca191dab1bd23e5cdd3b48b8c548a088dfcbe20ee7baa2bed2dccd48",
    "XmlFileName": "fv09010914030002500000095"
  },
  "XmlBase64Bytes": "",
  "AttachedDocument": {
    "pathZip": "1/ad/z09010914030002500000042.zip",
    "path": "1/ad/ad09010914030002500000041.xml",
    "url": "https://sandbox-api.matias-api.com/attachments/1/ad/ad09010914030002500000041.xml",
    "data": ""
  },
  "qr": {
    "qrDian": "",
    "url": "",
    "path": "1/fv09010914030002500000095.png",
    "data": ""
  },
  "pdf": {
    "path": "1/fv09010914030002500000095.pdf",
    "url": "https://sandbox-api.matias-api.com/pdf/1/fv09010914030002500000095.pdf",
    "data": ""
  },
  "success": true
}
```

:::success
**¡Tu factura está lista!**

Con los datos de la respuesta puedes:
- 📥 **Descargar el PDF**: Usa `pdf.url`
- 📄 **Obtener el XML**: Usa `AttachedDocument.url`
- 📱 **Compartir el QR**: Usa `qr.url`
- ✅ **Verificar**: El CUFE (`XmlDocumentKey`) es único e irrepetible
:::

**Tiempo estimado de validación DIAN**: 30 minutos a 2 horas

## Paso 7: Enviar Comprobante al Cliente

Si configuraste `send_email: 1`, la API enviará automáticamente. Para enviar nuevamente, usa el CUFE de la factura (`XmlDocumentKey`) como `{trackId}` (ver [envío y reenvío de correos](https://docs.matias-api.com/docs/endpoints/queries-status#correos-adquirentes)):

```bash
curl -X POST "{{url}}/documents/sendmail/{trackId}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email_to": "compras@cliente.com"
  }'
```

## Checklist de Éxito

- [x] JSON coincide con estructura del API
- [x] Todos los campos requeridos presentes
- [x] Cálculos de totales e impuestos correctos
- [x] NIT del cliente válido
- [x] Respuesta HTTP 200 o 201
- [x] `status_id: 1` o superior en respuesta
- [x] CUFE generado correctamente
- [x] Cliente recibió email

## Troubleshooting

### ❌ "invalid_json"
**Causa**: JSON malformado o campos extras  
**Solución**: Usa la estructura exacta del ejemplo. Revisa la documentación de campos obligatorios.

### ❌ "NIT verificador inválido"
**Causa**: El dígito verificador del NIT es incorrecto  
**Solución**: Usa el validador NITValidator en herramientas interactivas

### ❌ "Duplicate document"
**Causa**: Ya existe una factura con el mismo `prefix` y `document_number`  
**Solución**: Incrementa el `document_number` o usa diferente `prefix`

### ❌ "tax_amount calculation error"
**Causa**: Los impuestos no se calculan correctamente  
**Solución**: `tax_amount` = `taxable_amount` × (`percent` / 100)

## Próximos Pasos

¡Felicidades! Has emitido tu primera factura electrónica. Ahora puedes:

- 📖 [Consultar la guía de Facturas con Descuentos](https://docs.matias-api.com/docs/use-cases/invoice-with-discounts.md)
- 📖 [Aprender sobre Exportaciones](https://docs.matias-api.com/docs/use-cases/export-scenarios.md)
- 📋 [Ver Referencias Técnicas](https://docs.matias-api.com/docs/billing-fields.md)

---

**Última actualización**: Octubre 2025
**Tiempo estimado**: 15 minutos
**Nivel de dificultad**: ⭐ Principiante
