cfdi-cli 0.1.0

CLI tool to parse, validate and convert Mexican CFDI 4.0 electronic invoices
Documentation
<div align="center">

# cfdi-cli

**Parse, validate and convert Mexican CFDI 4.0 electronic invoices from your terminal.**

[![CI](https://github.com/orbita-pos/cfdi-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/orbita-pos/cfdi-cli/actions/workflows/ci.yml)
[![Release](https://github.com/orbita-pos/cfdi-cli/actions/workflows/release.yml/badge.svg)](https://github.com/orbita-pos/cfdi-cli/releases)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

<img src="assets/demo.svg" alt="cfdi-cli demo" width="700">

</div>

---

A fast, single-binary CLI tool for working with Mexican CFDI 4.0 XML invoices. No internet required, no API keys, no runtime dependencies. Built with Rust for maximum performance.

## Installation

### Download binary (recommended)

Grab the latest release for your platform from [GitHub Releases](https://github.com/orbita-pos/cfdi-cli/releases):

| Platform | Download |
|----------|----------|
| Windows x86_64 | `cfdi-cli-windows-x86_64.zip` |
| Linux x86_64 | `cfdi-cli-linux-x86_64.tar.gz` |
| macOS Apple Silicon | `cfdi-cli-macos-aarch64.tar.gz` |
| macOS Intel | `cfdi-cli-macos-x86_64.tar.gz` |

### Install from crates.io

```bash
cargo install cfdi-cli
```

### Build from source

```bash
git clone https://github.com/orbita-pos/cfdi-cli.git
cd cfdi-cli
cargo build --release
# Binary at target/release/cfdi-cli
```

## Usage

### Quick info

```bash
$ cfdi-cli info factura.xml

==================================================
  UUID: A1234567-B890-C123-D456-E78901234567
  Fecha: 2024-08-01T12:00:00
  Tipo: Ingreso (I)
  Serie: SRV  Folio: 2450
  Emisor: IIA040805DZ4 - INDUSTRIAS INTEGRALES DE ACERO SA DE CV
  Receptor: EKU9003173C9 - ESCUELA KEMPER URGATE SA DE CV
  Total: $46980.00 MXN
==================================================
```

### Parse to JSON

```bash
$ cfdi-cli parse factura.xml
{
  "version": "4.0",
  "fecha": "2024-08-01T12:00:00",
  "emisor": { "rfc": "IIA040805DZ4", "nombre": "INDUSTRIAS INTEGRALES DE ACERO SA DE CV" },
  "receptor": { "rfc": "EKU9003173C9", "nombre": "ESCUELA KEMPER URGATE SA DE CV" },
  "total": "46980.00",
  ...
}
```

### Parse to table

```bash
$ cfdi-cli parse factura.xml -o table

============================================================
  UUID: 7E5FD72B-13A1-4B84-B6F7-1E5F2A4D78C9
  Fecha: 2024-06-15T09:45:30  Tipo: Ingreso  Moneda: MXN

  EMISOR
    RFC:    EKU9003173C9
    Nombre: ESCUELA KEMPER URGATE SA DE CV

  CONCEPTOS
    1. Laptop HP ProBook 450 G10 (x10) $1500.00 = $15000.00

  TOTALES
    SubTotal: $15000.00
    IVA Trasladado: $2400.00
    Total: $17400.00
============================================================
```

### Parse to CSV

```bash
$ cfdi-cli parse factura.xml -o csv
UUID,Fecha,Tipo,Serie,Folio,EmisorRFC,EmisorNombre,...
7E5FD72B-...,2024-06-15T09:45:30,I,F,1001,EKU9003173C9,...
```

### Validate

```bash
$ cfdi-cli validate factura.xml
VALIDO factura.xml
```

If there are issues:

```bash
$ cfdi-cli validate bad.xml
INVALIDO bad.xml
  ERROR: Emisor RFC invalido: ABC
  ERROR: Debe tener al menos un Concepto
  WARN: No tiene TimbreFiscalDigital (UUID)
```

### Bulk process a directory

```bash
$ cfdi-cli bulk ./facturas/ -o reporte.csv
# Exports all XMLs as a single CSV file

$ cfdi-cli bulk ./facturas/ -f json
# Output as JSON array to stdout
```

### Summary

```bash
$ cfdi-cli summary ./facturas/

RESUMEN DE CFDIS
==================================================
  Archivos procesados: 4/4

  Por tipo:
    Ingreso: 3
    Egreso: 1

  Totales:
    Ingresos: $69600.00
    Egresos: $4060.00
    IVA Trasladado: $10880.00
    Neto: $65540.00

  Por RFC Emisor:
    IIA040805DZ4: $46980.00
    EKU9003173C9: $21460.00
    EMP010101AAA: $5220.00
==================================================
```

## Commands

| Command | Description |
|---------|-------------|
| `info <file>` | Quick metadata: UUID, emisor, receptor, total |
| `parse <file> -o json\|csv\|table` | Parse CFDI to structured output |
| `validate <file>` | Validate structure, RFC, required fields, totals |
| `bulk <dir> -o <file> -f csv\|json\|table` | Batch process a directory |
| `summary <dir>` | Totals by type, IVA, by RFC emisor |

## CFDI fields extracted

- **Comprobante**: UUID, fecha, serie, folio, tipo, moneda, tipo de cambio, metodo/forma de pago
- **Emisor**: RFC, nombre, regimen fiscal
- **Receptor**: RFC, nombre, uso CFDI, domicilio fiscal
- **Conceptos**: clave producto, cantidad, unidad, descripcion, valor unitario, importe
- **Impuestos**: IVA trasladado, IVA retenido, ISR retenido
- **Timbre**: UUID, fecha timbrado, sello SAT, certificado SAT

## WebAssembly

The parser core compiles to WebAssembly for use in web applications:

```bash
wasm-pack build --target web --features wasm --no-default-features
```

Exports: `parseCfdi`, `parseCfdiPretty`, `validateCfdi`, `infoCfdi`, `parseCfdiBulk`

```javascript
import init, { parseCfdi, validateCfdi } from './pkg/cfdi_cli.js';

await init();

const json = parseCfdi(xmlString);
const result = JSON.parse(validateCfdi(xmlString));
// { valid: true, errors: [], warnings: [] }
```

## Performance

- Single XML: < 1ms
- 10,000 XMLs: < 5 seconds
- Binary size: ~3 MB
- WASM size: ~210 KB

## License

[MIT](LICENSE) - Built by [Orbita POS](https://github.com/orbita-pos)