Anticipos

Este documento explica el tratamiento tributario de los anticipos y el proceso para emitirlos correctamente a través de la API de facturación electrónica de Perú: la factura de anticipo, la factura final que lo descuenta, y las reglas de validación aplicables.

1. Concepto de anticipo

Un anticipo es un pago —total o parcial— que el cliente entrega antes de que el bien sea entregado o el servicio sea prestado. La sola recepción del pago genera la obligación de emitir un comprobante por el importe percibido.

Base legal

El artículo 3°, numeral 3 del Reglamento de la Ley del IGV establece que, en la venta de bienes muebles, los pagos recibidos antes de la entrega o puesta a disposición del bien dan lugar al nacimiento de la obligación tributaria por el monto percibido. Para servicios, la obligación nace en el momento en que se percibe el ingreso, sea total o parcial, incluso si el pago se recibe a título de arras, depósito o garantía.

Excepción — solo para bienes
Las arras de retractación, depósito o garantía entregadas antes de que exista la obligación de transferir un bien NO generan el nacimiento de la obligación tributaria, siempre que no superen en conjunto el 3% del valor total de venta. Si se supera ese porcentaje, nace la obligación por el importe TOTAL entregado. Esta excepción del 3% no aplica de la misma forma a los servicios.

La jurisprudencia del Tribunal Fiscal (RTF N.º 04937-4-2014) precisa que la denominación que las partes le den al pago ("anticipo", "separación", "reserva") no es determinante; lo relevante es la verdadera naturaleza económica y contractual de la operación, y en particular si ya existía la obligación de transferir el bien en el momento en que se recibió el dinero. Cualquier clasificación operativa interna (por ejemplo, para decidir si algo se trata como anticipo o como cuota de una venta a crédito ya facturada) debe apoyarse en ese criterio y no únicamente en si el bien/servicio y el precio ya estaban acordados.

Importante — no existe un profileId especial para anticipos
El Catálogo de Tipos de Operación vigente (Catálogo 51) no tiene ningún código dedicado a anticipos para Factura o Boleta. Tanto la factura de anticipo como la factura final usan siempre profileId "0101" (Venta interna).

2. Flujo completo del proceso

El proceso tiene siempre dos etapas: (1) emitir la factura de anticipo al recibir el pago, y (2) emitir la factura final al entregar el bien o servicio, deduciendo el anticipo ya pagado.

Etapa 1 — Factura de anticipo (al recibir el pago)

Cuándo emitirla: en el momento en que el cliente realiza el pago anticipado, antes de que el bien sea entregado o el servicio prestado.

  • profileId: "0101" — igual que cualquier factura de venta interna.
  • Serie: se recomienda (no es obligatorio) usar una serie distinta a las facturas de venta habituales, por ejemplo FANT, para distinguirlas operativamente.
  • itemDetails: se validan con el mismo rigor que cualquier otra factura — description, quantity, unitMeasure, unitValue, unitPrice, subtotal y taxes son obligatorios. No hay ninguna validación relajada documentada para ítems de anticipo.
  • totals.prepaidAmount = 0.00 — en esta etapa no hay anticipos previos que deducir.

Request de ejemplo — factura de anticipo:

{
  "information": {
    "series": "FANT",
    "number": 1,
    "profileId": "0101",
    "issueDate": "2026-05-01",
    "igvPercentage": "1",
    "currencyCode": "PEN"
  },
  "customer": {
    "identificationType": "6",
    "identificationNumber": "20131312955",
    "name": "EMPRESA COMPRADORA SAC"
  },
  "payment": { "type": "1" },
  "itemDetails": [
    {
      "description": "Anticipo por servicio de consultoria - Proyecto X",
      "quantity": 1,
      "unitMeasure": "ZZ",
      "unitValue": 1000.00,
      "unitPrice": 1180.00,
      "subtotal": 1000.00,
      "taxes": {
        "igv": { "type": "10", "amount": 180.00 },
        "totalTaxes": 180.00
      }
    }
  ],
  "totals": {
    "baseAmount": 1000.00,
    "totalTaxes": 180.00,
    "igvTotal": 180.00,
    "grossAmount": 1180.00,
    "totalAmount": 1180.00,
    "prepaidAmount": 0.00
  }
}

