Skip to main content
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:
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
If bloquearSiRFCNoCoincide or bloquearSiRegimenNoCoincide are enabled in the profile, invoices that fail these validations will be rejected during upload.

Payment status tracking

Contafy automatically calculates payment status by analyzing both the invoice and any related payment complements:
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
For PPD invoices, Contafy automatically links payment complements to their parent invoices using the UUID references in the facturasRelacionadas array.

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
interface CreateManualIncomeRequest {
  profileId: string;
  fecha: string;
  total: number;
  subtotal: number;
  iva: number;
  concepto?: string;
  categoria?: string;
}
Manual income entries have tipo_origen: 'MANUAL' and uuid: null in the database. They appear alongside XML-based invoices in the invoices list.

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)
The invoices table uses TanStack Query with keepPreviousData to provide smooth pagination and filtering without loading states when changing pages.

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
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)

Invoice data structure

Complete TypeScript interface from the source code:
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;
}