> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contafy.com.mx/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoice management

> Upload, validate, and track Mexican CFDI invoices with automatic payment status calculation

Contafy's invoice management system handles Mexican CFDI invoices (Comprobante Fiscal Digital por Internet), including both regular invoices and payment complements (complementos de pago).

## Upload and validation

### Supported invoice types

Contafy automatically detects and processes:

* **PUE (Pago en Una sola Exhibición)** - Single payment invoices
* **PPD (Pago en Parcialidades o Diferido)** - Partial or deferred payment invoices
* **COMPLEMENTO\_PAGO** - Payment complements that reference PPD invoices

### Automatic validation

Each uploaded invoice undergoes comprehensive validation:

```typescript theme={null}
interface ValidationState {
  rfcVerificado: boolean;
  regimenFiscalVerificado: boolean;
  uuidDuplicado: boolean;
  advertencias: string[];
  errores: string[];
  valido: boolean;
}
```

Validation checks include:

* **RFC verification** - Ensures the RFC matches the profile configuration
* **Tax regime verification** - Validates regimen fiscal against profile settings
* **UUID duplicate detection** - Prevents duplicate invoice uploads
* **Profile-specific rules** - Respects custom validation settings per profile

<Warning>
  If `bloquearSiRFCNoCoincide` or `bloquearSiRegimenNoCoincide` are enabled in the profile, invoices that fail these validations will be rejected during upload.
</Warning>

## Payment status tracking

Contafy automatically calculates payment status by analyzing both the invoice and any related payment complements:

```typescript theme={null}
interface EstadoPagoDetalle {
  estado: 'PAGADO' | 'PAGO_PARCIAL' | 'NO_PAGADO';
  totalFactura: number;
  totalPagado: number;
  saldoPendiente: number;
  porcentajePagado: number;
  completamentePagado: boolean;
  ultimoSaldoInsoluto: number | null;
  tieneComplementos: boolean;
  tienePagosManuales: boolean;
}
```

### Payment status calculation

* **PAGADO** - Invoice is fully paid (100% of total collected)
* **PAGO\_PARCIAL** - Invoice has received partial payment (complementos exist)
* **NO\_PAGADO** - No payment complements or payments recorded

The system tracks:

* Total invoice amount
* Cumulative payments from complementos de pago
* Outstanding balance (saldo insoluto)
* Percentage paid

<Info>
  For PPD invoices, Contafy automatically links payment complements to their parent invoices using the UUID references in the `facturasRelacionadas` array.
</Info>

## Manual income entry

For scenarios where you need to record income without a formal CFDI:

### Requirements

* A specific profile must be selected (not "Todas las empresas")
* The period must have a valid period\_id (not "aggregated")
* The period\_id must be a valid UUID format

### Creating manual income

Manual income records support:

* Custom description/concept
* Amount breakdown (subtotal, IVA)
* Date selection
* Category assignment
* Payment status tracking

```typescript theme={null}
interface CreateManualIncomeRequest {
  profileId: string;
  fecha: string;
  total: number;
  subtotal: number;
  iva: number;
  concepto?: string;
  categoria?: string;
}
```

<Note>
  Manual income entries have `tipo_origen: 'MANUAL'` and `uuid: null` in the database. They appear alongside XML-based invoices in the invoices list.
</Note>

## Invoice list interface

The invoices page provides:

### Filtering options

* Profile selector (specific business or all businesses)
* Month and year selectors
* Régimen fiscal filter
* Text search across invoice fields

### Summary metrics

* **Total facturado** - Sum of accrued income for the period
* **Total facturas** - Count of invoices
* **Facturas pendientes de pago** - Count of unpaid/partially paid invoices

### Data table

Each invoice row displays:

* Issue date and UUID
* Emisor (issuer) and receptor (receiver) information
* Total amount with tax breakdown
* Payment type (PUE/PPD/COMPLEMENTO\_PAGO)
* Payment status badge with color coding
* Actions menu (view details, delete)

<Tip>
  The invoices table uses TanStack Query with `keepPreviousData` to provide smooth pagination and filtering without loading states when changing pages.
</Tip>

## Bulk upload

The upload interface supports:

* Drag-and-drop XML file upload
* Multiple file selection
* Real-time upload queue with progress tracking
* Validation results displayed immediately
* Profile selection before upload

### Upload workflow

1. Select the profile to associate invoices with
2. Drop XML files or click to select
3. Review files in queue
4. Upload processes each file sequentially
5. View validation results and warnings

```typescript theme={null}
interface UploadInvoiceResponse {
  message: string;
  data: Invoice;
  validacion: ValidationState;
  tipo: 'factura' | 'gasto';
}
```

## Tax breakdown

Contafy extracts and displays all tax information from CFDI:

* **IVA trasladado** - Sales tax charged (iva\_amount)
* **Retención IVA** - VAT withholding (retencion\_iva\_amount)
* **Retención ISR** - Income tax withholding (retencion\_isr\_amount)

## Related features

<CardGroup cols={2}>
  <Card title="Dashboard" icon="gauge" href="/features/dashboard">
    View invoice metrics on the main dashboard
  </Card>

  <Card title="Multi-Profile" icon="building" href="/features/multi-profile">
    Manage invoices across multiple business profiles
  </Card>

  <Card title="Reports & Analytics" icon="chart-bar" href="/features/reports-analytics">
    Generate detailed invoice reports
  </Card>
</CardGroup>

## Invoice data structure

Complete TypeScript interface from the source code:

```typescript theme={null}
export interface Invoice {
  id: string;
  profile_id: string;
  uuid: string;
  fecha: string;
  mes: number;
  año: number;
  total: number;
  subtotal: number;
  iva: number;
  iva_amount?: number;
  retencion_iva_amount?: number;
  retencion_isr_amount?: number;
  tipo: 'PUE' | 'PPD' | 'COMPLEMENTO_PAGO';
  rfc_emisor: string;
  nombre_emisor: string;
  regimen_fiscal_emisor: string | null;
  rfc_receptor: string;
  nombre_receptor: string;
  regimen_fiscal_receptor: string | null;
  concepto: string | null;
  pagos: Array<{
    fechaPago: string;
    formaPago: string;
    monedaPago: string;
    monto: number;
    numOperacion?: string;
  }>;
  complemento_pago: {...} | null;
  validacion: ValidationState;
  estadoPago?: EstadoPagoDetalle | null;
  profile?: {
    id: string;
    nombre: string;
    rfc: string;
  };
  created_at: string;
  updated_at: string;
}
```