Etapa 2 — Factura final (al entregar el bien o servicio)

Cuándo emitirla: al completar la entrega del bien o la prestación del servicio.

  • profileId: "0101".
  • itemDetails: describe el bien o servicio a su VALOR TOTAL, sin descontar el anticipo.
  • prepaidPayments[]: referencia cada anticipo previamente pagado (ver sección 3).

Qué NO enviar
El objeto adjustment con reasonCode "04", "05" o "06" NO se envía manualmente. El enum vigente de adjustment.reasonCode es 02, 03, 20, 45, 46, 49, 50, 51, 52, 53, 61, 62, 63 — los códigos 04/05/06 quedan reservados para que el motor genere el descuento automáticamente a partir de prepaidPayments[].taxAffectation. Enviar "04" en adjustment.reasonCode produce un valor fuera de enum y la petición es rechazada.

Reglas de cálculo de totales

  • baseAmount = valor de venta ÍNTEGRO de los ítems de esta factura. No se reduce por el anticipo.
  • Base sin IGV del anticipo = paidAmount / (1 + igvPercentage) — solo aplica a anticipos con taxAffectation "04" (gravado). Para "05" (exonerado) o "06" (inafecto) se usa el paidAmount completo, sin dividir.
  • igvTotal = (baseAmount − base sin IGV de los anticipos gravados) × tasa de IGV vigente.
  • grossAmount = baseAmount + (baseAmount × tasa de IGV) — íntegro, sin descontar anticipos.
  • totalAmount = grossAmount − prepaidAmount. Aquí es donde se refleja la deducción del anticipo.
  • prepaidAmount = suma de todos los paidAmount del array prepaidPayments[] (montos con IGV).
  • totals.prepaidAmount debe ser igual a esa suma con una tolerancia de ±0.01 — hay que dejarle margen a los redondeos de centavos. Además, prepaidPayments[] y totals.prepaidAmount > 0 son obligatorios el uno con el otro: si se envía uno sin el otro, la petición se rechaza.

Punto de máxima confusión
baseAmount y grossAmount NUNCA se reducen por el anticipo — reflejan el valor íntegro del bien o servicio entregado en esta factura. Solo igvTotal y totalAmount reflejan la deducción. El saldo final (totalAmount) puede coincidir numéricamente si se calcula restando la base del anticipo directamente de baseAmount, pero eso reporta a SUNAT un LineExtensionAmount y un TaxInclusiveAmount incorrectos, aunque el PayableAmount final sea el mismo.

3. Objeto prepaidPayments[] — definición completa

Array que se envía únicamente en la factura final. Cada elemento referencia un comprobante de anticipo previamente emitido y aceptado por SUNAT. Se agrega al nivel raíz del request, al mismo nivel que itemDetails y totals.

CampoFormatoCond.Descripción
paidAmountn(12,2) > 0MMonto del anticipo pagado, con IGV — el monto bruto que pagó el cliente. Corresponde al totalAmount completo de la factura de anticipo.
taxAffectation"04" / "05" / "06"Opcional, default "04"Determina el tipo de descuento que genera el motor: "04" anticipo gravado (se descuenta el IGV del paidAmount), "05" exonerado, "06" inafecto (se usa el paidAmount completo en ambos).
paidDateYYYY-MM-DDOpcionalFecha del pago del anticipo. SUNAT no aplica validación activa sobre este campo.
documentType"02" / "03"MTipo del comprobante de anticipo: "02" factura, "03" boleta.
seriesan..4MSerie del comprobante de anticipo referenciado (ej. "FANT").
numbern..8MNúmero correlativo del comprobante de anticipo referenciado.
issuerRucn11OpcionalRUC del emisor del anticipo, solo si es distinto al emisor de la factura final (ej. copago con aseguradoras). Si no se envía, se usa el RUC del emisor de la factura final.

No declarar el anticipo en relatedDocuments.additionalDocuments
El catálogo de tipos de documento relacionado (Catálogo 12) también acepta "02" y "03" (factura/boleta de anticipo) dentro de relatedDocuments.additionalDocuments[]. No los uses ahí: ese array es para OTROS documentos relacionados con la operación — tickets de salida ENAPU, código SCOP, DAM/DSI, carta porte, declaración de exportación. prepaidPayments[] ya construye automáticamente el bloque cac:AdditionalDocumentReference correspondiente al anticipo; declarar el mismo comprobante también en additionalDocuments[] duplicaría la referencia dentro del mismo comprobante, algo que el propio schema prohíbe de forma explícita.

No enviar el campo id
El campo id no existe en el schema y no debe enviarse. La vinculación entre cada anticipo y su referencia dentro del XML la resuelve la API automáticamente, en el mismo orden en que se envían los elementos del array prepaidPayments[]: el primer elemento queda vinculado al primer bloque de referencia generado, el segundo al segundo, y así sucesivamente.

4. Ejemplos

Ejemplo 1 — Factura final con un anticipo

El cliente pagó S/ 1,180.00 de anticipo (FANT-1). El servicio completo vale S/ 5,900.00 con IGV incluido.

{
  "information": {
    "series": "FTQA",
    "number": 5,
    "profileId": "0101",
    "issueDate": "2026-06-15",
    "igvPercentage": "1",
    "currencyCode": "PEN"
  },
  "customer": {
    "identificationType": "6",
    "identificationNumber": "20131312955",
    "name": "EMPRESA COMPRADORA SAC"
  },
  "payment": { "type": "1" },
  "itemDetails": [
    {
      "description": "Servicio de consultoria - Proyecto X",
      "quantity": 1,
      "unitMeasure": "ZZ",
      "unitValue": 5000.00,
      "unitPrice": 5900.00,
      "subtotal": 5000.00,
      "taxes": {
        "igv": { "type": "10", "amount": 900.00 },
        "totalTaxes": 900.00
      }
    }
  ],
  "prepaidPayments": [
    {
      "paidAmount": 1180.00,
      "taxAffectation": "04",
      "paidDate": "2026-05-01",
      "documentType": "02",
      "series": "FANT",
      "number": 1
    }
  ],
  "totals": {
    "baseAmount": 5000.00,
    "totalTaxes": 720.00,
    "igvTotal": 720.00,
    "grossAmount": 5900.00,
    "totalAmount": 4720.00,
    "prepaidAmount": 1180.00
  }
}
ConceptoValor (S/)
Valor total del servicio (baseAmount, sin reducir)5,000.00
IGV 18% sobre base neta del anticipo (igvTotal)720.00
Subtotal de la factura con IGV pleno (grossAmount)5,900.00
Anticipo ya pagado, con IGV (prepaidAmount)1,180.00
Saldo a pagar por el cliente (totalAmount)4,720.00

Ejemplo 2 — Factura final con múltiples anticipos

El cliente realizó 3 pagos anticipados de S/ 1,180.00 cada uno (FANT-2, FANT-3, FANT-4). El servicio completo vale S/ 11,800.00 con IGV incluido.

{
  "information": {
    "series": "FTQA",
    "number": 6,
    "profileId": "0101",
    "issueDate": "2026-06-20",
    "igvPercentage": "1",
    "currencyCode": "PEN"
  },
  "customer": {
    "identificationType": "6",
    "identificationNumber": "20131312955",
    "name": "EMPRESA COMPRADORA SAC"
  },
  "payment": { "type": "1" },
  "itemDetails": [
    {
      "description": "Servicio de consultoria - Proyecto Y",
      "quantity": 1,
      "unitMeasure": "ZZ",
      "unitValue": 10000.00,
      "unitPrice": 11800.00,
      "subtotal": 10000.00,
      "taxes": {
        "igv": { "type": "10", "amount": 1800.00 },
        "totalTaxes": 1800.00
      }
    }
  ],
  "prepaidPayments": [
    {
      "paidAmount": 1180.00,
      "taxAffectation": "04",
      "paidDate": "2026-04-10",
      "documentType": "02",
      "series": "FANT",
      "number": 2
    },
    {
      "paidAmount": 1180.00,
      "taxAffectation": "04",
      "paidDate": "2026-05-01",
      "documentType": "02",
      "series": "FANT",
      "number": 3
    },
    {
      "paidAmount": 1180.00,
      "taxAffectation": "04",
      "paidDate": "2026-06-01",
      "documentType": "02",
      "series": "FANT",
      "number": 4
    }
  ],
  "totals": {
    "baseAmount": 10000.00,
    "totalTaxes": 1260.00,
    "igvTotal": 1260.00,
    "grossAmount": 11800.00,
    "totalAmount": 8260.00,
    "prepaidAmount": 3540.00
  }
}
ConceptoValor (S/)
Valor total del servicio (baseAmount, sin reducir)10,000.00
IGV 18% sobre base neta de los 3 anticipos (igvTotal)1,260.00
Subtotal de la factura con IGV pleno (grossAmount)11,800.00
Total de anticipos ya pagados (prepaidAmount)3,540.00
Saldo a pagar por el cliente (totalAmount)8,260.00

Ejemplo 3 — Anticipo que cubre el 100% del valor

Este escenario NO se resuelve con una factura final en cero
SUNAT rechaza cualquier comprobante con PayableAmount = 0 (ERROR 2062). Una factura final con todos los totales en 0.00 nunca es la forma correcta de cerrar un anticipo que cubrió el 100% del valor, sin importar que el anticipo ya esté totalmente pagado.

Manejo correcto según el valor final de la operación:

  • Si el valor final del bien/servicio es igual al anticipo ya pagado: no se emite ninguna factura adicional. La factura de anticipo ya es el comprobante completo de la operación.
  • Si el valor final es menor al anticipo pagado: se emite una nota de crédito contra la factura de anticipo, por la diferencia.
  • Si la operación se cancela por completo: se emite una nota de crédito que anula el anticipo en su totalidad.

La construcción del request de nota de crédito para estos casos no se documenta aquí — usa el endpoint dedicado a notas electrónicas (createadjustmentnote) y su propio conjunto de reglas, que conviene validar por separado antes de implementarlo.

5. Qué NO hacer — resumen

No hacerPor qué
Usar profileId "0401", "0501" o "0601" para anticipos"0501"/"0601" no existen en el catálogo (rechazo inmediato). "0401" sí existe pero significa "ventas a no domiciliados que no califican como exportación" — pasa la validación de schema pero clasifica mal la operación ante SUNAT.
Enviar adjustment con reasonCode "04", "05" o "06" en la factura finalEsos códigos no están en el enum vigente de adjustment.reasonCode. El motor los genera automáticamente desde prepaidPayments[].taxAffectation.
Restar la base del anticipo directamente de totals.baseAmount o totals.grossAmountAmbos campos deben reflejar el valor íntegro de los ítems de la factura. Solo igvTotal y totalAmount se reducen por el anticipo.
Emitir una factura final con totalAmount = 0.00 cuando el anticipo cubrió el 100%SUNAT rechaza PayableAmount = 0 (ERROR 2062). Usar nota de crédito o no emitir factura adicional, según corresponda.
Usar los nombres documentSeries / documentNumber dentro de prepaidPayments[]Los campos correctos son series y number.

6. Referencia — errores relacionados con anticipos

CódigoDescripción
2062El dato ingresado en PayableAmount no cumple con el formato establecido — se dispara si totalAmount llega en 0.00.
2503paidAmount ≤ 0.
3220Existe paidAmount > 0 y no hay totals.prepaidAmount > 0.
2505documentType distinto de "02"/"03".
2521El formato de series no corresponde al documentType.
3278totals.baseAmount no coincide con la fórmula esperada.